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