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