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.util.ArrayList;
23  import java.util.Collections;
24  import java.util.List;
25  
26  import org.apache.maven.RepositoryUtils;
27  import org.apache.maven.artifact.Artifact;
28  import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
29  import org.apache.maven.project.DefaultDependencyResolutionRequest;
30  import org.apache.maven.project.DependencyResolutionException;
31  import org.apache.maven.project.DependencyResolutionRequest;
32  import org.apache.maven.project.DependencyResolutionResult;
33  import org.apache.maven.project.MavenProject;
34  import org.apache.maven.project.ProjectBuildingRequest;
35  import org.apache.maven.project.ProjectDependenciesResolver;
36  import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
37  import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException;
38  import org.apache.maven.shared.dependency.graph.DependencyNode;
39  import org.codehaus.plexus.component.annotations.Component;
40  import org.codehaus.plexus.component.annotations.Requirement;
41  import org.codehaus.plexus.logging.AbstractLogEnabled;
42  import org.sonatype.aether.graph.DependencyFilter;
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      extends AbstractLogEnabled
56      implements DependencyGraphBuilder
57  {
58      @Requirement
59      private ProjectDependenciesResolver resolver;
60  
61      /**
62       * Builds the dependency graph for Maven 3.
63       *
64       * @param buildingRequest the buildingRequest
65       * @param filter artifact filter (can be <code>null</code>)
66       * @return DependencyNode containing the dependency graph.
67       * @throws DependencyGraphBuilderException if some of the dependencies could not be resolved.
68       */
69      @Override
70      public DependencyNode buildDependencyGraph( ProjectBuildingRequest buildingRequest, ArtifactFilter filter )
71          throws DependencyGraphBuilderException
72      {
73          MavenProject project = buildingRequest.getProject();
74  
75          DependencyResolutionRequest request =
76              new DefaultDependencyResolutionRequest( project, buildingRequest.getRepositorySession() );
77  
78          // only download the poms, not the artifacts
79          DependencyFilter collectFilter = new DependencyFilter()
80          {
81              @Override
82              public boolean accept( org.sonatype.aether.graph.DependencyNode node,
83                                     List<org.sonatype.aether.graph.DependencyNode> parents )
84              {
85                  return false;
86              }
87          };
88          request.setResolutionFilter( collectFilter );
89  
90          DependencyResolutionResult result = resolveDependencies( request );
91  
92          return buildDependencyNode( null, result.getDependencyGraph(), project.getArtifact(), filter );
93      }
94  
95      private DependencyResolutionResult resolveDependencies( DependencyResolutionRequest request )
96          throws DependencyGraphBuilderException
97      {
98          try
99          {
100             return resolver.resolve( request );
101         }
102         catch ( DependencyResolutionException e )
103         {
104             throw new DependencyGraphBuilderException( "Could not resolve following dependencies: "
105                 + e.getResult().getUnresolvedDependencies(), e );
106         }
107     }
108 
109     private Artifact getDependencyArtifact( Dependency dep )
110     {
111         Artifact mavenArtifact = RepositoryUtils.toArtifact( dep.getArtifact() );
112 
113         mavenArtifact.setScope( dep.getScope() );
114         mavenArtifact.setOptional( dep.isOptional() );
115 
116         return mavenArtifact;
117     }
118 
119     private DependencyNode buildDependencyNode( DependencyNode parent, org.sonatype.aether.graph.DependencyNode node,
120                                                 Artifact artifact, ArtifactFilter filter )
121     {
122         DefaultDependencyNode current =
123             new DefaultDependencyNode( parent, artifact,
124                                        null /* node.getPremanagedVersion() */,
125                                        null /* node.getPremanagedScope() */,
126                                        getVersionSelectedFromRange( node.getVersionConstraint() ) );
127 
128         List<DependencyNode> nodes = new ArrayList<DependencyNode>( node.getChildren().size() );
129         for ( org.sonatype.aether.graph.DependencyNode child : node.getChildren() )
130         {
131             Artifact childArtifact = getDependencyArtifact( child.getDependency() );
132 
133             if ( ( filter == null ) || filter.include( childArtifact ) )
134             {
135                 nodes.add( buildDependencyNode( current, child, childArtifact, filter ) );
136             }
137         }
138 
139         current.setChildren( Collections.unmodifiableList( nodes ) );
140 
141         return current;
142     }
143 
144     private String getVersionSelectedFromRange( VersionConstraint constraint )
145     {
146         if ( ( constraint == null ) || ( constraint.getVersion() != null ) )
147         {
148             return null;
149         }
150 
151         StringBuilder sb = new StringBuilder();
152         for ( org.sonatype.aether.version.VersionRange range : constraint.getRanges() )
153         {
154             if ( sb.length() > 0 )
155             {
156                 sb.append( ',' );
157             }
158             sb.append( range );
159         }
160 
161         return sb.toString();
162     }
163 }