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