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