diff --git a/maven-dependency-analyzer/pom.xml b/maven-dependency-analyzer/pom.xml
index 002d4497c..90923170b 100644
--- a/maven-dependency-analyzer/pom.xml
+++ b/maven-dependency-analyzer/pom.xml
@@ -105,6 +105,12 @@
3.8.2
test
+
+ org.apache.maven.wagon
+ wagon-http
+ 2.6
+ test
+
diff --git a/maven-dependency-analyzer/src/main/java/org/apache/maven/shared/dependency/analyzer/ArtifactDependencyAnalyzer.java b/maven-dependency-analyzer/src/main/java/org/apache/maven/shared/dependency/analyzer/ArtifactDependencyAnalyzer.java
new file mode 100644
index 000000000..13ffecc90
--- /dev/null
+++ b/maven-dependency-analyzer/src/main/java/org/apache/maven/shared/dependency/analyzer/ArtifactDependencyAnalyzer.java
@@ -0,0 +1,50 @@
+package org.apache.maven.shared.dependency.analyzer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.project.ProjectBuildingException;
+
+/**
+ * Analyze an artifact's declared dependencies and effective classes used to find which artifacts are:
+ *
+ * - used and declared,
+ * - used but not declared,
+ * - not used but declared.
+ *
+ *
+ * @author Simon Wang
+ * @version $Id$
+ */
+public interface ArtifactDependencyAnalyzer
+{
+ // fields -----------------------------------------------------------------
+
+ String ROLE = ArtifactDependencyAnalyzer.class.getName();
+
+ // public methods ---------------------------------------------------------
+
+ ProjectDependencyAnalysis analyze( Artifact artifact, List remoteArtifactRepositories,
+ ArtifactRepository localRepository )
+ throws ProjectDependencyAnalyzerException, ProjectBuildingException;
+}
diff --git a/maven-dependency-analyzer/src/main/java/org/apache/maven/shared/dependency/analyzer/DefaultArtifactDependencyAnalyzer.java b/maven-dependency-analyzer/src/main/java/org/apache/maven/shared/dependency/analyzer/DefaultArtifactDependencyAnalyzer.java
new file mode 100644
index 000000000..8edca544c
--- /dev/null
+++ b/maven-dependency-analyzer/src/main/java/org/apache/maven/shared/dependency/analyzer/DefaultArtifactDependencyAnalyzer.java
@@ -0,0 +1,134 @@
+package org.apache.maven.shared.dependency.analyzer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.resolver.ArtifactResolver;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.MavenProjectBuilder;
+import org.apache.maven.project.ProjectBuildingException;
+import org.apache.maven.project.artifact.InvalidDependencyVersionException;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+/**
+ * This analyzer will analyze specified artifact. The actual analyzing work would be done by ProjectDependencyAnalyzer.
+ *
+ * @author Simon Wang
+ * @version $Id$
+ */
+@Component( role = ArtifactDependencyAnalyzer.class )
+public class DefaultArtifactDependencyAnalyzer
+ implements ArtifactDependencyAnalyzer
+{
+
+ // fields -----------------------------------------------------------------
+
+ @Requirement
+ private ProjectDependencyAnalyzer projectDependencyAnalyzer;
+
+ @Requirement
+ private MavenProjectBuilder mavenProjectBuilder;
+
+ @Requirement
+ private ArtifactResolver artifactResolver;
+
+ @Requirement
+ private ArtifactFactory artifactFactory;
+
+ // public methods ---------------------------------------------------------
+
+ public ProjectDependencyAnalysis analyze( Artifact artifact, List remoteArtifactRepositories,
+ ArtifactRepository localRepository )
+ throws ProjectDependencyAnalyzerException
+ {
+ try
+ {
+ if ( !artifact.isResolved() )
+ {
+ artifactResolver.resolve( artifact, remoteArtifactRepositories, localRepository );
+ }
+
+ Artifact projectArtifact =
+ artifactFactory.createProjectArtifact( artifact.getGroupId(), artifact.getArtifactId(),
+ artifact.getVersion() );
+
+ File pomFile = new File( localRepository.getBasedir(), localRepository.pathOf( projectArtifact ) );
+
+ MavenProject project = this.mavenProjectBuilder.buildWithDependencies( pomFile, localRepository, null );
+ project.setDependencyArtifacts( project.createArtifacts( artifactFactory, null, null ) );
+
+ return this.projectDependencyAnalyzer.analyze( project );
+ }
+ catch ( ProjectBuildingException e )
+ {
+ throw new ProjectDependencyAnalyzerException( "can't build maven project for artifact - "
+ + artifact.toString(), e );
+ }
+ catch ( ArtifactResolutionException e )
+ {
+ throw new ProjectDependencyAnalyzerException( "can't resolve artifact - " + artifact.toString(), e );
+ }
+ catch ( ArtifactNotFoundException e )
+ {
+ throw new ProjectDependencyAnalyzerException( "can't find artifact - " + artifact.toString(), e );
+ }
+ catch ( InvalidDependencyVersionException e )
+ {
+ throw new ProjectDependencyAnalyzerException( "Invalid dependency version for artifact - "
+ + artifact.toString(), e );
+ }
+ }
+
+ // ClassFileVisitor methods for testing -----------------------------------------------
+
+ protected void setProjectDependencyAnalyzer( ProjectDependencyAnalyzer projectDependencyAnalyzer )
+ {
+ this.projectDependencyAnalyzer = projectDependencyAnalyzer;
+ }
+
+ protected void setMavenProjectBuilder( MavenProjectBuilder mavenProjectBuilder )
+ {
+ this.mavenProjectBuilder = mavenProjectBuilder;
+ }
+
+ protected void setArtifactResolver( ArtifactResolver artifactResolver )
+ {
+ this.artifactResolver = artifactResolver;
+ }
+
+ protected ArtifactFactory getFactory()
+ {
+ return artifactFactory;
+ }
+
+ protected void setArtifactFactory( ArtifactFactory factory )
+ {
+ this.artifactFactory = factory;
+ }
+
+}
\ No newline at end of file
diff --git a/maven-dependency-analyzer/src/main/java/org/apache/maven/shared/dependency/analyzer/DefaultProjectDependencyAnalyzer.java b/maven-dependency-analyzer/src/main/java/org/apache/maven/shared/dependency/analyzer/DefaultProjectDependencyAnalyzer.java
index cb8f86dbd..c2d85746f 100644
--- a/maven-dependency-analyzer/src/main/java/org/apache/maven/shared/dependency/analyzer/DefaultProjectDependencyAnalyzer.java
+++ b/maven-dependency-analyzer/src/main/java/org/apache/maven/shared/dependency/analyzer/DefaultProjectDependencyAnalyzer.java
@@ -179,6 +179,14 @@ protected Set buildDependencyClasses( MavenProject project )
{
Set dependencyClasses = new HashSet();
+ File basedir = project.getBasedir();
+
+ // if project is a artifact project.
+ if ( ( basedir == null || !basedir.exists() ) && project.getArtifact() != null )
+ {
+ return buildDependencyClasses( project.getArtifact().getFile() );
+ }
+
String outputDirectory = project.getBuild().getOutputDirectory();
dependencyClasses.addAll( buildDependencyClasses( outputDirectory ) );
@@ -196,6 +204,14 @@ private Set buildDependencyClasses( String path )
return dependencyAnalyzer.analyze( url );
}
+ private Set buildDependencyClasses( File artifactFile )
+ throws IOException
+ {
+ URL url = artifactFile.toURI().toURL();
+
+ return dependencyAnalyzer.analyze( url );
+ }
+
private Set buildDeclaredArtifacts( MavenProject project )
{
@SuppressWarnings( "unchecked" ) Set declaredArtifacts = project.getDependencyArtifacts();
diff --git a/maven-dependency-analyzer/src/test/java/org/apache/maven/shared/dependency/analyzer/DefaultArtifactDependencyAnalyzerTest.java b/maven-dependency-analyzer/src/test/java/org/apache/maven/shared/dependency/analyzer/DefaultArtifactDependencyAnalyzerTest.java
new file mode 100644
index 000000000..ee9eacc88
--- /dev/null
+++ b/maven-dependency-analyzer/src/test/java/org/apache/maven/shared/dependency/analyzer/DefaultArtifactDependencyAnalyzerTest.java
@@ -0,0 +1,131 @@
+package org.apache.maven.shared.dependency.analyzer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.resolver.ArtifactResolver;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.MavenProjectBuilder;
+import org.apache.maven.project.ProjectBuildingException;
+import org.apache.maven.shared.test.plugin.ProjectTool;
+import org.apache.maven.shared.test.plugin.RepositoryTool;
+import org.apache.maven.shared.test.plugin.TestToolsException;
+import org.codehaus.plexus.PlexusTestCase;
+
+/**
+ * Tests DefaultProjectDependencyAnalyzer.
+ *
+ * @author Simon Wang
+ * @version $Id$
+ * @see DefaultArtifactDependencyAnalyzer
+ */
+public class DefaultArtifactDependencyAnalyzerTest
+ extends PlexusTestCase
+{
+ // fields -----------------------------------------------------------------
+
+ private ProjectTool projectTool;
+
+ private DefaultArtifactDependencyAnalyzer analyzer;
+
+ private static ArtifactRepository localRepo;
+
+ private ProjectDependencyAnalyzer projectDependencyAnalyzer;
+
+ private MavenProjectBuilder mavenProjectBuilder;
+
+ private ArtifactResolver artifactResolver;
+
+ private ArtifactFactory artifactFactory;
+
+ // TestCase methods -------------------------------------------------------
+
+ /*
+ * @see org.codehaus.plexus.PlexusTestCase#setUp()
+ */
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ projectTool = (ProjectTool) lookup( ProjectTool.ROLE );
+
+ if ( localRepo == null )
+ {
+ RepositoryTool repositoryTool = (RepositoryTool) lookup( RepositoryTool.ROLE );
+
+ localRepo = repositoryTool.createLocalArtifactRepositoryInstance();
+ }
+
+ analyzer = (DefaultArtifactDependencyAnalyzer) lookup( ArtifactDependencyAnalyzer.ROLE );
+
+ projectDependencyAnalyzer = (ProjectDependencyAnalyzer) lookup( ProjectDependencyAnalyzer.ROLE );
+
+ mavenProjectBuilder = (MavenProjectBuilder) lookup( MavenProjectBuilder.ROLE );
+
+ artifactResolver = (ArtifactResolver) lookup( ArtifactResolver.ROLE );
+
+ artifactFactory = (ArtifactFactory) lookup( ArtifactFactory.ROLE );
+
+ }
+
+ private MavenProject getProject( String pomPath )
+ throws TestToolsException
+ {
+ File pom = getTestFile( "target/test-classes/", pomPath );
+
+ return projectTool.readProjectWithDependencies( pom );
+ }
+
+ private Artifact createArtifact( String groupId, String artifactId, String type, String version, String scope )
+ {
+ return artifactFactory.createArtifact( groupId, artifactId, version, scope, type );
+ }
+
+ // tests ------------------------------------------------------------------
+ public void testJarWithXmlTransitiveDependency()
+ throws TestToolsException, ProjectDependencyAnalyzerException, ProjectBuildingException,
+ ArtifactResolutionException, ArtifactNotFoundException
+ {
+ System.setProperty( "maven.home", "C:/apache-maven-3.0.5" );
+
+ MavenProject project = getProject( "jarWithXmlTransitiveDependency/pom.xml" );
+
+ Artifact jdom = createArtifact( "xalan", "xalan", "jar", "2.7.1", "compile" );
+
+ analyzer.setArtifactResolver( artifactResolver );
+ analyzer.setMavenProjectBuilder( mavenProjectBuilder );
+ analyzer.setProjectDependencyAnalyzer( projectDependencyAnalyzer );
+ analyzer.setArtifactFactory( artifactFactory );
+ ProjectDependencyAnalysis actualAnalysis =
+ analyzer.analyze( jdom, project.getRemoteArtifactRepositories(), localRepo );
+
+ System.out.println( actualAnalysis.getUnusedDeclaredArtifacts().toString() );
+ System.out.println( actualAnalysis.getUsedDeclaredArtifacts().toString() );
+ System.out.println( actualAnalysis.getUsedUndeclaredArtifacts().toString() );
+ }
+
+}
diff --git a/maven-dependency-analyzer/src/test/resources/jarWithXmlTransitiveDependency/pom.xml b/maven-dependency-analyzer/src/test/resources/jarWithXmlTransitiveDependency/pom.xml
index 6d1c83a88..41dfe4b63 100644
--- a/maven-dependency-analyzer/src/test/resources/jarWithXmlTransitiveDependency/pom.xml
+++ b/maven-dependency-analyzer/src/test/resources/jarWithXmlTransitiveDependency/pom.xml
@@ -37,5 +37,10 @@
dom4j
1.6.1
+
+ xalan
+ xalan
+ 2.7.1
+