1 package org.eclipse.aether.internal.impl.collect;
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.HashMap;
26 import java.util.HashSet;
27 import java.util.LinkedHashMap;
28 import java.util.List;
29 import java.util.Map;
30 import static java.util.Objects.requireNonNull;
31
32 import javax.inject.Inject;
33 import javax.inject.Named;
34
35 import org.eclipse.aether.DefaultRepositorySystemSession;
36 import org.eclipse.aether.RepositoryException;
37 import org.eclipse.aether.RepositorySystemSession;
38 import org.eclipse.aether.RequestTrace;
39 import org.eclipse.aether.artifact.Artifact;
40 import org.eclipse.aether.artifact.ArtifactProperties;
41 import org.eclipse.aether.collection.CollectRequest;
42 import org.eclipse.aether.collection.CollectResult;
43 import org.eclipse.aether.collection.DependencyCollectionException;
44 import org.eclipse.aether.collection.DependencyGraphTransformer;
45 import org.eclipse.aether.collection.DependencyManagement;
46 import org.eclipse.aether.collection.DependencyManager;
47 import org.eclipse.aether.collection.DependencySelector;
48 import org.eclipse.aether.collection.DependencyTraverser;
49 import org.eclipse.aether.collection.VersionFilter;
50 import org.eclipse.aether.graph.DefaultDependencyNode;
51 import org.eclipse.aether.graph.Dependency;
52 import org.eclipse.aether.graph.DependencyNode;
53 import org.eclipse.aether.graph.Exclusion;
54 import org.eclipse.aether.impl.ArtifactDescriptorReader;
55 import org.eclipse.aether.impl.DependencyCollector;
56 import org.eclipse.aether.impl.RemoteRepositoryManager;
57 import org.eclipse.aether.impl.VersionRangeResolver;
58 import org.eclipse.aether.repository.ArtifactRepository;
59 import org.eclipse.aether.repository.RemoteRepository;
60 import org.eclipse.aether.resolution.ArtifactDescriptorException;
61 import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
62 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
63 import org.eclipse.aether.resolution.VersionRangeRequest;
64 import org.eclipse.aether.resolution.VersionRangeResolutionException;
65 import org.eclipse.aether.resolution.VersionRangeResult;
66 import org.eclipse.aether.spi.locator.Service;
67 import org.eclipse.aether.spi.locator.ServiceLocator;
68 import org.eclipse.aether.util.ConfigUtils;
69 import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
70 import org.eclipse.aether.util.graph.transformer.TransformationContextKeys;
71 import org.eclipse.aether.version.Version;
72 import org.slf4j.Logger;
73 import org.slf4j.LoggerFactory;
74
75
76
77 @Named
78 public class DefaultDependencyCollector
79 implements DependencyCollector, Service
80 {
81
82 private static final String CONFIG_PROP_MAX_EXCEPTIONS = "aether.dependencyCollector.maxExceptions";
83
84 private static final int CONFIG_PROP_MAX_EXCEPTIONS_DEFAULT = 50;
85
86 private static final String CONFIG_PROP_MAX_CYCLES = "aether.dependencyCollector.maxCycles";
87
88 private static final int CONFIG_PROP_MAX_CYCLES_DEFAULT = 10;
89
90 private static final Logger LOGGER = LoggerFactory.getLogger( DefaultDependencyCollector.class );
91
92 private RemoteRepositoryManager remoteRepositoryManager;
93
94 private ArtifactDescriptorReader descriptorReader;
95
96 private VersionRangeResolver versionRangeResolver;
97
98 public DefaultDependencyCollector()
99 {
100
101 }
102
103 @Inject
104 DefaultDependencyCollector( RemoteRepositoryManager remoteRepositoryManager,
105 ArtifactDescriptorReader artifactDescriptorReader,
106 VersionRangeResolver versionRangeResolver )
107 {
108 setRemoteRepositoryManager( remoteRepositoryManager );
109 setArtifactDescriptorReader( artifactDescriptorReader );
110 setVersionRangeResolver( versionRangeResolver );
111 }
112
113 public void initService( ServiceLocator locator )
114 {
115 setRemoteRepositoryManager( locator.getService( RemoteRepositoryManager.class ) );
116 setArtifactDescriptorReader( locator.getService( ArtifactDescriptorReader.class ) );
117 setVersionRangeResolver( locator.getService( VersionRangeResolver.class ) );
118 }
119
120 public DefaultDependencyCollector setRemoteRepositoryManager( RemoteRepositoryManager remoteRepositoryManager )
121 {
122 this.remoteRepositoryManager =
123 requireNonNull( remoteRepositoryManager, "remote repository provider cannot be null" );
124 return this;
125 }
126
127 public DefaultDependencyCollector setArtifactDescriptorReader( ArtifactDescriptorReader artifactDescriptorReader )
128 {
129 descriptorReader = requireNonNull( artifactDescriptorReader, "artifact descriptor reader cannot be null" );
130 return this;
131 }
132
133 public DefaultDependencyCollector setVersionRangeResolver( VersionRangeResolver versionRangeResolver )
134 {
135 this.versionRangeResolver =
136 requireNonNull( versionRangeResolver, "version range resolver cannot be null" );
137 return this;
138 }
139
140 @SuppressWarnings( "checkstyle:methodlength" )
141 public CollectResult collectDependencies( RepositorySystemSession session, CollectRequest request )
142 throws DependencyCollectionException
143 {
144 session = optimizeSession( session );
145
146 RequestTrace trace = RequestTrace.newChild( request.getTrace(), request );
147
148 CollectResult result = new CollectResult( request );
149
150 DependencySelector depSelector = session.getDependencySelector();
151 DependencyManager depManager = session.getDependencyManager();
152 DependencyTraverser depTraverser = session.getDependencyTraverser();
153 VersionFilter verFilter = session.getVersionFilter();
154
155 Dependency root = request.getRoot();
156 List<RemoteRepository> repositories = request.getRepositories();
157 List<Dependency> dependencies = request.getDependencies();
158 List<Dependency> managedDependencies = request.getManagedDependencies();
159
160 Map<String, Object> stats = LOGGER.isDebugEnabled() ? new LinkedHashMap<String, Object>() : null;
161 long time1 = System.nanoTime();
162
163 DefaultDependencyNode node;
164 if ( root != null )
165 {
166 List<? extends Version> versions;
167 VersionRangeResult rangeResult;
168 try
169 {
170 VersionRangeRequest rangeRequest =
171 new VersionRangeRequest( root.getArtifact(), request.getRepositories(),
172 request.getRequestContext() );
173 rangeRequest.setTrace( trace );
174 rangeResult = versionRangeResolver.resolveVersionRange( session, rangeRequest );
175 versions = filterVersions( root, rangeResult, verFilter, new DefaultVersionFilterContext( session ) );
176 }
177 catch ( VersionRangeResolutionException e )
178 {
179 result.addException( e );
180 throw new DependencyCollectionException( result, e.getMessage() );
181 }
182
183 Version version = versions.get( versions.size() - 1 );
184 root = root.setArtifact( root.getArtifact().setVersion( version.toString() ) );
185
186 ArtifactDescriptorResult descriptorResult;
187 try
188 {
189 ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest();
190 descriptorRequest.setArtifact( root.getArtifact() );
191 descriptorRequest.setRepositories( request.getRepositories() );
192 descriptorRequest.setRequestContext( request.getRequestContext() );
193 descriptorRequest.setTrace( trace );
194 if ( isLackingDescriptor( root.getArtifact() ) )
195 {
196 descriptorResult = new ArtifactDescriptorResult( descriptorRequest );
197 }
198 else
199 {
200 descriptorResult = descriptorReader.readArtifactDescriptor( session, descriptorRequest );
201 }
202 }
203 catch ( ArtifactDescriptorException e )
204 {
205 result.addException( e );
206 throw new DependencyCollectionException( result, e.getMessage() );
207 }
208
209 root = root.setArtifact( descriptorResult.getArtifact() );
210
211 if ( !session.isIgnoreArtifactDescriptorRepositories() )
212 {
213 repositories = remoteRepositoryManager.aggregateRepositories( session, repositories,
214 descriptorResult.getRepositories(),
215 true );
216 }
217 dependencies = mergeDeps( dependencies, descriptorResult.getDependencies() );
218 managedDependencies = mergeDeps( managedDependencies, descriptorResult.getManagedDependencies() );
219
220 node = new DefaultDependencyNode( root );
221 node.setRequestContext( request.getRequestContext() );
222 node.setRelocations( descriptorResult.getRelocations() );
223 node.setVersionConstraint( rangeResult.getVersionConstraint() );
224 node.setVersion( version );
225 node.setAliases( descriptorResult.getAliases() );
226 node.setRepositories( request.getRepositories() );
227 }
228 else
229 {
230 node = new DefaultDependencyNode( request.getRootArtifact() );
231 node.setRequestContext( request.getRequestContext() );
232 node.setRepositories( request.getRepositories() );
233 }
234
235 result.setRoot( node );
236
237 boolean traverse = root == null || depTraverser == null || depTraverser.traverseDependency( root );
238 String errorPath = null;
239 if ( traverse && !dependencies.isEmpty() )
240 {
241 DataPool pool = new DataPool( session );
242
243 NodeStack nodes = new NodeStack();
244 nodes.push( node );
245
246 DefaultDependencyCollectionContext context =
247 new DefaultDependencyCollectionContext( session, request.getRootArtifact(), root, managedDependencies );
248
249 DefaultVersionFilterContext versionContext = new DefaultVersionFilterContext( session );
250
251 Args args = new Args( session, trace, pool, nodes, context, versionContext, request );
252 Results results = new Results( result, session );
253
254 process( args, results, dependencies, repositories,
255 depSelector != null ? depSelector.deriveChildSelector( context ) : null,
256 depManager != null ? depManager.deriveChildManager( context ) : null,
257 depTraverser != null ? depTraverser.deriveChildTraverser( context ) : null,
258 verFilter != null ? verFilter.deriveChildFilter( context ) : null );
259
260 errorPath = results.errorPath;
261 }
262
263 long time2 = System.nanoTime();
264
265 DependencyGraphTransformer transformer = session.getDependencyGraphTransformer();
266 if ( transformer != null )
267 {
268 try
269 {
270 DefaultDependencyGraphTransformationContext context =
271 new DefaultDependencyGraphTransformationContext( session );
272 context.put( TransformationContextKeys.STATS, stats );
273 result.setRoot( transformer.transformGraph( node, context ) );
274 }
275 catch ( RepositoryException e )
276 {
277 result.addException( e );
278 }
279 }
280
281 if ( stats != null )
282 {
283 long time3 = System.nanoTime();
284 stats.put( "DefaultDependencyCollector.collectTime", time2 - time1 );
285 stats.put( "DefaultDependencyCollector.transformTime", time3 - time2 );
286 LOGGER.debug( "Dependency collection stats: " + stats );
287 }
288
289 if ( errorPath != null )
290 {
291 throw new DependencyCollectionException( result, "Failed to collect dependencies at " + errorPath );
292 }
293 if ( !result.getExceptions().isEmpty() )
294 {
295 throw new DependencyCollectionException( result );
296 }
297
298 return result;
299 }
300
301 private static RepositorySystemSession optimizeSession( RepositorySystemSession session )
302 {
303 DefaultRepositorySystemSession optimized = new DefaultRepositorySystemSession( session );
304 optimized.setArtifactTypeRegistry( CachingArtifactTypeRegistry.newInstance( session ) );
305 return optimized;
306 }
307
308 private List<Dependency> mergeDeps( List<Dependency> dominant, List<Dependency> recessive )
309 {
310 List<Dependency> result;
311 if ( dominant == null || dominant.isEmpty() )
312 {
313 result = recessive;
314 }
315 else if ( recessive == null || recessive.isEmpty() )
316 {
317 result = dominant;
318 }
319 else
320 {
321 int initialCapacity = dominant.size() + recessive.size();
322 result = new ArrayList<>( initialCapacity );
323 Collection<String> ids = new HashSet<String>( initialCapacity, 1.0f );
324 for ( Dependency dependency : dominant )
325 {
326 ids.add( getId( dependency.getArtifact() ) );
327 result.add( dependency );
328 }
329 for ( Dependency dependency : recessive )
330 {
331 if ( !ids.contains( getId( dependency.getArtifact() ) ) )
332 {
333 result.add( dependency );
334 }
335 }
336 }
337 return result;
338 }
339
340 private static String getId( Artifact a )
341 {
342 return a.getGroupId() + ':' + a.getArtifactId() + ':' + a.getClassifier() + ':' + a.getExtension();
343 }
344
345 @SuppressWarnings( "checkstyle:parameternumber" )
346 private void process( final Args args, Results results, List<Dependency> dependencies,
347 List<RemoteRepository> repositories, DependencySelector depSelector,
348 DependencyManager depManager, DependencyTraverser depTraverser, VersionFilter verFilter )
349 {
350 for ( Dependency dependency : dependencies )
351 {
352 processDependency( args, results, repositories, depSelector, depManager, depTraverser, verFilter,
353 dependency );
354 }
355 }
356
357 @SuppressWarnings( "checkstyle:parameternumber" )
358 private void processDependency( Args args, Results results, List<RemoteRepository> repositories,
359 DependencySelector depSelector, DependencyManager depManager,
360 DependencyTraverser depTraverser, VersionFilter verFilter, Dependency dependency )
361 {
362
363 List<Artifact> relocations = Collections.emptyList();
364 boolean disableVersionManagement = false;
365 processDependency( args, results, repositories, depSelector, depManager, depTraverser, verFilter, dependency,
366 relocations, disableVersionManagement );
367 }
368
369 @SuppressWarnings( "checkstyle:parameternumber" )
370 private void processDependency( Args args, Results results, List<RemoteRepository> repositories,
371 DependencySelector depSelector, DependencyManager depManager,
372 DependencyTraverser depTraverser, VersionFilter verFilter, Dependency dependency,
373 List<Artifact> relocations, boolean disableVersionManagement )
374 {
375
376 if ( depSelector != null && !depSelector.selectDependency( dependency ) )
377 {
378 return;
379 }
380
381 PremanagedDependency preManaged =
382 PremanagedDependency.create( depManager, dependency, disableVersionManagement, args.premanagedState );
383 dependency = preManaged.managedDependency;
384
385 boolean noDescriptor = isLackingDescriptor( dependency.getArtifact() );
386
387 boolean traverse = !noDescriptor && ( depTraverser == null || depTraverser.traverseDependency( dependency ) );
388
389 List<? extends Version> versions;
390 VersionRangeResult rangeResult;
391 try
392 {
393 VersionRangeRequest rangeRequest = createVersionRangeRequest( args, repositories, dependency );
394
395 rangeResult = cachedResolveRangeResult( rangeRequest, args.pool, args.session );
396
397 versions = filterVersions( dependency, rangeResult, verFilter, args.versionContext );
398 }
399 catch ( VersionRangeResolutionException e )
400 {
401 results.addException( dependency, e, args.nodes );
402 return;
403 }
404
405 for ( Version version : versions )
406 {
407 Artifact originalArtifact = dependency.getArtifact().setVersion( version.toString() );
408 Dependency d = dependency.setArtifact( originalArtifact );
409
410 ArtifactDescriptorRequest descriptorRequest = createArtifactDescriptorRequest( args, repositories, d );
411
412 final ArtifactDescriptorResult descriptorResult =
413 getArtifactDescriptorResult( args, results, noDescriptor, d, descriptorRequest );
414 if ( descriptorResult != null )
415 {
416 d = d.setArtifact( descriptorResult.getArtifact() );
417
418 DependencyNode node = args.nodes.top();
419
420 int cycleEntry = args.nodes.find( d.getArtifact() );
421 if ( cycleEntry >= 0 )
422 {
423 results.addCycle( args.nodes, cycleEntry, d );
424 DependencyNode cycleNode = args.nodes.get( cycleEntry );
425 if ( cycleNode.getDependency() != null )
426 {
427 DefaultDependencyNode child =
428 createDependencyNode( relocations, preManaged, rangeResult, version, d, descriptorResult,
429 cycleNode );
430 node.getChildren().add( child );
431 continue;
432 }
433 }
434
435 if ( !descriptorResult.getRelocations().isEmpty() )
436 {
437 boolean disableVersionManagementSubsequently =
438 originalArtifact.getGroupId().equals( d.getArtifact().getGroupId() )
439 && originalArtifact.getArtifactId().equals( d.getArtifact().getArtifactId() );
440
441 processDependency( args, results, repositories, depSelector, depManager, depTraverser, verFilter, d,
442 descriptorResult.getRelocations(), disableVersionManagementSubsequently );
443 return;
444 }
445 else
446 {
447 d = args.pool.intern( d.setArtifact( args.pool.intern( d.getArtifact() ) ) );
448
449 List<RemoteRepository> repos =
450 getRemoteRepositories( rangeResult.getRepository( version ), repositories );
451
452 DefaultDependencyNode child =
453 createDependencyNode( relocations, preManaged, rangeResult, version, d,
454 descriptorResult.getAliases(), repos, args.request.getRequestContext() );
455
456 node.getChildren().add( child );
457
458 boolean recurse = traverse && !descriptorResult.getDependencies().isEmpty();
459 if ( recurse )
460 {
461 doRecurse( args, results, repositories, depSelector, depManager, depTraverser, verFilter, d,
462 descriptorResult, child );
463 }
464 }
465 }
466 else
467 {
468 DependencyNode node = args.nodes.top();
469 List<RemoteRepository> repos =
470 getRemoteRepositories( rangeResult.getRepository( version ), repositories );
471 DefaultDependencyNode child =
472 createDependencyNode( relocations, preManaged, rangeResult, version, d, null, repos,
473 args.request.getRequestContext() );
474 node.getChildren().add( child );
475 }
476 }
477 }
478
479 @SuppressWarnings( "checkstyle:parameternumber" )
480 private void doRecurse( Args args, Results results, List<RemoteRepository> repositories,
481 DependencySelector depSelector, DependencyManager depManager,
482 DependencyTraverser depTraverser, VersionFilter verFilter, Dependency d,
483 ArtifactDescriptorResult descriptorResult, DefaultDependencyNode child )
484 {
485 DefaultDependencyCollectionContext context = args.collectionContext;
486 context.set( d, descriptorResult.getManagedDependencies() );
487
488 DependencySelector childSelector = depSelector != null ? depSelector.deriveChildSelector( context ) : null;
489 DependencyManager childManager = depManager != null ? depManager.deriveChildManager( context ) : null;
490 DependencyTraverser childTraverser = depTraverser != null ? depTraverser.deriveChildTraverser( context ) : null;
491 VersionFilter childFilter = verFilter != null ? verFilter.deriveChildFilter( context ) : null;
492
493 final List<RemoteRepository> childRepos =
494 args.ignoreRepos
495 ? repositories
496 : remoteRepositoryManager.aggregateRepositories( args.session, repositories,
497 descriptorResult.getRepositories(), true );
498
499 Object key =
500 args.pool.toKey( d.getArtifact(), childRepos, childSelector, childManager, childTraverser, childFilter );
501
502 List<DependencyNode> children = args.pool.getChildren( key );
503 if ( children == null )
504 {
505 args.pool.putChildren( key, child.getChildren() );
506
507 args.nodes.push( child );
508
509 process( args, results, descriptorResult.getDependencies(), childRepos, childSelector, childManager,
510 childTraverser, childFilter );
511
512 args.nodes.pop();
513 }
514 else
515 {
516 child.setChildren( children );
517 }
518 }
519
520 private ArtifactDescriptorResult getArtifactDescriptorResult( Args args, Results results, boolean noDescriptor,
521 Dependency d,
522 ArtifactDescriptorRequest descriptorRequest )
523 {
524 return noDescriptor
525 ? new ArtifactDescriptorResult( descriptorRequest )
526 : resolveCachedArtifactDescriptor( args.pool, descriptorRequest, args.session, d, results, args );
527
528 }
529
530 private ArtifactDescriptorResult resolveCachedArtifactDescriptor( DataPool pool,
531 ArtifactDescriptorRequest descriptorRequest,
532 RepositorySystemSession session, Dependency d,
533 Results results, Args args )
534 {
535 Object key = pool.toKey( descriptorRequest );
536 ArtifactDescriptorResult descriptorResult = pool.getDescriptor( key, descriptorRequest );
537 if ( descriptorResult == null )
538 {
539 try
540 {
541 descriptorResult = descriptorReader.readArtifactDescriptor( session, descriptorRequest );
542 pool.putDescriptor( key, descriptorResult );
543 }
544 catch ( ArtifactDescriptorException e )
545 {
546 results.addException( d, e, args.nodes );
547 pool.putDescriptor( key, e );
548 return null;
549 }
550
551 }
552 else if ( descriptorResult == DataPool.NO_DESCRIPTOR )
553 {
554 return null;
555 }
556
557 return descriptorResult;
558 }
559
560 @SuppressWarnings( "checkstyle:parameternumber" )
561 private static DefaultDependencyNode createDependencyNode( List<Artifact> relocations,
562 PremanagedDependency preManaged,
563 VersionRangeResult rangeResult, Version version,
564 Dependency d, Collection<Artifact> aliases,
565 List<RemoteRepository> repos, String requestContext )
566 {
567 DefaultDependencyNode child = new DefaultDependencyNode( d );
568 preManaged.applyTo( child );
569 child.setRelocations( relocations );
570 child.setVersionConstraint( rangeResult.getVersionConstraint() );
571 child.setVersion( version );
572 child.setAliases( aliases );
573 child.setRepositories( repos );
574 child.setRequestContext( requestContext );
575 return child;
576 }
577
578 private static DefaultDependencyNode createDependencyNode( List<Artifact> relocations,
579 PremanagedDependency preManaged,
580 VersionRangeResult rangeResult, Version version,
581 Dependency d, ArtifactDescriptorResult descriptorResult,
582 DependencyNode cycleNode )
583 {
584 DefaultDependencyNode child =
585 createDependencyNode( relocations, preManaged, rangeResult, version, d, descriptorResult.getAliases(),
586 cycleNode.getRepositories(), cycleNode.getRequestContext() );
587 child.setChildren( cycleNode.getChildren() );
588 return child;
589 }
590
591 private static ArtifactDescriptorRequest createArtifactDescriptorRequest( Args args,
592 List<RemoteRepository> repositories,
593 Dependency d )
594 {
595 ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest();
596 descriptorRequest.setArtifact( d.getArtifact() );
597 descriptorRequest.setRepositories( repositories );
598 descriptorRequest.setRequestContext( args.request.getRequestContext() );
599 descriptorRequest.setTrace( args.trace );
600 return descriptorRequest;
601 }
602
603 private static VersionRangeRequest createVersionRangeRequest( Args args, List<RemoteRepository> repositories,
604 Dependency dependency )
605 {
606 VersionRangeRequest rangeRequest = new VersionRangeRequest();
607 rangeRequest.setArtifact( dependency.getArtifact() );
608 rangeRequest.setRepositories( repositories );
609 rangeRequest.setRequestContext( args.request.getRequestContext() );
610 rangeRequest.setTrace( args.trace );
611 return rangeRequest;
612 }
613
614 private VersionRangeResult cachedResolveRangeResult( VersionRangeRequest rangeRequest, DataPool pool,
615 RepositorySystemSession session )
616 throws VersionRangeResolutionException
617 {
618 Object key = pool.toKey( rangeRequest );
619 VersionRangeResult rangeResult = pool.getConstraint( key, rangeRequest );
620 if ( rangeResult == null )
621 {
622 rangeResult = versionRangeResolver.resolveVersionRange( session, rangeRequest );
623 pool.putConstraint( key, rangeResult );
624 }
625 return rangeResult;
626 }
627
628 private static boolean isLackingDescriptor( Artifact artifact )
629 {
630 return artifact.getProperty( ArtifactProperties.LOCAL_PATH, null ) != null;
631 }
632
633 private static List<RemoteRepository> getRemoteRepositories( ArtifactRepository repository,
634 List<RemoteRepository> repositories )
635 {
636 if ( repository instanceof RemoteRepository )
637 {
638 return Collections.singletonList( (RemoteRepository) repository );
639 }
640 if ( repository != null )
641 {
642 return Collections.emptyList();
643 }
644 return repositories;
645 }
646
647 private static List<? extends Version> filterVersions( Dependency dependency, VersionRangeResult rangeResult,
648 VersionFilter verFilter,
649 DefaultVersionFilterContext verContext )
650 throws VersionRangeResolutionException
651 {
652 if ( rangeResult.getVersions().isEmpty() )
653 {
654 throw new VersionRangeResolutionException( rangeResult,
655 "No versions available for " + dependency.getArtifact()
656 + " within specified range" );
657 }
658
659 List<? extends Version> versions;
660 if ( verFilter != null && rangeResult.getVersionConstraint().getRange() != null )
661 {
662 verContext.set( dependency, rangeResult );
663 try
664 {
665 verFilter.filterVersions( verContext );
666 }
667 catch ( RepositoryException e )
668 {
669 throw new VersionRangeResolutionException( rangeResult,
670 "Failed to filter versions for " + dependency.getArtifact()
671 + ": " + e.getMessage(), e );
672 }
673 versions = verContext.get();
674 if ( versions.isEmpty() )
675 {
676 throw new VersionRangeResolutionException( rangeResult,
677 "No acceptable versions for " + dependency.getArtifact()
678 + ": " + rangeResult.getVersions() );
679 }
680 }
681 else
682 {
683 versions = rangeResult.getVersions();
684 }
685 return versions;
686 }
687
688 static class Args
689 {
690
691 final RepositorySystemSession session;
692
693 final boolean ignoreRepos;
694
695 final boolean premanagedState;
696
697 final RequestTrace trace;
698
699 final DataPool pool;
700
701 final NodeStack nodes;
702
703 final DefaultDependencyCollectionContext collectionContext;
704
705 final DefaultVersionFilterContext versionContext;
706
707 final CollectRequest request;
708
709 Args( RepositorySystemSession session, RequestTrace trace, DataPool pool, NodeStack nodes,
710 DefaultDependencyCollectionContext collectionContext, DefaultVersionFilterContext versionContext,
711 CollectRequest request )
712 {
713 this.session = session;
714 this.request = request;
715 this.ignoreRepos = session.isIgnoreArtifactDescriptorRepositories();
716 this.premanagedState = ConfigUtils.getBoolean( session, false, DependencyManagerUtils.CONFIG_PROP_VERBOSE );
717 this.trace = trace;
718 this.pool = pool;
719 this.nodes = nodes;
720 this.collectionContext = collectionContext;
721 this.versionContext = versionContext;
722 }
723
724 }
725
726 static class Results
727 {
728
729 private final CollectResult result;
730
731 final int maxExceptions;
732
733 final int maxCycles;
734
735 String errorPath;
736
737 Results( CollectResult result, RepositorySystemSession session )
738 {
739 this.result = result;
740
741 maxExceptions =
742 ConfigUtils.getInteger( session, CONFIG_PROP_MAX_EXCEPTIONS_DEFAULT, CONFIG_PROP_MAX_EXCEPTIONS );
743
744 maxCycles = ConfigUtils.getInteger( session, CONFIG_PROP_MAX_CYCLES_DEFAULT, CONFIG_PROP_MAX_CYCLES );
745 }
746
747 public void addException( Dependency dependency, Exception e, NodeStack nodes )
748 {
749 if ( maxExceptions < 0 || result.getExceptions().size() < maxExceptions )
750 {
751 result.addException( e );
752 if ( errorPath == null )
753 {
754 StringBuilder buffer = new StringBuilder( 256 );
755 for ( int i = 0; i < nodes.size(); i++ )
756 {
757 if ( buffer.length() > 0 )
758 {
759 buffer.append( " -> " );
760 }
761 Dependency dep = nodes.get( i ).getDependency();
762 if ( dep != null )
763 {
764 buffer.append( dep.getArtifact() );
765 }
766 }
767 if ( buffer.length() > 0 )
768 {
769 buffer.append( " -> " );
770 }
771 buffer.append( dependency.getArtifact() );
772 errorPath = buffer.toString();
773 }
774 }
775 }
776
777 public void addCycle( NodeStack nodes, int cycleEntry, Dependency dependency )
778 {
779 if ( maxCycles < 0 || result.getCycles().size() < maxCycles )
780 {
781 result.addCycle( new DefaultDependencyCycle( nodes, cycleEntry, dependency ) );
782 }
783 }
784
785 }
786
787 static class PremanagedDependency
788 {
789
790 final String premanagedVersion;
791
792 final String premanagedScope;
793
794 final Boolean premanagedOptional;
795
796
797
798
799 final Collection<Exclusion> premanagedExclusions;
800
801
802
803
804 final Map<String, String> premanagedProperties;
805
806 final int managedBits;
807
808 final Dependency managedDependency;
809
810 final boolean premanagedState;
811
812 @SuppressWarnings( "checkstyle:parameternumber" )
813 PremanagedDependency( String premanagedVersion, String premanagedScope, Boolean premanagedOptional,
814 Collection<Exclusion> premanagedExclusions, Map<String, String> premanagedProperties,
815 int managedBits, Dependency managedDependency, boolean premanagedState )
816 {
817 this.premanagedVersion = premanagedVersion;
818 this.premanagedScope = premanagedScope;
819 this.premanagedOptional = premanagedOptional;
820 this.premanagedExclusions =
821 premanagedExclusions != null
822 ? Collections.unmodifiableCollection( new ArrayList<>( premanagedExclusions ) )
823 : null;
824
825 this.premanagedProperties =
826 premanagedProperties != null
827 ? Collections.unmodifiableMap( new HashMap<>( premanagedProperties ) )
828 : null;
829
830 this.managedBits = managedBits;
831 this.managedDependency = managedDependency;
832 this.premanagedState = premanagedState;
833 }
834
835 static PremanagedDependency create( DependencyManager depManager, Dependency dependency,
836 boolean disableVersionManagement, boolean premanagedState )
837 {
838 DependencyManagement depMngt = depManager != null ? depManager.manageDependency( dependency ) : null;
839
840 int managedBits = 0;
841 String premanagedVersion = null;
842 String premanagedScope = null;
843 Boolean premanagedOptional = null;
844 Collection<Exclusion> premanagedExclusions = null;
845 Map<String, String> premanagedProperties = null;
846
847 if ( depMngt != null )
848 {
849 if ( depMngt.getVersion() != null && !disableVersionManagement )
850 {
851 Artifact artifact = dependency.getArtifact();
852 premanagedVersion = artifact.getVersion();
853 dependency = dependency.setArtifact( artifact.setVersion( depMngt.getVersion() ) );
854 managedBits |= DependencyNode.MANAGED_VERSION;
855 }
856 if ( depMngt.getProperties() != null )
857 {
858 Artifact artifact = dependency.getArtifact();
859 premanagedProperties = artifact.getProperties();
860 dependency = dependency.setArtifact( artifact.setProperties( depMngt.getProperties() ) );
861 managedBits |= DependencyNode.MANAGED_PROPERTIES;
862 }
863 if ( depMngt.getScope() != null )
864 {
865 premanagedScope = dependency.getScope();
866 dependency = dependency.setScope( depMngt.getScope() );
867 managedBits |= DependencyNode.MANAGED_SCOPE;
868 }
869 if ( depMngt.getOptional() != null )
870 {
871 premanagedOptional = dependency.isOptional();
872 dependency = dependency.setOptional( depMngt.getOptional() );
873 managedBits |= DependencyNode.MANAGED_OPTIONAL;
874 }
875 if ( depMngt.getExclusions() != null )
876 {
877 premanagedExclusions = dependency.getExclusions();
878 dependency = dependency.setExclusions( depMngt.getExclusions() );
879 managedBits |= DependencyNode.MANAGED_EXCLUSIONS;
880 }
881 }
882 return new PremanagedDependency( premanagedVersion, premanagedScope, premanagedOptional,
883 premanagedExclusions, premanagedProperties, managedBits, dependency,
884 premanagedState );
885
886 }
887
888 public void applyTo( DefaultDependencyNode child )
889 {
890 child.setManagedBits( managedBits );
891 if ( premanagedState )
892 {
893 child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_VERSION, premanagedVersion );
894 child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_SCOPE, premanagedScope );
895 child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_OPTIONAL, premanagedOptional );
896 child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_EXCLUSIONS, premanagedExclusions );
897 child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_PROPERTIES, premanagedProperties );
898 }
899 }
900
901 }
902
903 }