package org.codehaus.mojo.cis.maven;
import java.io.File;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.AbstractArtifactResolutionException;
import org.apache.maven.artifact.resolver.ArtifactCollector;
import org.apache.maven.artifact.resolver.ArtifactResolver;
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.maven.shared.dependency.tree.DependencyTree;
import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder;
import org.apache.maven.shared.dependency.tree.DependencyTreeBuilderException;
import org.codehaus.mojo.cis.core.CisUtils;
/**
* Abstract base class for deriving CIS related mojos.
*/
public abstract class AbstractCisMojo extends AbstractMojo
{
private static final String CIS_GROUP_ID = "com.softwareag.cis";
private static final String CIS_ARTIFACT_ID = "cis";
/**
* Specifies a particular CIS webapp artifact to use.
* By default, the CIS webapp is derived from the cis jar file.
* The CIS webapp artifact is used to extract the {@code cisconfig.xml}
* file.
*
* @parameter
*/
private org.codehaus.mojo.cis.model.Artifact cisWebappArtifact;
/**
* The CIS home directory. This is the directory, where the
* web application is being assembled.
* @parameter expression="${cis.homeDir}"
*/
private File cisHomeDir;
/**
* The CIS markers directory. This is the directory, where the
* marker files are being created.
*
* @parameter expression="${cis.markersDir}" default-value="${project.build.directory}/cis-maven-plugin/markers"
*/
private File cisMarkersDirectory;
/**
* The maven project. This is a component, which is set automatically by Maven and
* must not be set by the user.
*
* @parameter expression="${project}"
* @required
* @readonly
*/
private MavenProject project;
/**
* The dependency tree builder to use. This is a component,
* which is set automatically by Maven and must not be set
* by the user.
*
* @component
* @required
* @readonly
*/
private DependencyTreeBuilder dependencyTreeBuilder;
/**
* The artifact collector to use. This is a component,
* which is set automatically by Maven and must not be set
* by the user.
*
* @component
* @required
* @readonly
*/
private ArtifactCollector artifactCollector;
/**
* The artifact metadata source to use. This is a component,
* which is set automatically by Maven and must not be set
* by the user.
*
* @component
* @required
* @readonly
*/
private ArtifactMetadataSource artifactMetadataSource;
/**
* Returns the web application directory.
*/
protected File getCisHomeDir()
{
return cisHomeDir;
}
/**
* Returns the marker directory.
*/
protected File getCisMarkersDir()
{
return cisMarkersDirectory;
}
/**
* Returns a new instance of {@link CisUtils}.
*/
protected CisUtils newCisUtils()
{
return new MavenCisUtils(this);
}
/**
* Returns the Maven project, which is currently being built.
*/
protected MavenProject getProject() {
return project;
}
/**
* The artifact factory to use. This is a component,
* which is set automatically by Maven and must not be set
* by the user.
*
* @component
* @required
* @readonly
*/
private ArtifactFactory artifactFactory;
/**
* The artifact resolver to use. This is a component,
* which is set automatically by Maven and must not be set
* by the user.
*
* @component
* @required
* @readonly
*/
private ArtifactResolver artifactResolver;
/**
* The local repository to use. This is a parameter,
* which is set automatically by Maven and must not be set
* by the user.
*
* @parameter expression="${localRepository}"
* @required
* @readonly
*/
private ArtifactRepository localRepository;
/**
* The list of remote repositories to use. This is a parameter,
* which is set automatically by Maven and must not be set
* by the user.
*
* @parameter expression="${project.remoteArtifactRepositories}"
* @required
* @readonly
*/
private List remoteRepositories;
/**
* Returns the location of the {@code cis.jar} artifact.
*/
protected Artifact getCisJar( boolean pRequired )
throws MojoFailureException, MojoExecutionException
{
return getDependency( CIS_GROUP_ID, CIS_ARTIFACT_ID, "jar", "", pRequired );
}
/**
* Returns the location of the given artifact.
*/
protected Artifact getDependency( final String pGroupId,
final String pArtifactId, final String pType,
final String pClassifier,
boolean pRequired)
throws MojoExecutionException, MojoFailureException
{
// Search for cis-x.y.jar, first in the direct dependencies
Artifact a = getDirectDependency( pGroupId, pArtifactId, pType, pClassifier );
if ( a == null )
{
a = getIndirectDependency( pGroupId, pArtifactId, pType, pClassifier );
if ( a == null )
{
if ( pRequired )
{
throw new MojoFailureException( "The project doesn't have a dependency "
+ pGroupId + ":" + pArtifactId + ":"
+ pClassifier + ":" + pType );
}
}
}
return a;
}
private Artifact getIndirectDependency( final String pGroupId,
final String pArtifactId, final String pType,
final String pClassifier )
throws MojoExecutionException
{
// Not found, search for cis-x.y.jar in the transitive dependencies
DependencyTree tree;
try
{
tree = dependencyTreeBuilder.buildDependencyTree( getProject(), localRepository, artifactFactory,
artifactMetadataSource, artifactCollector );
}
catch ( DependencyTreeBuilderException e )
{
throw new MojoExecutionException( e.getMessage(), e );
}
for ( Iterator iter = tree.getArtifacts().iterator(); iter.hasNext(); )
{
Artifact a = (Artifact) iter.next();
final String cl = a.getClassifier() == null ? "" : a.getClassifier();
if ( pGroupId.equals( a.getGroupId() )
&& pArtifactId.equals( a.getArtifactId() )
&& pClassifier.equals( cl )
&& pType.equals( a.getType() ) )
{
return a;
}
}
return null;
}
private Artifact getDirectDependency( final String pGroupId,
final String pArtifactId, final String pType,
final String pClassifier )
{
final Set artifacts = getProject().getDependencyArtifacts();
if ( artifacts != null )
{
for ( Iterator iter = artifacts.iterator(); iter.hasNext(); )
{
Artifact a = (Artifact) iter.next();
final String cl = a.getClassifier() == null ? "" : a.getClassifier();
if ( pGroupId.equals( a.getGroupId() )
&& pArtifactId.equals( a.getArtifactId() )
&& pClassifier.equals( cl )
&& pType.equals( a.getType() ) )
{
return a;
}
}
}
return null;
}
/**
* Returns the location of the {@code cis.war} artifact.
*/
protected Artifact getCisWebapp()
throws MojoExecutionException, MojoFailureException
{
if ( cisWebappArtifact == null )
{
final Artifact cisJarArtifact = getCisJar( true );
if ( cisJarArtifact == null )
{
throw new MojoFailureException( "Unable to determine a source file. "
+ " Use either of the parameters "
+ " cisConfigSourceFile or"
+ " cisWebappArtifact to configure it." );
}
cisWebappArtifact = new org.codehaus.mojo.cis.model.Artifact();
cisWebappArtifact.setArtifactId( cisJarArtifact.getArtifactId() + "-webapp" );
cisWebappArtifact.setGroupId( cisJarArtifact.getGroupId() );
cisWebappArtifact.setVersion( cisJarArtifact.getVersion() );
cisWebappArtifact.setScope( cisJarArtifact.getScope() );
cisWebappArtifact.setClassifier( cisJarArtifact.getClassifier() );
cisWebappArtifact.setType( "war" );
}
return findCisWebapp();
}
private Artifact findCisWebapp() throws MojoExecutionException
{
final String groupId = cisWebappArtifact.getGroupId();
final String artifactId = cisWebappArtifact.getArtifactId();
final String version = cisWebappArtifact.getVersion();
final String scope = cisWebappArtifact.getScope() == null ? Artifact.SCOPE_COMPILE : cisWebappArtifact.getScope();
final String classifier = cisWebappArtifact.getClassifier();
final String type = cisWebappArtifact.getType() == null ? "war" : cisWebappArtifact.getType();
Artifact artifact = artifactFactory.createArtifactWithClassifier( groupId, artifactId, version, type, classifier );
artifact.setScope( scope );
/* Make sure, that the artifact is available in the local repository.
* This ensures, that we can access it through
* <code>localRepository.pathOf( artifact )</code> later on.
*/
try
{
artifactResolver.resolve( artifact, remoteRepositories, localRepository );
}
catch ( AbstractArtifactResolutionException e )
{
throw new MojoExecutionException( "Failed to resolve artifact "
+ artifact.getGroupId() + ":"
+ artifact.getArtifactId() + ":"
+ artifact.getVersion() + ": "
+ e.getMessage(), e );
}
return artifact;
}
/**
* Returns the location of the {@code cis.war} file as an
* instance of {@link java.io.File}.
*/
protected File getCisWebappFile() throws MojoExecutionException, MojoFailureException
{
final Artifact artifact = getCisWebapp();
return new File( localRepository.getBasedir(), localRepository.pathOf( artifact ) );
}
}