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