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 = new LinkedHashMap<>();
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 long time3 = System.nanoTime();
282 stats.put( "DefaultDependencyCollector.collectTime", time2 - time1 );
283 stats.put( "DefaultDependencyCollector.transformTime", time3 - time2 );
284 LOGGER.debug( "Dependency collection stats {}", stats );
285
286 if ( errorPath != null )
287 {
288 throw new DependencyCollectionException( result, "Failed to collect dependencies at " + errorPath );
289 }
290 if ( !result.getExceptions().isEmpty() )
291 {
292 throw new DependencyCollectionException( result );
293 }
294
295 return result;
296 }
297
298 private static RepositorySystemSession optimizeSession( RepositorySystemSession session )
299 {
300 DefaultRepositorySystemSession optimized = new DefaultRepositorySystemSession( session );
301 optimized.setArtifactTypeRegistry( CachingArtifactTypeRegistry.newInstance( session ) );
302 return optimized;
303 }
304
305 private List<Dependency> mergeDeps( List<Dependency> dominant, List<Dependency> recessive )
306 {
307 List<Dependency> result;
308 if ( dominant == null || dominant.isEmpty() )
309 {
310 result = recessive;
311 }
312 else if ( recessive == null || recessive.isEmpty() )
313 {
314 result = dominant;
315 }
316 else
317 {
318 int initialCapacity = dominant.size() + recessive.size();
319 result = new ArrayList<>( initialCapacity );
320 Collection<String> ids = new HashSet<>( initialCapacity, 1.0f );
321 for ( Dependency dependency : dominant )
322 {
323 ids.add( getId( dependency.getArtifact() ) );
324 result.add( dependency );
325 }
326 for ( Dependency dependency : recessive )
327 {
328 if ( !ids.contains( getId( dependency.getArtifact() ) ) )
329 {
330 result.add( dependency );
331 }
332 }
333 }
334 return result;
335 }
336
337 private static String getId( Artifact a )
338 {
339 return a.getGroupId() + ':' + a.getArtifactId() + ':' + a.getClassifier() + ':' + a.getExtension();
340 }
341
342 @SuppressWarnings( "checkstyle:parameternumber" )
343 private void process( final Args args, Results results, List<Dependency> dependencies,
344 List<RemoteRepository> repositories, DependencySelector depSelector,
345 DependencyManager depManager, DependencyTraverser depTraverser, VersionFilter verFilter )
346 {
347 for ( Dependency dependency : dependencies )
348 {
349 processDependency( args, results, repositories, depSelector, depManager, depTraverser, verFilter,
350 dependency );
351 }
352 }
353
354 @SuppressWarnings( "checkstyle:parameternumber" )
355 private void processDependency( Args args, Results results, List<RemoteRepository> repositories,
356 DependencySelector depSelector, DependencyManager depManager,
357 DependencyTraverser depTraverser, VersionFilter verFilter, Dependency dependency )
358 {
359
360 List<Artifact> relocations = Collections.emptyList();
361 boolean disableVersionManagement = false;
362 processDependency( args, results, repositories, depSelector, depManager, depTraverser, verFilter, dependency,
363 relocations, disableVersionManagement );
364 }
365
366 @SuppressWarnings( "checkstyle:parameternumber" )
367 private void processDependency( Args args, Results results, List<RemoteRepository> repositories,
368 DependencySelector depSelector, DependencyManager depManager,
369 DependencyTraverser depTraverser, VersionFilter verFilter, Dependency dependency,
370 List<Artifact> relocations, boolean disableVersionManagement )
371 {
372
373 if ( depSelector != null && !depSelector.selectDependency( dependency ) )
374 {
375 return;
376 }
377
378 PremanagedDependency preManaged =
379 PremanagedDependency.create( depManager, dependency, disableVersionManagement, args.premanagedState );
380 dependency = preManaged.managedDependency;
381
382 boolean noDescriptor = isLackingDescriptor( dependency.getArtifact() );
383
384 boolean traverse = !noDescriptor && ( depTraverser == null || depTraverser.traverseDependency( dependency ) );
385
386 List<? extends Version> versions;
387 VersionRangeResult rangeResult;
388 try
389 {
390 VersionRangeRequest rangeRequest = createVersionRangeRequest( args, repositories, dependency );
391
392 rangeResult = cachedResolveRangeResult( rangeRequest, args.pool, args.session );
393
394 versions = filterVersions( dependency, rangeResult, verFilter, args.versionContext );
395 }
396 catch ( VersionRangeResolutionException e )
397 {
398 results.addException( dependency, e, args.nodes );
399 return;
400 }
401
402 for ( Version version : versions )
403 {
404 Artifact originalArtifact = dependency.getArtifact().setVersion( version.toString() );
405 Dependency d = dependency.setArtifact( originalArtifact );
406
407 ArtifactDescriptorRequest descriptorRequest = createArtifactDescriptorRequest( args, repositories, d );
408
409 final ArtifactDescriptorResult descriptorResult =
410 getArtifactDescriptorResult( args, results, noDescriptor, d, descriptorRequest );
411 if ( descriptorResult != null )
412 {
413 d = d.setArtifact( descriptorResult.getArtifact() );
414
415 DependencyNode node = args.nodes.top();
416
417 int cycleEntry = args.nodes.find( d.getArtifact() );
418 if ( cycleEntry >= 0 )
419 {
420 results.addCycle( args.nodes, cycleEntry, d );
421 DependencyNode cycleNode = args.nodes.get( cycleEntry );
422 if ( cycleNode.getDependency() != null )
423 {
424 DefaultDependencyNode child =
425 createDependencyNode( relocations, preManaged, rangeResult, version, d, descriptorResult,
426 cycleNode );
427 node.getChildren().add( child );
428 continue;
429 }
430 }
431
432 if ( !descriptorResult.getRelocations().isEmpty() )
433 {
434 boolean disableVersionManagementSubsequently =
435 originalArtifact.getGroupId().equals( d.getArtifact().getGroupId() )
436 && originalArtifact.getArtifactId().equals( d.getArtifact().getArtifactId() );
437
438 processDependency( args, results, repositories, depSelector, depManager, depTraverser, verFilter, d,
439 descriptorResult.getRelocations(), disableVersionManagementSubsequently );
440 return;
441 }
442 else
443 {
444 d = args.pool.intern( d.setArtifact( args.pool.intern( d.getArtifact() ) ) );
445
446 List<RemoteRepository> repos =
447 getRemoteRepositories( rangeResult.getRepository( version ), repositories );
448
449 DefaultDependencyNode child =
450 createDependencyNode( relocations, preManaged, rangeResult, version, d,
451 descriptorResult.getAliases(), repos, args.request.getRequestContext() );
452
453 node.getChildren().add( child );
454
455 boolean recurse = traverse && !descriptorResult.getDependencies().isEmpty();
456 if ( recurse )
457 {
458 doRecurse( args, results, repositories, depSelector, depManager, depTraverser, verFilter, d,
459 descriptorResult, child );
460 }
461 }
462 }
463 else
464 {
465 DependencyNode node = args.nodes.top();
466 List<RemoteRepository> repos =
467 getRemoteRepositories( rangeResult.getRepository( version ), repositories );
468 DefaultDependencyNode child =
469 createDependencyNode( relocations, preManaged, rangeResult, version, d, null, repos,
470 args.request.getRequestContext() );
471 node.getChildren().add( child );
472 }
473 }
474 }
475
476 @SuppressWarnings( "checkstyle:parameternumber" )
477 private void doRecurse( Args args, Results results, List<RemoteRepository> repositories,
478 DependencySelector depSelector, DependencyManager depManager,
479 DependencyTraverser depTraverser, VersionFilter verFilter, Dependency d,
480 ArtifactDescriptorResult descriptorResult, DefaultDependencyNode child )
481 {
482 DefaultDependencyCollectionContext context = args.collectionContext;
483 context.set( d, descriptorResult.getManagedDependencies() );
484
485 DependencySelector childSelector = depSelector != null ? depSelector.deriveChildSelector( context ) : null;
486 DependencyManager childManager = depManager != null ? depManager.deriveChildManager( context ) : null;
487 DependencyTraverser childTraverser = depTraverser != null ? depTraverser.deriveChildTraverser( context ) : null;
488 VersionFilter childFilter = verFilter != null ? verFilter.deriveChildFilter( context ) : null;
489
490 final List<RemoteRepository> childRepos =
491 args.ignoreRepos
492 ? repositories
493 : remoteRepositoryManager.aggregateRepositories( args.session, repositories,
494 descriptorResult.getRepositories(), true );
495
496 Object key =
497 args.pool.toKey( d.getArtifact(), childRepos, childSelector, childManager, childTraverser, childFilter );
498
499 List<DependencyNode> children = args.pool.getChildren( key );
500 if ( children == null )
501 {
502 args.pool.putChildren( key, child.getChildren() );
503
504 args.nodes.push( child );
505
506 process( args, results, descriptorResult.getDependencies(), childRepos, childSelector, childManager,
507 childTraverser, childFilter );
508
509 args.nodes.pop();
510 }
511 else
512 {
513 child.setChildren( children );
514 }
515 }
516
517 private ArtifactDescriptorResult getArtifactDescriptorResult( Args args, Results results, boolean noDescriptor,
518 Dependency d,
519 ArtifactDescriptorRequest descriptorRequest )
520 {
521 return noDescriptor
522 ? new ArtifactDescriptorResult( descriptorRequest )
523 : resolveCachedArtifactDescriptor( args.pool, descriptorRequest, args.session, d, results, args );
524
525 }
526
527 private ArtifactDescriptorResult resolveCachedArtifactDescriptor( DataPool pool,
528 ArtifactDescriptorRequest descriptorRequest,
529 RepositorySystemSession session, Dependency d,
530 Results results, Args args )
531 {
532 Object key = pool.toKey( descriptorRequest );
533 ArtifactDescriptorResult descriptorResult = pool.getDescriptor( key, descriptorRequest );
534 if ( descriptorResult == null )
535 {
536 try
537 {
538 descriptorResult = descriptorReader.readArtifactDescriptor( session, descriptorRequest );
539 pool.putDescriptor( key, descriptorResult );
540 }
541 catch ( ArtifactDescriptorException e )
542 {
543 results.addException( d, e, args.nodes );
544 pool.putDescriptor( key, e );
545 return null;
546 }
547
548 }
549 else if ( descriptorResult == DataPool.NO_DESCRIPTOR )
550 {
551 return null;
552 }
553
554 return descriptorResult;
555 }
556
557 @SuppressWarnings( "checkstyle:parameternumber" )
558 private static DefaultDependencyNode createDependencyNode( List<Artifact> relocations,
559 PremanagedDependency preManaged,
560 VersionRangeResult rangeResult, Version version,
561 Dependency d, Collection<Artifact> aliases,
562 List<RemoteRepository> repos, String requestContext )
563 {
564 DefaultDependencyNode child = new DefaultDependencyNode( d );
565 preManaged.applyTo( child );
566 child.setRelocations( relocations );
567 child.setVersionConstraint( rangeResult.getVersionConstraint() );
568 child.setVersion( version );
569 child.setAliases( aliases );
570 child.setRepositories( repos );
571 child.setRequestContext( requestContext );
572 return child;
573 }
574
575 private static DefaultDependencyNode createDependencyNode( List<Artifact> relocations,
576 PremanagedDependency preManaged,
577 VersionRangeResult rangeResult, Version version,
578 Dependency d, ArtifactDescriptorResult descriptorResult,
579 DependencyNode cycleNode )
580 {
581 DefaultDependencyNode child =
582 createDependencyNode( relocations, preManaged, rangeResult, version, d, descriptorResult.getAliases(),
583 cycleNode.getRepositories(), cycleNode.getRequestContext() );
584 child.setChildren( cycleNode.getChildren() );
585 return child;
586 }
587
588 private static ArtifactDescriptorRequest createArtifactDescriptorRequest( Args args,
589 List<RemoteRepository> repositories,
590 Dependency d )
591 {
592 ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest();
593 descriptorRequest.setArtifact( d.getArtifact() );
594 descriptorRequest.setRepositories( repositories );
595 descriptorRequest.setRequestContext( args.request.getRequestContext() );
596 descriptorRequest.setTrace( args.trace );
597 return descriptorRequest;
598 }
599
600 private static VersionRangeRequest createVersionRangeRequest( Args args, List<RemoteRepository> repositories,
601 Dependency dependency )
602 {
603 VersionRangeRequest rangeRequest = new VersionRangeRequest();
604 rangeRequest.setArtifact( dependency.getArtifact() );
605 rangeRequest.setRepositories( repositories );
606 rangeRequest.setRequestContext( args.request.getRequestContext() );
607 rangeRequest.setTrace( args.trace );
608 return rangeRequest;
609 }
610
611 private VersionRangeResult cachedResolveRangeResult( VersionRangeRequest rangeRequest, DataPool pool,
612 RepositorySystemSession session )
613 throws VersionRangeResolutionException
614 {
615 Object key = pool.toKey( rangeRequest );
616 VersionRangeResult rangeResult = pool.getConstraint( key, rangeRequest );
617 if ( rangeResult == null )
618 {
619 rangeResult = versionRangeResolver.resolveVersionRange( session, rangeRequest );
620 pool.putConstraint( key, rangeResult );
621 }
622 return rangeResult;
623 }
624
625 private static boolean isLackingDescriptor( Artifact artifact )
626 {
627 return artifact.getProperty( ArtifactProperties.LOCAL_PATH, null ) != null;
628 }
629
630 private static List<RemoteRepository> getRemoteRepositories( ArtifactRepository repository,
631 List<RemoteRepository> repositories )
632 {
633 if ( repository instanceof RemoteRepository )
634 {
635 return Collections.singletonList( (RemoteRepository) repository );
636 }
637 if ( repository != null )
638 {
639 return Collections.emptyList();
640 }
641 return repositories;
642 }
643
644 private static List<? extends Version> filterVersions( Dependency dependency, VersionRangeResult rangeResult,
645 VersionFilter verFilter,
646 DefaultVersionFilterContext verContext )
647 throws VersionRangeResolutionException
648 {
649 if ( rangeResult.getVersions().isEmpty() )
650 {
651 throw new VersionRangeResolutionException( rangeResult,
652 "No versions available for " + dependency.getArtifact()
653 + " within specified range" );
654 }
655
656 List<? extends Version> versions;
657 if ( verFilter != null && rangeResult.getVersionConstraint().getRange() != null )
658 {
659 verContext.set( dependency, rangeResult );
660 try
661 {
662 verFilter.filterVersions( verContext );
663 }
664 catch ( RepositoryException e )
665 {
666 throw new VersionRangeResolutionException( rangeResult,
667 "Failed to filter versions for " + dependency.getArtifact()
668 + ": " + e.getMessage(), e );
669 }
670 versions = verContext.get();
671 if ( versions.isEmpty() )
672 {
673 throw new VersionRangeResolutionException( rangeResult,
674 "No acceptable versions for " + dependency.getArtifact()
675 + ": " + rangeResult.getVersions() );
676 }
677 }
678 else
679 {
680 versions = rangeResult.getVersions();
681 }
682 return versions;
683 }
684
685 static class Args
686 {
687
688 final RepositorySystemSession session;
689
690 final boolean ignoreRepos;
691
692 final boolean premanagedState;
693
694 final RequestTrace trace;
695
696 final DataPool pool;
697
698 final NodeStack nodes;
699
700 final DefaultDependencyCollectionContext collectionContext;
701
702 final DefaultVersionFilterContext versionContext;
703
704 final CollectRequest request;
705
706 Args( RepositorySystemSession session, RequestTrace trace, DataPool pool, NodeStack nodes,
707 DefaultDependencyCollectionContext collectionContext, DefaultVersionFilterContext versionContext,
708 CollectRequest request )
709 {
710 this.session = session;
711 this.request = request;
712 this.ignoreRepos = session.isIgnoreArtifactDescriptorRepositories();
713 this.premanagedState = ConfigUtils.getBoolean( session, false, DependencyManagerUtils.CONFIG_PROP_VERBOSE );
714 this.trace = trace;
715 this.pool = pool;
716 this.nodes = nodes;
717 this.collectionContext = collectionContext;
718 this.versionContext = versionContext;
719 }
720
721 }
722
723 static class Results
724 {
725
726 private final CollectResult result;
727
728 final int maxExceptions;
729
730 final int maxCycles;
731
732 String errorPath;
733
734 Results( CollectResult result, RepositorySystemSession session )
735 {
736 this.result = result;
737
738 maxExceptions =
739 ConfigUtils.getInteger( session, CONFIG_PROP_MAX_EXCEPTIONS_DEFAULT, CONFIG_PROP_MAX_EXCEPTIONS );
740
741 maxCycles = ConfigUtils.getInteger( session, CONFIG_PROP_MAX_CYCLES_DEFAULT, CONFIG_PROP_MAX_CYCLES );
742 }
743
744 public void addException( Dependency dependency, Exception e, NodeStack nodes )
745 {
746 if ( maxExceptions < 0 || result.getExceptions().size() < maxExceptions )
747 {
748 result.addException( e );
749 if ( errorPath == null )
750 {
751 StringBuilder buffer = new StringBuilder( 256 );
752 for ( int i = 0; i < nodes.size(); i++ )
753 {
754 if ( buffer.length() > 0 )
755 {
756 buffer.append( " -> " );
757 }
758 Dependency dep = nodes.get( i ).getDependency();
759 if ( dep != null )
760 {
761 buffer.append( dep.getArtifact() );
762 }
763 }
764 if ( buffer.length() > 0 )
765 {
766 buffer.append( " -> " );
767 }
768 buffer.append( dependency.getArtifact() );
769 errorPath = buffer.toString();
770 }
771 }
772 }
773
774 public void addCycle( NodeStack nodes, int cycleEntry, Dependency dependency )
775 {
776 if ( maxCycles < 0 || result.getCycles().size() < maxCycles )
777 {
778 result.addCycle( new DefaultDependencyCycle( nodes, cycleEntry, dependency ) );
779 }
780 }
781
782 }
783
784 static class PremanagedDependency
785 {
786
787 final String premanagedVersion;
788
789 final String premanagedScope;
790
791 final Boolean premanagedOptional;
792
793
794
795
796 final Collection<Exclusion> premanagedExclusions;
797
798
799
800
801 final Map<String, String> premanagedProperties;
802
803 final int managedBits;
804
805 final Dependency managedDependency;
806
807 final boolean premanagedState;
808
809 @SuppressWarnings( "checkstyle:parameternumber" )
810 PremanagedDependency( String premanagedVersion, String premanagedScope, Boolean premanagedOptional,
811 Collection<Exclusion> premanagedExclusions, Map<String, String> premanagedProperties,
812 int managedBits, Dependency managedDependency, boolean premanagedState )
813 {
814 this.premanagedVersion = premanagedVersion;
815 this.premanagedScope = premanagedScope;
816 this.premanagedOptional = premanagedOptional;
817 this.premanagedExclusions =
818 premanagedExclusions != null
819 ? Collections.unmodifiableCollection( new ArrayList<>( premanagedExclusions ) )
820 : null;
821
822 this.premanagedProperties =
823 premanagedProperties != null
824 ? Collections.unmodifiableMap( new HashMap<>( premanagedProperties ) )
825 : null;
826
827 this.managedBits = managedBits;
828 this.managedDependency = managedDependency;
829 this.premanagedState = premanagedState;
830 }
831
832 static PremanagedDependency create( DependencyManager depManager, Dependency dependency,
833 boolean disableVersionManagement, boolean premanagedState )
834 {
835 DependencyManagement depMngt = depManager != null ? depManager.manageDependency( dependency ) : null;
836
837 int managedBits = 0;
838 String premanagedVersion = null;
839 String premanagedScope = null;
840 Boolean premanagedOptional = null;
841 Collection<Exclusion> premanagedExclusions = null;
842 Map<String, String> premanagedProperties = null;
843
844 if ( depMngt != null )
845 {
846 if ( depMngt.getVersion() != null && !disableVersionManagement )
847 {
848 Artifact artifact = dependency.getArtifact();
849 premanagedVersion = artifact.getVersion();
850 dependency = dependency.setArtifact( artifact.setVersion( depMngt.getVersion() ) );
851 managedBits |= DependencyNode.MANAGED_VERSION;
852 }
853 if ( depMngt.getProperties() != null )
854 {
855 Artifact artifact = dependency.getArtifact();
856 premanagedProperties = artifact.getProperties();
857 dependency = dependency.setArtifact( artifact.setProperties( depMngt.getProperties() ) );
858 managedBits |= DependencyNode.MANAGED_PROPERTIES;
859 }
860 if ( depMngt.getScope() != null )
861 {
862 premanagedScope = dependency.getScope();
863 dependency = dependency.setScope( depMngt.getScope() );
864 managedBits |= DependencyNode.MANAGED_SCOPE;
865 }
866 if ( depMngt.getOptional() != null )
867 {
868 premanagedOptional = dependency.isOptional();
869 dependency = dependency.setOptional( depMngt.getOptional() );
870 managedBits |= DependencyNode.MANAGED_OPTIONAL;
871 }
872 if ( depMngt.getExclusions() != null )
873 {
874 premanagedExclusions = dependency.getExclusions();
875 dependency = dependency.setExclusions( depMngt.getExclusions() );
876 managedBits |= DependencyNode.MANAGED_EXCLUSIONS;
877 }
878 }
879 return new PremanagedDependency( premanagedVersion, premanagedScope, premanagedOptional,
880 premanagedExclusions, premanagedProperties, managedBits, dependency,
881 premanagedState );
882
883 }
884
885 public void applyTo( DefaultDependencyNode child )
886 {
887 child.setManagedBits( managedBits );
888 if ( premanagedState )
889 {
890 child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_VERSION, premanagedVersion );
891 child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_SCOPE, premanagedScope );
892 child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_OPTIONAL, premanagedOptional );
893 child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_EXCLUSIONS, premanagedExclusions );
894 child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_PROPERTIES, premanagedProperties );
895 }
896 }
897
898 }
899
900 }