Skip to content
This repository was archived by the owner on Jan 29, 2020. It is now read-only.

MSHARED-341: New API to support to analyze artifact's dependencies #8

Open
wants to merge 1 commit into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions maven-dependency-analyzer/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@
<version>3.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-http</artifactId>
<version>2.6</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -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:
* <ul>
* <li>used and declared,</li>
* <li>used but not declared,</li>
* <li>not used but declared.</li>
* </ul>
*
* @author <a href="mailto:wangyf2010@gmail.com">Simon Wang</a>
* @version $Id$
*/
public interface ArtifactDependencyAnalyzer
{
// fields -----------------------------------------------------------------

String ROLE = ArtifactDependencyAnalyzer.class.getName();

// public methods ---------------------------------------------------------

ProjectDependencyAnalysis analyze( Artifact artifact, List remoteArtifactRepositories,
ArtifactRepository localRepository )
throws ProjectDependencyAnalyzerException, ProjectBuildingException;
}
Original file line number Diff line number Diff line change
@@ -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 <a href="mailto:wangyf2010@gmail.com">Simon Wang</a>
* @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;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,14 @@ protected Set<String> buildDependencyClasses( MavenProject project )
{
Set<String> dependencyClasses = new HashSet<String>();

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 ) );

Expand All @@ -196,6 +204,14 @@ private Set<String> buildDependencyClasses( String path )
return dependencyAnalyzer.analyze( url );
}

private Set<String> buildDependencyClasses( File artifactFile )
throws IOException
{
URL url = artifactFile.toURI().toURL();

return dependencyAnalyzer.analyze( url );
}

private Set<Artifact> buildDeclaredArtifacts( MavenProject project )
{
@SuppressWarnings( "unchecked" ) Set<Artifact> declaredArtifacts = project.getDependencyArtifacts();
Expand Down
Original file line number Diff line number Diff line change
@@ -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 <code>DefaultProjectDependencyAnalyzer</code>.
*
* @author <a href="mailto:wangyf2010@gmail.com">Simon Wang</a>
* @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() );
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,10 @@
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>xalan</groupId>
<artifactId>xalan</artifactId>
<version>2.7.1</version>
</dependency>
</dependencies>
</project>