AndroMDAGenTask.java
package org.andromda.ant.task;
import java.io.FileNotFoundException;
import java.net.URL;
import java.util.Map;
import org.andromda.core.AndroMDA;
import org.andromda.core.common.ResourceUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.taskdefs.MatchingTask;
/**
* <p/> This class wraps the AndroMDA model processor so that AndroMDA can be
* used as an Ant task. Represents the <code><andromda></code> custom
* task which can be called from an Ant build script.
* </p>
*
* @author <a href="http://www.mbohlen.de">Matthias Bohlen </a>
* @author <a href="http://www.amowers.com">Anthony Mowers </a>
* @author Chad Brandon
* @see org.andromda.core.AndroMDA
*/
public class AndroMDAGenTask
extends MatchingTask
{
/**
* Initialize the context class loader.
*/
static
{
initializeContextClassLoader();
}
/**
* Stores the configuration URI.
*/
private URL configurationUri;
/**
* Sets the URI to the configuration file.
*
* @param configurationUri
*/
public void setConfigurationUri(final URL configurationUri)
{
this.configurationUri = configurationUri;
}
/**
* <p/>
* Starts the generation of source code from an object model. </p>
* <p/>
* This is the main entry point of the application when running Ant. It is called by ant whenever the surrounding
* task is executed (which could be multiple times). </p>
*
* @throws BuildException if something goes wrong
*/
public void execute()
throws BuildException
{
// initialize before the execute as well in case we
// want to execute more than once
initializeContextClassLoader();
try
{
if (this.configurationUri == null)
{
throw new BuildException("Configuration is not a valid URI --> '" + this.configurationUri + '\'');
}
final AndroMDA andromda = AndroMDA.newInstance();
if (andromda != null)
{
andromda.run(
this.replaceProperties(ResourceUtils.getContents(configurationUri)));
andromda.shutdown();
}
}
catch (Throwable throwable)
{
final Throwable cause = ExceptionUtils.getCause(throwable);
if (cause != null)
{
throwable = cause;
}
if (throwable instanceof FileNotFoundException)
{
throw new BuildException("No configuration could be loaded from --> '" + configurationUri + '\'');
}
throw new BuildException(throwable);
}
finally
{
// Set the context class loader back ot its system class loaders
// so that any processes running after won't be trying to use
// the ContextClassLoader for this class.
Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
}
}
/**
* Replaces all properties having the style
* <code>${some.property}</code> with the value
* of the specified property if there is one.
*
* @param string the fileContents to perform replacement on.
* @return replaced properties
*/
protected String replaceProperties(String string)
{
@SuppressWarnings("unchecked")
final Map<String, Object> properties = this.getProject().getProperties();
if (properties != null)
{
for (Map.Entry<String, Object> entry : properties.entrySet())
{
final String name = entry.getKey();
final String value = (String)entry.getValue();
final String property = "${" + name + '}';
string = StringUtils.replace(string, property, value);
}
}
// remove any left over property references
string = this.removePropertyReferences(string);
return string;
}
/**
* The property reference pattern.
*/
private static final String PROPERTY_REFERENCE = "\\$\\{.*\\}";
/**
* Removes any ${some.property} type references from the string
* and returns the modifed string.
* @param string the string from which to remove the property
* references
*
* @return the modified string.
*/
public String removePropertyReferences(String string)
{
if (string != null)
{
string = string.replaceAll(PROPERTY_REFERENCE, "");
}
return string;
}
/**
* Set the context class loader so that any classes using it (the contextContextClassLoader) have access to the
* correct loader.
*/
private static void initializeContextClassLoader()
{
Thread.currentThread().setContextClassLoader(AndroMDAGenTask.class.getClassLoader());
}
}