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 import javax.inject.Singleton;
35
36 import org.eclipse.aether.DefaultRepositorySystemSession;
37 import org.eclipse.aether.RepositoryException;
38 import org.eclipse.aether.RepositorySystemSession;
39 import org.eclipse.aether.RequestTrace;
40 import org.eclipse.aether.artifact.Artifact;
41 import org.eclipse.aether.artifact.ArtifactProperties;
42 import org.eclipse.aether.collection.CollectRequest;
43 import org.eclipse.aether.collection.CollectResult;
44 import org.eclipse.aether.collection.DependencyCollectionException;
45 import org.eclipse.aether.collection.DependencyGraphTransformer;
46 import org.eclipse.aether.collection.DependencyManagement;
47 import org.eclipse.aether.collection.DependencyManager;
48 import org.eclipse.aether.collection.DependencySelector;
49 import org.eclipse.aether.collection.DependencyTraverser;
50 import org.eclipse.aether.collection.VersionFilter;
51 import org.eclipse.aether.graph.DefaultDependencyNode;
52 import org.eclipse.aether.graph.Dependency;
53 import org.eclipse.aether.graph.DependencyNode;
54 import org.eclipse.aether.graph.Exclusion;
55 import org.eclipse.aether.impl.ArtifactDescriptorReader;
56 import org.eclipse.aether.impl.DependencyCollector;
57 import org.eclipse.aether.impl.RemoteRepositoryManager;
58 import org.eclipse.aether.impl.VersionRangeResolver;
59 import org.eclipse.aether.repository.ArtifactRepository;
60 import org.eclipse.aether.repository.RemoteRepository;
61 import org.eclipse.aether.resolution.ArtifactDescriptorException;
62 import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
63 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
64 import org.eclipse.aether.resolution.VersionRangeRequest;
65 import org.eclipse.aether.resolution.VersionRangeResolutionException;
66 import org.eclipse.aether.resolution.VersionRangeResult;
67 import org.eclipse.aether.spi.locator.Service;
68 import org.eclipse.aether.spi.locator.ServiceLocator;
69 import org.eclipse.aether.util.ConfigUtils;
70 import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
71 import org.eclipse.aether.util.graph.transformer.TransformationContextKeys;
72 import org.eclipse.aether.version.Version;
73 import org.slf4j.Logger;
74 import org.slf4j.LoggerFactory;
75
76
77
78 @Singleton
79 @Named
80 public class DefaultDependencyCollector
81 implements DependencyCollector, Service
82 {
83
84 private static final String CONFIG_PROP_MAX_EXCEPTIONS = "aether.dependencyCollector.maxExceptions";
85
86 private static final int CONFIG_PROP_MAX_EXCEPTIONS_DEFAULT = 50;
87
88 private static final String CONFIG_PROP_MAX_CYCLES = "aether.dependencyCollector.maxCycles";
89
90 private static final int CONFIG_PROP_MAX_CYCLES_DEFAULT = 10;
91
92 private static final Logger LOGGER = LoggerFactory.getLogger( DefaultDependencyCollector.class );
93
94 private RemoteRepositoryManager remoteRepositoryManager;
95
96 private ArtifactDescriptorReader descriptorReader;
97
98 private VersionRangeResolver versionRangeResolver;
99
100 public DefaultDependencyCollector()
101 {
102
103 }
104
105 @Inject
106 DefaultDependencyCollector( RemoteRepositoryManager remoteRepositoryManager,
107 ArtifactDescriptorReader artifactDescriptorReader,
108 VersionRangeResolver versionRangeResolver )
109 {
110 setRemoteRepositoryManager( remoteRepositoryManager );
111 setArtifactDescriptorReader( artifactDescriptorReader );
112 setVersionRangeResolver( versionRangeResolver );
113 }
114
115 public void initService( ServiceLocator locator )
116 {
117 setRemoteRepositoryManager( locator.getService( RemoteRepositoryManager.class ) );
118 setArtifactDescriptorReader( locator.getService( ArtifactDescriptorReader.class ) );
119 setVersionRangeResolver( locator.getService( VersionRangeResolver.class ) );
120 }
121
122 public DefaultDependencyCollector setRemoteRepositoryManager( RemoteRepositoryManager remoteRepositoryManager )
123 {
124 this.remoteRepositoryManager =
125 requireNonNull( remoteRepositoryManager, "remote repository provider cannot be null" );
126 return this;
127 }
128
129 public DefaultDependencyCollector setArtifactDescriptorReader( ArtifactDescriptorReader artifactDescriptorReader )
130 {
131 descriptorReader = requireNonNull( artifactDescriptorReader, "artifact descriptor reader cannot be null" );
132 return this;
133 }
134
135 public DefaultDependencyCollector setVersionRangeResolver( VersionRangeResolver versionRangeResolver )
136 {
137 this.versionRangeResolver =
138 requireNonNull( versionRangeResolver, "version range resolver cannot be null" );
139 return this;
140 }
141
142 @SuppressWarnings( "checkstyle:methodlength" )
143 public CollectResult collectDependencies( RepositorySystemSession session, CollectRequest request )
144 throws DependencyCollectionException
145 {
146 requireNonNull( session, "session cannot be null" );
147 requireNonNull( request, "request cannot be null" );
148 session = optimizeSession( session );
149
150 RequestTrace trace = RequestTrace.newChild( request.getTrace(), request );
151
152 CollectResult result = new CollectResult( request );
153
154 DependencySelector depSelector = session.getDependencySelector();
155 DependencyManager depManager = session.getDependencyManager();
156 DependencyTraverser depTraverser = session.getDependencyTraverser();
157 VersionFilter verFilter = session.getVersionFilter();
158
159 Dependency root = request.getRoot();
160 List<RemoteRepository> repositories = request.getRepositories();
161 List<Dependency> dependencies = request.getDependencies();
162 List<Dependency> managedDependencies = request.getManagedDependencies();
163
164 Map<String, Object> stats = new LinkedHashMap<>();
165 long time1 = System.nanoTime();
166
167 DefaultDependencyNode node;
168 if ( root != null )
169 {
170 List<? extends Version> versions;
171 VersionRangeResult rangeResult;
172 try
173 {
174 VersionRangeRequest rangeRequest =
175 new VersionRangeRequest( root.getArtifact(), request.getRepositories(),
176 request.getRequestContext() );
177 rangeRequest.setTrace( trace );
178 rangeResult = versionRangeResolver.resolveVersionRange( session, rangeRequest );
179 versions = filterVersions( root, rangeResult, verFilter, new DefaultVersionFilterContext( session ) );
180 }
181 catch ( VersionRangeResolutionException e )
182 {
183 result.addException( e );
184 throw new DependencyCollectionException( result, e.getMessage() );
185 }
186
187 Version version = versions.get( versions.size() - 1 );
188 root = root.setArtifact( root.getArtifact().setVersion( version.toString() ) );
189
190 ArtifactDescriptorResult descriptorResult;
191 try
192 {
193 ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest();
194 descriptorRequest.setArtifact( root.getArtifact() );
195 descriptorRequest.setRepositories( request.getRepositories() );
196 descriptorRequest.setRequestContext( request.getRequestContext() );
197 descriptorRequest.setTrace( trace );
198 if ( isLackingDescriptor( root.getArtifact() ) )
199 {
200 descriptorResult = new ArtifactDescriptorResult( descriptorRequest );
201 }
202 else
203 {
204 descriptorResult = descriptorReader.readArtifactDescriptor( session, descriptorRequest );
205 }
206 }
207 catch ( ArtifactDescriptorException e )
208 {
209 result.addException( e );
210 throw new DependencyCollectionException( result, e.getMessage() );
211 }
212
213 root = root.setArtifact( descriptorResult.getArtifact() );
214
215 if ( !session.isIgnoreArtifactDescriptorRepositories() )
216 {
217 repositories = remoteRepositoryManager.aggregateRepositories( session, repositories,
218 descriptorResult.getRepositories(),
219 true );
220 }
221 dependencies = mergeDeps( dependencies, descriptorResult.getDependencies() );
222 managedDependencies = mergeDeps( managedDependencies, descriptorResult.getManagedDependencies() );
223
224 node = new DefaultDependencyNode( root );
225 node.setRequestContext( request.getRequestContext() );
226 node.setRelocations( descriptorResult.getRelocations() );
227 node.setVersionConstraint( rangeResult.getVersionConstraint() );
228 node.setVersion( version );
229 node.setAliases( descriptorResult.getAliases() );
230 node.setRepositories( request.getRepositories() );
231 }
232 else
233 {
234 node = new DefaultDependencyNode( request.getRootArtifact() );
235 node.setRequestContext( request.getRequestContext() );
236 node.setRepositories( request.getRepositories() );
237 }
238
239 result.setRoot( node );
240
241 boolean traverse = root == null || depTraverser == null || depTraverser.traverseDependency( root );
242 String errorPath = null;
243 if ( traverse && !dependencies.isEmpty() )
244 {
245 DataPool pool = new DataPool( session );
246
247 NodeStack nodes = new NodeStack();
248 nodes.push( node );
249
250 DefaultDependencyCollectionContext context =
251 new DefaultDependencyCollectionContext( session, request.getRootArtifact(), root, managedDependencies );
252
253 DefaultVersionFilterContext versionContext = new DefaultVersionFilterContext( session );
254
255 Args args = new Args( session, trace, pool, nodes, context, versionContext, request );
256 Results results = new Results( result, session );
257
258 process( args, results, dependencies, repositories,
259 depSelector != null ? depSelector.deriveChildSelector( context ) : null,
260 depManager != null ? depManager.deriveChildManager( context ) : null,
261 depTraverser != null ? depTraverser.deriveChildTraverser( context ) : null,
262 verFilter != null ? verFilter.deriveChildFilter( context ) : null );
263
264 errorPath = results.errorPath;
265 }
266
267 long time2 = System.nanoTime();
268
269 DependencyGraphTransformer transformer = session.getDependencyGraphTransformer();
270 if ( transformer != null )
271 {
272 try
273 {
274 DefaultDependencyGraphTransformationContext context =
275 new DefaultDependencyGraphTransformationContext( session );
276 context.put( TransformationContextKeys.STATS, stats );
277 result.setRoot( transformer.transformGraph( node, context ) );
278 }
279 catch ( RepositoryException e )
280 {
281 result.addException( e );
282 }
283 }
284
285 long time3 = System.nanoTime();
286 stats.put( "DefaultDependencyCollector.collectTime", time2 - time1 );
287 stats.put( "DefaultDependencyCollector.transformTime", time3 - time2 );
288 LOGGER.debug( "Dependency collection stats {}", stats );
289
290 if ( errorPath != null )
291 {
292 throw new DependencyCollectionException( result, "Failed to collect dependencies at " + errorPath );
293 }
294 if ( !result.getExceptions().isEmpty() )
295 {
296 throw new DependencyCollectionException( result );
297 }
298
299 return result;
300 }
301
302 private static RepositorySystemSession optimizeSession( RepositorySystemSession session )
303 {
304 DefaultRepositorySystemSession optimized = new DefaultRepositorySystemSession( session );
305 optimized.setArtifactTypeRegistry( CachingArtifactTypeRegistry.newInstance( session ) );
306 return optimized;
307 }
308
309 private List<Dependency> mergeDeps( List<Dependency> dominant, List<Dependency> recessive )
310 {
311 List<Dependency> result;
312 if ( dominant == null || dominant.isEmpty() )
313 {
314 result = recessive;
315 }
316 else if ( recessive == null || recessive.isEmpty() )
317 {
318 result = dominant;
319 }
320 else
321 {
322 int initialCapacity = dominant.size() + recessive.size();
323 result = new ArrayList<>( initialCapacity );
324 Collection<String> ids = new HashSet<>( initialCapacity, 1.0f );
325 for ( Dependency dependency : dominant )
326 {
327 ids.add( getId( dependency.getArtifact() ) );
328 result.add( dependency );
329 }
330 for ( Dependency dependency : recessive )
331 {
332 if ( !ids.contains( getId( dependency.getArtifact() ) ) )
333 {
334 result.add( dependency );
335 }
336 }
337 }
338 return result;
339 }
340
341 private static String getId( Artifact a )
342 {
343 return a.getGroupId() + ':' + a.getArtifactId() + ':' + a.getClassifier() + ':' + a.getExtension();
344 }
345
346 @SuppressWarnings( "checkstyle:parameternumber" )
347 private void process( final Args args, Results results, List<Dependency> dependencies,
348 List<RemoteRepository> repositories, DependencySelector depSelector,
349 DependencyManager depManager, DependencyTraverser depTraverser, VersionFilter verFilter )
350 {
351 for ( Dependency dependency : dependencies )
352 {
353 processDependency( args, results, repositories, depSelector, depManager, depTraverser, verFilter,
354 dependency );
355 }
356 }
357
358 @SuppressWarnings( "checkstyle:parameternumber" )
359 private void processDependency( Args args, Results results, List<RemoteRepository> repositories,
360 DependencySelector depSelector, DependencyManager depManager,
361 DependencyTraverser depTraverser, VersionFilter verFilter, Dependency dependency )
362 {
363
364 List<Artifact> relocations = Collections.emptyList();
365 processDependency( args, results, repositories, depSelector, depManager, depTraverser, verFilter, dependency,
366 relocations, false );
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 }