Index: AbstractWarMojo.java =================================================================== --- AbstractWarMojo.java (revision 549923) +++ AbstractWarMojo.java (working copy) @@ -22,6 +22,13 @@ import org.apache.maven.archiver.MavenArchiveConfiguration; import org.apache.maven.archiver.MavenArchiver; import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.DefaultArtifact; +import org.apache.maven.artifact.metadata.ArtifactMetadataSource; +import org.apache.maven.artifact.resolver.ArtifactNotFoundException; +import org.apache.maven.artifact.resolver.ArtifactResolutionException; +import org.apache.maven.artifact.resolver.ArtifactResolutionResult; +import org.apache.maven.artifact.resolver.ResolutionNode; +import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter; import org.apache.maven.model.Resource; import org.apache.maven.plugin.AbstractMojo; @@ -61,7 +68,42 @@ public abstract class AbstractWarMojo extends AbstractMojo { + + /** + * Location of the local repository. + * + * @parameter expression="${localRepository}" + * @readonly + * @required + */ + protected org.apache.maven.artifact.repository.ArtifactRepository local; + /** + * List of Remote Repositories used by the resolver + * + * @parameter expression="${project.remoteArtifactRepositories}" + * @readonly + * @required + */ + protected java.util.List remoteRepos; + + /** + * Used to look up Artifacts in the remote repository. + * + * @parameter expression="${component.org.apache.maven.artifact.resolver.ArtifactResolver}" + * @required + * @readonly + */ + protected org.apache.maven.artifact.resolver.ArtifactResolver resolver; + + /** + * @component + * @required + * @readonly + */ + protected ArtifactMetadataSource source; + + /** * The maven project. * * @parameter expression="${project}" @@ -586,86 +628,146 @@ copyDirectoryStructureIfModified( classesDirectory, webappClassesDirectory ); } } + + Set dependencyArtifacts = project.getDependencyArtifacts(); + ArtifactResolutionResult resolverResult; + ArtifactFilter filter = new ScopeArtifactFilter(DefaultArtifact.SCOPE_RUNTIME); + + try { + resolverResult = resolver.resolveTransitively(dependencyArtifacts, project.getArtifact(),local,remoteRepos, source, filter); + + filterOptional(resolverResult); + + Set artifacts = resolverResult.getArtifacts(); + + List duplicates = findDuplicates( artifacts ); - Set artifacts = project.getArtifacts(); + List dependentWarDirectories = new ArrayList(); - List duplicates = findDuplicates( artifacts ); + for ( Iterator iter = artifacts.iterator(); iter.hasNext(); ) + { + Artifact artifact = (Artifact) iter.next(); + String targetFileName = getFinalName( artifact ); - List dependentWarDirectories = new ArrayList(); + getLog().debug( "Processing: " + targetFileName ); - for ( Iterator iter = artifacts.iterator(); iter.hasNext(); ) - { - Artifact artifact = (Artifact) iter.next(); - String targetFileName = getFinalName( artifact ); + if ( duplicates.contains( targetFileName ) ) + { + getLog().debug( "Duplicate found: " + targetFileName ); + targetFileName = artifact.getGroupId() + "-" + targetFileName; + getLog().debug( "Renamed to: " + targetFileName ); + } + + if ( !artifact.isOptional() && filter.include( artifact ) ) + { + String type = artifact.getType(); + if ( "tld".equals( type ) ) + { + copyFileIfModified( artifact.getFile(), new File( tldDirectory, targetFileName ) ); + } + else if ( "aar".equals( type ) ) + { + copyFileIfModified( artifact.getFile(), new File( servicesDirectory, targetFileName ) ); + } + else + { + if ( "jar".equals( type ) || "ejb".equals( type ) || "ejb-client".equals( type ) || + "test-jar".equals( type ) ) + { + copyFileIfModified( artifact.getFile(), new File( libDirectory, targetFileName ) ); + } + else + { + if ( "par".equals( type ) ) + { + targetFileName = targetFileName.substring( 0, targetFileName.lastIndexOf( '.' ) ) + ".jar"; - getLog().debug( "Processing: " + targetFileName ); + getLog().debug( + "Copying " + artifact.getFile() + " to " + new File( libDirectory, targetFileName ) ); - if ( duplicates.contains( targetFileName ) ) - { - getLog().debug( "Duplicate found: " + targetFileName ); - targetFileName = artifact.getGroupId() + "-" + targetFileName; - getLog().debug( "Renamed to: " + targetFileName ); - } + copyFileIfModified( artifact.getFile(), new File( libDirectory, targetFileName ) ); + } + else + { + if ( "war".equals( type ) ) + { + dependentWarDirectories.add( unpackWarToTempDirectory( artifact ) ); + } + else + { + getLog().debug( "Skipping artifact of type " + type + " for WEB-INF/lib" ); + } + } + } + } + } + } - // TODO: utilise appropriate methods from project builder - ScopeArtifactFilter filter = new ScopeArtifactFilter( Artifact.SCOPE_RUNTIME ); - if ( !artifact.isOptional() && filter.include( artifact ) ) - { - String type = artifact.getType(); - if ( "tld".equals( type ) ) - { - copyFileIfModified( artifact.getFile(), new File( tldDirectory, targetFileName ) ); - } - else if ( "aar".equals( type ) ) - { - copyFileIfModified( artifact.getFile(), new File( servicesDirectory, targetFileName ) ); - } - else - { - if ( "jar".equals( type ) || "ejb".equals( type ) || "ejb-client".equals( type ) || - "test-jar".equals( type ) ) - { - copyFileIfModified( artifact.getFile(), new File( libDirectory, targetFileName ) ); - } - else - { - if ( "par".equals( type ) ) - { - targetFileName = targetFileName.substring( 0, targetFileName.lastIndexOf( '.' ) ) + ".jar"; + if ( dependentWarDirectories.size() > 0 ) + { + getLog().info( "Overlaying " + dependentWarDirectories.size() + " war(s)." ); - getLog().debug( - "Copying " + artifact.getFile() + " to " + new File( libDirectory, targetFileName ) ); + // overlay dependent wars + for ( Iterator iter = dependentWarDirectories.iterator(); iter.hasNext(); ) + { + copyDependentWarContents( (File) iter.next(), webappDirectory ); + } + } + + } catch (ArtifactResolutionException e) { + getLog().error("Artifact doesn't exist.", e); + throw new MojoExecutionException("Artifact doesn't exist.", e); + + } catch (ArtifactNotFoundException e) { + getLog().error("Artifact doesn't exist.", e); + throw new MojoExecutionException("Artifact doesn't exist.", e); + } + + + } - copyFileIfModified( artifact.getFile(), new File( libDirectory, targetFileName ) ); - } - else - { - if ( "war".equals( type ) ) - { - dependentWarDirectories.add( unpackWarToTempDirectory( artifact ) ); - } - else - { - getLog().debug( "Skipping artifact of type " + type + " for WEB-INF/lib" ); - } - } - } - } - } - } + protected void filterOptional(ArtifactResolutionResult resolverResult) { + /* + * This block of code is necessary to fix an error in Maven's dependency resolution + * for optional dependencies http://jira.codehaus.org/browse/MNG-3067 + * + * if includeOptions == true it will weed out all top level dependencies with a + * depth == 2 and then set the resolverResult to the new ResolutionNode Set + */ + + Set nodes = resolverResult.getArtifactResolutionNodes(); + + for (Iterator iter = nodes.iterator(); iter.hasNext();) { + ResolutionNode node = (ResolutionNode) iter.next(); + + /* + * if the artifact isn't marked optional yet has a top-level depth > 1 + * then remove it from the ResolutionNode Set + */ + if (!node.getArtifact().isOptional()) { + if (node.getDepth() != 1) { + iter.remove(); + if (getLog().isDebugEnabled()) { + getLog().debug("Removing top-level, depth > 1 non-optional dependency: " + node.toString()); + } + } + } - if ( dependentWarDirectories.size() > 0 ) - { - getLog().info( "Overlaying " + dependentWarDirectories.size() + " war(s)." ); - - // overlay dependent wars - for ( Iterator iter = dependentWarDirectories.iterator(); iter.hasNext(); ) - { - copyDependentWarContents( (File) iter.next(), webappDirectory ); - } - } - } - + if (node.getArtifact().isOptional()) { + // remove the optional dependency and it's dependency graph. + if (getLog().isDebugEnabled()) { + getLog().debug("Removing optional dependency: " + node.toString()); + } + + iter.remove(); + } + + } + + resolverResult.setArtifactResolutionNodes(nodes); + + } + /** * Searches a set of artifacts for duplicate filenames and returns a list of duplicates. *