View Javadoc

1   package org.apache.maven.shared.dependency.graph.internal;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.lang.reflect.InvocationTargetException;
23  import java.util.ArrayList;
24  import java.util.Collections;
25  import java.util.List;
26  
27  import org.apache.maven.artifact.Artifact;
28  import org.apache.maven.artifact.factory.ArtifactFactory;
29  import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
30  import org.apache.maven.artifact.versioning.VersionRange;
31  import org.apache.maven.project.DefaultDependencyResolutionRequest;
32  import org.apache.maven.project.DependencyResolutionException;
33  import org.apache.maven.project.DependencyResolutionRequest;
34  import org.apache.maven.project.DependencyResolutionResult;
35  import org.apache.maven.project.MavenProject;
36  import org.apache.maven.project.ProjectBuildingRequest;
37  import org.apache.maven.project.ProjectDependenciesResolver;
38  import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
39  import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException;
40  import org.apache.maven.shared.dependency.graph.DependencyNode;
41  import org.codehaus.plexus.component.annotations.Component;
42  import org.codehaus.plexus.component.annotations.Requirement;
43  import org.sonatype.aether.graph.Dependency;
44  import org.sonatype.aether.version.VersionConstraint;
45  
46  /**
47   * Wrapper around Maven 3 dependency resolver.
48   *
49   * @see ProjectDependenciesResolver
50   * @author Hervé Boutemy
51   * @since 2.0
52   */
53  @Component( role = DependencyGraphBuilder.class, hint = "maven3" )
54  public class Maven3DependencyGraphBuilder
55      implements DependencyGraphBuilder
56  {
57      @Requirement
58      private ProjectDependenciesResolver resolver;
59  
60      @Requirement
61      private ArtifactFactory factory;
62  
63      public DependencyNode buildDependencyGraph( MavenProject project, ArtifactFilter filter )
64          throws DependencyGraphBuilderException
65      {
66          try
67          {
68              ProjectBuildingRequest projectBuildingRequest =
69                  (ProjectBuildingRequest) invoke( project, "getProjectBuildingRequest" );
70  
71              DependencyResolutionRequest request =
72                  new DefaultDependencyResolutionRequest( project, projectBuildingRequest.getRepositorySession() );
73  
74              DependencyResolutionResult result = resolver.resolve( request );
75  
76              return buildDependencyNode( null, result.getDependencyGraph(), project.getArtifact(), filter );
77          }
78          catch ( DependencyResolutionException e )
79          {
80              throw new DependencyGraphBuilderException( e.getMessage(), e );
81          }
82          catch ( IllegalAccessException e )
83          {
84              throw new DependencyGraphBuilderException( e.getMessage(), e );
85          }
86          catch ( InvocationTargetException e )
87          {
88              throw new DependencyGraphBuilderException( e.getMessage(), e );
89          }
90          catch ( NoSuchMethodException e )
91          {
92              throw new DependencyGraphBuilderException( e.getMessage(), e );
93          }
94      }
95  
96      private Object invoke( Object object, String method )
97          throws IllegalAccessException, InvocationTargetException, NoSuchMethodException
98      {
99          return object.getClass().getMethod( method ).invoke( object );
100     }
101 
102     private Artifact getDependencyArtifact( Dependency dep )
103     {
104         org.sonatype.aether.artifact.Artifact artifact = dep.getArtifact();
105 
106         return factory.createDependencyArtifact( artifact.getGroupId(), artifact.getArtifactId(),
107                                                  VersionRange.createFromVersion( artifact.getVersion() ),
108                                                  artifact.getExtension(), artifact.getClassifier(), dep.getScope(),
109                                                  dep.isOptional() );
110     }
111 
112     private DependencyNode buildDependencyNode( DependencyNode parent, org.sonatype.aether.graph.DependencyNode node,
113                                                 Artifact artifact, ArtifactFilter filter )
114     {
115         DefaultDependencyNode current =
116             new DefaultDependencyNode( parent, artifact, node.getPremanagedVersion(), node.getPremanagedScope(),
117                                        getVersionSelectedFromRange( node.getVersionConstraint() ) );
118 
119         List<DependencyNode> nodes = new ArrayList<DependencyNode>( node.getChildren().size() );
120         for ( org.sonatype.aether.graph.DependencyNode child : node.getChildren() )
121         {
122             Artifact childArtifact = getDependencyArtifact( child.getDependency() );
123 
124             if ( ( filter == null ) || filter.include( childArtifact ) )
125             {
126                 nodes.add( buildDependencyNode( current, child, childArtifact, filter ) );
127             }
128         }
129 
130         current.setChildren( Collections.unmodifiableList( nodes ) );
131 
132         return current;
133     }
134 
135     private String getVersionSelectedFromRange( VersionConstraint constraint )
136     {
137         if ( ( constraint == null ) || ( constraint.getVersion() != null ) )
138         {
139             return null;
140         }
141 
142         StringBuilder sb = new StringBuilder();
143         for ( org.sonatype.aether.version.VersionRange range : constraint.getRanges() )
144         {
145             if ( sb.length() > 0 )
146             {
147                 sb.append( ',' );
148             }
149             sb.append( range );
150         }
151 
152         return sb.toString();
153     }
154 }