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 Map<String, List<String>> getGroupsMap(final List<String> files, final int level) {
1147 Map<String, List<String>> groups = new HashMap<>();
1148
1149 for (String file : files) {
1150 String directory = PathUtils.getDirectory(file, level);
1151
1152 directory = StringUtils.replace(directory, File.separator, "/");
1153
1154 if (!groups.containsKey(directory)) {
1155 groups.put(directory, new ArrayList<>());
1156 }
1157
1158 List<String> group = groups.get(directory);
1159
1160 String innerPath = file.substring(directory.length() + 1);
1161
1162 innerPath = StringUtils.replace(innerPath, File.separator, "/");
1163
1164 group.add(innerPath);
1165 }
1166
1167 LOGGER.debug("Sorted " + groups.size() + " groups in " + files.size() + " files");
1168 LOGGER.debug("Sorted Files: " + files);
1169
1170 return groups;
1171 }
1172
1173 private FileSet getPackagedFileSet(
1174 final boolean filtered,
1175 final Set<String> packagedExtensions,
1176 final String group,
1177 final Set<String> unpackagedExtensions,
1178 final List<String> unpackagedFiles,
1179 String defaultEncoding) {
1180 List<String> includes = new ArrayList<>();
1181 List<String> excludes = new ArrayList<>();
1182
1183 for (String extension : packagedExtensions) {
1184 includes.add("**/*." + extension);
1185
1186 if (unpackagedExtensions.contains(extension)) {
1187 excludes.addAll(archetypeFilesResolver.getFilesWithExtension(unpackagedFiles, extension));
1188 }
1189 }
1190
1191 return createFileSet(excludes, true, filtered, group, includes, defaultEncoding);
1192 }
1193
1194 private List<FileSet> getPackagedFileSets(
1195 final boolean filtered,
1196 final String group,
1197 final List<String> groupFiles,
1198 final String packageName,
1199 String defaultEncoding) {
1200 String packageAsDir = StringUtils.replace(packageName, ".", "/");
1201
1202 List<FileSet> packagedFileSets = new ArrayList<>();
1203 List<String> packagedFiles = archetypeFilesResolver.getPackagedFiles(groupFiles, packageAsDir);
1204 LOGGER.debug("Found packaged Files:" + packagedFiles);
1205
1206 List<String> unpackagedFiles = archetypeFilesResolver.getUnpackagedFiles(groupFiles, packageAsDir);
1207 LOGGER.debug("Found unpackaged Files:" + unpackagedFiles);
1208
1209 Set<String> packagedExtensions = getExtensions(packagedFiles);
1210 LOGGER.debug("Found packaged extensions " + packagedExtensions);
1211
1212 Set<String> unpackagedExtensions = getExtensions(unpackagedFiles);
1213
1214 if (!packagedExtensions.isEmpty()) {
1215 packagedFileSets.add(getPackagedFileSet(
1216 filtered, packagedExtensions, group, unpackagedExtensions, unpackagedFiles, defaultEncoding));
1217 }
1218
1219 if (!unpackagedExtensions.isEmpty()) {
1220 LOGGER.debug("Found unpackaged extensions " + unpackagedExtensions);
1221
1222 packagedFileSets.add(getUnpackagedFileSet(
1223 filtered, unpackagedExtensions, unpackagedFiles, group, packagedExtensions, defaultEncoding));
1224 }
1225
1226 return packagedFileSets;
1227 }
1228
1229 private void setParentArtifactId(Properties properties, String parentArtifactId) {
1230 properties.setProperty(Constants.PARENT_ARTIFACT_ID, parentArtifactId);
1231 }
1232
1233 @SuppressWarnings("checkstyle:ParameterNumber")
1234 private void processFileSet(
1235 File basedir,
1236 File archetypeFilesDirectory,
1237 String directory,
1238 List<String> fileSetResources,
1239 boolean packaged,
1240 String packageName,
1241 Properties reverseProperties,
1242 String defaultEncoding)
1243 throws IOException {
1244 String packageAsDirectory = StringUtils.replace(packageName, ".", File.separator);
1245
1246 LOGGER.debug("Package as Directory: Package:" + packageName + "->" + packageAsDirectory);
1247
1248 for (String inputFileName : fileSetResources) {
1249 String initialFilename = packaged
1250 ? StringUtils.replace(inputFileName, packageAsDirectory + File.separator, "")
1251 : inputFileName;
1252
1253 LOGGER.debug("InputFileName:" + inputFileName);
1254
1255 File inputFile = new File(basedir, inputFileName);
1256
1257 String fileEncoding = getFileCharsetEncoding(inputFile, defaultEncoding);
1258
1259 String initialcontent = IOUtil.toString(Files.newInputStream(inputFile.toPath()), fileEncoding);
1260
1261 for (Iterator<?> properties = reverseProperties.keySet().iterator(); properties.hasNext(); ) {
1262 String property = (String) properties.next();
1263
1264 if (initialcontent.indexOf("${" + property + "}") > 0) {
1265 LOGGER.warn("Archetype uses ${" + property + "} for internal processing, but file " + inputFile
1266 + " contains this property already");
1267 }
1268 }
1269
1270 String content = getReversedContent(initialcontent, reverseProperties);
1271 String outputFilename = getReversedFilename(initialFilename, reverseProperties);
1272
1273 LOGGER.debug("OutputFileName:" + outputFilename);
1274
1275 File outputFile = new File(archetypeFilesDirectory, outputFilename);
1276 outputFile.getParentFile().mkdirs();
1277
1278 if (!outputFile.exists() && !outputFile.createNewFile()) {
1279 LOGGER.warn("Could not create new file \"" + outputFile.getPath() + "\" or the file already exists.");
1280 }
1281
1282 try (OutputStream os = Files.newOutputStream(outputFile.toPath())) {
1283 write(content, os, fileEncoding);
1284 }
1285 }
1286 }
1287
1288 private Properties getReversedProperties(ArchetypeDescriptor archetypeDescriptor, Properties properties) {
1289 Properties reversedProperties = new Properties();
1290
1291 reversedProperties.putAll(properties);
1292 reversedProperties.remove(Constants.ARCHETYPE_GROUP_ID);
1293 reversedProperties.remove(Constants.ARCHETYPE_ARTIFACT_ID);
1294 reversedProperties.remove(Constants.ARCHETYPE_VERSION);
1295
1296 String packageName = properties.getProperty(Constants.PACKAGE);
1297 String packageInPathFormat = getPackageInPathFormat(packageName);
1298 if (!packageInPathFormat.equals(packageName)) {
1299 reversedProperties.setProperty(Constants.PACKAGE_IN_PATH_FORMAT, packageInPathFormat);
1300 }
1301
1302
1303
1304
1305 return reversedProperties;
1306 }
1307
1308 private List<String> resolveFileNames(final Model pom, final File basedir, List<String> excludePatterns)
1309 throws IOException {
1310 LOGGER.debug("Resolving files for " + pom.getId() + " in " + basedir);
1311
1312 StringBuilder buff = new StringBuilder("pom.xml*,archetype.properties*,target/**,");
1313 for (String module : pom.getModules()) {
1314 buff.append(',').append(module).append("/**");
1315 }
1316
1317 for (String defaultExclude : ListScanner.DEFAULTEXCLUDES) {
1318 buff.append(',').append(defaultExclude).append("/**");
1319 }
1320
1321 for (String excludePattern : excludePatterns) {
1322 buff.append(',').append(excludePattern);
1323 }
1324
1325 String excludes = PathUtils.convertPathForOS(buff.toString());
1326
1327 List<String> fileNames = FileUtils.getFileNames(basedir, "**,.*,**/.*", excludes, false);
1328
1329 LOGGER.debug("Resolved " + fileNames.size() + " files");
1330 LOGGER.debug("Resolved Files:" + fileNames);
1331
1332 return fileNames;
1333 }
1334
1335 @SuppressWarnings("checkstyle:MethodLength")
1336 private List<FileSet> resolveFileSets(
1337 String packageName,
1338 List<String> fileNames,
1339 List<String> languages,
1340 List<String> filtereds,
1341 String defaultEncoding) {
1342 List<FileSet> resolvedFileSets = new ArrayList<>();
1343 LOGGER.debug("Resolving filesets with package=" + packageName + ", languages=" + languages + " and extentions="
1344 + filtereds);
1345
1346 List<String> files = new ArrayList<>(fileNames);
1347
1348 StringBuilder languageIncludes = new StringBuilder();
1349
1350 for (String language : languages) {
1351 languageIncludes.append(((languageIncludes.length() == 0) ? "" : ",") + language + "/**");
1352 }
1353
1354 LOGGER.debug("Using languages includes " + languageIncludes);
1355
1356 StringBuilder filteredIncludes = new StringBuilder();
1357 for (String filtered : filtereds) {
1358 filteredIncludes.append(((filteredIncludes.length() == 0) ? "" : ",") + "**/"
1359 + (filtered.startsWith(".") ? "" : "*.") + filtered);
1360 }
1361
1362 LOGGER.debug("Using filtered includes " + filteredIncludes);
1363
1364
1365 List<String> sourcesMainFiles = archetypeFilesResolver.findSourcesMainFiles(files, languageIncludes.toString());
1366 if (!sourcesMainFiles.isEmpty()) {
1367 files.removeAll(sourcesMainFiles);
1368
1369 List<String> filteredFiles =
1370 archetypeFilesResolver.getFilteredFiles(sourcesMainFiles, filteredIncludes.toString());
1371 sourcesMainFiles.removeAll(filteredFiles);
1372
1373 List<String> unfilteredFiles = sourcesMainFiles;
1374 if (!filteredFiles.isEmpty()) {
1375 resolvedFileSets.addAll(createFileSets(filteredFiles, 3, true, packageName, true, defaultEncoding));
1376 }
1377
1378 if (!unfilteredFiles.isEmpty()) {
1379 resolvedFileSets.addAll(createFileSets(unfilteredFiles, 3, true, packageName, false, defaultEncoding));
1380 }
1381 }
1382
1383
1384 List<String> resourcesMainFiles =
1385 archetypeFilesResolver.findResourcesMainFiles(files, languageIncludes.toString());
1386 if (!resourcesMainFiles.isEmpty()) {
1387 files.removeAll(resourcesMainFiles);
1388
1389 List<String> filteredFiles =
1390 archetypeFilesResolver.getFilteredFiles(resourcesMainFiles, filteredIncludes.toString());
1391 resourcesMainFiles.removeAll(filteredFiles);
1392
1393 List<String> unfilteredFiles = resourcesMainFiles;
1394 if (!filteredFiles.isEmpty()) {
1395 resolvedFileSets.addAll(createFileSets(filteredFiles, 3, false, packageName, true, defaultEncoding));
1396 }
1397 if (!unfilteredFiles.isEmpty()) {
1398 resolvedFileSets.addAll(createFileSets(unfilteredFiles, 3, false, packageName, false, defaultEncoding));
1399 }
1400 }
1401
1402
1403 List<String> sourcesTestFiles = archetypeFilesResolver.findSourcesTestFiles(files, languageIncludes.toString());
1404 if (!sourcesTestFiles.isEmpty()) {
1405 files.removeAll(sourcesTestFiles);
1406
1407 List<String> filteredFiles =
1408 archetypeFilesResolver.getFilteredFiles(sourcesTestFiles, filteredIncludes.toString());
1409 sourcesTestFiles.removeAll(filteredFiles);
1410
1411 List<String> unfilteredFiles = sourcesTestFiles;
1412 if (!filteredFiles.isEmpty()) {
1413 resolvedFileSets.addAll(createFileSets(filteredFiles, 3, true, packageName, true, defaultEncoding));
1414 }
1415 if (!unfilteredFiles.isEmpty()) {
1416 resolvedFileSets.addAll(createFileSets(unfilteredFiles, 3, true, packageName, false, defaultEncoding));
1417 }
1418 }
1419
1420
1421 List<String> resourcesTestFiles =
1422 archetypeFilesResolver.findResourcesTestFiles(files, languageIncludes.toString());
1423 if (!resourcesTestFiles.isEmpty()) {
1424 files.removeAll(resourcesTestFiles);
1425
1426 List<String> filteredFiles =
1427 archetypeFilesResolver.getFilteredFiles(resourcesTestFiles, filteredIncludes.toString());
1428 resourcesTestFiles.removeAll(filteredFiles);
1429
1430 List<String> unfilteredFiles = resourcesTestFiles;
1431 if (!filteredFiles.isEmpty()) {
1432 resolvedFileSets.addAll(createFileSets(filteredFiles, 3, false, packageName, true, defaultEncoding));
1433 }
1434 if (!unfilteredFiles.isEmpty()) {
1435 resolvedFileSets.addAll(createFileSets(unfilteredFiles, 3, false, packageName, false, defaultEncoding));
1436 }
1437 }
1438
1439
1440 List<String> siteFiles = archetypeFilesResolver.findSiteFiles(files, languageIncludes.toString());
1441 if (!siteFiles.isEmpty()) {
1442 files.removeAll(siteFiles);
1443
1444 List<String> filteredFiles =
1445 archetypeFilesResolver.getFilteredFiles(siteFiles, filteredIncludes.toString());
1446 siteFiles.removeAll(filteredFiles);
1447
1448 List<String> unfilteredFiles = siteFiles;
1449 if (!filteredFiles.isEmpty()) {
1450 resolvedFileSets.addAll(createFileSets(filteredFiles, 2, false, packageName, true, defaultEncoding));
1451 }
1452 if (!unfilteredFiles.isEmpty()) {
1453 resolvedFileSets.addAll(createFileSets(unfilteredFiles, 2, false, packageName, false, defaultEncoding));
1454 }
1455 }
1456
1457
1458 List<String> thirdLevelSourcesfiles =
1459 archetypeFilesResolver.findOtherSources(3, files, languageIncludes.toString());
1460 if (!thirdLevelSourcesfiles.isEmpty()) {
1461 files.removeAll(thirdLevelSourcesfiles);
1462
1463 List<String> filteredFiles =
1464 archetypeFilesResolver.getFilteredFiles(thirdLevelSourcesfiles, filteredIncludes.toString());
1465 thirdLevelSourcesfiles.removeAll(filteredFiles);
1466
1467 List<String> unfilteredFiles = thirdLevelSourcesfiles;
1468 if (!filteredFiles.isEmpty()) {
1469 resolvedFileSets.addAll(createFileSets(filteredFiles, 3, true, packageName, true, defaultEncoding));
1470 }
1471 if (!unfilteredFiles.isEmpty()) {
1472 resolvedFileSets.addAll(createFileSets(unfilteredFiles, 3, true, packageName, false, defaultEncoding));
1473 }
1474
1475
1476 List<String> thirdLevelResourcesfiles = archetypeFilesResolver.findOtherResources(
1477 3, files, thirdLevelSourcesfiles, languageIncludes.toString());
1478 if (!thirdLevelResourcesfiles.isEmpty()) {
1479 files.removeAll(thirdLevelResourcesfiles);
1480 filteredFiles =
1481 archetypeFilesResolver.getFilteredFiles(thirdLevelResourcesfiles, filteredIncludes.toString());
1482 thirdLevelResourcesfiles.removeAll(filteredFiles);
1483 unfilteredFiles = thirdLevelResourcesfiles;
1484 if (!filteredFiles.isEmpty()) {
1485 resolvedFileSets.addAll(
1486 createFileSets(filteredFiles, 3, false, packageName, true, defaultEncoding));
1487 }
1488 if (!unfilteredFiles.isEmpty()) {
1489 resolvedFileSets.addAll(
1490 createFileSets(unfilteredFiles, 3, false, packageName, false, defaultEncoding));
1491 }
1492 }
1493 }
1494
1495
1496 List<String> secondLevelSourcesfiles =
1497 archetypeFilesResolver.findOtherSources(2, files, languageIncludes.toString());
1498 if (!secondLevelSourcesfiles.isEmpty()) {
1499 files.removeAll(secondLevelSourcesfiles);
1500
1501 List<String> filteredFiles =
1502 archetypeFilesResolver.getFilteredFiles(secondLevelSourcesfiles, filteredIncludes.toString());
1503 secondLevelSourcesfiles.removeAll(filteredFiles);
1504
1505 List<String> unfilteredFiles = secondLevelSourcesfiles;
1506 if (!filteredFiles.isEmpty()) {
1507 resolvedFileSets.addAll(createFileSets(filteredFiles, 2, true, packageName, true, defaultEncoding));
1508 }
1509 if (!unfilteredFiles.isEmpty()) {
1510 resolvedFileSets.addAll(createFileSets(unfilteredFiles, 2, true, packageName, false, defaultEncoding));
1511 }
1512 }
1513
1514
1515 List<String> secondLevelResourcesfiles =
1516 archetypeFilesResolver.findOtherResources(2, files, languageIncludes.toString());
1517 if (!secondLevelResourcesfiles.isEmpty()) {
1518 files.removeAll(secondLevelResourcesfiles);
1519
1520 List<String> filteredFiles =
1521 archetypeFilesResolver.getFilteredFiles(secondLevelResourcesfiles, filteredIncludes.toString());
1522 secondLevelResourcesfiles.removeAll(filteredFiles);
1523
1524 List<String> unfilteredFiles = secondLevelResourcesfiles;
1525 if (!filteredFiles.isEmpty()) {
1526 resolvedFileSets.addAll(createFileSets(filteredFiles, 2, false, packageName, true, defaultEncoding));
1527 }
1528 if (!unfilteredFiles.isEmpty()) {
1529 resolvedFileSets.addAll(createFileSets(unfilteredFiles, 2, false, packageName, false, defaultEncoding));
1530 }
1531 }
1532
1533
1534 List<String> rootResourcesfiles =
1535 archetypeFilesResolver.findOtherResources(0, files, languageIncludes.toString());
1536 if (!rootResourcesfiles.isEmpty()) {
1537 files.removeAll(rootResourcesfiles);
1538
1539 List<String> filteredFiles =
1540 archetypeFilesResolver.getFilteredFiles(rootResourcesfiles, filteredIncludes.toString());
1541 rootResourcesfiles.removeAll(filteredFiles);
1542
1543 List<String> unfilteredFiles = rootResourcesfiles;
1544 if (!filteredFiles.isEmpty()) {
1545 resolvedFileSets.addAll(createFileSets(filteredFiles, 0, false, packageName, true, defaultEncoding));
1546 }
1547 if (!unfilteredFiles.isEmpty()) {
1548 resolvedFileSets.addAll(createFileSets(unfilteredFiles, 0, false, packageName, false, defaultEncoding));
1549 }
1550 }
1551
1552
1553 if (!files.isEmpty()) {
1554 LOGGER.info("Ignored files: " + files);
1555 }
1556
1557 return resolvedFileSets;
1558 }
1559
1560 private void restoreArtifactId(Properties properties, String artifactId) {
1561 if (artifactId == null || artifactId.isEmpty()) {
1562 properties.remove(Constants.ARTIFACT_ID);
1563 } else {
1564 properties.setProperty(Constants.ARTIFACT_ID, artifactId);
1565 }
1566 }
1567
1568 private void restoreParentArtifactId(Properties properties, String parentArtifactId) {
1569 if (parentArtifactId == null || parentArtifactId.isEmpty()) {
1570 properties.remove(Constants.PARENT_ARTIFACT_ID);
1571 } else {
1572 properties.setProperty(Constants.PARENT_ARTIFACT_ID, parentArtifactId);
1573 }
1574 }
1575
1576 private String getReversedContent(String content, Properties properties) {
1577 String result =
1578 StringUtils.replace(StringUtils.replace(content, "$", "${symbol_dollar}"), "\\", "${symbol_escape}");
1579 result = getReversedPlainContent(result, properties);
1580
1581
1582 return "#set( $symbol_pound = '#' )\n" + "#set( $symbol_dollar = '$' )\n" + "#set( $symbol_escape = '\\' )\n"
1583 + StringUtils.replace(result, "#", "${symbol_pound}");
1584 }
1585
1586 private String getReversedPlainContent(String content, Properties properties) {
1587 String result = content;
1588
1589 for (Iterator<?> propertyIterator = properties.keySet().iterator(); propertyIterator.hasNext(); ) {
1590 String propertyKey = (String) propertyIterator.next();
1591
1592 result = StringUtils.replace(result, properties.getProperty(propertyKey), "${" + propertyKey + "}");
1593 }
1594 return result;
1595 }
1596
1597 private String getReversedFilename(String filename, Properties properties) {
1598 String result = filename;
1599
1600 for (Iterator<?> propertyIterator = properties.keySet().iterator(); propertyIterator.hasNext(); ) {
1601 String propertyKey = (String) propertyIterator.next();
1602
1603 result = StringUtils.replace(result, properties.getProperty(propertyKey), "__" + propertyKey + "__");
1604 }
1605
1606 return result;
1607 }
1608
1609 private String getTemplateOutputDirectory() {
1610 return Constants.SRC + File.separator + Constants.MAIN + File.separator + Constants.RESOURCES;
1611 }
1612
1613 private FileSet getUnpackagedFileSet(
1614 final boolean filtered, final String group, final List<String> groupFiles, String defaultEncoding) {
1615 Set<String> extensions = getExtensions(groupFiles);
1616
1617 List<String> includes = new ArrayList<>();
1618 List<String> excludes = new ArrayList<>();
1619
1620 for (String extension : extensions) {
1621 includes.add("**/*." + extension);
1622 }
1623
1624 return createFileSet(excludes, false, filtered, group, includes, defaultEncoding);
1625 }
1626
1627 private String getFileCharsetEncoding(File detectedFile, String defaultEncoding) {
1628 try (InputStream in = new BufferedInputStream(Files.newInputStream(detectedFile.toPath()))) {
1629 CharsetDetector detector = new CharsetDetector();
1630 detector.setText(in);
1631 CharsetMatch match = detector.detect();
1632 return match.getName().toUpperCase(Locale.ENGLISH);
1633 } catch (IOException e) {
1634 return defaultEncoding;
1635 }
1636 }
1637
1638 private FileSet getUnpackagedFileSet(
1639 final boolean filtered,
1640 final Set<String> unpackagedExtensions,
1641 final List<String> unpackagedFiles,
1642 final String group,
1643 final Set<String> packagedExtensions,
1644 String defaultEncoding) {
1645 List<String> includes = new ArrayList<>();
1646 List<String> excludes = new ArrayList<>();
1647
1648 for (String extension : unpackagedExtensions) {
1649 if (packagedExtensions.contains(extension)) {
1650 includes.addAll(archetypeFilesResolver.getFilesWithExtension(unpackagedFiles, extension));
1651 } else {
1652 if (extension == null || extension.isEmpty()) {
1653 includes.add("**/*");
1654 } else {
1655 includes.add("**/*." + extension);
1656 }
1657 }
1658 }
1659
1660 return createFileSet(excludes, false, filtered, group, includes, defaultEncoding);
1661 }
1662
1663 private static final String MAVEN_PROPERTIES =
1664 "META-INF/maven/org.apache.maven.archetype/archetype-common/pom.properties";
1665
1666 public String getArchetypeVersion() {
1667
1668
1669 String version = "version";
1670
1671 try (InputStream is = getClass().getClassLoader().getResourceAsStream(MAVEN_PROPERTIES)) {
1672 Properties properties = new Properties();
1673
1674 if (is != null) {
1675 properties.load(is);
1676
1677 String property = properties.getProperty("version");
1678
1679 if (property != null) {
1680 return property;
1681 }
1682 }
1683
1684 return version;
1685 } catch (IOException e) {
1686 return version;
1687 }
1688 }
1689 }