BootstrapInstallMojo.java
package org.andromda.maven.plugin.bootstrap.install;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Provides the installation of bootstrap artifacts.
*
* @author Chad Brandon
* @goal install
* @phase install
*/
public class BootstrapInstallMojo
extends AbstractMojo
{
/**
* The maven project.
*
* @parameter expression="${project}"
* @required
* @readonly
* @description "the maven project to use"
*/
protected MavenProject project;
/**
* @parameter expression="${localRepository}"
* @required
* @readonly
*/
protected ArtifactRepository localRepository;
/**
* @parameter expression="${bootstrap.artifacts}"
* @description whether or not bootstrap artifacts should be installed, by default they are.
*/
protected boolean installBootstraps = true;
/**
* @parameter
* @required
* @description the directory to which the bootstrap artifact should be installed.
*/
protected String installDirectory;
/**
* @parameter expression="org.andromda"
* @required
* @readonly
* @description the name of the project groupId.
*/
protected String projectGroupId;
/**
* @parameter expression="org.andromda.bootstrap"
* @required
* @readonly
* @description the name of the project bootstrap groupId.
*/
protected String projectBootstrapGroupId;
/**
* The extension for "JAR" files.
*/
private static final String JAR_EXTENSION = "jar";
/**
* The extension for "POM" files.
*/
private static final String POM_EXTENSION = "pom";
/**
* The qualifier for source artifacts.
*/
private static final String SOURCES_QUALIFIER = "-sources";
/**
* The qualifier for javadoc artifacts.
*/
private static final String JAVADOC_QUALIFIER = "-javadoc";
/**
* The qualifier for test artifacts.
*/
private static final String TEST_QUALIFIER = "-test";
/**
* @see org.apache.maven.plugin.Mojo#execute()
*/
public void execute()
throws MojoExecutionException, MojoFailureException
{
if (this.installBootstraps)
{
try
{
final File installDirectory = new File(this.installDirectory);
if (!installDirectory.exists() || !installDirectory.isDirectory())
{
throw new MojoExecutionException("'" + installDirectory + "' is not a valid install directory");
}
Artifact artifact = this.project.getArtifact();
final String path = this.replaceExtension(artifact, JAR_EXTENSION, null);
final String localRepositoryDirectory = this.localRepository.getBasedir();
final File existingFile = new File(localRepositoryDirectory, path);
final String bootstrapGroupId = this.getBootstrapGroupId(artifact);
final String bootstrapPath = bootstrapGroupId.replace('.', '/')
+ '/' + artifact.getArtifactId();
final File bootstrapPomFile = new File(installDirectory, bootstrapPath + '.' + POM_EXTENSION);
this.writeMinimalPom(bootstrapPomFile);
final File bootstrapFile = new File(installDirectory, bootstrapPath + '.' + JAR_EXTENSION);
this.getLog().info("Installing bootstrap artifact: " + bootstrapFile);
if (path != null)
{
FileUtils.copyFile(existingFile, bootstrapFile);
}
final String sourcePath = this.replaceExtension(artifact, JAR_EXTENSION, SOURCES_QUALIFIER);
if (sourcePath != null)
{
this.getLog().info("Installing bootstrap artifact: " + sourcePath);
FileUtils.copyFile(new File(localRepositoryDirectory, sourcePath), new File(installDirectory, bootstrapPath + SOURCES_QUALIFIER + '.' + JAR_EXTENSION));
}
final String javadocPath = this.replaceExtension(artifact, JAR_EXTENSION, JAVADOC_QUALIFIER);
if (javadocPath != null)
{
this.getLog().info("Installing bootstrap artifact: " + javadocPath);
FileUtils.copyFile(new File(localRepositoryDirectory, javadocPath), new File(installDirectory, bootstrapPath + JAVADOC_QUALIFIER + '.' + JAR_EXTENSION));
}
final String testSourcePath = this.replaceExtension(artifact, JAR_EXTENSION, TEST_QUALIFIER + SOURCES_QUALIFIER);
if (testSourcePath != null)
{
this.getLog().info("Installing bootstrap artifact: " + testSourcePath);
FileUtils.copyFile(new File(localRepositoryDirectory, testSourcePath), new File(installDirectory, bootstrapPath + TEST_QUALIFIER + SOURCES_QUALIFIER + '.' + JAR_EXTENSION));
}
final String testJavadocPath = this.replaceExtension(artifact, JAR_EXTENSION, TEST_QUALIFIER + JAVADOC_QUALIFIER);
if (testJavadocPath != null)
{
this.getLog().info("Installing bootstrap artifact: " + testJavadocPath);
FileUtils.copyFile(new File(localRepositoryDirectory, testJavadocPath), new File(installDirectory, bootstrapPath + TEST_QUALIFIER + JAVADOC_QUALIFIER + '.' + JAR_EXTENSION));
}
}
catch (final Throwable throwable)
{
throw new MojoExecutionException("Error creating bootstrap artifact", throwable);
}
}
}
/**
* Clears the POM's model of its parent or any dependencies
* it may have so that we can write a POM that isn't dependent on anything
* (which we need for bootstrap artifacts).
*
* @param bootstrapPomFile the bootstrap POM file to write.
*/
private void writeMinimalPom(final File bootstrapPomFile)
throws IOException
{
final Model model = this.project.getModel();
final MavenProject minimalProject = new MavenProject();
final Model minModel = minimalProject.getModel();
minModel.setGroupId(getBootstrapGroupId(this.project.getArtifact()));
minModel.setArtifactId(model.getArtifactId());
minModel.setVersion(model.getVersion());
minModel.setName(model.getName());
minModel.setPackaging("jar");
minModel.setDescription(model.getDescription());
minModel.setModelEncoding(model.getModelEncoding());
minModel.setModelVersion(model.getModelVersion());
minModel.setUrl(model.getUrl());
minModel.setScm(model.getScm());
minModel.setDevelopers(model.getDevelopers());
minModel.setCiManagement(model.getCiManagement());
minModel.setIssueManagement(model.getIssueManagement());
minModel.setPrerequisites(model.getPrerequisites());
minModel.setOrganization(model.getOrganization());
minModel.setInceptionYear(model.getInceptionYear());
minModel.setLicenses(model.getLicenses());
final List<Dependency> dependencies = new ArrayList<Dependency>(model.getDependencies());
// filter all of andromda dependencies away
CollectionUtils.filter(dependencies, new Predicate()
{
public boolean evaluate(Object object)
{
Dependency dependency = (Dependency)object;
final String lGroupId = dependency.getGroupId();
return !lGroupId.startsWith("org.andromda") || lGroupId.startsWith("org.andromda.thirdparty");
}
});
minModel.setDependencies(dependencies);
final FileWriter fileWriter = new FileWriter(bootstrapPomFile);
minimalProject.writeModel(fileWriter);
fileWriter.flush();
}
/**
* Retrieves the project's bootstrap groupId from the given <code>artifact</code>.
*
* @param artifact the artifact from which to retrieve the group Id.
* @return the bootstrap groupId.
*/
private String getBootstrapGroupId(final Artifact artifact)
{
return StringUtils.replaceOnce(
artifact.getGroupId(),
this.projectGroupId,
this.projectBootstrapGroupId);
}
/**
* Retrieves the repository artifact file name with extension removed and qualifier added.
* If the file does not yet exist in the local repository, returns null
*
* @param artifact the artifact from which to retrieve the version information.
* @param newExtension new extension for the file
* @param qualifier the -qualifier for the repo artifact such as -sources -javadocs -test-sources -test-javadocs
* @return the artifact name with no version and extension removed.
*/
private String replaceExtension(
final Artifact artifact,
final String newExtension,
final String qualifier)
{
String path = this.localRepository.pathOf(artifact);
File artifactFile = new File(this.localRepository.getBasedir(), path);
if (!artifactFile.exists())
{
this.getLog().error("Bootstrap artifact does not exist: " + path);
return null;
}
final String version = artifact.getVersion() != null ? artifact.getVersion().trim() : "";
int versionIndex = path.lastIndexOf(artifact.getVersion());
final String extension = path.substring(
versionIndex + version.length() + 1,
path.length());
int extensionIndex = path.lastIndexOf(extension);
if (StringUtils.isNotBlank(qualifier))
{
path = path.substring(0, extensionIndex-1) + qualifier + '.' + extension;
File qualifiedFile = new File(this.localRepository.getBasedir(), path);
if (!qualifiedFile.exists())
{
this.getLog().warn("Bootstrap qualified artifact does not exist: " + path);
return null;
}
}
if (!newExtension.equals(extension))
{
path = path.substring(0, extensionIndex) + newExtension;
}
return path;
}
}