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