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: + * + * + * @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 +