1 package org.apache.maven.shared.dependency.graph.internal;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.HashSet;
26 import java.util.List;
27 import java.util.Set;
28
29 import org.apache.maven.RepositoryUtils;
30 import org.apache.maven.artifact.Artifact;
31 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
32 import org.apache.maven.project.DefaultDependencyResolutionRequest;
33 import org.apache.maven.project.DependencyResolutionException;
34 import org.apache.maven.project.DependencyResolutionRequest;
35 import org.apache.maven.project.DependencyResolutionResult;
36 import org.apache.maven.project.MavenProject;
37 import org.apache.maven.project.ProjectBuildingRequest;
38 import org.apache.maven.project.ProjectDependenciesResolver;
39 import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
40 import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException;
41 import org.apache.maven.shared.dependency.graph.DependencyNode;
42 import org.codehaus.plexus.component.annotations.Component;
43 import org.codehaus.plexus.component.annotations.Requirement;
44 import org.codehaus.plexus.logging.AbstractLogEnabled;
45 import org.sonatype.aether.graph.Dependency;
46 import org.sonatype.aether.version.VersionConstraint;
47
48
49
50
51
52
53
54
55 @Component( role = DependencyGraphBuilder.class, hint = "maven3" )
56 public class Maven3DependencyGraphBuilder
57 extends AbstractLogEnabled
58 implements DependencyGraphBuilder
59 {
60 @Requirement
61 private ProjectDependenciesResolver resolver;
62
63
64
65
66
67
68
69
70
71 @Override
72 public DependencyNode buildDependencyGraph( ProjectBuildingRequest buildingRequest, ArtifactFilter filter )
73 throws DependencyGraphBuilderException
74 {
75 return buildDependencyGraph( buildingRequest, filter, null );
76 }
77
78
79
80
81
82
83
84
85
86
87
88 @Override
89 public DependencyNode buildDependencyGraph( ProjectBuildingRequest buildingRequest, ArtifactFilter filter,
90 Collection<MavenProject> reactorProjects )
91 throws DependencyGraphBuilderException
92 {
93 MavenProject project = buildingRequest.getProject();
94
95 DependencyResolutionRequest request =
96 new DefaultDependencyResolutionRequest( project, buildingRequest.getRepositorySession() );
97
98 DependencyResolutionResult result = resolveDependencies( request, reactorProjects );
99
100 return buildDependencyNode( null, result.getDependencyGraph(), project.getArtifact(), filter );
101 }
102
103 private DependencyResolutionResult resolveDependencies( DependencyResolutionRequest request,
104 Collection<MavenProject> reactorProjects )
105 throws DependencyGraphBuilderException
106 {
107 try
108 {
109 return resolver.resolve( request );
110 }
111 catch ( DependencyResolutionException e )
112 {
113 if ( reactorProjects == null )
114 {
115 throw new DependencyGraphBuilderException( "Could not resolve following dependencies: "
116 + e.getResult().getUnresolvedDependencies(), e );
117 }
118
119
120 return collectDependenciesFromReactor( e, reactorProjects );
121 }
122 }
123
124 private DependencyResolutionResult collectDependenciesFromReactor( DependencyResolutionException e,
125 Collection<MavenProject> reactorProjects )
126 throws DependencyGraphBuilderException
127 {
128 DependencyResolutionResult result = e.getResult();
129
130 List<Dependency> reactorDeps = getReactorDependencies( reactorProjects, result.getUnresolvedDependencies() );
131
132 result.getUnresolvedDependencies().removeAll( reactorDeps );
133 Invoker.invoke( result.getResolvedDependencies(), "addAll", Collection.class, reactorDeps );
134
135 if ( !result.getUnresolvedDependencies().isEmpty() )
136 {
137 throw new DependencyGraphBuilderException( "Could not resolve nor collect following dependencies: "
138 + result.getUnresolvedDependencies(), e );
139 }
140
141 return result;
142 }
143
144 private List<org.sonatype.aether.graph.Dependency> getReactorDependencies( Collection<MavenProject> reactorProjects,
145 List<?> dependencies )
146 {
147 Set<ArtifactKey> reactorProjectsIds = new HashSet<ArtifactKey>();
148 for ( MavenProject project : reactorProjects )
149 {
150 reactorProjectsIds.add( new ArtifactKey( project ) );
151 }
152
153 List<Dependency> reactorDeps = new ArrayList<Dependency>();
154 for ( Object untypedDependency : dependencies )
155 {
156 Dependency dependency = (Dependency) untypedDependency;
157 org.sonatype.aether.artifact.Artifact depArtifact = dependency.getArtifact();
158
159 ArtifactKey key =
160 new ArtifactKey( depArtifact.getGroupId(), depArtifact.getArtifactId(), depArtifact.getVersion() );
161
162 if ( reactorProjectsIds.contains( key ) )
163 {
164 reactorDeps.add( dependency );
165 }
166 }
167
168 return reactorDeps;
169 }
170
171 private Artifact getDependencyArtifact( Dependency dep )
172 {
173 Artifact mavenArtifact = RepositoryUtils.toArtifact( dep.getArtifact() );
174
175 mavenArtifact.setScope( dep.getScope() );
176
177 return mavenArtifact;
178 }
179
180 private DependencyNode buildDependencyNode( DependencyNode parent, org.sonatype.aether.graph.DependencyNode node,
181 Artifact artifact, ArtifactFilter filter )
182 {
183 DefaultDependencyNode current =
184 new DefaultDependencyNode( parent, artifact,
185 null ,
186 null ,
187 getVersionSelectedFromRange( node.getVersionConstraint() ) );
188
189 List<DependencyNode> nodes = new ArrayList<DependencyNode>( node.getChildren().size() );
190 for ( org.sonatype.aether.graph.DependencyNode child : node.getChildren() )
191 {
192 Artifact childArtifact = getDependencyArtifact( child.getDependency() );
193
194 if ( ( filter == null ) || filter.include( childArtifact ) )
195 {
196 nodes.add( buildDependencyNode( current, child, childArtifact, filter ) );
197 }
198 }
199
200 current.setChildren( Collections.unmodifiableList( nodes ) );
201
202 return current;
203 }
204
205 private String getVersionSelectedFromRange( VersionConstraint constraint )
206 {
207 if ( ( constraint == null ) || ( constraint.getVersion() != null ) )
208 {
209 return null;
210 }
211
212 StringBuilder sb = new StringBuilder();
213 for ( org.sonatype.aether.version.VersionRange range : constraint.getRanges() )
214 {
215 if ( sb.length() > 0 )
216 {
217 sb.append( ',' );
218 }
219 sb.append( range );
220 }
221
222 return sb.toString();
223 }
224 }