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