blob: 0f08bad9ff1f153a58a4921a01d5bf2599d13c4d [file] [log] [blame]
package org.apache.maven.archetype.generator;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import org.apache.maven.archetype.ArchetypeGenerationRequest;
import org.apache.maven.archetype.common.ArchetypeArtifactManager;
import org.apache.maven.archetype.common.ArchetypeFilesResolver;
import org.apache.maven.archetype.common.Constants;
import org.apache.maven.archetype.common.PomManager;
import org.apache.maven.archetype.exception.ArchetypeGenerationFailure;
import org.apache.maven.archetype.exception.ArchetypeNotConfigured;
import org.apache.maven.archetype.exception.InvalidPackaging;
import org.apache.maven.archetype.exception.OutputFileExists;
import org.apache.maven.archetype.exception.PomFileExists;
import org.apache.maven.archetype.exception.ProjectDirectoryExists;
import org.apache.maven.archetype.exception.UnknownArchetype;
import org.apache.maven.archetype.metadata.AbstractArchetypeDescriptor;
import org.apache.maven.archetype.metadata.ArchetypeDescriptor;
import org.apache.maven.archetype.metadata.FileSet;
import org.apache.maven.archetype.metadata.ModuleDescriptor;
import org.apache.maven.archetype.metadata.RequiredProperty;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.context.Context;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.codehaus.plexus.velocity.VelocityComponent;
import org.dom4j.DocumentException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@Component( role = FilesetArchetypeGenerator.class )
public class DefaultFilesetArchetypeGenerator
extends AbstractLogEnabled
implements FilesetArchetypeGenerator
{
@Requirement
private ArchetypeArtifactManager archetypeArtifactManager;
@Requirement
private ArchetypeFilesResolver archetypeFilesResolver;
@Requirement
private PomManager pomManager;
@Requirement
private VelocityComponent velocity;
/**
* Pattern used to detect tokens in a string. Tokens are any text surrounded
* by the delimiter <code>__</code>.
*/
private static final Pattern TOKEN_PATTERN = Pattern.compile( "__((?:[^_]+_)*[^_]+)__" );
@Override
public void generateArchetype( ArchetypeGenerationRequest request, File archetypeFile )
throws UnknownArchetype, ArchetypeNotConfigured, ProjectDirectoryExists, PomFileExists, OutputFileExists,
ArchetypeGenerationFailure
{
ClassLoader old = Thread.currentThread().getContextClassLoader();
try
{
ArchetypeDescriptor archetypeDescriptor =
archetypeArtifactManager.getFileSetArchetypeDescriptor( archetypeFile );
if ( !isArchetypeConfigured( archetypeDescriptor, request ) )
{
if ( request.isInteractiveMode() )
{
throw new ArchetypeNotConfigured( "No archetype was chosen.", null );
}
StringBuilder exceptionMessage = new StringBuilder(
"Archetype " + request.getArchetypeGroupId() + ":" + request.getArchetypeArtifactId() + ":"
+ request.getArchetypeVersion() + " is not configured" );
List<String> missingProperties = new ArrayList<>( 0 );
for ( RequiredProperty requiredProperty : archetypeDescriptor.getRequiredProperties() )
{
if ( StringUtils.isEmpty( request.getProperties().getProperty( requiredProperty.getKey() ) ) )
{
exceptionMessage.append( "\n\tProperty " + requiredProperty.getKey() + " is missing." );
missingProperties.add( requiredProperty.getKey() );
}
}
throw new ArchetypeNotConfigured( exceptionMessage.toString(), missingProperties );
}
Context context = prepareVelocityContext( request );
String packageName = request.getPackage();
String artifactId = request.getArtifactId();
File outputDirectoryFile = new File( request.getOutputDirectory(), artifactId );
File basedirPom = new File( request.getOutputDirectory(), Constants.ARCHETYPE_POM );
File pom = new File( outputDirectoryFile, Constants.ARCHETYPE_POM );
List<String> archetypeResources = archetypeArtifactManager.getFilesetArchetypeResources( archetypeFile );
ZipFile archetypeZipFile = archetypeArtifactManager.getArchetypeZipFile( archetypeFile );
ClassLoader archetypeJarLoader = archetypeArtifactManager.getArchetypeJarLoader( archetypeFile );
Thread.currentThread().setContextClassLoader( archetypeJarLoader );
if ( archetypeDescriptor.isPartial() )
{
getLogger().debug( "Processing partial archetype " + archetypeDescriptor.getName() );
if ( outputDirectoryFile.exists() )
{
if ( !pom.exists() )
{
throw new PomFileExists( "This is a partial archetype and the pom.xml file doesn't exist." );
}
processPomWithMerge( context, pom, "" );
processArchetypeTemplatesWithWarning( archetypeDescriptor, archetypeResources, archetypeZipFile, "",
context, packageName, outputDirectoryFile );
}
else
{
if ( basedirPom.exists() )
{
processPomWithMerge( context, basedirPom, "" );
processArchetypeTemplatesWithWarning( archetypeDescriptor, archetypeResources, archetypeZipFile,
"", context, packageName,
new File( request.getOutputDirectory() ) );
}
else
{
processPom( context, pom, "" );
processArchetypeTemplates( archetypeDescriptor, archetypeResources, archetypeZipFile, "",
context, packageName, outputDirectoryFile );
}
}
if ( archetypeDescriptor.getModules().size() > 0 )
{
getLogger().info( "Modules ignored in partial mode" );
}
}
else
{
getLogger().debug( "Processing complete archetype " + archetypeDescriptor.getName() );
if ( outputDirectoryFile.exists() && pom.exists() )
{
throw new ProjectDirectoryExists(
"A Maven 2 project already exists in the directory " + outputDirectoryFile.getPath() );
}
if ( outputDirectoryFile.exists() )
{
getLogger().warn( "The directory " + outputDirectoryFile.getPath() + " already exists." );
}
context.put( "rootArtifactId", artifactId );
processFilesetModule( artifactId, artifactId, archetypeResources, pom, archetypeZipFile, "", basedirPom,
outputDirectoryFile, packageName, archetypeDescriptor, context );
}
String postGenerationScript = archetypeArtifactManager.getPostGenerationScript( archetypeFile );
if ( postGenerationScript != null )
{
getLogger().info( "Executing " + Constants.ARCHETYPE_POST_GENERATION_SCRIPT
+ " post-generation script" );
Binding binding = new Binding();
final Properties archetypeGeneratorProperties = new Properties();
archetypeGeneratorProperties.putAll( System.getProperties() );
if ( request.getProperties() != null )
{
archetypeGeneratorProperties.putAll( request.getProperties() );
}
for ( Map.Entry<Object, Object> entry : archetypeGeneratorProperties.entrySet() )
{
binding.setVariable( entry.getKey().toString(), entry.getValue() );
}
binding.setVariable( "request", request );
GroovyShell shell = new GroovyShell( binding );
shell.evaluate( postGenerationScript );
}
// ----------------------------------------------------------------------
// Log message on OldArchetype creation
// ----------------------------------------------------------------------
if ( getLogger().isInfoEnabled() )
{
getLogger().info( "Project created from Archetype in dir: " + outputDirectoryFile.getAbsolutePath() );
}
}
catch ( FileNotFoundException ex )
{
throw new ArchetypeGenerationFailure( ex );
}
catch ( IOException ex )
{
throw new ArchetypeGenerationFailure( ex );
}
catch ( XmlPullParserException ex )
{
throw new ArchetypeGenerationFailure( ex );
}
catch ( DocumentException ex )
{
throw new ArchetypeGenerationFailure( ex );
}
catch ( ArchetypeGenerationFailure ex )
{
throw new ArchetypeGenerationFailure( ex );
}
catch ( InvalidPackaging ex )
{
throw new ArchetypeGenerationFailure( ex );
}
finally
{
Thread.currentThread().setContextClassLoader( old );
}
}
public String getPackageAsDirectory( String packageName )
{
return StringUtils.replace( packageName, ".", "/" );
}
private boolean copyFile( final File outFile, final String template, final boolean failIfExists,
final ZipFile archetypeZipFile )
throws FileNotFoundException, OutputFileExists, IOException
{
getLogger().debug( "Copying file " + template );
if ( failIfExists && outFile.exists() )
{
throw new OutputFileExists( "Don't rewrite file " + outFile.getName() );
}
else if ( outFile.exists() )
{
getLogger().warn( "CP Don't override file " + outFile );
return false;
}
ZipEntry input = archetypeZipFile.getEntry( Constants.ARCHETYPE_RESOURCES + "/" + template );
if ( input.isDirectory() )
{
outFile.mkdirs();
}
else
{
outFile.getParentFile().mkdirs();
try ( InputStream inputStream = archetypeZipFile.getInputStream( input );
OutputStream out = new FileOutputStream( outFile ) )
{
IOUtil.copy( inputStream, out );
}
}
return true;
}
private int copyFiles( String directory, List<String> fileSetResources, boolean packaged, String packageName,
File outputDirectoryFile, ZipFile archetypeZipFile, String moduleOffset,
boolean failIfExists, Context context )
throws OutputFileExists, FileNotFoundException, IOException
{
int count = 0;
for ( String template : fileSetResources )
{
File outputFile =
getOutputFile( template, directory, outputDirectoryFile, packaged, packageName, moduleOffset, context );
if ( copyFile( outputFile, template, failIfExists, archetypeZipFile ) )
{
count++;
}
}
return count;
}
private String getEncoding( String archetypeEncoding )
{
return StringUtils.isEmpty( archetypeEncoding ) ? "UTF-8" : archetypeEncoding;
}
private String getOffsetSeparator( String moduleOffset )
{
return StringUtils.isEmpty( moduleOffset ) ? "/" : ( "/" + moduleOffset + "/" );
}
private File getOutputFile( String template, String directory, File outputDirectoryFile, boolean packaged,
String packageName, String moduleOffset, Context context )
{
String templateName = StringUtils.replaceOnce( template, directory, "" );
String outputFileName =
directory + "/" + ( packaged ? getPackageAsDirectory( packageName ) : "" ) + "/" + templateName.substring(
moduleOffset.length() );
outputFileName = replaceFilenameTokens( outputFileName, context );
return new File( outputDirectoryFile, outputFileName );
}
/**
* Replaces all tokens (text matching {@link #TOKEN_PATTERN}) within
* the given string, using properties contained within the context. If a
* property does not exist in the context, the token is left unmodified
* and a warning is logged.
*
* @param filePath the file name and path to be interpolated
* @param context contains the available properties
*/
private String replaceFilenameTokens( final String filePath, final Context context )
{
StringBuffer interpolatedResult = new StringBuffer();
Matcher matcher = TOKEN_PATTERN.matcher( filePath );
while ( matcher.find() )
{
String propertyToken = matcher.group( 1 );
String contextPropertyValue = (String) context.get( propertyToken );
if ( contextPropertyValue != null && contextPropertyValue.trim().length() > 0 )
{
if ( getLogger().isDebugEnabled() )
{
getLogger().debug( "Replacing property '" + propertyToken + "' in file path '" + filePath
+ "' with value '" + contextPropertyValue + "'." );
}
matcher.appendReplacement( interpolatedResult, contextPropertyValue );
}
else
{
// Need to skip the undefined property
getLogger().warn( "Property '" + propertyToken + "' was not specified, so the token in '" + filePath
+ "' is not being replaced." );
}
}
matcher.appendTail( interpolatedResult );
if ( getLogger().isDebugEnabled() )
{
getLogger().debug( "Final interpolated file path: '" + interpolatedResult + "'" );
}
return interpolatedResult.toString();
}
private String getPackageInPathFormat( String aPackage )
{
return StringUtils.replace( aPackage, ".", "/" );
}
private boolean isArchetypeConfigured( ArchetypeDescriptor archetypeDescriptor, ArchetypeGenerationRequest request )
{
for ( RequiredProperty requiredProperty : archetypeDescriptor.getRequiredProperties() )
{
if ( StringUtils.isEmpty( request.getProperties().getProperty( requiredProperty.getKey() ) ) )
{
return false;
}
}
return true;
}
private void setParentArtifactId( Context context, String artifactId )
{
context.put( Constants.PARENT_ARTIFACT_ID, artifactId );
}
private Context prepareVelocityContext( ArchetypeGenerationRequest request )
{
Context context = new VelocityContext();
context.put( Constants.GROUP_ID, request.getGroupId() );
context.put( Constants.ARTIFACT_ID, request.getArtifactId() );
context.put( Constants.VERSION, request.getVersion() );
context.put( Constants.PACKAGE, request.getPackage() );
final String packageInPathFormat = getPackageInPathFormat( request.getPackage() );
context.put( Constants.PACKAGE_IN_PATH_FORMAT, packageInPathFormat );
if ( getLogger().isInfoEnabled() )
{
getLogger().info( "----------------------------------------------------------------------------" );
getLogger().info(
"Using following parameters for creating project from Archetype: " + request.getArchetypeArtifactId()
+ ":" + request.getArchetypeVersion() );
getLogger().info( "----------------------------------------------------------------------------" );
getLogger().info( "Parameter: " + Constants.GROUP_ID + ", Value: " + request.getGroupId() );
getLogger().info( "Parameter: " + Constants.ARTIFACT_ID + ", Value: " + request.getArtifactId() );
getLogger().info( "Parameter: " + Constants.VERSION + ", Value: " + request.getVersion() );
getLogger().info( "Parameter: " + Constants.PACKAGE + ", Value: " + request.getPackage() );
getLogger().info( "Parameter: " + Constants.PACKAGE_IN_PATH_FORMAT + ", Value: " + packageInPathFormat );
}
for ( Iterator<?> iterator = request.getProperties().keySet().iterator(); iterator.hasNext(); )
{
String key = (String) iterator.next();
String value = request.getProperties().getProperty( key );
if ( maybeVelocityExpression( value ) )
{
value = evaluateExpression( context, key, value );
}
context.put( key, value );
if ( getLogger().isInfoEnabled() )
{
getLogger().info( "Parameter: " + key + ", Value: " + value );
}
}
return context;
}
private boolean maybeVelocityExpression( String value )
{
return value != null && value.contains( "${" );
}
private String evaluateExpression( Context context, String key, String value )
{
try ( StringWriter stringWriter = new StringWriter() )
{
Velocity.evaluate( context, stringWriter, key, value );
return stringWriter.toString();
}
catch ( Exception ex )
{
return value;
}
}
private void processArchetypeTemplates( AbstractArchetypeDescriptor archetypeDescriptor,
List<String> archetypeResources, ZipFile archetypeZipFile,
String moduleOffset, Context context, String packageName,
File outputDirectoryFile )
throws OutputFileExists, ArchetypeGenerationFailure, FileNotFoundException, IOException
{
processTemplates( packageName, outputDirectoryFile, context, archetypeDescriptor, archetypeResources,
archetypeZipFile, moduleOffset, false );
}
private void processArchetypeTemplatesWithWarning( ArchetypeDescriptor archetypeDescriptor,
List<String> archetypeResources, ZipFile archetypeZipFile,
String moduleOffset, Context context, String packageName,
File outputDirectoryFile )
throws OutputFileExists, ArchetypeGenerationFailure, FileNotFoundException, IOException
{
processTemplates( packageName, outputDirectoryFile, context, archetypeDescriptor, archetypeResources,
archetypeZipFile, moduleOffset, true );
}
private int processFileSet( String directory, List<String> fileSetResources, boolean packaged, String packageName,
Context context, File outputDirectoryFile, String moduleOffset,
String archetypeEncoding, boolean failIfExists )
throws OutputFileExists, ArchetypeGenerationFailure
{
int count = 0;
for ( String template : fileSetResources )
{
File outputFile =
getOutputFile( template, directory, outputDirectoryFile, packaged, packageName, moduleOffset, context );
if ( processTemplate( outputFile, context, Constants.ARCHETYPE_RESOURCES + "/" + template,
archetypeEncoding, failIfExists ) )
{
count++;
}
}
return count;
}
private void processFilesetModule( final String rootArtifactId, final String artifactId,
final List<String> archetypeResources, File pom, final ZipFile archetypeZipFile,
String moduleOffset, File basedirPom, File outputDirectoryFile,
final String packageName, final AbstractArchetypeDescriptor archetypeDescriptor,
final Context context )
throws DocumentException, XmlPullParserException, ArchetypeGenerationFailure, InvalidPackaging, IOException,
OutputFileExists
{
outputDirectoryFile.mkdirs();
getLogger().debug( "Processing module " + artifactId );
getLogger().debug( "Processing module rootArtifactId " + rootArtifactId );
getLogger().debug( "Processing module pom " + pom );
getLogger().debug( "Processing module moduleOffset " + moduleOffset );
getLogger().debug( "Processing module outputDirectoryFile " + outputDirectoryFile );
processFilesetProject( archetypeDescriptor,
StringUtils.replace( artifactId, "${rootArtifactId}", rootArtifactId ),
archetypeResources, pom, archetypeZipFile, moduleOffset, context, packageName,
outputDirectoryFile, basedirPom );
String parentArtifactId = (String) context.get( Constants.PARENT_ARTIFACT_ID );
Iterator<ModuleDescriptor> subprojects = archetypeDescriptor.getModules().iterator();
if ( subprojects.hasNext() )
{
getLogger().debug( artifactId + " has modules (" + archetypeDescriptor.getModules() + ")" );
setParentArtifactId( context, StringUtils.replace( artifactId, "${rootArtifactId}", rootArtifactId ) );
}
while ( subprojects.hasNext() )
{
ModuleDescriptor project = subprojects.next();
String modulePath = StringUtils.replace( project.getDir(), "__rootArtifactId__", rootArtifactId );
modulePath = replaceFilenameTokens( modulePath, context );
File moduleOutputDirectoryFile = new File( outputDirectoryFile, modulePath );
context.put( Constants.ARTIFACT_ID,
StringUtils.replace( project.getId(), "${rootArtifactId}", rootArtifactId ) );
String moduleArtifactId = StringUtils.replace( project.getDir(), "__rootArtifactId__", rootArtifactId );
moduleArtifactId = replaceFilenameTokens( moduleArtifactId, context );
processFilesetModule( rootArtifactId, moduleArtifactId,
archetypeResources, new File( moduleOutputDirectoryFile, Constants.ARCHETYPE_POM ),
archetypeZipFile,
( StringUtils.isEmpty( moduleOffset ) ? "" : ( moduleOffset + "/" ) )
+ StringUtils.replace( project.getDir(), "${rootArtifactId}", rootArtifactId ),
pom, moduleOutputDirectoryFile, packageName, project, context );
}
restoreParentArtifactId( context, parentArtifactId );
getLogger().debug( "Processed " + artifactId );
}
private void processFilesetProject( final AbstractArchetypeDescriptor archetypeDescriptor, final String moduleId,
final List<String> archetypeResources, final File pom,
final ZipFile archetypeZipFile, String moduleOffset, final Context context,
final String packageName, final File outputDirectoryFile,
final File basedirPom )
throws DocumentException, XmlPullParserException, ArchetypeGenerationFailure, InvalidPackaging, IOException,
FileNotFoundException, OutputFileExists
{
getLogger().debug( "Processing fileset project moduleId " + moduleId );
getLogger().debug( "Processing fileset project pom " + pom );
getLogger().debug( "Processing fileset project moduleOffset " + moduleOffset );
getLogger().debug( "Processing fileset project outputDirectoryFile " + outputDirectoryFile );
getLogger().debug( "Processing fileset project basedirPom " + basedirPom );
if ( basedirPom.exists() )
{
processPomWithParent( context, pom, moduleOffset, basedirPom, moduleId );
}
else
{
processPom( context, pom, moduleOffset );
}
processArchetypeTemplates( archetypeDescriptor, archetypeResources, archetypeZipFile, moduleOffset, context,
packageName, outputDirectoryFile );
}
private void processPom( Context context, File pom, String moduleOffset )
throws OutputFileExists, ArchetypeGenerationFailure
{
getLogger().debug( "Processing pom " + pom );
processTemplate( pom, context,
Constants.ARCHETYPE_RESOURCES + getOffsetSeparator( moduleOffset ) + Constants.ARCHETYPE_POM,
getEncoding( null ), true );
}
private void processPomWithMerge( Context context, File pom, String moduleOffset )
throws OutputFileExists, IOException, XmlPullParserException, ArchetypeGenerationFailure
{
getLogger().debug( "Processing pom " + pom + " with merge" );
File temporaryPom = getTemporaryFile( pom );
processTemplate( temporaryPom, context,
Constants.ARCHETYPE_RESOURCES + getOffsetSeparator( moduleOffset ) + Constants.ARCHETYPE_POM,
getEncoding( null ), true );
pomManager.mergePoms( pom, temporaryPom );
// getTemporaryFile sets deleteOnExit. Lets try to delete and then make sure deleteOnExit is
// still set. Windows has issues deleting files with certain JDKs.
try
{
FileUtils.forceDelete( temporaryPom );
}
catch ( IOException e )
{
temporaryPom.deleteOnExit();
}
}
private void processPomWithParent( Context context, File pom, String moduleOffset, File basedirPom,
String moduleId )
throws OutputFileExists, XmlPullParserException, DocumentException, IOException, InvalidPackaging,
ArchetypeGenerationFailure
{
getLogger().debug( "Processing pom " + pom + " with parent " + basedirPom );
processTemplate( pom, context,
Constants.ARCHETYPE_RESOURCES + getOffsetSeparator( moduleOffset ) + Constants.ARCHETYPE_POM,
getEncoding( null ), true );
getLogger().debug( "Adding module " + moduleId );
pomManager.addModule( basedirPom, moduleId );
pomManager.addParent( pom, basedirPom );
}
@SuppressWarnings( "deprecation" )
private boolean processTemplate( File outFile, Context context, String templateFileName, String encoding,
boolean failIfExists )
throws OutputFileExists, ArchetypeGenerationFailure
{
templateFileName = templateFileName.replace( File.separatorChar, '/' );
String localTemplateFileName = templateFileName.replace( '/', File.separatorChar );
if ( !templateFileName.equals( localTemplateFileName ) && !velocity.getEngine().templateExists(
templateFileName ) && velocity.getEngine().templateExists( localTemplateFileName ) )
{
templateFileName = localTemplateFileName;
}
getLogger().debug( "Processing template " + templateFileName );
if ( outFile.exists() )
{
if ( failIfExists )
{
throw new OutputFileExists( "Don't override file " + outFile.getAbsolutePath() );
}
getLogger().warn( "Don't override file " + outFile );
return false;
}
if ( templateFileName.endsWith( "/" ) )
{
getLogger().debug( "Creating directory " + outFile );
outFile.mkdirs();
return true;
}
if ( !outFile.getParentFile().exists() )
{
outFile.getParentFile().mkdirs();
}
getLogger().debug( "Merging into " + outFile );
try ( Writer writer = new OutputStreamWriter( new FileOutputStream( outFile ), encoding ) )
{
StringWriter stringWriter = new StringWriter();
velocity.getEngine().mergeTemplate( templateFileName, encoding, context, stringWriter );
writer.write( StringUtils.unifyLineSeparators( stringWriter.toString() ) );
writer.flush();
}
catch ( Exception e )
{
throw new ArchetypeGenerationFailure( "Error merging velocity templates: " + e.getMessage(), e );
}
return true;
}
private void processTemplates( String packageName, File outputDirectoryFile, Context context,
AbstractArchetypeDescriptor archetypeDescriptor, List<String> archetypeResources,
ZipFile archetypeZipFile, String moduleOffset, boolean failIfExists )
throws OutputFileExists, ArchetypeGenerationFailure, FileNotFoundException, IOException
{
Iterator<FileSet> iterator = archetypeDescriptor.getFileSets().iterator();
if ( iterator.hasNext() )
{
getLogger().debug( "Processing filesets" + "\n " + archetypeResources );
}
int count = 0;
while ( iterator.hasNext() )
{
FileSet fileSet = iterator.next();
count++;
List<String> fileSetResources =
archetypeFilesResolver.filterFiles( moduleOffset, fileSet, archetypeResources );
// This creates an empty directory, even if there is no file to process
// Fix for ARCHETYPE-57
getOutputFile( moduleOffset, fileSet.getDirectory(), outputDirectoryFile, fileSet.isPackaged(), packageName,
moduleOffset, context ).mkdirs();
if ( fileSet.isFiltered() )
{
getLogger().debug( " Processing fileset " + fileSet + " -> " + fileSetResources.size() + ":\n "
+ fileSetResources );
int processed =
processFileSet( fileSet.getDirectory(), fileSetResources, fileSet.isPackaged(), packageName,
context, outputDirectoryFile, moduleOffset, getEncoding( fileSet.getEncoding() ),
failIfExists );
getLogger().debug( " Processed " + processed + " files." );
}
else
{
getLogger().debug( " Copying fileset " + fileSet + " -> " + fileSetResources.size() + ":\n "
+ fileSetResources );
int copied = copyFiles( fileSet.getDirectory(), fileSetResources, fileSet.isPackaged(), packageName,
outputDirectoryFile, archetypeZipFile, moduleOffset, failIfExists, context );
getLogger().debug( " Copied " + copied + " files." );
}
}
getLogger().debug( "Processed " + count + " filesets" );
}
private void restoreParentArtifactId( Context context, String parentArtifactId )
{
if ( StringUtils.isEmpty( parentArtifactId ) )
{
context.remove( Constants.PARENT_ARTIFACT_ID );
}
else
{
context.put( Constants.PARENT_ARTIFACT_ID, parentArtifactId );
}
}
private File getTemporaryFile( File file )
{
File tmp = FileUtils.createTempFile( file.getName(), Constants.TMP, file.getParentFile() );
tmp.deleteOnExit();
return tmp;
}
}