// TODO temporarily allow partial generation, remove it later
if (!archetype.isAllowPartial() &&
outputDirectoryFile.exists() &&
outputDirectoryFile.listFiles().length > 0)
{
throw new ArchetypeTemplateProcessingException(
outputDirectoryFile.getName() + " already exists - please run from a clean directory");
}
outputDirectoryFile.mkdir();
}
String outputDirectory = outputDirectoryFile.getAbsolutePath();
// ----------------------------------------------------------------------
// Set up the Velocity context
// ----------------------------------------------------------------------
VelocityContext context = new VelocityContext();
String packageName = (String) parameters.get("package");
addParamToContext("package", packageName, context);
addParamToContext("packagePath", StringUtils.replace(packageName, ".", "/"), context);
for (Iterator iterator = parameters.keySet().iterator(); iterator.hasNext();)
{
String key = (String) iterator.next();
Object value = parameters.get(key);
addParamToContext(key, value, context);
}
//add in the specified system properties
//if this were a mojo could have set the settings using the ${settings} expression. Since it is not need to get it from the settings builder
boolean inInteractiveMode = false;
try
{
inInteractiveMode = settingsBuilder.buildSettings().getInteractiveMode().booleanValue();
//TODO there must be a cleaner way of doing this
String temp = System.getProperty("interactive", null);
if (temp != null)
{
inInteractiveMode = Boolean.valueOf(temp).booleanValue();
}
getLogger().info("Interactive is: " + inInteractiveMode);
}
catch (Exception ie)
{
throw new ArchetypeTemplateProcessingException("unable to read settings ", ie);
}
if (inInteractiveMode)
{
getLogger().info("Please enter the values for the following archetype variables:");
}
final List variables = archetype.getVariables();
processVariables(variables.iterator(), context, inInteractiveMode);
// ---------------------------------------------------------------------
// Get Logger and display all parameters used
// ---------------------------------------------------------------------
if (getLogger().isInfoEnabled())
{
Object[] keys = context.getKeys();
if (keys.length > 0)
{
getLogger().info("----------------------------------------------------------------------------");
getLogger().info("Using following parameters for creating Archetype: " + archetypeArtifactId + ":" +
archetypeVersion);
getLogger().info("----------------------------------------------------------------------------");
for (int i = 0; i < keys.length; i++)
{
String parameterName = (String) keys[i];
Object parameterValue = context.get(parameterName);
getLogger().info("Parameter: " + parameterName + " = " + parameterValue);
}
}
else
{
getLogger().info("No Parameters found for creating Archetype");
}
}
// ----------------------------------------------------------------------
// Extract the archetype to the chosen directory
// ----------------------------------------------------------------------
try
{
archetypeJarFile = new JarFile(archetypeArtifact.getFile());
Enumeration entries = archetypeJarFile.entries();
while (entries.hasMoreElements())
{
JarEntry entry = (JarEntry) entries.nextElement();
String path = entry.getName();
if (!path.startsWith(ARCHETYPE_RESOURCES) || path.endsWith(".vm"))
{
continue;
}
File t = new File(outputDirectory, path.substring(19));
if (entry.isDirectory())
{
// Assume directories are stored parents first then children.
getLogger().debug("Extracting directory: " + entry.getName() + " to " + t.getAbsolutePath());
t.mkdir();
continue;
}
getLogger().debug("Extracting file: " + entry.getName() + " to " + t.getAbsolutePath());
t.createNewFile();
IOUtil.copy(archetypeJarFile.getInputStream(entry), new FileOutputStream(t));
}
archetypeJarFile.close();
//remove the archetype descriptor
File t = new File(outputDirectory, ARCHETYPE_DESCRIPTOR);
t.delete();
}
catch (IOException ioe)
{
throw new ArchetypeTemplateProcessingException("Error extracting archetype", ioe);
}
// ----------------------------------------------------------------------
// Process the templates
// ----------------------------------------------------------------------
// use the out of the box codehaus velocity component that loads templates
//from the class path
ClassLoader old = Thread.currentThread().getContextClassLoader();
try
{
URL[] urls = new URL[1];
urls[0] = archetypeArtifact.getFile().toURI().toURL();
URLClassLoader archetypeJarLoader = new URLClassLoader(urls);
Thread.currentThread().setContextClassLoader(archetypeJarLoader);
for (Iterator i = archetype.getTemplates().iterator(); i.hasNext();)
{
final Template template = (Template) i.next();
// Check the optional 'condition' property on the template.
// If present and the variable it points to is 'true', then
// continue processing. If it's false, then skip.
// If condition is not specified, assume the template should
// be processed.
boolean shouldProcess = true;
String condition = template.getDependsOnVar();
String requiredValue = null;
List options = new ArrayList();
if (StringUtils.isNotEmpty(condition))
{
//Crappy logic processing -- for now
boolean not = false;
//Allow very simple matching logic to match templates against variable values
int x = condition.indexOf("!=");
getLogger().debug("Processing Condition : " + condition);
if (x > -1)
{
not = true;
requiredValue = condition.substring(x + 2).trim();
options = getListOfValues(requiredValue);
condition = condition.substring(0, x).trim();
}
else
{
x = condition.indexOf("=");
if (x > -1)
{
requiredValue = condition.substring(x + 1);
options = getListOfValues(requiredValue);
condition = condition.substring(0, x);
}
}
getLogger().debug("Not Expr: " + not);
getLogger().debug("Condition Value: '" + condition + "'");
getLogger().debug("Required Value: '" + requiredValue + "'");
final Variable var = (Variable) findVariable(condition, variables);
if (var != null)
{
final String strValue = (String) context.get(var.getName());
getLogger().debug("Variable Value is: '" + strValue + "'");
if (requiredValue == null)
{
if (!Boolean.valueOf(strValue).booleanValue())
{
shouldProcess = false;
}
}
else
{
if (!options.contains(strValue))
{
shouldProcess = false;
}
}
}
else
{
getLogger().debug("Variable Value is: null");
shouldProcess = false;
}
if (not)
{
shouldProcess = !shouldProcess;
}
}
if (shouldProcess)
{
processTemplate(template, outputDirectory, context);
}
else
{
getLogger().debug("Condition not met, skipping " + template.getOutput());
}
}
}
catch (MalformedURLException mfe)
{
throw new ArchetypeTemplateProcessingException("Error loading archetype resources into the classpath", mfe);
}
finally
{
Thread.currentThread().setContextClassLoader(old);
}