001package org.eclipse.aether.internal.impl.collect; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import static org.eclipse.aether.internal.impl.collect.DependencyCollectionUtils.addDependencyNode; 023import static org.eclipse.aether.internal.impl.collect.DependencyCollectionUtils.createArtifactDescriptorRequest; 024import static org.eclipse.aether.internal.impl.collect.DependencyCollectionUtils.createDependencyNode; 025import static org.eclipse.aether.internal.impl.collect.DependencyCollectionUtils.createVersionRangeRequest; 026import static org.eclipse.aether.internal.impl.collect.DependencyCollectionUtils.filterVersions; 027 028import java.util.ArrayList; 029import java.util.Collection; 030import java.util.Collections; 031import java.util.HashSet; 032import java.util.LinkedHashMap; 033import java.util.List; 034import java.util.Map; 035import static java.util.Objects.requireNonNull; 036import java.util.concurrent.Callable; 037import java.util.concurrent.ExecutionException; 038import java.util.concurrent.ExecutorService; 039import java.util.concurrent.Future; 040import java.util.concurrent.LinkedBlockingQueue; 041import java.util.concurrent.ThreadPoolExecutor; 042import java.util.concurrent.TimeUnit; 043 044import javax.inject.Inject; 045import javax.inject.Named; 046 047import org.eclipse.aether.RepositoryException; 048import org.eclipse.aether.RepositorySystemSession; 049import org.eclipse.aether.RequestTrace; 050import org.eclipse.aether.artifact.Artifact; 051import org.eclipse.aether.artifact.ArtifactProperties; 052import org.eclipse.aether.collection.CollectRequest; 053import org.eclipse.aether.collection.CollectResult; 054import org.eclipse.aether.collection.DependencyCollectionException; 055import org.eclipse.aether.collection.DependencyGraphTransformer; 056import org.eclipse.aether.collection.DependencyTraverser; 057import org.eclipse.aether.graph.DefaultDependencyNode; 058import org.eclipse.aether.graph.Dependency; 059import org.eclipse.aether.graph.DependencyNode; 060import org.eclipse.aether.impl.ArtifactDescriptorReader; 061import org.eclipse.aether.impl.DependencyCollector; 062import org.eclipse.aether.impl.RemoteRepositoryManager; 063import org.eclipse.aether.impl.VersionRangeResolver; 064import org.eclipse.aether.repository.ArtifactRepository; 065import org.eclipse.aether.repository.RemoteRepository; 066import org.eclipse.aether.resolution.ArtifactDescriptorException; 067import org.eclipse.aether.resolution.ArtifactDescriptorRequest; 068import org.eclipse.aether.resolution.ArtifactDescriptorResult; 069import org.eclipse.aether.resolution.VersionRangeRequest; 070import org.eclipse.aether.resolution.VersionRangeResolutionException; 071import org.eclipse.aether.resolution.VersionRangeResult; 072import org.eclipse.aether.spi.locator.Service; 073import org.eclipse.aether.spi.locator.ServiceLocator; 074import org.eclipse.aether.util.ConfigUtils; 075import org.eclipse.aether.util.concurrency.FutureResult; 076import org.eclipse.aether.util.concurrency.WorkerThreadFactory; 077import org.eclipse.aether.util.graph.transformer.TransformationContextKeys; 078import org.eclipse.aether.version.Version; 079import org.slf4j.Logger; 080import org.slf4j.LoggerFactory; 081 082/** 083 */ 084@Named 085public class DefaultDependencyCollector 086 implements DependencyCollector, Service 087{ 088 089 static final String CONFIG_PROP_MAX_EXCEPTIONS = "aether.dependencyCollector.maxExceptions"; 090 091 static final String CONFIG_PROP_MAX_CYCLES = "aether.dependencyCollector.maxCycles"; 092 093 private static final String CONFIG_PROP_THREADS = "aether.artifactDescriptor.threads"; 094 private static final int DEFAULT_THREADS = 5; 095 096 private static final Logger LOGGER = LoggerFactory.getLogger( DefaultDependencyCollector.class ); 097 098 private RemoteRepositoryManager remoteRepositoryManager; 099 100 private ArtifactDescriptorReader descriptorReader; 101 102 private VersionRangeResolver versionRangeResolver; 103 104 public DefaultDependencyCollector() 105 { 106 // enables default constructor 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}