1 package org.apache.maven.project;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.Collection;
23 import java.util.HashMap;
24 import java.util.Map;
25
26 import org.apache.maven.RepositoryUtils;
27 import org.apache.maven.artifact.Artifact;
28 import org.apache.maven.model.Dependency;
29 import org.apache.maven.model.DependencyManagement;
30 import org.apache.maven.model.Exclusion;
31 import org.apache.maven.model.InputLocation;
32 import org.apache.maven.model.InputSource;
33 import org.codehaus.plexus.component.annotations.Component;
34 import org.codehaus.plexus.component.annotations.Requirement;
35 import org.codehaus.plexus.logging.Logger;
36 import org.sonatype.aether.RepositorySystem;
37 import org.sonatype.aether.RepositorySystemSession;
38 import org.sonatype.aether.RequestTrace;
39 import org.sonatype.aether.artifact.ArtifactTypeRegistry;
40 import org.sonatype.aether.collection.CollectRequest;
41 import org.sonatype.aether.collection.DependencyCollectionException;
42 import org.sonatype.aether.graph.DependencyFilter;
43 import org.sonatype.aether.graph.DependencyNode;
44 import org.sonatype.aether.graph.DependencyVisitor;
45 import org.sonatype.aether.resolution.ArtifactResult;
46 import org.sonatype.aether.resolution.DependencyRequest;
47 import org.sonatype.aether.util.DefaultRequestTrace;
48 import org.sonatype.aether.util.artifact.ArtifacIdUtils;
49 import org.sonatype.aether.util.artifact.ArtifactProperties;
50 import org.sonatype.aether.util.artifact.JavaScopes;
51
52
53
54
55 @Component( role = ProjectDependenciesResolver.class )
56 public class DefaultProjectDependenciesResolver
57 implements ProjectDependenciesResolver
58 {
59
60 @Requirement
61 private Logger logger;
62
63 @Requirement
64 private RepositorySystem repoSystem;
65
66 public DependencyResolutionResult resolve( DependencyResolutionRequest request )
67 throws DependencyResolutionException
68 {
69 RequestTrace trace = DefaultRequestTrace.newChild( null, request );
70
71 DefaultDependencyResolutionResult result = new DefaultDependencyResolutionResult();
72
73 MavenProject project = request.getMavenProject();
74 RepositorySystemSession session = request.getRepositorySession();
75 DependencyFilter filter = request.getResolutionFilter();
76
77 ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry();
78
79 CollectRequest collect = new CollectRequest();
80 collect.setRequestContext( "project" );
81 collect.setRepositories( project.getRemoteProjectRepositories() );
82
83 if ( project.getDependencyArtifacts() == null )
84 {
85 for ( Dependency dependency : project.getDependencies() )
86 {
87 collect.addDependency( RepositoryUtils.toDependency( dependency, stereotypes ) );
88 }
89 }
90 else
91 {
92 Map<String, Dependency> dependencies = new HashMap<String, Dependency>();
93 for ( Dependency dependency : project.getDependencies() )
94 {
95 String key = dependency.getManagementKey();
96 dependencies.put( key, dependency );
97 }
98 for ( Artifact artifact : project.getDependencyArtifacts() )
99 {
100 String key = artifact.getDependencyConflictId();
101 Dependency dependency = dependencies.get( key );
102 Collection<Exclusion> exclusions = dependency != null ? dependency.getExclusions() : null;
103 org.sonatype.aether.graph.Dependency dep = RepositoryUtils.toDependency( artifact, exclusions );
104 if ( !JavaScopes.SYSTEM.equals( dep.getScope() ) && dep.getArtifact().getFile() != null )
105 {
106
107 org.sonatype.aether.artifact.Artifact art = dep.getArtifact();
108 art = art.setFile( null ).setVersion( art.getBaseVersion() );
109 dep = dep.setArtifact( art );
110 }
111 collect.addDependency( dep );
112 }
113 }
114
115 DependencyManagement depMngt = project.getDependencyManagement();
116 if ( depMngt != null )
117 {
118 for ( Dependency dependency : depMngt.getDependencies() )
119 {
120 collect.addManagedDependency( RepositoryUtils.toDependency( dependency, stereotypes ) );
121 }
122 }
123
124 DependencyRequest depRequest = new DependencyRequest( collect, filter );
125 depRequest.setTrace( trace );
126
127 DependencyNode node;
128 try
129 {
130 collect.setTrace( DefaultRequestTrace.newChild( trace, depRequest ) );
131 node = repoSystem.collectDependencies( session, collect ).getRoot();
132 result.setDependencyGraph( node );
133 }
134 catch ( DependencyCollectionException e )
135 {
136 result.setDependencyGraph( e.getResult().getRoot() );
137 result.setCollectionErrors( e.getResult().getExceptions() );
138
139 throw new DependencyResolutionException( result, "Could not resolve dependencies for project "
140 + project.getId() + ": " + e.getMessage(), e );
141 }
142
143 depRequest.setRoot( node );
144
145 if ( logger.isWarnEnabled() )
146 {
147 for ( DependencyNode child : node.getChildren() )
148 {
149 if ( !child.getRelocations().isEmpty() )
150 {
151 logger.warn( "The artifact " + child.getRelocations().get( 0 ) + " has been relocated to "
152 + child.getDependency().getArtifact() );
153 }
154 }
155 }
156
157 if ( logger.isDebugEnabled() )
158 {
159 node.accept( new GraphLogger( project ) );
160 }
161
162 try
163 {
164 process( result, repoSystem.resolveDependencies( session, depRequest ).getArtifactResults() );
165 }
166 catch ( org.sonatype.aether.resolution.DependencyResolutionException e )
167 {
168 process( result, e.getResult().getArtifactResults() );
169
170 throw new DependencyResolutionException( result, "Could not resolve dependencies for project "
171 + project.getId() + ": " + e.getMessage(), e );
172 }
173
174 return result;
175 }
176
177 private void process( DefaultDependencyResolutionResult result, Collection<ArtifactResult> results )
178 {
179 for ( ArtifactResult ar : results )
180 {
181 DependencyNode node = ar.getRequest().getDependencyNode();
182 if ( ar.isResolved() )
183 {
184 result.addResolvedDependency( node.getDependency() );
185 }
186 else
187 {
188 result.setResolutionErrors( node.getDependency(), ar.getExceptions() );
189 }
190 }
191 }
192
193 class GraphLogger
194 implements DependencyVisitor
195 {
196
197 private final MavenProject project;
198
199 private String indent = "";
200
201 private Map<String, Dependency> managed;
202
203 public GraphLogger( MavenProject project )
204 {
205 this.project = project;
206 }
207
208 public boolean visitEnter( DependencyNode node )
209 {
210 StringBuilder buffer = new StringBuilder( 128 );
211 buffer.append( indent );
212 org.sonatype.aether.graph.Dependency dep = node.getDependency();
213 if ( dep != null )
214 {
215 org.sonatype.aether.artifact.Artifact art = dep.getArtifact();
216
217 buffer.append( art );
218 buffer.append( ':' ).append( dep.getScope() );
219
220 if ( node.getPremanagedScope() != null && !node.getPremanagedScope().equals( dep.getScope() ) )
221 {
222 buffer.append( " (scope managed from " ).append( node.getPremanagedScope() );
223 appendManagementSource( buffer, art, "scope" );
224 buffer.append( ")" );
225 }
226
227 if ( node.getPremanagedVersion() != null && !node.getPremanagedVersion().equals( art.getVersion() ) )
228 {
229 buffer.append( " (version managed from " ).append( node.getPremanagedVersion() );
230 appendManagementSource( buffer, art, "version" );
231 buffer.append( ")" );
232 }
233 }
234 else
235 {
236 buffer.append( project.getGroupId() );
237 buffer.append( ':' ).append( project.getArtifactId() );
238 buffer.append( ':' ).append( project.getPackaging() );
239 buffer.append( ':' ).append( project.getVersion() );
240 }
241
242 logger.debug( buffer.toString() );
243 indent += " ";
244 return true;
245 }
246
247 public boolean visitLeave( DependencyNode node )
248 {
249 indent = indent.substring( 0, indent.length() - 3 );
250 return true;
251 }
252
253 private void appendManagementSource( StringBuilder buffer, org.sonatype.aether.artifact.Artifact artifact,
254 String field )
255 {
256 if ( managed == null )
257 {
258 managed = new HashMap<String, Dependency>();
259 if ( project.getDependencyManagement() != null )
260 {
261 for ( Dependency dep : project.getDependencyManagement().getDependencies() )
262 {
263 managed.put( dep.getManagementKey(), dep );
264 }
265 }
266 }
267
268 String key =
269 ArtifacIdUtils.toVersionlessId( artifact.getGroupId(), artifact.getArtifactId(),
270 artifact.getProperty( ArtifactProperties.TYPE, "jar" ),
271 artifact.getClassifier() );
272
273 Dependency dependency = managed.get( key );
274 if ( dependency != null )
275 {
276 InputLocation location = dependency.getLocation( field );
277 if ( location != null )
278 {
279 InputSource source = location.getSource();
280 if ( source != null )
281 {
282 buffer.append( " by " ).append( source.getModelId() );
283 }
284 }
285 }
286 }
287
288 }
289
290 }