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