AbstractConfigurationMojo.java
package org.andromda.maven.plugin.configuration;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
import java.util.Properties;
import org.andromda.core.common.ResourceUtils;
import org.andromda.core.configuration.Configuration;
import org.apache.commons.lang.ObjectUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Settings;
import org.apache.maven.shared.filtering.PropertyUtils;
import org.codehaus.plexus.util.InterpolationFilterReader;
/**
* An abstract Mojo for dealing with the AndroMDA configuration,
* if a plugin needs to use the AndroMDA configuration, it should extend this
* class.
*
* @author Chad Brandon
* @author Bob Fields
*/
public abstract class AbstractConfigurationMojo
extends AbstractMojo
{
/**
* The path to the mappings within the plugin.
*/
private static final String MAPPINGS_PATH = "META-INF/andromda/mappings";
/**
* Creates the Configuration instance from the {@link URL}
*
* @param configurationUri
* @return the configuration instance
* @throws IOException if the URL is invalid.
*/
protected Configuration getConfiguration(final URL configurationUri)
throws IOException
{
final String contents = this.replaceProperties(ResourceUtils.getContents(configurationUri));
final Configuration configuration = Configuration.getInstance(contents);
final URL mappingsUrl = ResourceUtils.getResource(MAPPINGS_PATH);
if (mappingsUrl != null)
{
configuration.addMappingsSearchLocation(mappingsUrl.toString());
}
return configuration;
}
/**
* Collects and returns all properties as a Properties instance.
*
* @return the properties including those from the project, settings, etc.
* @throws IOException
*/
protected Properties getProperties()
throws IOException
{
// System properties
final Properties properties = new Properties();
properties.put(
"settings",
this.getSettings());
// - project properties
properties.putAll(this.getProject().getProperties());
for (final String propertiesFile : (Iterable<String>) this.getPropertyFiles())
{
final Properties projectProperties = PropertyUtils.loadPropertyFile(
new File(propertiesFile),
true,
true);
properties.putAll(projectProperties);
}
for (Object objProperty : properties.keySet())
{
final String property = (String) objProperty;
final String value = this.replaceProperties(
properties,
ObjectUtils.toString(properties.get(property)));
properties.put(
property,
value);
}
properties.putAll(System.getProperties());
return properties;
}
/**
* Replaces all properties having the style
* <code>${some.property}</code> with the value
* of the specified property if there is one.
*
* @param string the string to perform replacement on.
* @return this.replaceProperties(this.getProperties(),string);
* @throws IOException
*/
protected String replaceProperties(final String string)
throws IOException
{
return this.replaceProperties(
this.getProperties(),
string);
}
/**
* The begin token for interpolation.
*/
private static final String BEGIN_TOKEN = "${";
/**
* The end token for interpolation.
*/
private static final String END_TOKEN = "}";
/**
* Replaces all properties having the style
* <code>${some.property}</code> with the value
* of the specified property if there is one.
*
* @param properties the properties used to perform the replacement.
* @param string the fileContents to perform replacement on.
*/
private String replaceProperties(
final Properties properties,
final String string)
throws IOException
{
final StringReader stringReader = new StringReader(string);
InterpolationFilterReader reader = new InterpolationFilterReader(stringReader, properties, "${", "}");
reader.reset();
reader = new InterpolationFilterReader(
reader,
new BeanProperties(this.getProject()),
BEGIN_TOKEN,
END_TOKEN);
reader = new InterpolationFilterReader(
reader,
new BeanProperties(this.getSettings()),
BEGIN_TOKEN,
END_TOKEN);
return ResourceUtils.getContents(reader);
}
/**
* Sets the current context class loader from the given runtime classpath elements.
*
* @param classpathFiles
* @throws MalformedURLException
*/
protected void initializeClasspathFromClassPathElements(final List<String> classpathFiles)
throws MalformedURLException
{
if (classpathFiles != null && !classpathFiles.isEmpty())
{
final URL[] classpathUrls = new URL[classpathFiles.size()];
for (int ctr = 0; ctr < classpathFiles.size(); ++ctr)
{
final File file = new File(classpathFiles.get(ctr));
if (this.getLog().isDebugEnabled())
{
getLog().debug("adding to classpath '" + file + '\'');
}
classpathUrls[ctr] = file.toURI().toURL();
}
final URLClassLoader loader =
new ConfigurationClassLoader(classpathUrls,
Thread.currentThread().getContextClassLoader());
Thread.currentThread().setContextClassLoader(loader);
}
}
/**
* Adds any dependencies to the current project from the plugin
* having the given <code>pluginArtifactId</code>.
*
* @param pluginArtifactId the artifactId of the plugin of which to add its dependencies.
* @param scope the artifact scope in which to add them (runtime, compile, etc).
*/
protected void addPluginDependencies(
final String pluginArtifactId,
final String scope)
{
if (pluginArtifactId != null)
{
final List<Plugin> plugins = this.getPlugins();
if (plugins != null)
{
for (final Plugin plugin : plugins)
{
if (pluginArtifactId.equals(plugin.getArtifactId()))
{
final List<Dependency> dependencies = plugin.getDependencies();
if (dependencies != null)
{
for (Dependency dependency : plugin.getDependencies())
{
this.addDependency(
dependency,
scope);
}
}
}
}
}
}
}
// Can't do anything about raw Collection types in MavenProject dependency
@SuppressWarnings("unchecked")
/**
* Adds a dependency to the current project's dependencies.
*
* @param dependency
*/
private void addDependency(
final Dependency dependency,
final String scope)
{
final ArtifactRepository localRepository = this.getLocalRepository();
final MavenProject project = this.getProject();
if (project != null && localRepository != null)
{
if (dependency != null)
{
final Artifact artifact =
this.getFactory().createArtifact(
dependency.getGroupId(),
dependency.getArtifactId(),
dependency.getVersion(),
scope,
dependency.getType());
final File file = new File(
localRepository.getBasedir(),
localRepository.pathOf(artifact));
artifact.setFile(file);
project.getDependencies().add(dependency);
project.getArtifacts().add(artifact);
}
}
}
/**
* Gets the current project.
*
* @return Returns the project.
*/
protected abstract MavenProject getProject();
/**
* Gets the property files for the profile (the ones defined
* in the filters section of the POM).
*
* @return Returns the propertyFiles.
*/
protected abstract List<String> getPropertyFiles();
/**
* Gets the current settings of the project.
*
* @return Returns the settings.
*/
protected abstract Settings getSettings();
/**
* Gets the artifact factory used to construct any new required artifacts.
* @return ArtifactFactory
*/
protected abstract ArtifactFactory getFactory();
/**
* Gets the current project's registered plugin implementations.
* @return pluginList
*
* @parameter expression="${project.build.plugins}"
* @required
* @readonly
*/
protected abstract List<Plugin> getPlugins();
/**
* Gets the current local repository instance.
*
* @return the local repository instance of the current project.
*/
protected abstract ArtifactRepository getLocalRepository();
/**
* Set this to 'true' to bypass cartridge tests entirely. Its use is NOT RECOMMENDED, but quite convenient on occasion.
*
* @parameter expression="${maven.test.skip}" default-value="false"
*/
protected boolean skip;
/**
* Set this to 'true' to skip running tests, but still compile them. Its use is NOT RECOMMENDED, but quite convenient on occasion.
*
* @parameter expression="${skipTests}" default-value="false"
*/
protected boolean skipTests;
/**
* Set this to true to ignore a failure during testing. Its use is NOT RECOMMENDED, but quite convenient on occasion.
*
* @parameter expression="${maven.test.failure.ignore}" default-value="false"
*/
protected boolean testFailureIgnore;
}