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