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