1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.archetype.creator;
20
21 import javax.inject.Inject;
22 import javax.inject.Named;
23 import javax.inject.Singleton;
24
25 import java.io.BufferedInputStream;
26 import java.io.File;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.OutputStream;
30 import java.io.Reader;
31 import java.io.Writer;
32 import java.nio.file.Files;
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.Collections;
36 import java.util.HashMap;
37 import java.util.HashSet;
38 import java.util.Iterator;
39 import java.util.List;
40 import java.util.Locale;
41 import java.util.Map;
42 import java.util.Properties;
43 import java.util.Set;
44
45 import com.ibm.icu.text.CharsetDetector;
46 import com.ibm.icu.text.CharsetMatch;
47 import org.apache.commons.collections.CollectionUtils;
48 import org.apache.maven.archetype.ArchetypeCreationRequest;
49 import org.apache.maven.archetype.ArchetypeCreationResult;
50 import org.apache.maven.archetype.common.ArchetypeFilesResolver;
51 import org.apache.maven.archetype.common.Constants;
52 import org.apache.maven.archetype.common.PomManager;
53 import org.apache.maven.archetype.common.util.ListScanner;
54 import org.apache.maven.archetype.common.util.PathUtils;
55 import org.apache.maven.archetype.metadata.ArchetypeDescriptor;
56 import org.apache.maven.archetype.metadata.FileSet;
57 import org.apache.maven.archetype.metadata.ModuleDescriptor;
58 import org.apache.maven.archetype.metadata.RequiredProperty;
59 import org.apache.maven.archetype.metadata.io.xpp3.ArchetypeDescriptorXpp3Writer;
60 import org.apache.maven.model.Build;
61 import org.apache.maven.model.Dependency;
62 import org.apache.maven.model.Extension;
63 import org.apache.maven.model.Model;
64 import org.apache.maven.model.Plugin;
65 import org.apache.maven.model.Profile;
66 import org.apache.maven.model.Resource;
67 import org.apache.maven.project.MavenProject;
68 import org.apache.maven.shared.invoker.DefaultInvocationRequest;
69 import org.apache.maven.shared.invoker.InvocationRequest;
70 import org.apache.maven.shared.invoker.InvocationResult;
71 import org.apache.maven.shared.invoker.Invoker;
72 import org.codehaus.plexus.util.DirectoryScanner;
73 import org.codehaus.plexus.util.FileUtils;
74 import org.codehaus.plexus.util.IOUtil;
75 import org.codehaus.plexus.util.StringUtils;
76 import org.codehaus.plexus.util.xml.XmlStreamReader;
77 import org.codehaus.plexus.util.xml.XmlStreamWriter;
78 import org.codehaus.plexus.util.xml.Xpp3Dom;
79 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
80 import org.slf4j.Logger;
81 import org.slf4j.LoggerFactory;
82
83 import static org.apache.commons.io.IOUtils.write;
84
85
86
87
88
89 @Named("fileset")
90 @Singleton
91 public class FilesetArchetypeCreator implements ArchetypeCreator {
92 private static final Logger LOGGER = LoggerFactory.getLogger(FilesetArchetypeCreator.class);
93 private static final String DEFAULT_OUTPUT_DIRECTORY =
94 "target" + File.separator + "generated-sources" + File.separator + "archetype";
95
96 private ArchetypeFilesResolver archetypeFilesResolver;
97
98 private PomManager pomManager;
99
100 private Invoker invoker;
101
102 @Inject
103 public FilesetArchetypeCreator(
104 ArchetypeFilesResolver archetypeFilesResolver, PomManager pomManager, Invoker invoker) {
105 this.archetypeFilesResolver = archetypeFilesResolver;
106 this.pomManager = pomManager;
107 this.invoker = invoker;
108 }
109
110 @Override
111 @SuppressWarnings("checkstyle:MethodLength")
112 public void createArchetype(ArchetypeCreationRequest request, ArchetypeCreationResult result) {
113 MavenProject project = request.getProject();
114 List<String> languages = request.getLanguages();
115 List<String> filtereds = request.getFiltereds();
116 String defaultEncoding = request.getDefaultEncoding();
117 boolean preserveCData = request.isPreserveCData();
118 boolean keepParent = request.isKeepParent();
119 boolean partialArchetype = request.isPartialArchetype();
120 File outputDirectory = request.getOutputDirectory();
121 File basedir = project.getBasedir();
122
123 Properties properties = new Properties();
124 Properties configurationProperties = new Properties();
125 if (request.getProperties() != null) {
126 properties.putAll(request.getProperties());
127 configurationProperties.putAll(request.getProperties());
128 }
129
130 extractPropertiesFromProject(project, properties, configurationProperties, request.getPackageName());
131
132 if (outputDirectory == null) {
133 LOGGER.debug("No output directory defined, using default: " + DEFAULT_OUTPUT_DIRECTORY);
134 outputDirectory = FileUtils.resolveFile(basedir, DEFAULT_OUTPUT_DIRECTORY);
135 }
136 outputDirectory.mkdirs();
137
138 LOGGER.debug("Creating archetype in " + outputDirectory);
139
140 try {
141 File archetypePomFile = createArchetypeProjectPom(project, configurationProperties, outputDirectory);
142
143 File archetypeResourcesDirectory = new File(outputDirectory, getTemplateOutputDirectory());
144
145 File archetypeFilesDirectory = new File(archetypeResourcesDirectory, Constants.ARCHETYPE_RESOURCES);
146 LOGGER.debug("Archetype's files output directory " + archetypeFilesDirectory);
147
148 File archetypeDescriptorFile = new File(archetypeResourcesDirectory, Constants.ARCHETYPE_DESCRIPTOR);
149 archetypeDescriptorFile.getParentFile().mkdirs();
150
151 File archetypePostGenerationScript =
152 new File(archetypeResourcesDirectory, Constants.ARCHETYPE_POST_GENERATION_SCRIPT);
153 archetypePostGenerationScript.getParentFile().mkdirs();
154
155 if (request.getProject().getBuild() != null
156 && CollectionUtils.isNotEmpty(
157 request.getProject().getBuild().getResources())) {
158 for (Resource resource : request.getProject().getBuild().getResources()) {
159 File inputFile = new File(
160 resource.getDirectory() + File.separator + Constants.ARCHETYPE_POST_GENERATION_SCRIPT);
161 if (inputFile.exists()) {
162 FileUtils.copyFile(inputFile, archetypePostGenerationScript);
163 }
164 }
165 }
166
167 LOGGER.debug("Starting archetype's descriptor " + project.getArtifactId());
168 ArchetypeDescriptor archetypeDescriptor = new ArchetypeDescriptor();
169
170 archetypeDescriptor.setName(project.getArtifactId());
171 archetypeDescriptor.setPartial(partialArchetype);
172
173 addRequiredProperties(archetypeDescriptor, properties);
174
175
176 Properties reverseProperties = getReversedProperties(archetypeDescriptor, properties);
177
178
179
180 Properties pomReversedProperties = getReversedProperties(archetypeDescriptor, properties);
181
182
183 String packageName = configurationProperties.getProperty(Constants.PACKAGE);
184
185 Model pom = pomManager.readPom(project.getFile());
186
187 List<String> excludePatterns = configurationProperties.getProperty(Constants.EXCLUDE_PATTERNS) != null
188 ? Arrays.asList(configurationProperties
189 .getProperty(Constants.EXCLUDE_PATTERNS)
190 .split(","))
191 : Collections.emptyList();
192
193 List<String> fileNames = resolveFileNames(pom, basedir, excludePatterns);
194 if (LOGGER.isDebugEnabled()) {
195 LOGGER.debug("Scanned for files " + fileNames.size());
196
197 for (String name : fileNames) {
198 LOGGER.debug("- " + name);
199 }
200 }
201
202 List<FileSet> filesets = resolveFileSets(packageName, fileNames, languages, filtereds, defaultEncoding);
203 LOGGER.debug("Resolved filesets for " + archetypeDescriptor.getName());
204
205 archetypeDescriptor.setFileSets(filesets);
206
207 createArchetypeFiles(
208 reverseProperties,
209 filesets,
210 packageName,
211 basedir,
212 archetypeFilesDirectory,
213 defaultEncoding,
214 excludePatterns);
215 LOGGER.debug("Created files for " + archetypeDescriptor.getName());
216
217 setParentArtifactId(reverseProperties, configurationProperties.getProperty(Constants.ARTIFACT_ID));
218
219 for (String moduleId : pom.getModules()) {
220 String rootArtifactId = configurationProperties.getProperty(Constants.ARTIFACT_ID);
221 String moduleIdDirectory = moduleId;
222
223 if (moduleId.indexOf(rootArtifactId) >= 0) {
224 moduleIdDirectory = StringUtils.replace(moduleId, rootArtifactId, "__rootArtifactId__");
225 }
226
227 LOGGER.debug("Creating module " + moduleId);
228
229 ModuleDescriptor moduleDescriptor = createModule(
230 reverseProperties,
231 rootArtifactId,
232 moduleId,
233 packageName,
234 FileUtils.resolveFile(basedir, moduleId),
235 new File(archetypeFilesDirectory, moduleIdDirectory),
236 languages,
237 filtereds,
238 defaultEncoding,
239 preserveCData,
240 keepParent);
241
242 archetypeDescriptor.addModule(moduleDescriptor);
243
244 LOGGER.debug("Added module " + moduleDescriptor.getName() + " in " + archetypeDescriptor.getName());
245 }
246
247 restoreParentArtifactId(reverseProperties, null);
248 restoreArtifactId(reverseProperties, configurationProperties.getProperty(Constants.ARTIFACT_ID));
249
250 createPoms(
251 pom,
252 configurationProperties.getProperty(Constants.ARTIFACT_ID),
253 configurationProperties.getProperty(Constants.ARTIFACT_ID),
254 archetypeFilesDirectory,
255 basedir,
256 project.getFile(),
257 pomReversedProperties,
258 preserveCData,
259 keepParent);
260 LOGGER.debug("Created Archetype " + archetypeDescriptor.getName() + " template pom(s)");
261
262 try (Writer out = new XmlStreamWriter(archetypeDescriptorFile)) {
263 ArchetypeDescriptorXpp3Writer writer = new ArchetypeDescriptorXpp3Writer();
264
265 writer.write(out, archetypeDescriptor);
266
267 LOGGER.debug("Archetype " + archetypeDescriptor.getName() + " descriptor written");
268 }
269
270 createArchetypeBasicIt(archetypeDescriptor, outputDirectory);
271
272
273 File archetypeIntegrationTestInputFolder =
274 new File(basedir, Constants.SRC + File.separator + "it" + File.separator + "projects");
275 File archetypeIntegrationTestOutputFolder = new File(
276 outputDirectory,
277 Constants.SRC + File.separator + Constants.TEST
278 + File.separator + Constants.RESOURCES
279 + File.separator + "projects");
280
281 if (archetypeIntegrationTestInputFolder.exists()) {
282 LOGGER.info("Copying: " + archetypeIntegrationTestInputFolder.getAbsolutePath() + " into "
283 + archetypeIntegrationTestOutputFolder.getAbsolutePath());
284
285 FileUtils.copyDirectoryStructure(
286 archetypeIntegrationTestInputFolder, archetypeIntegrationTestOutputFolder);
287 }
288 InvocationRequest internalRequest = new DefaultInvocationRequest();
289 internalRequest.setPomFile(archetypePomFile);
290 internalRequest.setUserSettingsFile(request.getSettingsFile());
291 internalRequest.addArg(request.getPostPhase());
292 internalRequest.setLocalRepositoryDirectory(request.getLocalRepositoryBasedir());
293
294 String httpsProtocols = System.getProperty("https.protocols");
295 if (httpsProtocols != null) {
296 Properties userProperties = new Properties();
297 userProperties.setProperty("https.protocols", httpsProtocols);
298 internalRequest.setProperties(userProperties);
299 }
300
301 InvocationResult invokerResult = invoker.execute(internalRequest);
302 if (invokerResult.getExitCode() != 0) {
303 if (invokerResult.getExecutionException() != null) {
304 throw invokerResult.getExecutionException();
305 } else {
306 throw new Exception("Invoker process ended with result different than 0!");
307 }
308 }
309
310 } catch (Exception e) {
311 result.setCause(e);
312 }
313 }
314
315
316
317
318
319
320
321
322
323 private void createArchetypeBasicIt(ArchetypeDescriptor archetypeDescriptor, File generatedSourcesDirectory)
324 throws IOException {
325 String basic = Constants.SRC + File.separator + Constants.TEST + File.separator + Constants.RESOURCES
326 + File.separator + "projects" + File.separator + "basic";
327 File basicItDirectory = new File(generatedSourcesDirectory, basic);
328 basicItDirectory.mkdirs();
329
330 File archetypePropertiesFile = new File(basicItDirectory, "archetype.properties");
331 if (!archetypePropertiesFile.exists() && !archetypePropertiesFile.createNewFile()) {
332 LOGGER.warn("Could not create new file \"" + archetypePropertiesFile.getPath()
333 + "\" or the file already exists.");
334 }
335
336 try (InputStream in = FilesetArchetypeCreator.class.getResourceAsStream("archetype.properties");
337 OutputStream out = Files.newOutputStream(archetypePropertiesFile.toPath())) {
338 Properties archetypeProperties = new Properties();
339 archetypeProperties.load(in);
340
341 for (RequiredProperty req : archetypeDescriptor.getRequiredProperties()) {
342 archetypeProperties.put(req.getKey(), req.getDefaultValue());
343 }
344
345 archetypeProperties.store(out, null);
346 }
347
348 copyResource("goal.txt", new File(basicItDirectory, "goal.txt"));
349
350 LOGGER.debug("Added basic integration test");
351 }
352
353 private void extractPropertiesFromProject(
354 MavenProject project, Properties properties, Properties configurationProperties, String packageName) {
355 if (!properties.containsKey(Constants.GROUP_ID)) {
356 properties.setProperty(Constants.GROUP_ID, project.getGroupId());
357 }
358 configurationProperties.setProperty(Constants.GROUP_ID, properties.getProperty(Constants.GROUP_ID));
359
360 if (!properties.containsKey(Constants.ARTIFACT_ID)) {
361 properties.setProperty(Constants.ARTIFACT_ID, project.getArtifactId());
362 }
363 configurationProperties.setProperty(Constants.ARTIFACT_ID, properties.getProperty(Constants.ARTIFACT_ID));
364
365 if (!properties.containsKey(Constants.VERSION)) {
366 properties.setProperty(Constants.VERSION, project.getVersion());
367 }
368 configurationProperties.setProperty(Constants.VERSION, properties.getProperty(Constants.VERSION));
369
370 if (packageName != null) {
371 properties.setProperty(Constants.PACKAGE, packageName);
372 } else if (!properties.containsKey(Constants.PACKAGE)) {
373 properties.setProperty(Constants.PACKAGE, project.getGroupId());
374 }
375 configurationProperties.setProperty(Constants.PACKAGE, properties.getProperty(Constants.PACKAGE));
376 }
377
378
379
380
381 private File createArchetypeProjectPom(MavenProject project, Properties configurationProperties, File projectDir)
382 throws IOException {
383 Model model = new Model();
384 model.setModelVersion("4.0.0");
385
386 model.setGroupId(configurationProperties.getProperty(Constants.ARCHETYPE_GROUP_ID, project.getGroupId()));
387 model.setArtifactId(
388 configurationProperties.getProperty(Constants.ARCHETYPE_ARTIFACT_ID, project.getArtifactId()));
389 model.setVersion(configurationProperties.getProperty(Constants.ARCHETYPE_VERSION, project.getVersion()));
390 model.setPackaging("maven-archetype");
391 model.setName(configurationProperties.getProperty(Constants.ARCHETYPE_ARTIFACT_ID, project.getArtifactId()));
392 model.setUrl(configurationProperties.getProperty(Constants.ARCHETYPE_URL, project.getUrl()));
393 model.setDescription(
394 configurationProperties.getProperty(Constants.ARCHETYPE_DESCRIPTION, project.getDescription()));
395 model.setLicenses(project.getLicenses());
396 model.setDevelopers(project.getDevelopers());
397 model.setScm(project.getScm());
398 Build build = new Build();
399 model.setBuild(build);
400
401
402
403
404
405
406
407
408
409 if (project.getParent() != null) {
410 MavenProject p = project.getParent();
411
412 if (p.getDistributionManagement() != null) {
413 model.setDistributionManagement(p.getDistributionManagement());
414 }
415
416 if (p.getBuildExtensions() != null) {
417 for (Extension be : p.getBuildExtensions()) {
418 model.getBuild().addExtension(be);
419 }
420 }
421 }
422
423 Extension extension = new Extension();
424 extension.setGroupId("org.apache.maven.archetype");
425 extension.setArtifactId("archetype-packaging");
426 extension.setVersion(getArchetypeVersion());
427 model.getBuild().addExtension(extension);
428
429 LOGGER.debug("Creating archetype's pom");
430
431 File archetypePomFile = new File(projectDir, Constants.ARCHETYPE_POM);
432
433 archetypePomFile.getParentFile().mkdirs();
434
435 copyResource("pom-prototype.xml", archetypePomFile);
436
437 pomManager.writePom(model, archetypePomFile, archetypePomFile);
438
439 return archetypePomFile;
440 }
441
442 private void copyResource(String name, File destination) throws IOException {
443 if (!destination.exists() && !destination.createNewFile()) {
444 LOGGER.warn("Could not create new file \"" + destination.getPath() + "\" or the file already exists.");
445 }
446
447 try (InputStream in = FilesetArchetypeCreator.class.getResourceAsStream(name);
448 OutputStream out = Files.newOutputStream(destination.toPath())) {
449 IOUtil.copy(in, out);
450 }
451 }
452
453 private void addRequiredProperties(ArchetypeDescriptor archetypeDescriptor, Properties properties) {
454 Properties requiredProperties = new Properties();
455 requiredProperties.putAll(properties);
456 requiredProperties.remove(Constants.ARCHETYPE_GROUP_ID);
457 requiredProperties.remove(Constants.ARCHETYPE_ARTIFACT_ID);
458 requiredProperties.remove(Constants.ARCHETYPE_VERSION);
459 requiredProperties.remove(Constants.GROUP_ID);
460 requiredProperties.remove(Constants.ARTIFACT_ID);
461 requiredProperties.remove(Constants.VERSION);
462 requiredProperties.remove(Constants.PACKAGE);
463 requiredProperties.remove(Constants.EXCLUDE_PATTERNS);
464
465 for (Iterator<?> propertiesIterator = requiredProperties.keySet().iterator(); propertiesIterator.hasNext(); ) {
466 String propertyKey = (String) propertiesIterator.next();
467
468 RequiredProperty requiredProperty = new RequiredProperty();
469 requiredProperty.setKey(propertyKey);
470 requiredProperty.setDefaultValue(requiredProperties.getProperty(propertyKey));
471
472 archetypeDescriptor.addRequiredProperty(requiredProperty);
473
474 LOGGER.debug("Adding requiredProperty " + propertyKey + "=" + requiredProperties.getProperty(propertyKey)
475 + " to archetype's descriptor");
476 }
477 }
478
479 private void createModulePoms(
480 Properties pomReversedProperties,
481 String rootArtifactId,
482 String packageName,
483 File basedir,
484 File archetypeFilesDirectory,
485 boolean preserveCData,
486 boolean keepParent)
487 throws IOException, XmlPullParserException {
488 Model pom = pomManager.readPom(FileUtils.resolveFile(basedir, Constants.ARCHETYPE_POM));
489
490 String parentArtifactId = pomReversedProperties.getProperty(Constants.PARENT_ARTIFACT_ID);
491 String artifactId = pom.getArtifactId();
492 setParentArtifactId(pomReversedProperties, pomReversedProperties.getProperty(Constants.ARTIFACT_ID));
493 setArtifactId(pomReversedProperties, pom.getArtifactId());
494
495 for (String subModuleId : pom.getModules()) {
496 String subModuleIdDirectory = subModuleId;
497
498 if (subModuleId.indexOf(rootArtifactId) >= 0) {
499 subModuleIdDirectory = StringUtils.replace(subModuleId, rootArtifactId, "__rootArtifactId__");
500 }
501
502 createModulePoms(
503 pomReversedProperties,
504 rootArtifactId,
505 packageName,
506 FileUtils.resolveFile(basedir, subModuleId),
507 FileUtils.resolveFile(archetypeFilesDirectory, subModuleIdDirectory),
508 preserveCData,
509 keepParent);
510 }
511
512 createModulePom(
513 pom,
514 rootArtifactId,
515 archetypeFilesDirectory,
516 pomReversedProperties,
517 FileUtils.resolveFile(basedir, Constants.ARCHETYPE_POM),
518 preserveCData,
519 keepParent);
520
521 restoreParentArtifactId(pomReversedProperties, parentArtifactId);
522 restoreArtifactId(pomReversedProperties, artifactId);
523 }
524
525 @SuppressWarnings("checkstyle:ParameterNumber")
526 private void createPoms(
527 Model pom,
528 String rootArtifactId,
529 String artifactId,
530 File archetypeFilesDirectory,
531 File basedir,
532 File rootPom,
533 Properties pomReversedProperties,
534 boolean preserveCData,
535 boolean keepParent)
536 throws IOException, XmlPullParserException {
537 setArtifactId(pomReversedProperties, pom.getArtifactId());
538
539 for (String moduleId : pom.getModules()) {
540 String moduleIdDirectory = moduleId;
541
542 if (moduleId.indexOf(rootArtifactId) >= 0) {
543 moduleIdDirectory = StringUtils.replace(moduleId, rootArtifactId, "__rootArtifactId__");
544 }
545
546 createModulePoms(
547 pomReversedProperties,
548 rootArtifactId,
549 moduleId,
550 FileUtils.resolveFile(basedir, moduleId),
551 new File(archetypeFilesDirectory, moduleIdDirectory),
552 preserveCData,
553 keepParent);
554 }
555
556 restoreParentArtifactId(pomReversedProperties, null);
557 restoreArtifactId(pomReversedProperties, artifactId);
558
559 createArchetypePom(pom, archetypeFilesDirectory, pomReversedProperties, rootPom, preserveCData, keepParent);
560 }
561
562 private String getPackageInPathFormat(String aPackage) {
563 return StringUtils.replace(aPackage, ".", "/");
564 }
565
566 private void rewriteReferences(Model pom, String rootArtifactId, String groupId) {
567
568 if (pom.getDependencies() != null && !pom.getDependencies().isEmpty()) {
569 for (Dependency dependency : pom.getDependencies()) {
570 rewriteDependencyReferences(dependency, rootArtifactId, groupId);
571 }
572 }
573
574
575 if (pom.getDependencyManagement() != null
576 && pom.getDependencyManagement().getDependencies() != null
577 && !pom.getDependencyManagement().getDependencies().isEmpty()) {
578 for (Dependency dependency : pom.getDependencyManagement().getDependencies()) {
579 rewriteDependencyReferences(dependency, rootArtifactId, groupId);
580 }
581 }
582
583
584 if (pom.getBuild() != null
585 && pom.getBuild().getPlugins() != null
586 && !pom.getBuild().getPlugins().isEmpty()) {
587 for (Plugin plugin : pom.getBuild().getPlugins()) {
588 rewritePluginReferences(plugin, rootArtifactId, groupId);
589 }
590 }
591
592
593 if (pom.getBuild() != null
594 && pom.getBuild().getPluginManagement() != null
595 && pom.getBuild().getPluginManagement().getPlugins() != null
596 && !pom.getBuild().getPluginManagement().getPlugins().isEmpty()) {
597 for (Plugin plugin : pom.getBuild().getPluginManagement().getPlugins()) {
598 rewritePluginReferences(plugin, rootArtifactId, groupId);
599 }
600 }
601
602
603 if (pom.getProfiles() != null) {
604 for (Profile profile : pom.getProfiles()) {
605
606 if (profile.getDependencies() != null
607 && !profile.getDependencies().isEmpty()) {
608 for (Dependency dependency : profile.getDependencies()) {
609 rewriteDependencyReferences(dependency, rootArtifactId, groupId);
610 }
611 }
612
613
614 if (profile.getDependencyManagement() != null
615 && profile.getDependencyManagement().getDependencies() != null
616 && !profile.getDependencyManagement().getDependencies().isEmpty()) {
617 for (Dependency dependency :
618 profile.getDependencyManagement().getDependencies()) {
619 rewriteDependencyReferences(dependency, rootArtifactId, groupId);
620 }
621 }
622
623
624 if (profile.getBuild() != null
625 && profile.getBuild().getPlugins() != null
626 && !profile.getBuild().getPlugins().isEmpty()) {
627 for (Plugin plugin : profile.getBuild().getPlugins()) {
628 rewritePluginReferences(plugin, rootArtifactId, groupId);
629 }
630 }
631
632
633 if (profile.getBuild() != null
634 && profile.getBuild().getPluginManagement() != null
635 && profile.getBuild().getPluginManagement().getPlugins() != null
636 && !profile.getBuild()
637 .getPluginManagement()
638 .getPlugins()
639 .isEmpty()) {
640 for (Plugin plugin :
641 profile.getBuild().getPluginManagement().getPlugins()) {
642 rewritePluginReferences(plugin, rootArtifactId, groupId);
643 }
644 }
645 }
646 }
647 }
648
649 private void rewriteDependencyReferences(Dependency dependency, String rootArtifactId, String groupId) {
650 if (dependency.getArtifactId() != null && dependency.getArtifactId().indexOf(rootArtifactId) >= 0) {
651 if (dependency.getGroupId() != null) {
652 dependency.setGroupId(
653 StringUtils.replace(dependency.getGroupId(), groupId, "${" + Constants.GROUP_ID + "}"));
654 }
655
656 dependency.setArtifactId(
657 StringUtils.replace(dependency.getArtifactId(), rootArtifactId, "${rootArtifactId}"));
658
659 if (dependency.getVersion() != null) {
660 dependency.setVersion("${" + Constants.VERSION + "}");
661 }
662 }
663 }
664
665 private void rewritePluginReferences(Plugin plugin, String rootArtifactId, String groupId) {
666 if (plugin.getArtifactId() != null && plugin.getArtifactId().indexOf(rootArtifactId) >= 0) {
667 if (plugin.getGroupId() != null) {
668 String g = StringUtils.replace(plugin.getGroupId(), groupId, "${" + Constants.GROUP_ID + "}");
669 plugin.setGroupId(g);
670 }
671
672 plugin.setArtifactId(StringUtils.replace(plugin.getArtifactId(), rootArtifactId, "${rootArtifactId}"));
673
674 if (plugin.getVersion() != null) {
675 plugin.setVersion("${" + Constants.VERSION + "}");
676 }
677 }
678
679 if (plugin.getArtifactId() != null && "maven-ear-plugin".equals(plugin.getArtifactId())) {
680 rewriteEARPluginReferences(plugin, rootArtifactId, groupId);
681 }
682 }
683
684 private void rewriteEARPluginReferences(Plugin plugin, String rootArtifactId, String groupId) {
685 Xpp3Dom configuration = (Xpp3Dom) plugin.getConfiguration();
686 if (configuration != null) {
687 Xpp3Dom modulesConfiguration = configuration.getChild("modules");
688 Xpp3Dom[] modules = modulesConfiguration != null ? modulesConfiguration.getChildren() : new Xpp3Dom[0];
689 for (int i = 0; i < modules.length; i++) {
690 Xpp3Dom module = modules[i];
691 Xpp3Dom moduleGroupId = module.getChild("groupId");
692 Xpp3Dom moduleArtifactId = module.getChild("artifactId");
693 Xpp3Dom moduleBundleFileName = module.getChild("bundleFileName");
694 Xpp3Dom moduleModuleId = module.getChild("moduleId");
695 Xpp3Dom moduleContextRoot = module.getChild("contextRoot");
696
697 if (moduleGroupId != null) {
698 moduleGroupId.setValue(
699 StringUtils.replace(moduleGroupId.getValue(), groupId, "${" + Constants.GROUP_ID + "}"));
700 }
701
702 if (moduleArtifactId != null) {
703 moduleArtifactId.setValue(
704 StringUtils.replace(moduleArtifactId.getValue(), rootArtifactId, "${rootArtifactId}"));
705 }
706
707 if (moduleBundleFileName != null) {
708 moduleBundleFileName.setValue(
709 StringUtils.replace(moduleBundleFileName.getValue(), rootArtifactId, "${rootArtifactId}"));
710 }
711
712 if (moduleModuleId != null) {
713 moduleModuleId.setValue(
714 StringUtils.replace(moduleModuleId.getValue(), rootArtifactId, "${rootArtifactId}"));
715 }
716
717 if (moduleContextRoot != null) {
718 moduleContextRoot.setValue(
719 StringUtils.replace(moduleContextRoot.getValue(), rootArtifactId, "${rootArtifactId}"));
720 }
721 }
722 }
723 }
724
725 private void setArtifactId(Properties properties, String artifactId) {
726 properties.setProperty(Constants.ARTIFACT_ID, artifactId);
727 }
728
729 private List<String> concatenateToList(List<String> toConcatenate, String with) {
730 List<String> result = new ArrayList<>(toConcatenate.size());
731
732 for (String concatenate : toConcatenate) {
733 result.add(((!with.isEmpty()) ? (with + "/" + concatenate) : concatenate));
734 }
735
736 return result;
737 }
738
739 private List<String> addLists(List<String> list, List<String> other) {
740 List<String> result = new ArrayList<>(list.size() + other.size());
741 result.addAll(list);
742 result.addAll(other);
743 return result;
744 }
745
746 private void copyFiles(
747 File basedir,
748 File archetypeFilesDirectory,
749 String directory,
750 List<String> fileSetResources,
751 boolean packaged,
752 String packageName,
753 Properties reverseProperties)
754 throws IOException {
755 String packageAsDirectory = StringUtils.replace(packageName, ".", File.separator);
756
757 LOGGER.debug("Package as Directory: Package:" + packageName + "->" + packageAsDirectory);
758
759 for (String inputFileName : fileSetResources) {
760 String outputFileName = packaged
761 ? StringUtils.replace(inputFileName, packageAsDirectory + File.separator, "")
762 : inputFileName;
763 LOGGER.debug("InputFileName:" + inputFileName);
764 LOGGER.debug("OutputFileName:" + outputFileName);
765
766 reverseProperties.remove("archetype.languages");
767
768 String reversedOutputFilename = getReversedFilename(outputFileName, reverseProperties);
769
770 File outputFile = new File(archetypeFilesDirectory, reversedOutputFilename);
771
772 File inputFile = new File(basedir, inputFileName);
773
774 outputFile.getParentFile().mkdirs();
775
776 FileUtils.copyFile(inputFile, outputFile);
777 }
778 }
779
780 private void createArchetypeFiles(
781 Properties reverseProperties,
782 List<FileSet> fileSets,
783 String packageName,
784 File basedir,
785 File archetypeFilesDirectory,
786 String defaultEncoding,
787 List<String> excludePatterns)
788 throws IOException {
789 LOGGER.debug("Creating Archetype/Module files from " + basedir + " to " + archetypeFilesDirectory);
790
791 for (FileSet fileSet : fileSets) {
792 DirectoryScanner scanner = new DirectoryScanner();
793 scanner.setBasedir(basedir);
794 scanner.setIncludes(concatenateToList(fileSet.getIncludes(), fileSet.getDirectory())
795 .toArray(new String[fileSet.getIncludes().size()]));
796 scanner.setExcludes(addLists(fileSet.getExcludes(), excludePatterns)
797 .toArray(new String[fileSet.getExcludes().size()]));
798 scanner.addDefaultExcludes();
799 LOGGER.debug("Using fileset " + fileSet);
800 scanner.scan();
801
802 List<String> fileSetResources = Arrays.asList(scanner.getIncludedFiles());
803 LOGGER.debug("Scanned " + fileSetResources.size() + " resources");
804
805 if (fileSet.isFiltered()) {
806 processFileSet(
807 basedir,
808 archetypeFilesDirectory,
809 fileSet.getDirectory(),
810 fileSetResources,
811 fileSet.isPackaged(),
812 packageName,
813 reverseProperties,
814 defaultEncoding);
815 LOGGER.debug("Processed " + fileSet.getDirectory() + " files");
816 } else {
817 copyFiles(
818 basedir,
819 archetypeFilesDirectory,
820 fileSet.getDirectory(),
821 fileSetResources,
822 fileSet.isPackaged(),
823 packageName,
824 reverseProperties);
825 LOGGER.debug("Copied " + fileSet.getDirectory() + " files");
826 }
827 }
828 }
829
830 private void createArchetypePom(
831 Model pom,
832 File archetypeFilesDirectory,
833 Properties pomReversedProperties,
834 File initialPomFile,
835 boolean preserveCData,
836 boolean keepParent)
837 throws IOException {
838 File outputFile = FileUtils.resolveFile(archetypeFilesDirectory, Constants.ARCHETYPE_POM);
839
840 if (preserveCData) {
841 LOGGER.debug("Preserving CDATA parts of pom");
842 File inputFile = FileUtils.resolveFile(archetypeFilesDirectory, Constants.ARCHETYPE_POM + ".tmp");
843
844 FileUtils.copyFile(initialPomFile, inputFile);
845
846 outputFile.getParentFile().mkdirs();
847
848 try (Reader in = new XmlStreamReader(inputFile);
849 Writer out = new XmlStreamWriter(outputFile)) {
850 String initialcontent = IOUtil.toString(in);
851
852 String content = getReversedContent(initialcontent, pomReversedProperties);
853
854 IOUtil.copy(content, out);
855 }
856
857 inputFile.delete();
858 } else {
859 if (!keepParent) {
860 pom.setParent(null);
861 }
862
863 pom.setModules(null);
864 pom.setGroupId("${" + Constants.GROUP_ID + "}");
865 pom.setArtifactId("${" + Constants.ARTIFACT_ID + "}");
866 pom.setVersion("${" + Constants.VERSION + "}");
867 pom.setName(getReversedPlainContent(pom.getName(), pomReversedProperties));
868 pom.setDescription(getReversedPlainContent(pom.getDescription(), pomReversedProperties));
869 pom.setUrl(getReversedPlainContent(pom.getUrl(), pomReversedProperties));
870
871 rewriteReferences(
872 pom,
873 pomReversedProperties.getProperty(Constants.ARTIFACT_ID),
874 pomReversedProperties.getProperty(Constants.GROUP_ID));
875
876 pomManager.writePom(pom, outputFile, initialPomFile);
877 }
878
879 try (Reader in = new XmlStreamReader(initialPomFile)) {
880 String initialcontent = IOUtil.toString(in);
881
882 Iterator<?> properties = pomReversedProperties.keySet().iterator();
883 while (properties.hasNext()) {
884 String property = (String) properties.next();
885
886 if (initialcontent.indexOf("${" + property + "}") > 0) {
887 LOGGER.warn("Archetype uses ${" + property + "} for internal processing, but file " + initialPomFile
888 + " contains this property already");
889 }
890 }
891 }
892 }
893
894 private FileSet createFileSet(
895 final List<String> excludes,
896 final boolean packaged,
897 final boolean filtered,
898 final String group,
899 final List<String> includes,
900 String defaultEncoding) {
901 FileSet fileSet = new FileSet();
902
903 fileSet.setDirectory(group);
904 fileSet.setPackaged(packaged);
905 fileSet.setFiltered(filtered);
906 fileSet.setIncludes(includes);
907 fileSet.setExcludes(excludes);
908 fileSet.setEncoding(defaultEncoding);
909
910 LOGGER.debug("Created Fileset " + fileSet);
911
912 return fileSet;
913 }
914
915 private List<FileSet> createFileSets(
916 List<String> files,
917 int level,
918 boolean packaged,
919 String packageName,
920 boolean filtered,
921 String defaultEncoding) {
922 List<FileSet> fileSets = new ArrayList<>();
923
924 if (!files.isEmpty()) {
925 LOGGER.debug("Creating filesets" + (packaged ? (" packaged (" + packageName + ")") : "")
926 + (filtered ? " filtered" : "") + " at level " + level);
927 if (level == 0) {
928 List<String> includes = new ArrayList<>(files);
929 List<String> excludes = new ArrayList<>();
930
931 if (!includes.isEmpty()) {
932 fileSets.add(createFileSet(excludes, packaged, filtered, "", includes, defaultEncoding));
933 }
934 } else {
935 Map<String, List<String>> groups = getGroupsMap(files, level);
936
937 for (String group : groups.keySet()) {
938 LOGGER.debug("Creating filesets for group " + group);
939
940 if (!packaged) {
941 fileSets.add(getUnpackagedFileSet(filtered, group, groups.get(group), defaultEncoding));
942 } else {
943 fileSets.addAll(
944 getPackagedFileSets(filtered, group, groups.get(group), packageName, defaultEncoding));
945 }
946 }
947 }
948
949 LOGGER.debug("Resolved fileSets " + fileSets);
950 }
951
952 return fileSets;
953 }
954
955 @SuppressWarnings("checkstyle:ParameterNumber")
956 private ModuleDescriptor createModule(
957 Properties reverseProperties,
958 String rootArtifactId,
959 String moduleId,
960 String packageName,
961 File basedir,
962 File archetypeFilesDirectory,
963 List<String> languages,
964 List<String> filtereds,
965 String defaultEncoding,
966 boolean preserveCData,
967 boolean keepParent)
968 throws IOException, XmlPullParserException {
969 ModuleDescriptor archetypeDescriptor = new ModuleDescriptor();
970 LOGGER.debug("Starting module's descriptor " + moduleId);
971
972 archetypeFilesDirectory.mkdirs();
973 LOGGER.debug("Module's files output directory " + archetypeFilesDirectory);
974
975 Model pom = pomManager.readPom(FileUtils.resolveFile(basedir, Constants.ARCHETYPE_POM));
976 String replacementId = pom.getArtifactId();
977 String moduleDirectory = pom.getArtifactId();
978
979 if (replacementId.indexOf(rootArtifactId) >= 0) {
980 replacementId = StringUtils.replace(replacementId, rootArtifactId, "${rootArtifactId}");
981 moduleDirectory = StringUtils.replace(moduleId, rootArtifactId, "__rootArtifactId__");
982 }
983
984 if (moduleId.indexOf(rootArtifactId) >= 0) {
985 moduleDirectory = StringUtils.replace(moduleId, rootArtifactId, "__rootArtifactId__");
986 }
987
988 archetypeDescriptor.setName(replacementId);
989 archetypeDescriptor.setId(replacementId);
990 archetypeDescriptor.setDir(moduleDirectory);
991
992 setArtifactId(reverseProperties, pom.getArtifactId());
993
994 List<String> excludePatterns = reverseProperties.getProperty(Constants.EXCLUDE_PATTERNS) != null
995 ? Arrays.asList(StringUtils.split(reverseProperties.getProperty(Constants.EXCLUDE_PATTERNS), ","))
996 : Collections.emptyList();
997
998 List<String> fileNames = resolveFileNames(pom, basedir, excludePatterns);
999
1000 List<FileSet> filesets = resolveFileSets(packageName, fileNames, languages, filtereds, defaultEncoding);
1001 LOGGER.debug("Resolved filesets for module " + archetypeDescriptor.getName());
1002
1003 archetypeDescriptor.setFileSets(filesets);
1004
1005 createArchetypeFiles(
1006 reverseProperties,
1007 filesets,
1008 packageName,
1009 basedir,
1010 archetypeFilesDirectory,
1011 defaultEncoding,
1012 excludePatterns);
1013 LOGGER.debug("Created files for module " + archetypeDescriptor.getName());
1014
1015 String parentArtifactId = reverseProperties.getProperty(Constants.PARENT_ARTIFACT_ID);
1016 setParentArtifactId(reverseProperties, pom.getArtifactId());
1017
1018 for (String subModuleId : pom.getModules()) {
1019 String subModuleIdDirectory = subModuleId;
1020 if (subModuleId.indexOf(rootArtifactId) >= 0) {
1021 subModuleIdDirectory = StringUtils.replace(subModuleId, rootArtifactId, "__rootArtifactId__");
1022 }
1023
1024 LOGGER.debug("Creating module " + subModuleId);
1025
1026 ModuleDescriptor moduleDescriptor = createModule(
1027 reverseProperties,
1028 rootArtifactId,
1029 subModuleId,
1030 packageName,
1031 FileUtils.resolveFile(basedir, subModuleId),
1032 FileUtils.resolveFile(archetypeFilesDirectory, subModuleIdDirectory),
1033 languages,
1034 filtereds,
1035 defaultEncoding,
1036 preserveCData,
1037 keepParent);
1038
1039 archetypeDescriptor.addModule(moduleDescriptor);
1040
1041 LOGGER.debug("Added module " + moduleDescriptor.getName() + " in " + archetypeDescriptor.getName());
1042 }
1043
1044 restoreParentArtifactId(reverseProperties, parentArtifactId);
1045 restoreArtifactId(reverseProperties, pom.getArtifactId());
1046
1047 LOGGER.debug("Created Module " + archetypeDescriptor.getName() + " pom");
1048
1049 return archetypeDescriptor;
1050 }
1051
1052 private void createModulePom(
1053 Model pom,
1054 String rootArtifactId,
1055 File archetypeFilesDirectory,
1056 Properties pomReversedProperties,
1057 File initialPomFile,
1058 boolean preserveCData,
1059 boolean keepParent)
1060 throws IOException {
1061 File outputFile = FileUtils.resolveFile(archetypeFilesDirectory, Constants.ARCHETYPE_POM);
1062
1063 if (preserveCData) {
1064 LOGGER.debug("Preserving CDATA parts of pom");
1065 File inputFile = FileUtils.resolveFile(archetypeFilesDirectory, Constants.ARCHETYPE_POM + ".tmp");
1066
1067 FileUtils.copyFile(initialPomFile, inputFile);
1068
1069 outputFile.getParentFile().mkdirs();
1070
1071 try (Reader in = new XmlStreamReader(inputFile);
1072 Writer out = new XmlStreamWriter(outputFile)) {
1073 String initialcontent = IOUtil.toString(in);
1074
1075 String content = getReversedContent(initialcontent, pomReversedProperties);
1076
1077 IOUtil.copy(content, out);
1078 }
1079
1080 inputFile.delete();
1081 } else {
1082 if (pom.getParent() != null) {
1083 pom.getParent()
1084 .setGroupId(StringUtils.replace(
1085 pom.getParent().getGroupId(),
1086 pomReversedProperties.getProperty(Constants.GROUP_ID),
1087 "${" + Constants.GROUP_ID + "}"));
1088 if (pom.getParent().getArtifactId() != null
1089 && pom.getParent().getArtifactId().indexOf(rootArtifactId) >= 0) {
1090 pom.getParent()
1091 .setArtifactId(StringUtils.replace(
1092 pom.getParent().getArtifactId(), rootArtifactId, "${rootArtifactId}"));
1093 }
1094 if (pom.getParent().getVersion() != null) {
1095 pom.getParent().setVersion("${" + Constants.VERSION + "}");
1096 }
1097 }
1098 pom.setModules(null);
1099
1100 if (pom.getGroupId() != null) {
1101 pom.setGroupId(StringUtils.replace(
1102 pom.getGroupId(),
1103 pomReversedProperties.getProperty(Constants.GROUP_ID),
1104 "${" + Constants.GROUP_ID + "}"));
1105 }
1106
1107 pom.setArtifactId("${" + Constants.ARTIFACT_ID + "}");
1108
1109 if (pom.getVersion() != null) {
1110 pom.setVersion("${" + Constants.VERSION + "}");
1111 }
1112
1113 pom.setName(getReversedPlainContent(pom.getName(), pomReversedProperties));
1114 pom.setDescription(getReversedPlainContent(pom.getDescription(), pomReversedProperties));
1115 pom.setUrl(getReversedPlainContent(pom.getUrl(), pomReversedProperties));
1116
1117 rewriteReferences(pom, rootArtifactId, pomReversedProperties.getProperty(Constants.GROUP_ID));
1118
1119 pomManager.writePom(pom, outputFile, initialPomFile);
1120 }
1121
1122 try (Reader in = new XmlStreamReader(initialPomFile)) {
1123 String initialcontent = IOUtil.toString(in);
1124
1125 for (Iterator<?> properties = pomReversedProperties.keySet().iterator(); properties.hasNext(); ) {
1126 String property = (String) properties.next();
1127
1128 if (initialcontent.indexOf("${" + property + "}") > 0) {
1129 LOGGER.warn("OldArchetype uses ${" + property + "} for internal processing, but file "
1130 + initialPomFile + " contains this property already");
1131 }
1132 }
1133 }
1134 }
1135
1136 private Set<String> getExtensions(List<String> files) {
1137 Set<String> extensions = new HashSet<>();
1138
1139 for (String file : files) {
1140 extensions.add(FileUtils.extension(file));
1141 }
1142
1143 return extensions;
1144 }
1145
1146 private Set<String> getExtensionlessFiles(List<String> files) {
1147 Set<String> extensionlessFiles = new HashSet<>();
1148
1149 for (String file : files) {
1150 if (FileUtils.extension(file).isEmpty()) {
1151 extensionlessFiles.add(file);
1152 }
1153 }
1154
1155 return extensionlessFiles;
1156 }
1157
1158 private Map<String, List<String>> getGroupsMap(final List<String> files, final int level) {
1159 Map<String, List<String>> groups = new HashMap<>();
1160
1161 for (String file : files) {
1162 String directory = PathUtils.getDirectory(file, level);
1163
1164 directory = StringUtils.replace(directory, File.separator, "/");
1165
1166 if (!groups.containsKey(directory)) {
1167 groups.put(directory, new ArrayList<>());
1168 }
1169
1170 List<String> group = groups.get(directory);
1171
1172 String innerPath = file.substring(directory.length() + 1);
1173
1174 innerPath = StringUtils.replace(innerPath, File.separator, "/");
1175
1176 group.add(innerPath);
1177 }
1178
1179 LOGGER.debug("Sorted " + groups.size() + " groups in " + files.size() + " files");
1180 LOGGER.debug("Sorted Files: " + files);
1181
1182 return groups;
1183 }
1184
1185 private FileSet getPackagedFileSet(
1186 final boolean filtered,
1187 final Set<String> packagedExtensions,
1188 final String group,
1189 final Set<String> unpackagedExtensions,
1190 final List<String> unpackagedFiles,
1191 String defaultEncoding) {
1192 List<String> includes = new ArrayList<>();
1193 List<String> excludes = new ArrayList<>();
1194
1195 for (String extension : packagedExtensions) {
1196 includes.add("**/*." + extension);
1197
1198 if (unpackagedExtensions.contains(extension)) {
1199 excludes.addAll(archetypeFilesResolver.getFilesWithExtension(unpackagedFiles, extension));
1200 }
1201 }
1202
1203 return createFileSet(excludes, true, filtered, group, includes, defaultEncoding);
1204 }
1205
1206 private List<FileSet> getPackagedFileSets(
1207 final boolean filtered,
1208 final String group,
1209 final List<String> groupFiles,
1210 final String packageName,
1211 String defaultEncoding) {
1212 String packageAsDir = StringUtils.replace(packageName, ".", "/");
1213
1214 List<FileSet> packagedFileSets = new ArrayList<>();
1215 List<String> packagedFiles = archetypeFilesResolver.getPackagedFiles(groupFiles, packageAsDir);
1216 LOGGER.debug("Found packaged Files:" + packagedFiles);
1217
1218 List<String> unpackagedFiles = archetypeFilesResolver.getUnpackagedFiles(groupFiles, packageAsDir);
1219 LOGGER.debug("Found unpackaged Files:" + unpackagedFiles);
1220
1221 Set<String> packagedExtensions = getExtensions(packagedFiles);
1222 LOGGER.debug("Found packaged extensions " + packagedExtensions);
1223
1224 Set<String> unpackagedExtensions = getExtensions(unpackagedFiles);
1225
1226 if (!packagedExtensions.isEmpty()) {
1227 packagedFileSets.add(getPackagedFileSet(
1228 filtered, packagedExtensions, group, unpackagedExtensions, unpackagedFiles, defaultEncoding));
1229 }
1230
1231 if (!unpackagedExtensions.isEmpty()) {
1232 LOGGER.debug("Found unpackaged extensions " + unpackagedExtensions);
1233
1234 packagedFileSets.add(getUnpackagedFileSet(
1235 filtered, unpackagedExtensions, unpackagedFiles, group, packagedExtensions, defaultEncoding));
1236 }
1237
1238 return packagedFileSets;
1239 }
1240
1241 private void setParentArtifactId(Properties properties, String parentArtifactId) {
1242 properties.setProperty(Constants.PARENT_ARTIFACT_ID, parentArtifactId);
1243 }
1244
1245 @SuppressWarnings("checkstyle:ParameterNumber")
1246 private void processFileSet(
1247 File basedir,
1248 File archetypeFilesDirectory,
1249 String directory,
1250 List<String> fileSetResources,
1251 boolean packaged,
1252 String packageName,
1253 Properties reverseProperties,
1254 String defaultEncoding)
1255 throws IOException {
1256 String packageAsDirectory = StringUtils.replace(packageName, ".", File.separator);
1257
1258 LOGGER.debug("Package as Directory: Package:" + packageName + "->" + packageAsDirectory);
1259
1260 for (String inputFileName : fileSetResources) {
1261 String initialFilename = packaged
1262 ? StringUtils.replace(inputFileName, packageAsDirectory + File.separator, "")
1263 : inputFileName;
1264
1265 LOGGER.debug("InputFileName:" + inputFileName);
1266
1267 File inputFile = new File(basedir, inputFileName);
1268
1269 String fileEncoding = getFileCharsetEncoding(inputFile, defaultEncoding);
1270
1271 String initialcontent = IOUtil.toString(Files.newInputStream(inputFile.toPath()), fileEncoding);
1272
1273 for (Iterator<?> properties = reverseProperties.keySet().iterator(); properties.hasNext(); ) {
1274 String property = (String) properties.next();
1275
1276 if (initialcontent.indexOf("${" + property + "}") > 0) {
1277 LOGGER.warn("Archetype uses ${" + property + "} for internal processing, but file " + inputFile
1278 + " contains this property already");
1279 }
1280 }
1281
1282 String content = getReversedContent(initialcontent, reverseProperties);
1283 String outputFilename = getReversedFilename(initialFilename, reverseProperties);
1284
1285 LOGGER.debug("OutputFileName:" + outputFilename);
1286
1287 File outputFile = new File(archetypeFilesDirectory, outputFilename);
1288 outputFile.getParentFile().mkdirs();
1289
1290 if (!outputFile.exists() && !outputFile.createNewFile()) {
1291 LOGGER.warn("Could not create new file \"" + outputFile.getPath() + "\" or the file already exists.");
1292 }
1293
1294 try (OutputStream os = Files.newOutputStream(outputFile.toPath())) {
1295 write(content, os, fileEncoding);
1296 }
1297 }
1298 }
1299
1300 private Properties getReversedProperties(ArchetypeDescriptor archetypeDescriptor, Properties properties) {
1301 Properties reversedProperties = new Properties();
1302
1303 reversedProperties.putAll(properties);
1304 reversedProperties.remove(Constants.ARCHETYPE_GROUP_ID);
1305 reversedProperties.remove(Constants.ARCHETYPE_ARTIFACT_ID);
1306 reversedProperties.remove(Constants.ARCHETYPE_VERSION);
1307
1308 String packageName = properties.getProperty(Constants.PACKAGE);
1309 String packageInPathFormat = getPackageInPathFormat(packageName);
1310 if (!packageInPathFormat.equals(packageName)) {
1311 reversedProperties.setProperty(Constants.PACKAGE_IN_PATH_FORMAT, packageInPathFormat);
1312 }
1313
1314
1315
1316
1317 return reversedProperties;
1318 }
1319
1320 private List<String> resolveFileNames(final Model pom, final File basedir, List<String> excludePatterns)
1321 throws IOException {
1322 LOGGER.debug("Resolving files for " + pom.getId() + " in " + basedir);
1323
1324 StringBuilder buff = new StringBuilder("pom.xml*,archetype.properties*,target/**,");
1325 for (String module : pom.getModules()) {
1326 buff.append(',').append(module).append("/**");
1327 }
1328
1329 for (String defaultExclude : ListScanner.DEFAULTEXCLUDES) {
1330 buff.append(',').append(defaultExclude).append("/**");
1331 }
1332
1333 for (String excludePattern : excludePatterns) {
1334 buff.append(',').append(excludePattern);
1335 }
1336
1337 String excludes = PathUtils.convertPathForOS(buff.toString());
1338
1339 List<String> fileNames = FileUtils.getFileNames(basedir, "**,.*,**/.*", excludes, false);
1340
1341 LOGGER.debug("Resolved " + fileNames.size() + " files");
1342 LOGGER.debug("Resolved Files:" + fileNames);
1343
1344 return fileNames;
1345 }
1346
1347 @SuppressWarnings("checkstyle:MethodLength")
1348 private List<FileSet> resolveFileSets(
1349 String packageName,
1350 List<String> fileNames,
1351 List<String> languages,
1352 List<String> filtereds,
1353 String defaultEncoding) {
1354 List<FileSet> resolvedFileSets = new ArrayList<>();
1355 LOGGER.debug("Resolving filesets with package=" + packageName + ", languages=" + languages + " and extentions="
1356 + filtereds);
1357
1358 List<String> files = new ArrayList<>(fileNames);
1359
1360 StringBuilder languageIncludes = new StringBuilder();
1361
1362 for (String language : languages) {
1363 languageIncludes.append(((languageIncludes.length() == 0) ? "" : ",") + language + "/**");
1364 }
1365
1366 LOGGER.debug("Using languages includes " + languageIncludes);
1367
1368 StringBuilder filteredIncludes = new StringBuilder();
1369 for (String filtered : filtereds) {
1370 filteredIncludes.append(((filteredIncludes.length() == 0) ? "" : ",") + "**/"
1371 + (filtered.startsWith(".") ? "" : "*.") + filtered);
1372 }
1373
1374 LOGGER.debug("Using filtered includes " + filteredIncludes);
1375
1376
1377 List<String> sourcesMainFiles = archetypeFilesResolver.findSourcesMainFiles(files, languageIncludes.toString());
1378 if (!sourcesMainFiles.isEmpty()) {
1379 files.removeAll(sourcesMainFiles);
1380
1381 List<String> filteredFiles =
1382 archetypeFilesResolver.getFilteredFiles(sourcesMainFiles, filteredIncludes.toString());
1383 sourcesMainFiles.removeAll(filteredFiles);
1384
1385 List<String> unfilteredFiles = sourcesMainFiles;
1386 if (!filteredFiles.isEmpty()) {
1387 resolvedFileSets.addAll(createFileSets(filteredFiles, 3, true, packageName, true, defaultEncoding));
1388 }
1389
1390 if (!unfilteredFiles.isEmpty()) {
1391 resolvedFileSets.addAll(createFileSets(unfilteredFiles, 3, true, packageName, false, defaultEncoding));
1392 }
1393 }
1394
1395
1396 List<String> resourcesMainFiles =
1397 archetypeFilesResolver.findResourcesMainFiles(files, languageIncludes.toString());
1398 if (!resourcesMainFiles.isEmpty()) {
1399 files.removeAll(resourcesMainFiles);
1400
1401 List<String> filteredFiles =
1402 archetypeFilesResolver.getFilteredFiles(resourcesMainFiles, filteredIncludes.toString());
1403 resourcesMainFiles.removeAll(filteredFiles);
1404
1405 List<String> unfilteredFiles = resourcesMainFiles;
1406 if (!filteredFiles.isEmpty()) {
1407 resolvedFileSets.addAll(createFileSets(filteredFiles, 3, false, packageName, true, defaultEncoding));
1408 }
1409 if (!unfilteredFiles.isEmpty()) {
1410 resolvedFileSets.addAll(createFileSets(unfilteredFiles, 3, false, packageName, false, defaultEncoding));
1411 }
1412 }
1413
1414
1415 List<String> sourcesTestFiles = archetypeFilesResolver.findSourcesTestFiles(files, languageIncludes.toString());
1416 if (!sourcesTestFiles.isEmpty()) {
1417 files.removeAll(sourcesTestFiles);
1418
1419 List<String> filteredFiles =
1420 archetypeFilesResolver.getFilteredFiles(sourcesTestFiles, filteredIncludes.toString());
1421 sourcesTestFiles.removeAll(filteredFiles);
1422
1423 List<String> unfilteredFiles = sourcesTestFiles;
1424 if (!filteredFiles.isEmpty()) {
1425 resolvedFileSets.addAll(createFileSets(filteredFiles, 3, true, packageName, true, defaultEncoding));
1426 }
1427 if (!unfilteredFiles.isEmpty()) {
1428 resolvedFileSets.addAll(createFileSets(unfilteredFiles, 3, true, packageName, false, defaultEncoding));
1429 }
1430 }
1431
1432
1433 List<String> resourcesTestFiles =
1434 archetypeFilesResolver.findResourcesTestFiles(files, languageIncludes.toString());
1435 if (!resourcesTestFiles.isEmpty()) {
1436 files.removeAll(resourcesTestFiles);
1437
1438 List<String> filteredFiles =
1439 archetypeFilesResolver.getFilteredFiles(resourcesTestFiles, filteredIncludes.toString());
1440 resourcesTestFiles.removeAll(filteredFiles);
1441
1442 List<String> unfilteredFiles = resourcesTestFiles;
1443 if (!filteredFiles.isEmpty()) {
1444 resolvedFileSets.addAll(createFileSets(filteredFiles, 3, false, packageName, true, defaultEncoding));
1445 }
1446 if (!unfilteredFiles.isEmpty()) {
1447 resolvedFileSets.addAll(createFileSets(unfilteredFiles, 3, false, packageName, false, defaultEncoding));
1448 }
1449 }
1450
1451
1452 List<String> siteFiles = archetypeFilesResolver.findSiteFiles(files, languageIncludes.toString());
1453 if (!siteFiles.isEmpty()) {
1454 files.removeAll(siteFiles);
1455
1456 List<String> filteredFiles =
1457 archetypeFilesResolver.getFilteredFiles(siteFiles, filteredIncludes.toString());
1458 siteFiles.removeAll(filteredFiles);
1459
1460 List<String> unfilteredFiles = siteFiles;
1461 if (!filteredFiles.isEmpty()) {
1462 resolvedFileSets.addAll(createFileSets(filteredFiles, 2, false, packageName, true, defaultEncoding));
1463 }
1464 if (!unfilteredFiles.isEmpty()) {
1465 resolvedFileSets.addAll(createFileSets(unfilteredFiles, 2, false, packageName, false, defaultEncoding));
1466 }
1467 }
1468
1469
1470 List<String> thirdLevelSourcesfiles =
1471 archetypeFilesResolver.findOtherSources(3, files, languageIncludes.toString());
1472 if (!thirdLevelSourcesfiles.isEmpty()) {
1473 files.removeAll(thirdLevelSourcesfiles);
1474
1475 List<String> filteredFiles =
1476 archetypeFilesResolver.getFilteredFiles(thirdLevelSourcesfiles, filteredIncludes.toString());
1477 thirdLevelSourcesfiles.removeAll(filteredFiles);
1478
1479 List<String> unfilteredFiles = thirdLevelSourcesfiles;
1480 if (!filteredFiles.isEmpty()) {
1481 resolvedFileSets.addAll(createFileSets(filteredFiles, 3, true, packageName, true, defaultEncoding));
1482 }
1483 if (!unfilteredFiles.isEmpty()) {
1484 resolvedFileSets.addAll(createFileSets(unfilteredFiles, 3, true, packageName, false, defaultEncoding));
1485 }
1486
1487
1488 List<String> thirdLevelResourcesfiles = archetypeFilesResolver.findOtherResources(
1489 3, files, thirdLevelSourcesfiles, languageIncludes.toString());
1490 if (!thirdLevelResourcesfiles.isEmpty()) {
1491 files.removeAll(thirdLevelResourcesfiles);
1492 filteredFiles =
1493 archetypeFilesResolver.getFilteredFiles(thirdLevelResourcesfiles, filteredIncludes.toString());
1494 thirdLevelResourcesfiles.removeAll(filteredFiles);
1495 unfilteredFiles = thirdLevelResourcesfiles;
1496 if (!filteredFiles.isEmpty()) {
1497 resolvedFileSets.addAll(
1498 createFileSets(filteredFiles, 3, false, packageName, true, defaultEncoding));
1499 }
1500 if (!unfilteredFiles.isEmpty()) {
1501 resolvedFileSets.addAll(
1502 createFileSets(unfilteredFiles, 3, false, packageName, false, defaultEncoding));
1503 }
1504 }
1505 }
1506
1507
1508 List<String> secondLevelSourcesfiles =
1509 archetypeFilesResolver.findOtherSources(2, files, languageIncludes.toString());
1510 if (!secondLevelSourcesfiles.isEmpty()) {
1511 files.removeAll(secondLevelSourcesfiles);
1512
1513 List<String> filteredFiles =
1514 archetypeFilesResolver.getFilteredFiles(secondLevelSourcesfiles, filteredIncludes.toString());
1515 secondLevelSourcesfiles.removeAll(filteredFiles);
1516
1517 List<String> unfilteredFiles = secondLevelSourcesfiles;
1518 if (!filteredFiles.isEmpty()) {
1519 resolvedFileSets.addAll(createFileSets(filteredFiles, 2, true, packageName, true, defaultEncoding));
1520 }
1521 if (!unfilteredFiles.isEmpty()) {
1522 resolvedFileSets.addAll(createFileSets(unfilteredFiles, 2, true, packageName, false, defaultEncoding));
1523 }
1524 }
1525
1526
1527 List<String> secondLevelResourcesfiles =
1528 archetypeFilesResolver.findOtherResources(2, files, languageIncludes.toString());
1529 if (!secondLevelResourcesfiles.isEmpty()) {
1530 files.removeAll(secondLevelResourcesfiles);
1531
1532 List<String> filteredFiles =
1533 archetypeFilesResolver.getFilteredFiles(secondLevelResourcesfiles, filteredIncludes.toString());
1534 secondLevelResourcesfiles.removeAll(filteredFiles);
1535
1536 List<String> unfilteredFiles = secondLevelResourcesfiles;
1537 if (!filteredFiles.isEmpty()) {
1538 resolvedFileSets.addAll(createFileSets(filteredFiles, 2, false, packageName, true, defaultEncoding));
1539 }
1540 if (!unfilteredFiles.isEmpty()) {
1541 resolvedFileSets.addAll(createFileSets(unfilteredFiles, 2, false, packageName, false, defaultEncoding));
1542 }
1543 }
1544
1545
1546 List<String> rootResourcesfiles =
1547 archetypeFilesResolver.findOtherResources(0, files, languageIncludes.toString());
1548 if (!rootResourcesfiles.isEmpty()) {
1549 files.removeAll(rootResourcesfiles);
1550
1551 List<String> filteredFiles =
1552 archetypeFilesResolver.getFilteredFiles(rootResourcesfiles, filteredIncludes.toString());
1553 rootResourcesfiles.removeAll(filteredFiles);
1554
1555 List<String> unfilteredFiles = rootResourcesfiles;
1556 if (!filteredFiles.isEmpty()) {
1557 resolvedFileSets.addAll(createFileSets(filteredFiles, 0, false, packageName, true, defaultEncoding));
1558 }
1559 if (!unfilteredFiles.isEmpty()) {
1560 resolvedFileSets.addAll(createFileSets(unfilteredFiles, 0, false, packageName, false, defaultEncoding));
1561 }
1562 }
1563
1564
1565 if (!files.isEmpty()) {
1566 LOGGER.info("Ignored files: " + files);
1567 }
1568
1569 return resolvedFileSets;
1570 }
1571
1572 private void restoreArtifactId(Properties properties, String artifactId) {
1573 if (artifactId == null || artifactId.isEmpty()) {
1574 properties.remove(Constants.ARTIFACT_ID);
1575 } else {
1576 properties.setProperty(Constants.ARTIFACT_ID, artifactId);
1577 }
1578 }
1579
1580 private void restoreParentArtifactId(Properties properties, String parentArtifactId) {
1581 if (parentArtifactId == null || parentArtifactId.isEmpty()) {
1582 properties.remove(Constants.PARENT_ARTIFACT_ID);
1583 } else {
1584 properties.setProperty(Constants.PARENT_ARTIFACT_ID, parentArtifactId);
1585 }
1586 }
1587
1588 private String getReversedContent(String content, Properties properties) {
1589 String result =
1590 StringUtils.replace(StringUtils.replace(content, "$", "${symbol_dollar}"), "\\", "${symbol_escape}");
1591 result = getReversedPlainContent(result, properties);
1592
1593
1594 return "#set( $symbol_pound = '#' )\n" + "#set( $symbol_dollar = '$' )\n" + "#set( $symbol_escape = '\\' )\n"
1595 + StringUtils.replace(result, "#", "${symbol_pound}");
1596 }
1597
1598 private String getReversedPlainContent(String content, Properties properties) {
1599 String result = content;
1600
1601 for (Iterator<?> propertyIterator = properties.keySet().iterator(); propertyIterator.hasNext(); ) {
1602 String propertyKey = (String) propertyIterator.next();
1603
1604 result = StringUtils.replace(result, properties.getProperty(propertyKey), "${" + propertyKey + "}");
1605 }
1606 return result;
1607 }
1608
1609 private String getReversedFilename(String filename, Properties properties) {
1610 String result = filename;
1611
1612 for (Iterator<?> propertyIterator = properties.keySet().iterator(); propertyIterator.hasNext(); ) {
1613 String propertyKey = (String) propertyIterator.next();
1614
1615 result = StringUtils.replace(result, properties.getProperty(propertyKey), "__" + propertyKey + "__");
1616 }
1617
1618 return result;
1619 }
1620
1621 private String getTemplateOutputDirectory() {
1622 return Constants.SRC + File.separator + Constants.MAIN + File.separator + Constants.RESOURCES;
1623 }
1624
1625 private FileSet getUnpackagedFileSet(
1626 final boolean filtered, final String group, final List<String> groupFiles, String defaultEncoding) {
1627 Set<String> extensions = getExtensions(groupFiles);
1628 Set<String> extensionlessFiles = getExtensionlessFiles(groupFiles);
1629
1630 List<String> includes = new ArrayList<>();
1631 List<String> excludes = new ArrayList<>();
1632
1633 for (String extension : extensions) {
1634 if (!extension.isEmpty()) {
1635 includes.add("**/*." + extension);
1636 }
1637 }
1638 for (String extensionlessFile : extensionlessFiles) {
1639 includes.add("**/" + extensionlessFile);
1640 }
1641
1642 return createFileSet(excludes, false, filtered, group, includes, defaultEncoding);
1643 }
1644
1645 private String getFileCharsetEncoding(File detectedFile, String defaultEncoding) {
1646 try (InputStream in = new BufferedInputStream(Files.newInputStream(detectedFile.toPath()))) {
1647 CharsetDetector detector = new CharsetDetector();
1648 detector.setText(in);
1649 CharsetMatch match = detector.detect();
1650 return match.getName().toUpperCase(Locale.ENGLISH);
1651 } catch (IOException e) {
1652 return defaultEncoding;
1653 }
1654 }
1655
1656 private FileSet getUnpackagedFileSet(
1657 final boolean filtered,
1658 final Set<String> unpackagedExtensions,
1659 final List<String> unpackagedFiles,
1660 final String group,
1661 final Set<String> packagedExtensions,
1662 String defaultEncoding) {
1663 List<String> includes = new ArrayList<>();
1664 List<String> excludes = new ArrayList<>();
1665
1666 for (String extension : unpackagedExtensions) {
1667 if (packagedExtensions.contains(extension)) {
1668 includes.addAll(archetypeFilesResolver.getFilesWithExtension(unpackagedFiles, extension));
1669 } else {
1670 if (extension == null || extension.isEmpty()) {
1671 includes.add("**/*");
1672 } else {
1673 includes.add("**/*." + extension);
1674 }
1675 }
1676 }
1677
1678 return createFileSet(excludes, false, filtered, group, includes, defaultEncoding);
1679 }
1680
1681 private static final String MAVEN_PROPERTIES =
1682 "META-INF/maven/org.apache.maven.archetype/archetype-common/pom.properties";
1683
1684 public String getArchetypeVersion() {
1685
1686
1687 String version = "version";
1688
1689 try (InputStream is = getClass().getClassLoader().getResourceAsStream(MAVEN_PROPERTIES)) {
1690 Properties properties = new Properties();
1691
1692 if (is != null) {
1693 properties.load(is);
1694
1695 String property = properties.getProperty("version");
1696
1697 if (property != null) {
1698 return property;
1699 }
1700 }
1701
1702 return version;
1703 } catch (IOException e) {
1704 return version;
1705 }
1706 }
1707 }