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 static org.eclipse.aether.internal.impl.collect.DependencyCollectionUtils.addDependencyNode;
23 import static org.eclipse.aether.internal.impl.collect.DependencyCollectionUtils.createArtifactDescriptorRequest;
24 import static org.eclipse.aether.internal.impl.collect.DependencyCollectionUtils.createDependencyNode;
25 import static org.eclipse.aether.internal.impl.collect.DependencyCollectionUtils.createVersionRangeRequest;
26 import static org.eclipse.aether.internal.impl.collect.DependencyCollectionUtils.filterVersions;
27
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.Collections;
31 import java.util.HashSet;
32 import java.util.LinkedHashMap;
33 import java.util.List;
34 import java.util.Map;
35 import static java.util.Objects.requireNonNull;
36 import java.util.concurrent.Callable;
37 import java.util.concurrent.ExecutionException;
38 import java.util.concurrent.ExecutorService;
39 import java.util.concurrent.Future;
40 import java.util.concurrent.LinkedBlockingQueue;
41 import java.util.concurrent.ThreadPoolExecutor;
42 import java.util.concurrent.TimeUnit;
43
44 import javax.inject.Inject;
45 import javax.inject.Named;
46
47 import org.eclipse.aether.RepositoryException;
48 import org.eclipse.aether.RepositorySystemSession;
49 import org.eclipse.aether.RequestTrace;
50 import org.eclipse.aether.artifact.Artifact;
51 import org.eclipse.aether.artifact.ArtifactProperties;
52 import org.eclipse.aether.collection.CollectRequest;
53 import org.eclipse.aether.collection.CollectResult;
54 import org.eclipse.aether.collection.DependencyCollectionException;
55 import org.eclipse.aether.collection.DependencyGraphTransformer;
56 import org.eclipse.aether.collection.DependencyTraverser;
57 import org.eclipse.aether.graph.DefaultDependencyNode;
58 import org.eclipse.aether.graph.Dependency;
59 import org.eclipse.aether.graph.DependencyNode;
60 import org.eclipse.aether.impl.ArtifactDescriptorReader;
61 import org.eclipse.aether.impl.DependencyCollector;
62 import org.eclipse.aether.impl.RemoteRepositoryManager;
63 import org.eclipse.aether.impl.VersionRangeResolver;
64 import org.eclipse.aether.repository.ArtifactRepository;
65 import org.eclipse.aether.repository.RemoteRepository;
66 import org.eclipse.aether.resolution.ArtifactDescriptorException;
67 import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
68 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
69 import org.eclipse.aether.resolution.VersionRangeRequest;
70 import org.eclipse.aether.resolution.VersionRangeResolutionException;
71 import org.eclipse.aether.resolution.VersionRangeResult;
72 import org.eclipse.aether.spi.locator.Service;
73 import org.eclipse.aether.spi.locator.ServiceLocator;
74 import org.eclipse.aether.util.ConfigUtils;
75 import org.eclipse.aether.util.concurrency.FutureResult;
76 import org.eclipse.aether.util.concurrency.WorkerThreadFactory;
77 import org.eclipse.aether.util.graph.transformer.TransformationContextKeys;
78 import org.eclipse.aether.version.Version;
79 import org.slf4j.Logger;
80 import org.slf4j.LoggerFactory;
81
82
83
84 @Named
85 public class DefaultDependencyCollector
86 implements DependencyCollector, Service
87 {
88
89 static final String CONFIG_PROP_MAX_EXCEPTIONS = "aether.dependencyCollector.maxExceptions";
90
91 static final String CONFIG_PROP_MAX_CYCLES = "aether.dependencyCollector.maxCycles";
92
93 private static final String CONFIG_PROP_THREADS = "aether.artifactDescriptor.threads";
94 private static final int DEFAULT_THREADS = 5;
95
96 private static final Logger LOGGER = LoggerFactory.getLogger( DefaultDependencyCollector.class );
97
98 private RemoteRepositoryManager remoteRepositoryManager;
99
100 private ArtifactDescriptorReader descriptorReader;
101
102 private VersionRangeResolver versionRangeResolver;
103
104 public DefaultDependencyCollector()
105 {
106
107 }
108
109 @Inject
110 DefaultDependencyCollector( RemoteRepositoryManager remoteRepositoryManager,
111 ArtifactDescriptorReader artifactDescriptorReader,
112 VersionRangeResolver versionRangeResolver )
113 {
114 setRemoteRepositoryManager( remoteRepositoryManager );
115 setArtifactDescriptorReader( artifactDescriptorReader );
116 setVersionRangeResolver( versionRangeResolver );
117 }
118
119 public void initService( ServiceLocator locator )
120 {
121 setRemoteRepositoryManager( locator.getService( RemoteRepositoryManager.class ) );
122 setArtifactDescriptorReader( locator.getService( ArtifactDescriptorReader.class ) );
123 setVersionRangeResolver( locator.getService( VersionRangeResolver.class ) );
124 }
125
126 public DefaultDependencyCollector setRemoteRepositoryManager( RemoteRepositoryManager remoteRepositoryManager )
127 {
128 this.remoteRepositoryManager = requireNonNull(
129 remoteRepositoryManager, "remote repository provider cannot be null" );
130 return this;
131 }
132
133 public DefaultDependencyCollector setArtifactDescriptorReader( ArtifactDescriptorReader artifactDescriptorReader )
134 {
135 descriptorReader = requireNonNull( artifactDescriptorReader, "artifact descriptor reader cannot be null" );
136 return this;
137 }
138
139 public DefaultDependencyCollector setVersionRangeResolver( VersionRangeResolver versionRangeResolver )
140 {
141 this.versionRangeResolver = requireNonNull( versionRangeResolver, "version range resolver cannot be null" );
142 return this;
143 }
144
145 public CollectResult collectDependencies( RepositorySystemSession session, CollectRequest request )
146 throws DependencyCollectionException
147 {
148 int numThreads = ConfigUtils.getInteger( session, DEFAULT_THREADS, CONFIG_PROP_THREADS );
149 LOGGER.debug( "{} = {} ", CONFIG_PROP_THREADS, numThreads );
150 ThreadPoolExecutor executor = new ThreadPoolExecutor(
151 numThreads, numThreads, 3L, TimeUnit.SECONDS,
152 new LinkedBlockingQueue<Runnable>(), new WorkerThreadFactory( "artifact-descriptor-resolver" ) );
153 try
154 {
155 return collectDependenciesWithExecutor( session, request, executor );
156 }
157 finally
158 {
159 executor.shutdown();
160 }
161 }
162
163 private CollectResult collectDependenciesWithExecutor( RepositorySystemSession session, CollectRequest request,
164 ExecutorService executor )
165 throws DependencyCollectionException
166 {
167 session = DependencyCollectionUtils.optimizeSession( session );
168
169 RequestTrace trace = RequestTrace.newChild( request.getTrace(), request );
170
171 CollectResult result = new CollectResult( request );
172
173 Dependency root = request.getRoot();
174 List<RemoteRepository> repositories = request.getRepositories();
175 List<Dependency> managedDependencies = request.getManagedDependencies();
176
177 DefaultDependencyCollectionContext context =
178 new DefaultDependencyCollectionContext( session, request.getRootArtifact(), root, managedDependencies );
179 context.setDependencies( request.getDependencies() );
180 context.setCollectResult( result );
181 context.setTrace( trace );
182
183 Args args = new Args( session, trace, null, null, context, null, request, executor );
184 context.setArgs( args );
185
186 Map<String, Object> stats = LOGGER.isDebugEnabled() ? new LinkedHashMap<String, Object>() : null;
187 long time1 = System.nanoTime();
188
189 DefaultDependencyNode node;
190 if ( root != null )
191 {
192
193 VersionRangeResult rangeResult = resolveRootVersionRange( context );
194 ArtifactDescriptorResult descriptorResult = readRootArtifactDescriptor( context );
195 root = root.setArtifact( descriptorResult.getArtifact() );
196
197 if ( !session.isIgnoreArtifactDescriptorRepositories() )
198 {
199 repositories = remoteRepositoryManager.aggregateRepositories( session, repositories,
200 descriptorResult.getRepositories(),
201 true );
202 }
203 context.setDependencies( mergeDeps( context.getDependencies(), descriptorResult.getDependencies() ) );
204 context.setManagedDependencies( mergeDeps( managedDependencies,
205 descriptorResult.getManagedDependencies() ) );
206
207 node = new DefaultDependencyNode( root );
208 node.setRequestContext( request.getRequestContext() );
209 node.setRelocations( descriptorResult.getRelocations() );
210 node.setVersionConstraint( rangeResult.getVersionConstraint() );
211 node.setVersion( context.getVersion() );
212 node.setAliases( descriptorResult.getAliases() );
213 node.setRepositories( request.getRepositories() );
214 }
215 else
216 {
217 node = new DefaultDependencyNode( request.getRootArtifact() );
218 node.setRequestContext( request.getRequestContext() );
219 node.setRepositories( request.getRepositories() );
220 }
221
222 result.setRoot( node );
223
224 DependencyTraverser depTraverser = session.getDependencyTraverser();
225 boolean traverse = root == null || depTraverser == null || depTraverser.traverseDependency( root );
226 String errorPath = null;
227 if ( traverse && !context.getDependencies().isEmpty() )
228 {
229 DataPool pool = new DataPool( session );
230
231 NodeStack nodes = new NodeStack();
232 nodes.push( node );
233
234 DefaultVersionFilterContext versionContext = new DefaultVersionFilterContext( session );
235
236 args = new Args( session, trace, pool, nodes, context, versionContext, request, executor );
237 Results results = new Results( result, session );
238 context.setArgs( args );
239 context.setResults( results );
240 context.setRepositories( repositories );
241 context.setDepTraverser( depTraverser );
242 context.prepareDescent();
243
244 process( context );
245
246 errorPath = results.errorPath;
247 }
248
249 long time2 = System.nanoTime();
250
251 transformDependencyGraph( context, stats );
252
253 if ( stats != null )
254 {
255 long time3 = System.nanoTime();
256 stats.put( "DefaultDependencyCollector.collectTime", time2 - time1 );
257 stats.put( "DefaultDependencyCollector.transformTime", time3 - time2 );
258 LOGGER.debug( "Dependency collection stats: {}", stats );
259 }
260
261 if ( errorPath != null )
262 {
263 throw new DependencyCollectionException( result, "Failed to collect dependencies at " + errorPath );
264 }
265 if ( !result.getExceptions().isEmpty() )
266 {
267 throw new DependencyCollectionException( result );
268 }
269
270 return result;
271 }
272
273 private VersionRangeResult resolveRootVersionRange( DefaultDependencyCollectionContext context )
274 throws DependencyCollectionException
275 {
276 CollectRequest request = context.getArgs().request;
277 RepositorySystemSession session = context.getSession();
278 List<? extends Version> versions;
279 VersionRangeResult rangeResult;
280 Artifact artifact = request.getRoot().getArtifact();
281 try
282 {
283 VersionRangeRequest rangeRequest =
284 new VersionRangeRequest( artifact, request.getRepositories(), request.getRequestContext() );
285 rangeRequest.setTrace( context.getTrace() );
286 rangeResult = versionRangeResolver.resolveVersionRange( session, rangeRequest );
287 versions = filterVersions( context.getDependency(), rangeResult, context.getVerFilter(),
288 new DefaultVersionFilterContext( session ) );
289 }
290 catch ( VersionRangeResolutionException e )
291 {
292 context.getCollectResult().addException( e );
293 throw new DependencyCollectionException( context.getCollectResult(), e.getMessage() );
294 }
295
296 Version version = versions.get( versions.size() - 1 );
297 context.setVersion( version );
298 context.setDependency( request.getRoot().setArtifact( artifact.setVersion( version.toString() ) ) );
299 return rangeResult;
300 }
301
302 private ArtifactDescriptorResult readRootArtifactDescriptor( DefaultDependencyCollectionContext context )
303 throws DependencyCollectionException
304 {
305 CollectRequest request = context.getArgs().request;
306 Artifact artifact = request.getRoot().getArtifact();
307 try
308 {
309 ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest();
310 descriptorRequest.setArtifact( artifact );
311 descriptorRequest.setRepositories( request.getRepositories() );
312 descriptorRequest.setRequestContext( request.getRequestContext() );
313 descriptorRequest.setTrace( context.getTrace() );
314
315 ArtifactDescriptorResult descriptorResult =
316 isLackingDescriptor( artifact ) ? new ArtifactDescriptorResult( descriptorRequest )
317 : descriptorReader.readArtifactDescriptor( context.getSession(), descriptorRequest );
318 context.setDependency( request.getRoot().setArtifact( descriptorResult.getArtifact() ) );
319 return descriptorResult;
320 }
321 catch ( ArtifactDescriptorException e )
322 {
323 context.getCollectResult().addException( e );
324 throw new DependencyCollectionException( context.getCollectResult(), e.getMessage() );
325 }
326 }
327
328 private void transformDependencyGraph( DefaultDependencyCollectionContext context, Map<String, Object> stats )
329 {
330 RepositorySystemSession session = context.getSession();
331 DependencyGraphTransformer transformer = session.getDependencyGraphTransformer();
332 if ( transformer != null )
333 {
334 try
335 {
336 DefaultDependencyGraphTransformationContext tfContext =
337 new DefaultDependencyGraphTransformationContext( session );
338 tfContext.put( TransformationContextKeys.STATS, stats );
339 context.getCollectResult().setRoot( transformer.transformGraph( context.getCollectResult().getRoot(),
340 tfContext ) );
341 }
342 catch ( RepositoryException e )
343 {
344 context.getCollectResult().addException( e );
345 }
346 }
347 }
348
349 private List<Dependency> mergeDeps( List<Dependency> dominant, List<Dependency> recessive )
350 {
351 List<Dependency> result;
352 if ( dominant == null || dominant.isEmpty() )
353 {
354 result = recessive;
355 }
356 else if ( recessive == null || recessive.isEmpty() )
357 {
358 result = dominant;
359 }
360 else
361 {
362 int initialCapacity = dominant.size() + recessive.size();
363 result = new ArrayList<>( initialCapacity );
364 Collection<String> ids = new HashSet<>( initialCapacity, 1.0f );
365 for ( Dependency dependency : dominant )
366 {
367 ids.add( getId( dependency.getArtifact() ) );
368 result.add( dependency );
369 }
370 for ( Dependency dependency : recessive )
371 {
372 if ( !ids.contains( getId( dependency.getArtifact() ) ) )
373 {
374 result.add( dependency );
375 }
376 }
377 }
378 return result;
379 }
380
381 private static String getId( Artifact a )
382 {
383 return a.getGroupId() + ':' + a.getArtifactId() + ':' + a.getClassifier() + ':' + a.getExtension();
384 }
385
386 private void process( DefaultDependencyCollectionContext context )
387 {
388 List<DependencyContext> depContexts = new ArrayList<>();
389 for ( Dependency d : context.getDependencies() )
390 {
391 depContexts.add( new DependencyContext( context, d ) );
392 }
393
394 List<Future<DependencyContext>> futures = new ArrayList<>();
395 for ( DependencyContext dc : depContexts )
396 {
397 futures.add( asyncProcessDependency( dc ) );
398 }
399 int pos = 0;
400 for ( Future<DependencyContext> future : futures )
401 {
402 try
403 {
404 processDependencyNode( future.get() );
405 }
406 catch ( ExecutionException e )
407 {
408 context.getResults().addException( context.getDependencies().get( pos ), (Exception) e.getCause(),
409 context.getArgs().nodes );
410 }
411 catch ( InterruptedException e )
412 {
413 context.getResults().addException( context.getDependencies().get( pos ), e, context.getArgs().nodes );
414 }
415 pos++;
416 }
417 }
418
419 private Future<DependencyContext> asyncProcessDependency( final DependencyContext dc )
420 {
421 return dc.args.executor.submit( new Callable<DependencyContext>()
422 {
423 public DependencyContext call()
424 {
425 return processDependency( dc );
426 }
427 } );
428 }
429
430 private DependencyContext processDependency( DependencyContext dc )
431 {
432 DefaultDependencyCollectionContext context = dc.context;
433 Args args = context.getArgs();
434 Results results = context.getResults();
435
436 if ( context.getDepSelector() != null && !context.getDepSelector().selectDependency( dc.origDependency ) )
437 {
438 return null;
439 }
440
441 PremanagedDependency preManaged =
442 PremanagedDependency.create( context.getDepManager(), dc.origDependency, dc.disableVersionManagement,
443 args.premanagedState );
444 Dependency dependency = preManaged.managedDependency;
445
446 boolean noDescriptor = isLackingDescriptor( dependency.getArtifact() );
447
448 boolean traverse = !noDescriptor
449 && ( context.getDepTraverser() == null || context.getDepTraverser().traverseDependency( dependency ) );
450
451 try
452 {
453 VersionRangeRequest rangeRequest = createVersionRangeRequest( args, context.getRepositories(), dependency );
454 VersionRangeResult rangeResult = cachedResolveRangeResult( rangeRequest, args.pool, args.session );
455 for ( Version version : filterVersions( dependency, rangeResult, context.getVerFilter(),
456 args.versionContext ) )
457 {
458
459 Artifact originalArtifact = dependency.getArtifact().setVersion( version.toString() );
460 Dependency d = dependency.setArtifact( originalArtifact );
461
462 ArtifactDescriptorRequest descriptorRequest =
463 createArtifactDescriptorRequest( args, context.getRepositories(), d );
464
465 dc.args = args;
466 dc.preManaged = preManaged;
467 dc.traverse = traverse;
468 dc.rangeResult = rangeResult;
469 dc.version = version;
470 dc.originalArtifact = originalArtifact;
471 dc.managedDependency = d;
472 dc.futureDescriptorResult =
473 getArtifactDescriptorResult( args, results, noDescriptor, d, descriptorRequest );
474 }
475 }
476 catch ( VersionRangeResolutionException e )
477 {
478 results.addException( dependency, e, args.nodes );
479 }
480 return dc;
481 }
482
483 private void processDependencyNode( DependencyContext dc )
484 {
485 if ( dc == null )
486 {
487 return;
488 }
489 try
490 {
491 boolean noResult = dc.futureDescriptorResult == null;
492 if ( !noResult )
493 {
494 dc.descriptorResult = dc.futureDescriptorResult.get();
495 noResult = dc.descriptorResult == null;
496 }
497 if ( noResult )
498 {
499 List<RemoteRepository> repos =
500 getRemoteRepositories( dc.rangeResult.getRepository( dc.version ), dc.context.getRepositories() );
501 addDependencyNode( dc.args.nodes.top(), dc.relocations, dc.preManaged, dc.rangeResult, dc.version,
502 dc.managedDependency, null, repos, dc.args.request.getRequestContext() );
503 }
504 else
505 {
506 processDependencyVersion( dc );
507 }
508 }
509 catch ( InterruptedException e )
510 {
511 dc.context.getResults().addException( dc.preManaged.managedDependency, e, dc.args.nodes );
512 }
513 catch ( ExecutionException e )
514 {
515 dc.context.getResults().addException( dc.preManaged.managedDependency, (Exception) e.getCause(),
516 dc.args.nodes );
517 }
518 }
519
520 private boolean processDependencyVersion( DependencyContext dc )
521 {
522 Args args = dc.context.getArgs();
523 Results results = dc.context.getResults();
524 Dependency d = dc.managedDependency.setArtifact( dc.descriptorResult.getArtifact() );
525 dc.managedDependency = d;
526
527 DependencyNode node = args.nodes.top();
528
529 int cycleEntry = args.nodes.find( d.getArtifact() );
530 if ( cycleEntry >= 0 )
531 {
532 results.addCycle( args.nodes, cycleEntry, d );
533 DependencyNode cycleNode = args.nodes.get( cycleEntry );
534 if ( cycleNode.getDependency() != null )
535 {
536 createDependencyNode( node, dc.relocations, dc.preManaged, dc.rangeResult, dc.version, d,
537 dc.descriptorResult, cycleNode );
538 return true;
539 }
540 }
541
542 if ( !dc.descriptorResult.getRelocations().isEmpty() )
543 {
544 boolean disableVersionManagementSubsequently =
545 dc.originalArtifact.getGroupId().equals( d.getArtifact().getGroupId() )
546 && dc.originalArtifact.getArtifactId().equals( d.getArtifact().getArtifactId() );
547
548 DependencyContext dc2 = new DependencyContext();
549 dc2.context = dc.context;
550 dc2.origDependency = d;
551 dc2.relocations = dc.descriptorResult.getRelocations();
552 dc2.disableVersionManagement = disableVersionManagementSubsequently;
553 dc2 = processDependency( dc2 );
554 processDependencyNode( dc2 );
555 return true;
556 }
557 else
558 {
559 d = args.pool.intern( d );
560
561 List<RemoteRepository> repos =
562 getRemoteRepositories( dc.rangeResult.getRepository( dc.version ), dc.context.getRepositories() );
563
564 DefaultDependencyNode child =
565 addDependencyNode( node, dc.relocations, dc.preManaged, dc.rangeResult, dc.version, d,
566 dc.descriptorResult.getAliases(), repos, args.request.getRequestContext() );
567
568 if ( dc.traverse && !dc.descriptorResult.getDependencies().isEmpty() )
569 {
570 doRecurse( dc.context, d, dc.descriptorResult, child );
571 }
572 return false;
573 }
574 }
575
576 private void doRecurse( DefaultDependencyCollectionContext context, Dependency d,
577 ArtifactDescriptorResult descriptorResult, DefaultDependencyNode child )
578 {
579 context.setDependency( d );
580 context.setManagedDependencies( descriptorResult.getManagedDependencies() );
581
582 DefaultDependencyCollectionContext childContext = context.createChildContext();
583 Args args = context.getArgs();
584
585 final List<RemoteRepository> childRepos = args.ignoreRepos ? context.getRepositories()
586 : remoteRepositoryManager.aggregateRepositories( args.session, context.getRepositories(),
587 descriptorResult.getRepositories(), true );
588 childContext.setRepositories( childRepos );
589
590 Object key = args.pool.toKey( d.getArtifact(), childContext );
591
592 List<DependencyNode> children = args.pool.getChildren( key );
593 if ( children == null )
594 {
595 args.pool.putChildren( key, child.getChildren() );
596
597 args.nodes.push( child );
598
599 childContext.setArgs( args );
600 childContext.setResults( context.getResults() );
601 childContext.setDependencies( descriptorResult.getDependencies() );
602
603 process( childContext );
604
605 args.nodes.pop();
606 }
607 else
608 {
609 child.setChildren( children );
610 }
611 }
612
613 private Future<ArtifactDescriptorResult> getArtifactDescriptorResult( Args args, Results results,
614 boolean noDescriptor, Dependency d,
615 ArtifactDescriptorRequest descriptorRequest )
616 {
617 return noDescriptor
618 ? new FutureResult<>( new ArtifactDescriptorResult( descriptorRequest ) )
619 : resolveCachedArtifactDescriptor( args.pool, descriptorRequest, args.session, d, results,
620 args );
621 }
622
623 private Future<ArtifactDescriptorResult> resolveCachedArtifactDescriptor(
624 final DataPool pool, final ArtifactDescriptorRequest descriptorRequest,
625 final RepositorySystemSession session, final Dependency d, final Results results, final Args args )
626 {
627 final Object key = pool.toKey( descriptorRequest );
628 Future<ArtifactDescriptorResult> descriptorResult = pool.getDescriptor( key, descriptorRequest );
629 if ( descriptorResult == null )
630 {
631 descriptorResult = args.executor.submit( new Callable<ArtifactDescriptorResult>()
632 {
633 public ArtifactDescriptorResult call()
634 {
635 try
636 {
637 return descriptorReader.readArtifactDescriptor( session, descriptorRequest );
638 }
639 catch ( ArtifactDescriptorException e )
640 {
641 results.addException( d, e, args.nodes );
642 pool.putDescriptor( key, e );
643 return null;
644 }
645 }
646 } );
647
648 pool.putDescriptor( key, descriptorResult );
649 }
650 else if ( descriptorResult == DataPool.NO_DESCRIPTOR )
651 {
652 return new FutureResult<>( null );
653 }
654
655 return descriptorResult;
656 }
657 private VersionRangeResult cachedResolveRangeResult( VersionRangeRequest rangeRequest, DataPool pool,
658 RepositorySystemSession session )
659 throws VersionRangeResolutionException
660 {
661 Object key = pool.toKey( rangeRequest );
662 VersionRangeResult rangeResult = pool.getConstraint( key, rangeRequest );
663 if ( rangeResult == null )
664 {
665 rangeResult = versionRangeResolver.resolveVersionRange( session, rangeRequest );
666 pool.putConstraint( key, rangeResult );
667 }
668 return rangeResult;
669 }
670
671 private static boolean isLackingDescriptor( Artifact artifact )
672 {
673 return artifact.getProperty( ArtifactProperties.LOCAL_PATH, null ) != null;
674 }
675
676 private static List<RemoteRepository> getRemoteRepositories( ArtifactRepository repository,
677 List<RemoteRepository> repositories )
678 {
679 if ( repository instanceof RemoteRepository )
680 {
681 return Collections.singletonList( (RemoteRepository) repository );
682 }
683 if ( repository != null )
684 {
685 return Collections.emptyList();
686 }
687 return repositories;
688 }
689 }