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.List;
25 import java.util.Map;
26 import java.util.Objects;
27
28 import org.apache.maven.RepositoryUtils;
29 import org.apache.maven.artifact.Artifact;
30 import org.apache.maven.model.Dependency;
31 import org.apache.maven.model.DependencyManagement;
32 import org.apache.maven.model.Exclusion;
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.codehaus.plexus.util.StringUtils;
37 import org.eclipse.aether.DefaultRepositorySystemSession;
38 import org.eclipse.aether.RepositorySystem;
39 import org.eclipse.aether.RepositorySystemSession;
40 import org.eclipse.aether.RequestTrace;
41 import org.eclipse.aether.artifact.ArtifactType;
42 import org.eclipse.aether.artifact.ArtifactTypeRegistry;
43 import org.eclipse.aether.collection.CollectRequest;
44 import org.eclipse.aether.collection.DependencyCollectionException;
45 import org.eclipse.aether.graph.DependencyFilter;
46 import org.eclipse.aether.graph.DependencyNode;
47 import org.eclipse.aether.graph.DependencyVisitor;
48 import org.eclipse.aether.resolution.ArtifactResult;
49 import org.eclipse.aether.resolution.DependencyRequest;
50 import org.eclipse.aether.util.artifact.ArtifactIdUtils;
51 import org.eclipse.aether.util.artifact.JavaScopes;
52 import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
53
54
55
56
57 @Component( role = ProjectDependenciesResolver.class )
58 public class DefaultProjectDependenciesResolver
59 implements ProjectDependenciesResolver
60 {
61
62 @Requirement
63 private Logger logger;
64
65 @Requirement
66 private RepositorySystem repoSystem;
67
68 @Requirement
69 private List<RepositorySessionDecorator> decorators;
70
71 public DependencyResolutionResult resolve( DependencyResolutionRequest request )
72 throws DependencyResolutionException
73 {
74 final RequestTrace trace = RequestTrace.newChild( null, request );
75
76 final DefaultDependencyResolutionResult result = new DefaultDependencyResolutionResult();
77
78 final MavenProject project = request.getMavenProject();
79 final DependencyFilter filter = request.getResolutionFilter();
80 RepositorySystemSession session = request.getRepositorySession();
81 ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry();
82
83 if ( logger.isDebugEnabled()
84 && session.getConfigProperties().get( DependencyManagerUtils.CONFIG_PROP_VERBOSE ) == null )
85 {
86 DefaultRepositorySystemSession verbose = new DefaultRepositorySystemSession( session );
87 verbose.setConfigProperty( DependencyManagerUtils.CONFIG_PROP_VERBOSE, Boolean.TRUE );
88 session = verbose;
89 }
90
91 for ( RepositorySessionDecorator decorator : decorators )
92 {
93 RepositorySystemSession decorated = decorator.decorate( project, session );
94 if ( decorated != null )
95 {
96 session = decorated;
97 }
98 }
99
100 CollectRequest collect = new CollectRequest();
101 collect.setRootArtifact( RepositoryUtils.toArtifact( project.getArtifact() ) );
102 collect.setRequestContext( "project" );
103 collect.setRepositories( project.getRemoteProjectRepositories() );
104
105 if ( project.getDependencyArtifacts() == null )
106 {
107 for ( Dependency dependency : project.getDependencies() )
108 {
109 if ( StringUtils.isEmpty( dependency.getGroupId() ) || StringUtils.isEmpty( dependency.getArtifactId() )
110 || StringUtils.isEmpty( dependency.getVersion() ) )
111 {
112
113 continue;
114 }
115 collect.addDependency( RepositoryUtils.toDependency( dependency, stereotypes ) );
116 }
117 }
118 else
119 {
120 Map<String, Dependency> dependencies = new HashMap<>();
121 for ( Dependency dependency : project.getDependencies() )
122 {
123 String classifier = dependency.getClassifier();
124 if ( classifier == null )
125 {
126 ArtifactType type = stereotypes.get( dependency.getType() );
127 if ( type != null )
128 {
129 classifier = type.getClassifier();
130 }
131 }
132 String key =
133 ArtifactIdUtils.toVersionlessId( dependency.getGroupId(), dependency.getArtifactId(),
134 dependency.getType(), classifier );
135 dependencies.put( key, dependency );
136 }
137 for ( Artifact artifact : project.getDependencyArtifacts() )
138 {
139 String key = artifact.getDependencyConflictId();
140 Dependency dependency = dependencies.get( key );
141 Collection<Exclusion> exclusions = dependency != null ? dependency.getExclusions() : null;
142 org.eclipse.aether.graph.Dependency dep = RepositoryUtils.toDependency( artifact, exclusions );
143 if ( !JavaScopes.SYSTEM.equals( dep.getScope() ) && dep.getArtifact().getFile() != null )
144 {
145
146 org.eclipse.aether.artifact.Artifact art = dep.getArtifact();
147 art = art.setFile( null ).setVersion( art.getBaseVersion() );
148 dep = dep.setArtifact( art );
149 }
150 collect.addDependency( dep );
151 }
152 }
153
154 DependencyManagement depMgmt = project.getDependencyManagement();
155 if ( depMgmt != null )
156 {
157 for ( Dependency dependency : depMgmt.getDependencies() )
158 {
159 collect.addManagedDependency( RepositoryUtils.toDependency( dependency, stereotypes ) );
160 }
161 }
162
163 DependencyRequest depRequest = new DependencyRequest( collect, filter );
164 depRequest.setTrace( trace );
165
166 DependencyNode node;
167 try
168 {
169 collect.setTrace( RequestTrace.newChild( trace, depRequest ) );
170 node = repoSystem.collectDependencies( session, collect ).getRoot();
171 result.setDependencyGraph( node );
172 }
173 catch ( DependencyCollectionException e )
174 {
175 result.setDependencyGraph( e.getResult().getRoot() );
176 result.setCollectionErrors( e.getResult().getExceptions() );
177
178 throw new DependencyResolutionException( result, "Could not resolve dependencies for project "
179 + project.getId() + ": " + e.getMessage(), e );
180 }
181
182 depRequest.setRoot( node );
183
184 if ( logger.isWarnEnabled() )
185 {
186 for ( DependencyNode child : node.getChildren() )
187 {
188 if ( !child.getRelocations().isEmpty() )
189 {
190 org.eclipse.aether.artifact.Artifact relocated = child.getDependency().getArtifact();
191 String message = relocated instanceof org.apache.maven.repository.internal.RelocatedArtifact
192 ? ( ( org.apache.maven.repository.internal.RelocatedArtifact ) relocated ).getMessage()
193 : null;
194 logger.warn( "The artifact " + child.getRelocations().get( 0 ) + " has been relocated to "
195 + relocated + ( message != null ? ": " + message : "" ) );
196 }
197 }
198 }
199
200 if ( logger.isDebugEnabled() )
201 {
202 node.accept( new GraphLogger( project ) );
203 }
204
205 try
206 {
207 process( result, repoSystem.resolveDependencies( session, depRequest ).getArtifactResults() );
208 }
209 catch ( org.eclipse.aether.resolution.DependencyResolutionException e )
210 {
211 process( result, e.getResult().getArtifactResults() );
212
213 throw new DependencyResolutionException( result, "Could not resolve dependencies for project "
214 + project.getId() + ": " + e.getMessage(), e );
215 }
216
217 return result;
218 }
219
220 private void process( DefaultDependencyResolutionResult result, Collection<ArtifactResult> results )
221 {
222 for ( ArtifactResult ar : results )
223 {
224 DependencyNode node = ar.getRequest().getDependencyNode();
225 if ( ar.isResolved() )
226 {
227 result.addResolvedDependency( node.getDependency() );
228 }
229 else
230 {
231 result.setResolutionErrors( node.getDependency(), ar.getExceptions() );
232 }
233 }
234 }
235
236
237 class GraphLogger
238 implements DependencyVisitor
239 {
240
241 private final MavenProject project;
242
243 private String indent = "";
244
245 GraphLogger( MavenProject project )
246 {
247 this.project = project;
248 }
249
250 public boolean visitEnter( DependencyNode node )
251 {
252 StringBuilder buffer = new StringBuilder( 128 );
253 buffer.append( indent );
254 org.eclipse.aether.graph.Dependency dep = node.getDependency();
255 if ( dep != null )
256 {
257 org.eclipse.aether.artifact.Artifact art = dep.getArtifact();
258
259 buffer.append( art );
260 if ( StringUtils.isNotEmpty( dep.getScope() ) )
261 {
262 buffer.append( ':' ).append( dep.getScope() );
263 }
264
265 if ( dep.isOptional() )
266 {
267 buffer.append( " (optional)" );
268 }
269
270
271
272
273 if ( ( node.getManagedBits() & DependencyNode.MANAGED_SCOPE ) == DependencyNode.MANAGED_SCOPE )
274 {
275 final String premanagedScope = DependencyManagerUtils.getPremanagedScope( node );
276 buffer.append( " (scope managed from " );
277 buffer.append( Objects.toString( premanagedScope, "default" ) );
278 buffer.append( ')' );
279 }
280
281 if ( ( node.getManagedBits() & DependencyNode.MANAGED_VERSION ) == DependencyNode.MANAGED_VERSION )
282 {
283 final String premanagedVersion = DependencyManagerUtils.getPremanagedVersion( node );
284 buffer.append( " (version managed from " );
285 buffer.append( Objects.toString( premanagedVersion, "default" ) );
286 buffer.append( ')' );
287 }
288
289 if ( ( node.getManagedBits() & DependencyNode.MANAGED_OPTIONAL ) == DependencyNode.MANAGED_OPTIONAL )
290 {
291 final Boolean premanagedOptional = DependencyManagerUtils.getPremanagedOptional( node );
292 buffer.append( " (optionality managed from " );
293 buffer.append( Objects.toString( premanagedOptional, "default" ) );
294 buffer.append( ')' );
295 }
296
297 if ( ( node.getManagedBits() & DependencyNode.MANAGED_EXCLUSIONS )
298 == DependencyNode.MANAGED_EXCLUSIONS )
299 {
300 final Collection<org.eclipse.aether.graph.Exclusion> premanagedExclusions =
301 DependencyManagerUtils.getPremanagedExclusions( node );
302
303 buffer.append( " (exclusions managed from " );
304 buffer.append( Objects.toString( premanagedExclusions, "default" ) );
305 buffer.append( ')' );
306 }
307
308 if ( ( node.getManagedBits() & DependencyNode.MANAGED_PROPERTIES )
309 == DependencyNode.MANAGED_PROPERTIES )
310 {
311 final Map<String, String> premanagedProperties =
312 DependencyManagerUtils.getPremanagedProperties( node );
313
314 buffer.append( " (properties managed from " );
315 buffer.append( Objects.toString( premanagedProperties, "default" ) );
316 buffer.append( ')' );
317 }
318 }
319 else
320 {
321 buffer.append( project.getGroupId() );
322 buffer.append( ':' ).append( project.getArtifactId() );
323 buffer.append( ':' ).append( project.getPackaging() );
324 buffer.append( ':' ).append( project.getVersion() );
325 }
326
327 logger.debug( buffer.toString() );
328 indent += " ";
329 return true;
330 }
331
332 public boolean visitLeave( DependencyNode node )
333 {
334 indent = indent.substring( 0, indent.length() - 3 );
335 return true;
336 }
337
338 }
339
340 }