This is an automated email from the ASF dual-hosted git repository. cstamas pushed a commit to branch bf-df-coexitsts in repository https://gitbox.apache.org/repos/asf/maven-resolver.git
commit ac046e09093824fcb426d4b09db99e4f8c6412fb Author: Tamas Cservenak <ta...@cservenak.net> AuthorDate: Thu Mar 17 14:25:28 2022 +0100 DependencyCollector: DF vs BF coexists --- .../eclipse/aether/impl/guice/AetherModule.java | 22 + .../impl/collect/CachingArtifactTypeRegistry.java | 2 +- .../aether/internal/impl/collect/DataPool.java | 52 +- .../DefaultDependencyCollectionContext.java | 4 +- .../impl/collect/DefaultDependencyCollector.java | 868 +-------------------- ...efaultDependencyGraphTransformationContext.java | 4 +- .../impl/collect/DefaultVersionFilterContext.java | 4 +- .../impl/collect/DependencyCollectorDelegate.java | 29 + .../BfDependencyCollector.java} | 57 +- .../BfDependencyCycle.java} | 8 +- .../BfProcessingContext.java} | 10 +- .../DfDependencyCollector.java} | 237 +++--- .../DfDependencyCycle.java} | 61 +- .../aether/internal/impl/collect/df/NodeStack.java | 127 +++ .../BfDependencyCollectorTest.java} | 25 +- .../BfDependencyCycleTest.java} | 12 +- .../DfDependencyCollectorTest.java} | 26 +- .../DfDependencyCycleTest.java} | 15 +- 18 files changed, 467 insertions(+), 1096 deletions(-) diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/guice/AetherModule.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/guice/AetherModule.java index 9629dc9..2082422 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/guice/AetherModule.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/impl/guice/AetherModule.java @@ -48,6 +48,9 @@ import org.eclipse.aether.internal.impl.checksum.Sha1ChecksumAlgorithmFactory; import org.eclipse.aether.internal.impl.checksum.Sha256ChecksumAlgorithmFactory; import org.eclipse.aether.internal.impl.checksum.Sha512ChecksumAlgorithmFactory; import org.eclipse.aether.internal.impl.checksum.DefaultChecksumAlgorithmFactorySelector; +import org.eclipse.aether.internal.impl.collect.DependencyCollectorDelegate; +import org.eclipse.aether.internal.impl.collect.bf.BfDependencyCollector; +import org.eclipse.aether.internal.impl.collect.df.DfDependencyCollector; import org.eclipse.aether.internal.impl.synccontext.DefaultSyncContextFactory; import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactorySelector; import org.eclipse.aether.internal.impl.synccontext.named.SimpleNamedLockFactorySelector; @@ -132,8 +135,14 @@ public class AetherModule .to( DefaultRepositorySystem.class ).in( Singleton.class ); bind( ArtifactResolver.class ) // .to( DefaultArtifactResolver.class ).in( Singleton.class ); + bind( DependencyCollector.class ) // .to( DefaultDependencyCollector.class ).in( Singleton.class ); + bind( DependencyCollectorDelegate.class ).annotatedWith( Names.named( BfDependencyCollector.NAME ) ) // + .to( BfDependencyCollector.class ).in( Singleton.class ); + bind( DependencyCollectorDelegate.class ).annotatedWith( Names.named( DfDependencyCollector.NAME ) ) // + .to( DfDependencyCollector.class ).in( Singleton.class ); + bind( Deployer.class ) // .to( DefaultDeployer.class ).in( Singleton.class ); bind( Installer.class ) // @@ -214,6 +223,19 @@ public class AetherModule @Provides @Singleton + Map<String, DependencyCollectorDelegate> provideDependencyCollectorDelegates( + @Named( BfDependencyCollector.NAME ) DependencyCollectorDelegate bf, + @Named( DfDependencyCollector.NAME ) DependencyCollectorDelegate df + ) + { + Map<String, DependencyCollectorDelegate> providedDependencyCollectorDelegates = new HashMap<>(); + providedDependencyCollectorDelegates.put( BfDependencyCollector.NAME, bf ); + providedDependencyCollectorDelegates.put( DfDependencyCollector.NAME, df ); + return providedDependencyCollectorDelegates; + } + + @Provides + @Singleton Map<String, ProvidedChecksumsSource> provideChecksumSources( @Named( FileProvidedChecksumsSource.NAME ) ProvidedChecksumsSource fileProvidedChecksumSource ) diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/CachingArtifactTypeRegistry.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/CachingArtifactTypeRegistry.java index a260234..bb03b14 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/CachingArtifactTypeRegistry.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/CachingArtifactTypeRegistry.java @@ -29,7 +29,7 @@ import org.eclipse.aether.artifact.ArtifactTypeRegistry; /** * A short-lived artifact type registry that caches results from a presumedly slower type registry. */ -class CachingArtifactTypeRegistry +public class CachingArtifactTypeRegistry implements ArtifactTypeRegistry { diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DataPool.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DataPool.java index 4a14555..6190c76 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DataPool.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DataPool.java @@ -48,8 +48,9 @@ import org.eclipse.aether.version.Version; import org.eclipse.aether.version.VersionConstraint; /** + * DataPool. */ -final class DataPool +public final class DataPool { private static final String ARTIFACT_POOL = DataPool.class.getName() + "$Artifact"; @@ -58,7 +59,7 @@ final class DataPool private static final String DESCRIPTORS = DataPool.class.getName() + "$Descriptors"; - static final ArtifactDescriptorResult NO_DESCRIPTOR = + public static final ArtifactDescriptorResult NO_DESCRIPTOR = new ArtifactDescriptorResult( new ArtifactDescriptorRequest() ); private ObjectPool<Artifact> artifacts; @@ -72,7 +73,7 @@ final class DataPool private final Map<Object, List<DependencyNode>> nodes = new HashMap<>( 256 ); @SuppressWarnings( "unchecked" ) - DataPool( RepositorySystemSession session ) + public DataPool( RepositorySystemSession session ) { RepositoryCache cache = session.getCache(); @@ -121,12 +122,12 @@ final class DataPool return dependencies.intern( dependency ); } - Object toKey( ArtifactDescriptorRequest request ) + public Object toKey( ArtifactDescriptorRequest request ) { return request.getArtifact(); } - ArtifactDescriptorResult getDescriptor( Object key, ArtifactDescriptorRequest request ) + public ArtifactDescriptorResult getDescriptor( Object key, ArtifactDescriptorRequest request ) { Descriptor descriptor = descriptors.get( key ); if ( descriptor != null ) @@ -136,22 +137,22 @@ final class DataPool return null; } - void putDescriptor( Object key, ArtifactDescriptorResult result ) + public void putDescriptor( Object key, ArtifactDescriptorResult result ) { descriptors.put( key, new GoodDescriptor( result ) ); } - void putDescriptor( Object key, ArtifactDescriptorException e ) + public void putDescriptor( Object key, ArtifactDescriptorException e ) { descriptors.put( key, BadDescriptor.INSTANCE ); } - Object toKey( VersionRangeRequest request ) + public Object toKey( VersionRangeRequest request ) { return new ConstraintKey( request ); } - VersionRangeResult getConstraint( Object key, VersionRangeRequest request ) + public VersionRangeResult getConstraint( Object key, VersionRangeRequest request ) { Constraint constraint = constraints.get( key ); if ( constraint != null ) @@ -161,7 +162,7 @@ final class DataPool return null; } - void putConstraint( Object key, VersionRangeResult result ) + public void putConstraint( Object key, VersionRangeResult result ) { constraints.put( key, new Constraint( result ) ); } @@ -182,14 +183,20 @@ final class DataPool nodes.put( key, children ); } - abstract static class Descriptor + /** + * Descriptor + */ + public abstract static class Descriptor { public abstract ArtifactDescriptorResult toResult( ArtifactDescriptorRequest request ); } - static final class GoodDescriptor + /** + * GoodDescriptor + */ + public static final class GoodDescriptor extends Descriptor { @@ -205,7 +212,7 @@ final class DataPool final List<Dependency> managedDependencies; - GoodDescriptor( ArtifactDescriptorResult result ) + public GoodDescriptor( ArtifactDescriptorResult result ) { artifact = result.getArtifact(); relocations = result.getRelocations(); @@ -229,7 +236,10 @@ final class DataPool } - static final class BadDescriptor + /** + * BadDescriptor + */ + public static final class BadDescriptor extends Descriptor { @@ -285,7 +295,10 @@ final class DataPool } } - static final class ConstraintKey + /** + * ConstraintKey + */ + public static final class ConstraintKey { private final Artifact artifact; @@ -293,7 +306,7 @@ final class DataPool private final int hashCode; - ConstraintKey( VersionRangeRequest request ) + public ConstraintKey( VersionRangeRequest request ) { artifact = request.getArtifact(); repositories = request.getRepositories(); @@ -360,7 +373,10 @@ final class DataPool } } - static final class GraphKey + /** + * GraphKey + */ + public static final class GraphKey { private final Artifact artifact; @@ -376,7 +392,7 @@ final class DataPool private final int hashCode; - GraphKey( Artifact artifact, List<RemoteRepository> repositories, DependencySelector selector, + public GraphKey( Artifact artifact, List<RemoteRepository> repositories, DependencySelector selector, DependencyManager manager, DependencyTraverser traverser, VersionFilter filter ) { this.artifact = artifact; diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectionContext.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectionContext.java index 3bf4fe1..0c66fa7 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectionContext.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectionContext.java @@ -29,7 +29,7 @@ import org.eclipse.aether.graph.Dependency; /** * @see DefaultDependencyCollector */ -final class DefaultDependencyCollectionContext +public final class DefaultDependencyCollectionContext implements DependencyCollectionContext { @@ -41,7 +41,7 @@ final class DefaultDependencyCollectionContext private List<Dependency> managedDependencies; - DefaultDependencyCollectionContext( RepositorySystemSession session, Artifact artifact, + public DefaultDependencyCollectionContext( RepositorySystemSession session, Artifact artifact, Dependency dependency, List<Dependency> managedDependencies ) { this.session = session; diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java index a773367..0dba4e4 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java @@ -19,875 +19,79 @@ package org.eclipse.aether.internal.impl.collect; * under the License. */ -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Queue; - -import static java.util.Objects.requireNonNull; -import static org.eclipse.aether.internal.impl.collect.DefaultDependencyCycle.find; - import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; -import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.RepositoryException; +import java.util.HashMap; +import java.util.Map; + import org.eclipse.aether.RepositorySystemSession; -import org.eclipse.aether.RequestTrace; -import org.eclipse.aether.artifact.Artifact; -import org.eclipse.aether.artifact.ArtifactProperties; import org.eclipse.aether.collection.CollectRequest; import org.eclipse.aether.collection.CollectResult; import org.eclipse.aether.collection.DependencyCollectionException; -import org.eclipse.aether.collection.DependencyGraphTransformer; -import org.eclipse.aether.collection.DependencyManagement; -import org.eclipse.aether.collection.DependencyManager; -import org.eclipse.aether.collection.DependencySelector; -import org.eclipse.aether.collection.DependencyTraverser; -import org.eclipse.aether.collection.VersionFilter; -import org.eclipse.aether.graph.DefaultDependencyNode; -import org.eclipse.aether.graph.Dependency; -import org.eclipse.aether.graph.DependencyNode; -import org.eclipse.aether.graph.Exclusion; -import org.eclipse.aether.impl.ArtifactDescriptorReader; import org.eclipse.aether.impl.DependencyCollector; -import org.eclipse.aether.impl.RemoteRepositoryManager; -import org.eclipse.aether.impl.VersionRangeResolver; -import org.eclipse.aether.repository.ArtifactRepository; -import org.eclipse.aether.repository.RemoteRepository; -import org.eclipse.aether.resolution.ArtifactDescriptorException; -import org.eclipse.aether.resolution.ArtifactDescriptorRequest; -import org.eclipse.aether.resolution.ArtifactDescriptorResult; -import org.eclipse.aether.resolution.VersionRangeRequest; -import org.eclipse.aether.resolution.VersionRangeResolutionException; -import org.eclipse.aether.resolution.VersionRangeResult; +import org.eclipse.aether.internal.impl.collect.bf.BfDependencyCollector; +import org.eclipse.aether.internal.impl.collect.df.DfDependencyCollector; import org.eclipse.aether.spi.locator.Service; import org.eclipse.aether.spi.locator.ServiceLocator; import org.eclipse.aether.util.ConfigUtils; -import org.eclipse.aether.util.graph.manager.DependencyManagerUtils; -import org.eclipse.aether.util.graph.transformer.TransformationContextKeys; -import org.eclipse.aether.version.Version; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; + +import static java.util.Objects.requireNonNull; /** + * */ @Singleton @Named public class DefaultDependencyCollector - implements DependencyCollector, Service + implements DependencyCollector, Service { + private static final String CONFIG_PROP_COLLECTOR_IMPL = "aether.collector.impl"; - private static final String CONFIG_PROP_MAX_EXCEPTIONS = "aether.dependencyCollector.maxExceptions"; - - private static final int CONFIG_PROP_MAX_EXCEPTIONS_DEFAULT = 50; - - private static final String CONFIG_PROP_MAX_CYCLES = "aether.dependencyCollector.maxCycles"; - - private static final int CONFIG_PROP_MAX_CYCLES_DEFAULT = 10; - - private static final Logger LOGGER = LoggerFactory.getLogger( DefaultDependencyCollector.class ); + private static final String DEFAULT_COLLECTOR_IMPL = DfDependencyCollector.NAME; - private RemoteRepositoryManager remoteRepositoryManager; - - private ArtifactDescriptorReader descriptorReader; - - private VersionRangeResolver versionRangeResolver; + private final Map<String, DependencyCollectorDelegate> delegates; + /** + * Default ctor for SL. + * + * @deprecated SL is to be removed. + */ + @Deprecated public DefaultDependencyCollector() { - // enables default constructor + this.delegates = new HashMap<>(); } @Inject - DefaultDependencyCollector( RemoteRepositoryManager remoteRepositoryManager, - ArtifactDescriptorReader artifactDescriptorReader, - VersionRangeResolver versionRangeResolver ) + public DefaultDependencyCollector( Map<String, DependencyCollectorDelegate> delegates ) { - setRemoteRepositoryManager( remoteRepositoryManager ); - setArtifactDescriptorReader( artifactDescriptorReader ); - setVersionRangeResolver( versionRangeResolver ); + this.delegates = requireNonNull( delegates ); } + @Override public void initService( ServiceLocator locator ) { - setRemoteRepositoryManager( locator.getService( RemoteRepositoryManager.class ) ); - setArtifactDescriptorReader( locator.getService( ArtifactDescriptorReader.class ) ); - setVersionRangeResolver( locator.getService( VersionRangeResolver.class ) ); - } - - public DefaultDependencyCollector setRemoteRepositoryManager( RemoteRepositoryManager remoteRepositoryManager ) - { - this.remoteRepositoryManager = - requireNonNull( remoteRepositoryManager, "remote repository provider cannot be null" ); - return this; - } - - public DefaultDependencyCollector setArtifactDescriptorReader( ArtifactDescriptorReader artifactDescriptorReader ) - { - descriptorReader = requireNonNull( artifactDescriptorReader, "artifact descriptor reader cannot be null" ); - return this; - } - - public DefaultDependencyCollector setVersionRangeResolver( VersionRangeResolver versionRangeResolver ) - { - this.versionRangeResolver = - requireNonNull( versionRangeResolver, "version range resolver cannot be null" ); - return this; + BfDependencyCollector bf = new BfDependencyCollector(); + bf.initService( locator ); + DfDependencyCollector df = new DfDependencyCollector(); + df.initService( locator ); + this.delegates.put( BfDependencyCollector.NAME, bf ); + this.delegates.put( DfDependencyCollector.NAME, df ); } - @SuppressWarnings( "checkstyle:methodlength" ) + @Override public CollectResult collectDependencies( RepositorySystemSession session, CollectRequest request ) - throws DependencyCollectionException + throws DependencyCollectionException { - requireNonNull( session, "session cannot be null" ); - requireNonNull( request, "request cannot be null" ); - session = optimizeSession( session ); - - RequestTrace trace = RequestTrace.newChild( request.getTrace(), request ); - - CollectResult result = new CollectResult( request ); - - DependencySelector depSelector = session.getDependencySelector(); - DependencyManager depManager = session.getDependencyManager(); - DependencyTraverser depTraverser = session.getDependencyTraverser(); - VersionFilter verFilter = session.getVersionFilter(); - - Dependency root = request.getRoot(); - List<RemoteRepository> repositories = request.getRepositories(); - List<Dependency> dependencies = request.getDependencies(); - List<Dependency> managedDependencies = request.getManagedDependencies(); - - Map<String, Object> stats = new LinkedHashMap<>(); - long time1 = System.nanoTime(); - - DefaultDependencyNode node; - if ( root != null ) - { - List<? extends Version> versions; - VersionRangeResult rangeResult; - try - { - VersionRangeRequest rangeRequest = - new VersionRangeRequest( root.getArtifact(), request.getRepositories(), - request.getRequestContext() ); - rangeRequest.setTrace( trace ); - rangeResult = versionRangeResolver.resolveVersionRange( session, rangeRequest ); - versions = filterVersions( root, rangeResult, verFilter, new DefaultVersionFilterContext( session ) ); - } - catch ( VersionRangeResolutionException e ) - { - result.addException( e ); - throw new DependencyCollectionException( result, e.getMessage() ); - } - - Version version = versions.get( versions.size() - 1 ); - root = root.setArtifact( root.getArtifact().setVersion( version.toString() ) ); - - ArtifactDescriptorResult descriptorResult; - try - { - ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest(); - descriptorRequest.setArtifact( root.getArtifact() ); - descriptorRequest.setRepositories( request.getRepositories() ); - descriptorRequest.setRequestContext( request.getRequestContext() ); - descriptorRequest.setTrace( trace ); - if ( isLackingDescriptor( root.getArtifact() ) ) - { - descriptorResult = new ArtifactDescriptorResult( descriptorRequest ); - } - else - { - descriptorResult = descriptorReader.readArtifactDescriptor( session, descriptorRequest ); - } - } - catch ( ArtifactDescriptorException e ) - { - result.addException( e ); - throw new DependencyCollectionException( result, e.getMessage() ); - } - - root = root.setArtifact( descriptorResult.getArtifact() ); - - if ( !session.isIgnoreArtifactDescriptorRepositories() ) - { - repositories = remoteRepositoryManager.aggregateRepositories( session, repositories, - descriptorResult.getRepositories(), - true ); - } - dependencies = mergeDeps( dependencies, descriptorResult.getDependencies() ); - managedDependencies = mergeDeps( managedDependencies, descriptorResult.getManagedDependencies() ); - - node = new DefaultDependencyNode( root ); - node.setRequestContext( request.getRequestContext() ); - node.setRelocations( descriptorResult.getRelocations() ); - node.setVersionConstraint( rangeResult.getVersionConstraint() ); - node.setVersion( version ); - node.setAliases( descriptorResult.getAliases() ); - node.setRepositories( request.getRepositories() ); - } - else - { - node = new DefaultDependencyNode( request.getRootArtifact() ); - node.setRequestContext( request.getRequestContext() ); - node.setRepositories( request.getRepositories() ); - } - - result.setRoot( node ); - - boolean traverse = root == null || depTraverser == null || depTraverser.traverseDependency( root ); - String errorPath = null; - if ( traverse && !dependencies.isEmpty() ) + String delegateName = ConfigUtils.getString( session, DEFAULT_COLLECTOR_IMPL, CONFIG_PROP_COLLECTOR_IMPL ); + DependencyCollectorDelegate delegate = delegates.get( delegateName ); + if ( delegate == null ) { - DataPool pool = new DataPool( session ); - - DefaultDependencyCollectionContext context = - new DefaultDependencyCollectionContext( session, request.getRootArtifact(), root, managedDependencies ); - - DefaultVersionFilterContext versionContext = new DefaultVersionFilterContext( session ); - - Args args = new Args( session, trace, pool, context, versionContext, request ); - Results results = new Results( result, session ); - - DependencySelector rootDepSelector = - depSelector != null ? depSelector.deriveChildSelector( context ) : null; - DependencyManager rootDepManager = depManager != null ? depManager.deriveChildManager( context ) : null; - DependencyTraverser rootDepTraverser = - depTraverser != null ? depTraverser.deriveChildTraverser( context ) : null; - VersionFilter rootVerFilter = verFilter != null ? verFilter.deriveChildFilter( context ) : null; - - for ( Dependency dependency : dependencies ) - { - args.dependencyProcessingQueue.add( - new DependencyProcessingContext( rootDepSelector, rootDepManager, rootDepTraverser, - rootVerFilter, repositories, managedDependencies, Collections.singletonList( node ), - dependency ) ); - } - - while ( !args.dependencyProcessingQueue.isEmpty() ) - { - processDependency( args, results, args.dependencyProcessingQueue.remove(), Collections.emptyList(), - false ); - } - - errorPath = results.errorPath; - } - - long time2 = System.nanoTime(); - - DependencyGraphTransformer transformer = session.getDependencyGraphTransformer(); - if ( transformer != null ) - { - try - { - DefaultDependencyGraphTransformationContext context = - new DefaultDependencyGraphTransformationContext( session ); - context.put( TransformationContextKeys.STATS, stats ); - result.setRoot( transformer.transformGraph( node, context ) ); - } - catch ( RepositoryException e ) - { - result.addException( e ); - } - } - - long time3 = System.nanoTime(); - stats.put( "DefaultDependencyCollector.collectTime", time2 - time1 ); - stats.put( "DefaultDependencyCollector.transformTime", time3 - time2 ); - LOGGER.debug( "Dependency collection stats {}", stats ); - - if ( errorPath != null ) - { - throw new DependencyCollectionException( result, "Failed to collect dependencies at " + errorPath ); - } - if ( !result.getExceptions().isEmpty() ) - { - throw new DependencyCollectionException( result ); - } - - return result; - } - - private static RepositorySystemSession optimizeSession( RepositorySystemSession session ) - { - DefaultRepositorySystemSession optimized = new DefaultRepositorySystemSession( session ); - optimized.setArtifactTypeRegistry( CachingArtifactTypeRegistry.newInstance( session ) ); - return optimized; - } - - private List<Dependency> mergeDeps( List<Dependency> dominant, List<Dependency> recessive ) - { - List<Dependency> result; - if ( dominant == null || dominant.isEmpty() ) - { - result = recessive; - } - else if ( recessive == null || recessive.isEmpty() ) - { - result = dominant; - } - else - { - int initialCapacity = dominant.size() + recessive.size(); - result = new ArrayList<>( initialCapacity ); - Collection<String> ids = new HashSet<>( initialCapacity, 1.0f ); - for ( Dependency dependency : dominant ) - { - ids.add( getId( dependency.getArtifact() ) ); - result.add( dependency ); - } - for ( Dependency dependency : recessive ) - { - if ( !ids.contains( getId( dependency.getArtifact() ) ) ) - { - result.add( dependency ); - } - } - } - return result; - } - - private static String getId( Artifact a ) - { - return a.getGroupId() + ':' + a.getArtifactId() + ':' + a.getClassifier() + ':' + a.getExtension(); - } - - @SuppressWarnings( "checkstyle:parameternumber" ) - private void processDependency( Args args, Results results, DependencyProcessingContext context, - List<Artifact> relocations, boolean disableVersionManagement ) - { - - if ( context.depSelector != null && !context.depSelector.selectDependency( context.dependency ) ) - { - return; - } - - PremanagedDependency preManaged = - PremanagedDependency.create( context.depManager, context.dependency, disableVersionManagement, - args.premanagedState ); - Dependency dependency = preManaged.managedDependency; - - boolean noDescriptor = isLackingDescriptor( dependency.getArtifact() ); - - boolean traverse = - !noDescriptor && ( context.depTraverser == null || context.depTraverser.traverseDependency( - dependency ) ); - - List<? extends Version> versions; - VersionRangeResult rangeResult; - try - { - VersionRangeRequest rangeRequest = createVersionRangeRequest( args, context.repositories, dependency ); - - rangeResult = cachedResolveRangeResult( rangeRequest, args.pool, args.session ); - - versions = filterVersions( dependency, rangeResult, context.verFilter, args.versionContext ); - } - catch ( VersionRangeResolutionException e ) - { - results.addException( dependency, e, context.parents ); - return; - } - - for ( Version version : versions ) - { - Artifact originalArtifact = dependency.getArtifact().setVersion( version.toString() ); - Dependency d = dependency.setArtifact( originalArtifact ); - - ArtifactDescriptorRequest descriptorRequest = - createArtifactDescriptorRequest( args, context.repositories, d ); - - final ArtifactDescriptorResult descriptorResult = - noDescriptor - ? new ArtifactDescriptorResult( descriptorRequest ) - : resolveCachedArtifactDescriptor( args.pool, descriptorRequest, args.session, - context.withDependency( d ), results ); - - if ( descriptorResult != null ) - { - d = d.setArtifact( descriptorResult.getArtifact() ); - - int cycleEntry = find( context.parents, d.getArtifact() ); - if ( cycleEntry >= 0 ) - { - results.addCycle( context.parents, cycleEntry, d ); - DependencyNode cycleNode = context.parents.get( cycleEntry ); - if ( cycleNode.getDependency() != null ) - { - DefaultDependencyNode child = - createDependencyNode( relocations, preManaged, rangeResult, version, d, - descriptorResult, cycleNode ); - context.getParent().getChildren().add( child ); - continue; - } - } - - if ( !descriptorResult.getRelocations().isEmpty() ) - { - boolean disableVersionManagementSubsequently = - originalArtifact.getGroupId().equals( d.getArtifact().getGroupId() ) - && originalArtifact.getArtifactId().equals( d.getArtifact().getArtifactId() ); - - processDependency( args, results, context.withDependency( d ), descriptorResult.getRelocations(), - disableVersionManagementSubsequently ); - return; - } - else - { - d = args.pool.intern( d.setArtifact( args.pool.intern( d.getArtifact() ) ) ); - - List<RemoteRepository> repos = - getRemoteRepositories( rangeResult.getRepository( version ), context.repositories ); - - DefaultDependencyNode child = - createDependencyNode( relocations, preManaged, rangeResult, version, d, - descriptorResult.getAliases(), repos, args.request.getRequestContext() ); - - context.getParent().getChildren().add( child ); - - boolean recurse = traverse && !descriptorResult.getDependencies().isEmpty(); - if ( recurse ) - { - doRecurse( args, context.withDependency( d ), descriptorResult, child ); - } - } - } - else - { - List<RemoteRepository> repos = - getRemoteRepositories( rangeResult.getRepository( version ), context.repositories ); - DefaultDependencyNode child = - createDependencyNode( relocations, preManaged, rangeResult, version, d, null, repos, - args.request.getRequestContext() ); - context.getParent().getChildren().add( child ); - } + throw new IllegalArgumentException( "Unknown collector impl: '" + delegateName + + "', known implementations are " + delegates.keySet() ); } + return delegate.collectDependencies( session, request ); } - - @SuppressWarnings( "checkstyle:parameternumber" ) - private void doRecurse( Args args, DependencyProcessingContext parentContext, - ArtifactDescriptorResult descriptorResult, DefaultDependencyNode child ) - { - DefaultDependencyCollectionContext context = args.collectionContext; - context.set( parentContext.dependency, descriptorResult.getManagedDependencies() ); - - DependencySelector childSelector = - parentContext.depSelector != null ? parentContext.depSelector.deriveChildSelector( context ) : null; - DependencyManager childManager = - parentContext.depManager != null ? parentContext.depManager.deriveChildManager( context ) : null; - DependencyTraverser childTraverser = - parentContext.depTraverser != null ? parentContext.depTraverser.deriveChildTraverser( context ) : null; - VersionFilter childFilter = - parentContext.verFilter != null ? parentContext.verFilter.deriveChildFilter( context ) : null; - - final List<RemoteRepository> childRepos = - args.ignoreRepos - ? parentContext.repositories - : remoteRepositoryManager.aggregateRepositories( args.session, parentContext.repositories, - descriptorResult.getRepositories(), true ); - - Object key = - args.pool.toKey( parentContext.dependency.getArtifact(), childRepos, childSelector, childManager, - childTraverser, childFilter ); - - List<DependencyNode> children = args.pool.getChildren( key ); - if ( children == null ) - { - args.pool.putChildren( key, child.getChildren() ); - - List<DependencyNode> parents = new ArrayList<>( parentContext.parents ); - parents.add( child ); - for ( Dependency dependency : descriptorResult.getDependencies() ) - { - args.dependencyProcessingQueue.add( - new DependencyProcessingContext( childSelector, childManager, childTraverser, childFilter, - childRepos, descriptorResult.getManagedDependencies(), parents, dependency ) ); - } - } - else - { - child.setChildren( children ); - } - } - - private ArtifactDescriptorResult resolveCachedArtifactDescriptor( DataPool pool, - ArtifactDescriptorRequest descriptorRequest, - RepositorySystemSession session, - DependencyProcessingContext context, - Results results ) - { - Object key = pool.toKey( descriptorRequest ); - ArtifactDescriptorResult descriptorResult = pool.getDescriptor( key, descriptorRequest ); - if ( descriptorResult == null ) - { - try - { - descriptorResult = descriptorReader.readArtifactDescriptor( session, descriptorRequest ); - pool.putDescriptor( key, descriptorResult ); - } - catch ( ArtifactDescriptorException e ) - { - results.addException( context.dependency, e, context.parents ); - pool.putDescriptor( key, e ); - return null; - } - - } - else if ( descriptorResult == DataPool.NO_DESCRIPTOR ) - { - return null; - } - - return descriptorResult; - } - - @SuppressWarnings( "checkstyle:parameternumber" ) - private static DefaultDependencyNode createDependencyNode( List<Artifact> relocations, - PremanagedDependency preManaged, - VersionRangeResult rangeResult, Version version, - Dependency d, Collection<Artifact> aliases, - List<RemoteRepository> repos, String requestContext ) - { - DefaultDependencyNode child = new DefaultDependencyNode( d ); - preManaged.applyTo( child ); - child.setRelocations( relocations ); - child.setVersionConstraint( rangeResult.getVersionConstraint() ); - child.setVersion( version ); - child.setAliases( aliases ); - child.setRepositories( repos ); - child.setRequestContext( requestContext ); - return child; - } - - private static DefaultDependencyNode createDependencyNode( List<Artifact> relocations, - PremanagedDependency preManaged, - VersionRangeResult rangeResult, Version version, - Dependency d, ArtifactDescriptorResult descriptorResult, - DependencyNode cycleNode ) - { - DefaultDependencyNode child = - createDependencyNode( relocations, preManaged, rangeResult, version, d, descriptorResult.getAliases(), - cycleNode.getRepositories(), cycleNode.getRequestContext() ); - child.setChildren( cycleNode.getChildren() ); - return child; - } - - private static ArtifactDescriptorRequest createArtifactDescriptorRequest( Args args, - List<RemoteRepository> repositories, - Dependency d ) - { - ArtifactDescriptorRequest descriptorRequest = new ArtifactDescriptorRequest(); - descriptorRequest.setArtifact( d.getArtifact() ); - descriptorRequest.setRepositories( repositories ); - descriptorRequest.setRequestContext( args.request.getRequestContext() ); - descriptorRequest.setTrace( args.trace ); - return descriptorRequest; - } - - private static VersionRangeRequest createVersionRangeRequest( Args args, List<RemoteRepository> repositories, - Dependency dependency ) - { - VersionRangeRequest rangeRequest = new VersionRangeRequest(); - rangeRequest.setArtifact( dependency.getArtifact() ); - rangeRequest.setRepositories( repositories ); - rangeRequest.setRequestContext( args.request.getRequestContext() ); - rangeRequest.setTrace( args.trace ); - return rangeRequest; - } - - private VersionRangeResult cachedResolveRangeResult( VersionRangeRequest rangeRequest, DataPool pool, - RepositorySystemSession session ) - throws VersionRangeResolutionException - { - Object key = pool.toKey( rangeRequest ); - VersionRangeResult rangeResult = pool.getConstraint( key, rangeRequest ); - if ( rangeResult == null ) - { - rangeResult = versionRangeResolver.resolveVersionRange( session, rangeRequest ); - pool.putConstraint( key, rangeResult ); - } - return rangeResult; - } - - private static boolean isLackingDescriptor( Artifact artifact ) - { - return artifact.getProperty( ArtifactProperties.LOCAL_PATH, null ) != null; - } - - private static List<RemoteRepository> getRemoteRepositories( ArtifactRepository repository, - List<RemoteRepository> repositories ) - { - if ( repository instanceof RemoteRepository ) - { - return Collections.singletonList( (RemoteRepository) repository ); - } - if ( repository != null ) - { - return Collections.emptyList(); - } - return repositories; - } - - private static List<? extends Version> filterVersions( Dependency dependency, VersionRangeResult rangeResult, - VersionFilter verFilter, - DefaultVersionFilterContext verContext ) - throws VersionRangeResolutionException - { - if ( rangeResult.getVersions().isEmpty() ) - { - throw new VersionRangeResolutionException( rangeResult, - "No versions available for " + dependency.getArtifact() - + " within specified range" ); - } - - List<? extends Version> versions; - if ( verFilter != null && rangeResult.getVersionConstraint().getRange() != null ) - { - verContext.set( dependency, rangeResult ); - try - { - verFilter.filterVersions( verContext ); - } - catch ( RepositoryException e ) - { - throw new VersionRangeResolutionException( rangeResult, - "Failed to filter versions for " + dependency.getArtifact() - + ": " + e.getMessage(), e ); - } - versions = verContext.get(); - if ( versions.isEmpty() ) - { - throw new VersionRangeResolutionException( rangeResult, - "No acceptable versions for " + dependency.getArtifact() - + ": " + rangeResult.getVersions() ); - } - } - else - { - versions = rangeResult.getVersions(); - } - return versions; - } - - static class Args - { - - final RepositorySystemSession session; - - final boolean ignoreRepos; - - final boolean premanagedState; - - final RequestTrace trace; - - final DataPool pool; - - final Queue<DependencyProcessingContext> dependencyProcessingQueue = new ArrayDeque<>(); - - final DefaultDependencyCollectionContext collectionContext; - - final DefaultVersionFilterContext versionContext; - - final CollectRequest request; - - Args( RepositorySystemSession session, RequestTrace trace, DataPool pool, - DefaultDependencyCollectionContext collectionContext, DefaultVersionFilterContext versionContext, - CollectRequest request ) - { - this.session = session; - this.request = request; - this.ignoreRepos = session.isIgnoreArtifactDescriptorRepositories(); - this.premanagedState = ConfigUtils.getBoolean( session, false, DependencyManagerUtils.CONFIG_PROP_VERBOSE ); - this.trace = trace; - this.pool = pool; - this.collectionContext = collectionContext; - this.versionContext = versionContext; - } - - } - - static class Results - { - - private final CollectResult result; - - final int maxExceptions; - - final int maxCycles; - - String errorPath; - - Results( CollectResult result, RepositorySystemSession session ) - { - this.result = result; - - maxExceptions = - ConfigUtils.getInteger( session, CONFIG_PROP_MAX_EXCEPTIONS_DEFAULT, CONFIG_PROP_MAX_EXCEPTIONS ); - - maxCycles = ConfigUtils.getInteger( session, CONFIG_PROP_MAX_CYCLES_DEFAULT, CONFIG_PROP_MAX_CYCLES ); - } - - public void addException( Dependency dependency, Exception e, List<DependencyNode> nodes ) - { - if ( maxExceptions < 0 || result.getExceptions().size() < maxExceptions ) - { - result.addException( e ); - if ( errorPath == null ) - { - StringBuilder buffer = new StringBuilder( 256 ); - for ( DependencyNode node : nodes ) - { - if ( buffer.length() > 0 ) - { - buffer.append( " -> " ); - } - Dependency dep = node.getDependency(); - if ( dep != null ) - { - buffer.append( dep.getArtifact() ); - } - } - if ( buffer.length() > 0 ) - { - buffer.append( " -> " ); - } - buffer.append( dependency.getArtifact() ); - errorPath = buffer.toString(); - } - } - } - - public void addCycle( List<DependencyNode> nodes, int cycleEntry, Dependency dependency ) - { - if ( maxCycles < 0 || result.getCycles().size() < maxCycles ) - { - result.addCycle( new DefaultDependencyCycle( nodes, cycleEntry, dependency ) ); - } - } - - } - - static class PremanagedDependency - { - - final String premanagedVersion; - - final String premanagedScope; - - final Boolean premanagedOptional; - - /** - * @since 1.1.0 - */ - final Collection<Exclusion> premanagedExclusions; - - /** - * @since 1.1.0 - */ - final Map<String, String> premanagedProperties; - - final int managedBits; - - final Dependency managedDependency; - - final boolean premanagedState; - - @SuppressWarnings( "checkstyle:parameternumber" ) - PremanagedDependency( String premanagedVersion, String premanagedScope, Boolean premanagedOptional, - Collection<Exclusion> premanagedExclusions, Map<String, String> premanagedProperties, - int managedBits, Dependency managedDependency, boolean premanagedState ) - { - this.premanagedVersion = premanagedVersion; - this.premanagedScope = premanagedScope; - this.premanagedOptional = premanagedOptional; - this.premanagedExclusions = - premanagedExclusions != null - ? Collections.unmodifiableCollection( new ArrayList<>( premanagedExclusions ) ) - : null; - - this.premanagedProperties = - premanagedProperties != null - ? Collections.unmodifiableMap( new HashMap<>( premanagedProperties ) ) - : null; - - this.managedBits = managedBits; - this.managedDependency = managedDependency; - this.premanagedState = premanagedState; - } - - static PremanagedDependency create( DependencyManager depManager, Dependency dependency, - boolean disableVersionManagement, boolean premanagedState ) - { - DependencyManagement depMngt = depManager != null ? depManager.manageDependency( dependency ) : null; - - int managedBits = 0; - String premanagedVersion = null; - String premanagedScope = null; - Boolean premanagedOptional = null; - Collection<Exclusion> premanagedExclusions = null; - Map<String, String> premanagedProperties = null; - - if ( depMngt != null ) - { - if ( depMngt.getVersion() != null && !disableVersionManagement ) - { - Artifact artifact = dependency.getArtifact(); - premanagedVersion = artifact.getVersion(); - dependency = dependency.setArtifact( artifact.setVersion( depMngt.getVersion() ) ); - managedBits |= DependencyNode.MANAGED_VERSION; - } - if ( depMngt.getProperties() != null ) - { - Artifact artifact = dependency.getArtifact(); - premanagedProperties = artifact.getProperties(); - dependency = dependency.setArtifact( artifact.setProperties( depMngt.getProperties() ) ); - managedBits |= DependencyNode.MANAGED_PROPERTIES; - } - if ( depMngt.getScope() != null ) - { - premanagedScope = dependency.getScope(); - dependency = dependency.setScope( depMngt.getScope() ); - managedBits |= DependencyNode.MANAGED_SCOPE; - } - if ( depMngt.getOptional() != null ) - { - premanagedOptional = dependency.isOptional(); - dependency = dependency.setOptional( depMngt.getOptional() ); - managedBits |= DependencyNode.MANAGED_OPTIONAL; - } - if ( depMngt.getExclusions() != null ) - { - premanagedExclusions = dependency.getExclusions(); - dependency = dependency.setExclusions( depMngt.getExclusions() ); - managedBits |= DependencyNode.MANAGED_EXCLUSIONS; - } - } - return new PremanagedDependency( premanagedVersion, premanagedScope, premanagedOptional, - premanagedExclusions, premanagedProperties, managedBits, dependency, - premanagedState ); - - } - - public void applyTo( DefaultDependencyNode child ) - { - child.setManagedBits( managedBits ); - if ( premanagedState ) - { - child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_VERSION, premanagedVersion ); - child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_SCOPE, premanagedScope ); - child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_OPTIONAL, premanagedOptional ); - child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_EXCLUSIONS, premanagedExclusions ); - child.setData( DependencyManagerUtils.NODE_DATA_PREMANAGED_PROPERTIES, premanagedProperties ); - } - } - - } - } diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyGraphTransformationContext.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyGraphTransformationContext.java index 41c0126..28ea747 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyGraphTransformationContext.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyGraphTransformationContext.java @@ -28,7 +28,7 @@ import org.eclipse.aether.collection.DependencyGraphTransformationContext; /** */ -class DefaultDependencyGraphTransformationContext +public class DefaultDependencyGraphTransformationContext implements DependencyGraphTransformationContext { @@ -36,7 +36,7 @@ class DefaultDependencyGraphTransformationContext private final Map<Object, Object> map; - DefaultDependencyGraphTransformationContext( RepositorySystemSession session ) + public DefaultDependencyGraphTransformationContext( RepositorySystemSession session ) { this.session = session; this.map = new HashMap<>(); diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultVersionFilterContext.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultVersionFilterContext.java index bfea062..55b6fba 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultVersionFilterContext.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultVersionFilterContext.java @@ -36,7 +36,7 @@ import org.eclipse.aether.version.VersionConstraint; /** * @see DefaultDependencyCollector */ -final class DefaultVersionFilterContext +public final class DefaultVersionFilterContext implements VersionFilter.VersionFilterContext { private final RepositorySystemSession session; @@ -47,7 +47,7 @@ final class DefaultVersionFilterContext private List<Version> versions; - DefaultVersionFilterContext( RepositorySystemSession session ) + public DefaultVersionFilterContext( RepositorySystemSession session ) { this.session = session; } diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DependencyCollectorDelegate.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DependencyCollectorDelegate.java new file mode 100644 index 0000000..d47a2b9 --- /dev/null +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DependencyCollectorDelegate.java @@ -0,0 +1,29 @@ +package org.eclipse.aether.internal.impl.collect; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.eclipse.aether.impl.DependencyCollector; + +/** + * Sub-type for actual implementations. + */ +public interface DependencyCollectorDelegate extends DependencyCollector +{ +} diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/bf/BfDependencyCollector.java similarity index 95% copy from maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java copy to maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/bf/BfDependencyCollector.java index a773367..ad87c22 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/bf/BfDependencyCollector.java @@ -1,4 +1,4 @@ -package org.eclipse.aether.internal.impl.collect; +package org.eclipse.aether.internal.impl.collect.bf; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,6 +19,10 @@ package org.eclipse.aether.internal.impl.collect; * under the License. */ +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; @@ -30,13 +34,6 @@ import java.util.List; import java.util.Map; import java.util.Queue; -import static java.util.Objects.requireNonNull; -import static org.eclipse.aether.internal.impl.collect.DefaultDependencyCycle.find; - -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; - import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositoryException; import org.eclipse.aether.RepositorySystemSession; @@ -57,9 +54,14 @@ import org.eclipse.aether.graph.Dependency; import org.eclipse.aether.graph.DependencyNode; import org.eclipse.aether.graph.Exclusion; import org.eclipse.aether.impl.ArtifactDescriptorReader; -import org.eclipse.aether.impl.DependencyCollector; import org.eclipse.aether.impl.RemoteRepositoryManager; import org.eclipse.aether.impl.VersionRangeResolver; +import org.eclipse.aether.internal.impl.collect.CachingArtifactTypeRegistry; +import org.eclipse.aether.internal.impl.collect.DataPool; +import org.eclipse.aether.internal.impl.collect.DefaultDependencyCollectionContext; +import org.eclipse.aether.internal.impl.collect.DefaultDependencyGraphTransformationContext; +import org.eclipse.aether.internal.impl.collect.DefaultVersionFilterContext; +import org.eclipse.aether.internal.impl.collect.DependencyCollectorDelegate; import org.eclipse.aether.repository.ArtifactRepository; import org.eclipse.aether.repository.RemoteRepository; import org.eclipse.aether.resolution.ArtifactDescriptorException; @@ -77,13 +79,18 @@ import org.eclipse.aether.version.Version; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static java.util.Objects.requireNonNull; +import static org.eclipse.aether.internal.impl.collect.bf.BfDependencyCycle.find; + /** + * The breadth-first implementation of {@link org.eclipse.aether.impl.DependencyCollector}. */ @Singleton -@Named -public class DefaultDependencyCollector - implements DependencyCollector, Service +@Named( BfDependencyCollector.NAME ) +public class BfDependencyCollector + implements DependencyCollectorDelegate, Service { + public static final String NAME = "bf"; private static final String CONFIG_PROP_MAX_EXCEPTIONS = "aether.dependencyCollector.maxExceptions"; @@ -93,7 +100,7 @@ public class DefaultDependencyCollector private static final int CONFIG_PROP_MAX_CYCLES_DEFAULT = 10; - private static final Logger LOGGER = LoggerFactory.getLogger( DefaultDependencyCollector.class ); + private static final Logger LOGGER = LoggerFactory.getLogger( BfDependencyCollector.class ); private RemoteRepositoryManager remoteRepositoryManager; @@ -101,13 +108,13 @@ public class DefaultDependencyCollector private VersionRangeResolver versionRangeResolver; - public DefaultDependencyCollector() + public BfDependencyCollector() { // enables default constructor } @Inject - DefaultDependencyCollector( RemoteRepositoryManager remoteRepositoryManager, + BfDependencyCollector( RemoteRepositoryManager remoteRepositoryManager, ArtifactDescriptorReader artifactDescriptorReader, VersionRangeResolver versionRangeResolver ) { @@ -123,20 +130,20 @@ public class DefaultDependencyCollector setVersionRangeResolver( locator.getService( VersionRangeResolver.class ) ); } - public DefaultDependencyCollector setRemoteRepositoryManager( RemoteRepositoryManager remoteRepositoryManager ) + public BfDependencyCollector setRemoteRepositoryManager( RemoteRepositoryManager remoteRepositoryManager ) { this.remoteRepositoryManager = requireNonNull( remoteRepositoryManager, "remote repository provider cannot be null" ); return this; } - public DefaultDependencyCollector setArtifactDescriptorReader( ArtifactDescriptorReader artifactDescriptorReader ) + public BfDependencyCollector setArtifactDescriptorReader( ArtifactDescriptorReader artifactDescriptorReader ) { descriptorReader = requireNonNull( artifactDescriptorReader, "artifact descriptor reader cannot be null" ); return this; } - public DefaultDependencyCollector setVersionRangeResolver( VersionRangeResolver versionRangeResolver ) + public BfDependencyCollector setVersionRangeResolver( VersionRangeResolver versionRangeResolver ) { this.versionRangeResolver = requireNonNull( versionRangeResolver, "version range resolver cannot be null" ); @@ -266,7 +273,7 @@ public class DefaultDependencyCollector for ( Dependency dependency : dependencies ) { args.dependencyProcessingQueue.add( - new DependencyProcessingContext( rootDepSelector, rootDepManager, rootDepTraverser, + new BfProcessingContext( rootDepSelector, rootDepManager, rootDepTraverser, rootVerFilter, repositories, managedDependencies, Collections.singletonList( node ), dependency ) ); } @@ -360,7 +367,7 @@ public class DefaultDependencyCollector } @SuppressWarnings( "checkstyle:parameternumber" ) - private void processDependency( Args args, Results results, DependencyProcessingContext context, + private void processDependency( Args args, Results results, BfProcessingContext context, List<Artifact> relocations, boolean disableVersionManagement ) { @@ -472,7 +479,7 @@ public class DefaultDependencyCollector } @SuppressWarnings( "checkstyle:parameternumber" ) - private void doRecurse( Args args, DependencyProcessingContext parentContext, + private void doRecurse( Args args, BfProcessingContext parentContext, ArtifactDescriptorResult descriptorResult, DefaultDependencyNode child ) { DefaultDependencyCollectionContext context = args.collectionContext; @@ -507,7 +514,7 @@ public class DefaultDependencyCollector for ( Dependency dependency : descriptorResult.getDependencies() ) { args.dependencyProcessingQueue.add( - new DependencyProcessingContext( childSelector, childManager, childTraverser, childFilter, + new BfProcessingContext( childSelector, childManager, childTraverser, childFilter, childRepos, descriptorResult.getManagedDependencies(), parents, dependency ) ); } } @@ -520,7 +527,7 @@ public class DefaultDependencyCollector private ArtifactDescriptorResult resolveCachedArtifactDescriptor( DataPool pool, ArtifactDescriptorRequest descriptorRequest, RepositorySystemSession session, - DependencyProcessingContext context, + BfProcessingContext context, Results results ) { Object key = pool.toKey( descriptorRequest ); @@ -689,7 +696,7 @@ public class DefaultDependencyCollector final DataPool pool; - final Queue<DependencyProcessingContext> dependencyProcessingQueue = new ArrayDeque<>(); + final Queue<BfProcessingContext> dependencyProcessingQueue = new ArrayDeque<>(); final DefaultDependencyCollectionContext collectionContext; @@ -768,7 +775,7 @@ public class DefaultDependencyCollector { if ( maxCycles < 0 || result.getCycles().size() < maxCycles ) { - result.addCycle( new DefaultDependencyCycle( nodes, cycleEntry, dependency ) ); + result.addCycle( new BfDependencyCycle( nodes, cycleEntry, dependency ) ); } } diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCycle.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/bf/BfDependencyCycle.java similarity index 95% copy from maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCycle.java copy to maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/bf/BfDependencyCycle.java index dd1565c..fb370a6 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCycle.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/bf/BfDependencyCycle.java @@ -1,4 +1,4 @@ -package org.eclipse.aether.internal.impl.collect; +package org.eclipse.aether.internal.impl.collect.bf; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -30,9 +30,9 @@ import org.eclipse.aether.graph.DependencyNode; import org.eclipse.aether.util.artifact.ArtifactIdUtils; /** - * @see DefaultDependencyCollector + * @see BfDependencyCollector */ -final class DefaultDependencyCycle +final class BfDependencyCycle implements DependencyCycle { @@ -40,7 +40,7 @@ final class DefaultDependencyCycle private final int cycleEntry; - DefaultDependencyCycle( List<DependencyNode> nodes, int cycleEntry, Dependency dependency ) + BfDependencyCycle( List<DependencyNode> nodes, int cycleEntry, Dependency dependency ) { // skip root node unless it actually has a dependency or is considered the cycle entry (due to its label) int offset = ( cycleEntry > 0 && nodes.get( 0 ).getDependency() == null ) ? 1 : 0; diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DependencyProcessingContext.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/bf/BfProcessingContext.java similarity index 88% rename from maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DependencyProcessingContext.java rename to maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/bf/BfProcessingContext.java index 71815d0..2cca571 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DependencyProcessingContext.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/bf/BfProcessingContext.java @@ -1,4 +1,4 @@ -package org.eclipse.aether.internal.impl.collect; +package org.eclipse.aether.internal.impl.collect.bf; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -29,7 +29,7 @@ import org.eclipse.aether.graph.Dependency; import org.eclipse.aether.graph.DependencyNode; import org.eclipse.aether.repository.RemoteRepository; -final class DependencyProcessingContext +final class BfProcessingContext { final DependencySelector depSelector; final DependencyManager depManager; @@ -45,7 +45,7 @@ final class DependencyProcessingContext final Dependency dependency; @SuppressWarnings( "checkstyle:parameternumber" ) - DependencyProcessingContext( DependencySelector depSelector, + BfProcessingContext( DependencySelector depSelector, DependencyManager depManager, DependencyTraverser depTraverser, VersionFilter verFilter, @@ -64,9 +64,9 @@ final class DependencyProcessingContext this.parents = parents; } - DependencyProcessingContext withDependency( Dependency dependency ) + BfProcessingContext withDependency( Dependency dependency ) { - return new DependencyProcessingContext( depSelector, depManager, depTraverser, verFilter, repositories, + return new BfProcessingContext( depSelector, depManager, depTraverser, verFilter, repositories, managedDependencies, parents, dependency ); } diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/df/DfDependencyCollector.java similarity index 80% copy from maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java copy to maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/df/DfDependencyCollector.java index a773367..1fb00f4 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollector.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/df/DfDependencyCollector.java @@ -1,4 +1,4 @@ -package org.eclipse.aether.internal.impl.collect; +package org.eclipse.aether.internal.impl.collect.df; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,7 +19,10 @@ package org.eclipse.aether.internal.impl.collect; * under the License. */ -import java.util.ArrayDeque; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -28,14 +31,6 @@ import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Queue; - -import static java.util.Objects.requireNonNull; -import static org.eclipse.aether.internal.impl.collect.DefaultDependencyCycle.find; - -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositoryException; @@ -57,9 +52,14 @@ import org.eclipse.aether.graph.Dependency; import org.eclipse.aether.graph.DependencyNode; import org.eclipse.aether.graph.Exclusion; import org.eclipse.aether.impl.ArtifactDescriptorReader; -import org.eclipse.aether.impl.DependencyCollector; import org.eclipse.aether.impl.RemoteRepositoryManager; import org.eclipse.aether.impl.VersionRangeResolver; +import org.eclipse.aether.internal.impl.collect.CachingArtifactTypeRegistry; +import org.eclipse.aether.internal.impl.collect.DataPool; +import org.eclipse.aether.internal.impl.collect.DefaultDependencyCollectionContext; +import org.eclipse.aether.internal.impl.collect.DefaultDependencyGraphTransformationContext; +import org.eclipse.aether.internal.impl.collect.DefaultVersionFilterContext; +import org.eclipse.aether.internal.impl.collect.DependencyCollectorDelegate; import org.eclipse.aether.repository.ArtifactRepository; import org.eclipse.aether.repository.RemoteRepository; import org.eclipse.aether.resolution.ArtifactDescriptorException; @@ -77,13 +77,17 @@ import org.eclipse.aether.version.Version; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static java.util.Objects.requireNonNull; + /** + * The depth-first implementation of {@link org.eclipse.aether.impl.DependencyCollector}. */ @Singleton -@Named -public class DefaultDependencyCollector - implements DependencyCollector, Service +@Named( DfDependencyCollector.NAME ) +public class DfDependencyCollector + implements DependencyCollectorDelegate, Service { + public static final String NAME = "df"; private static final String CONFIG_PROP_MAX_EXCEPTIONS = "aether.dependencyCollector.maxExceptions"; @@ -93,7 +97,7 @@ public class DefaultDependencyCollector private static final int CONFIG_PROP_MAX_CYCLES_DEFAULT = 10; - private static final Logger LOGGER = LoggerFactory.getLogger( DefaultDependencyCollector.class ); + private static final Logger LOGGER = LoggerFactory.getLogger( DfDependencyCollector.class ); private RemoteRepositoryManager remoteRepositoryManager; @@ -101,15 +105,15 @@ public class DefaultDependencyCollector private VersionRangeResolver versionRangeResolver; - public DefaultDependencyCollector() + public DfDependencyCollector() { // enables default constructor } @Inject - DefaultDependencyCollector( RemoteRepositoryManager remoteRepositoryManager, - ArtifactDescriptorReader artifactDescriptorReader, - VersionRangeResolver versionRangeResolver ) + DfDependencyCollector( RemoteRepositoryManager remoteRepositoryManager, + ArtifactDescriptorReader artifactDescriptorReader, + VersionRangeResolver versionRangeResolver ) { setRemoteRepositoryManager( remoteRepositoryManager ); setArtifactDescriptorReader( artifactDescriptorReader ); @@ -123,20 +127,20 @@ public class DefaultDependencyCollector setVersionRangeResolver( locator.getService( VersionRangeResolver.class ) ); } - public DefaultDependencyCollector setRemoteRepositoryManager( RemoteRepositoryManager remoteRepositoryManager ) + public DfDependencyCollector setRemoteRepositoryManager( RemoteRepositoryManager remoteRepositoryManager ) { this.remoteRepositoryManager = requireNonNull( remoteRepositoryManager, "remote repository provider cannot be null" ); return this; } - public DefaultDependencyCollector setArtifactDescriptorReader( ArtifactDescriptorReader artifactDescriptorReader ) + public DfDependencyCollector setArtifactDescriptorReader( ArtifactDescriptorReader artifactDescriptorReader ) { descriptorReader = requireNonNull( artifactDescriptorReader, "artifact descriptor reader cannot be null" ); return this; } - public DefaultDependencyCollector setVersionRangeResolver( VersionRangeResolver versionRangeResolver ) + public DfDependencyCollector setVersionRangeResolver( VersionRangeResolver versionRangeResolver ) { this.versionRangeResolver = requireNonNull( versionRangeResolver, "version range resolver cannot be null" ); @@ -248,34 +252,23 @@ public class DefaultDependencyCollector { DataPool pool = new DataPool( session ); + NodeStack + nodes = new NodeStack(); + nodes.push( node ); + DefaultDependencyCollectionContext context = new DefaultDependencyCollectionContext( session, request.getRootArtifact(), root, managedDependencies ); DefaultVersionFilterContext versionContext = new DefaultVersionFilterContext( session ); - Args args = new Args( session, trace, pool, context, versionContext, request ); + Args args = new Args( session, trace, pool, nodes, context, versionContext, request ); Results results = new Results( result, session ); - DependencySelector rootDepSelector = - depSelector != null ? depSelector.deriveChildSelector( context ) : null; - DependencyManager rootDepManager = depManager != null ? depManager.deriveChildManager( context ) : null; - DependencyTraverser rootDepTraverser = - depTraverser != null ? depTraverser.deriveChildTraverser( context ) : null; - VersionFilter rootVerFilter = verFilter != null ? verFilter.deriveChildFilter( context ) : null; - - for ( Dependency dependency : dependencies ) - { - args.dependencyProcessingQueue.add( - new DependencyProcessingContext( rootDepSelector, rootDepManager, rootDepTraverser, - rootVerFilter, repositories, managedDependencies, Collections.singletonList( node ), - dependency ) ); - } - - while ( !args.dependencyProcessingQueue.isEmpty() ) - { - processDependency( args, results, args.dependencyProcessingQueue.remove(), Collections.emptyList(), - false ); - } + process( args, results, dependencies, repositories, + depSelector != null ? depSelector.deriveChildSelector( context ) : null, + depManager != null ? depManager.deriveChildManager( context ) : null, + depTraverser != null ? depTraverser.deriveChildTraverser( context ) : null, + verFilter != null ? verFilter.deriveChildFilter( context ) : null ); errorPath = results.errorPath; } @@ -360,39 +353,61 @@ public class DefaultDependencyCollector } @SuppressWarnings( "checkstyle:parameternumber" ) - private void processDependency( Args args, Results results, DependencyProcessingContext context, + private void process( final Args args, Results results, List<Dependency> dependencies, + List<RemoteRepository> repositories, DependencySelector depSelector, + DependencyManager depManager, DependencyTraverser depTraverser, VersionFilter verFilter ) + { + for ( Dependency dependency : dependencies ) + { + processDependency( args, results, repositories, depSelector, depManager, depTraverser, verFilter, + dependency ); + } + } + + @SuppressWarnings( "checkstyle:parameternumber" ) + private void processDependency( Args args, Results results, List<RemoteRepository> repositories, + DependencySelector depSelector, DependencyManager depManager, + DependencyTraverser depTraverser, VersionFilter verFilter, Dependency dependency ) + { + + List<Artifact> relocations = Collections.emptyList(); + processDependency( args, results, repositories, depSelector, depManager, depTraverser, verFilter, dependency, + relocations, false ); + } + + @SuppressWarnings( "checkstyle:parameternumber" ) + private void processDependency( Args args, Results results, List<RemoteRepository> repositories, + DependencySelector depSelector, DependencyManager depManager, + DependencyTraverser depTraverser, VersionFilter verFilter, Dependency dependency, List<Artifact> relocations, boolean disableVersionManagement ) { - if ( context.depSelector != null && !context.depSelector.selectDependency( context.dependency ) ) + if ( depSelector != null && !depSelector.selectDependency( dependency ) ) { return; } PremanagedDependency preManaged = - PremanagedDependency.create( context.depManager, context.dependency, disableVersionManagement, - args.premanagedState ); - Dependency dependency = preManaged.managedDependency; + PremanagedDependency.create( depManager, dependency, disableVersionManagement, args.premanagedState ); + dependency = preManaged.managedDependency; boolean noDescriptor = isLackingDescriptor( dependency.getArtifact() ); - boolean traverse = - !noDescriptor && ( context.depTraverser == null || context.depTraverser.traverseDependency( - dependency ) ); + boolean traverse = !noDescriptor && ( depTraverser == null || depTraverser.traverseDependency( dependency ) ); List<? extends Version> versions; VersionRangeResult rangeResult; try { - VersionRangeRequest rangeRequest = createVersionRangeRequest( args, context.repositories, dependency ); + VersionRangeRequest rangeRequest = createVersionRangeRequest( args, repositories, dependency ); rangeResult = cachedResolveRangeResult( rangeRequest, args.pool, args.session ); - versions = filterVersions( dependency, rangeResult, context.verFilter, args.versionContext ); + versions = filterVersions( dependency, rangeResult, verFilter, args.versionContext ); } catch ( VersionRangeResolutionException e ) { - results.addException( dependency, e, context.parents ); + results.addException( dependency, e, args.nodes ); return; } @@ -401,30 +416,27 @@ public class DefaultDependencyCollector Artifact originalArtifact = dependency.getArtifact().setVersion( version.toString() ); Dependency d = dependency.setArtifact( originalArtifact ); - ArtifactDescriptorRequest descriptorRequest = - createArtifactDescriptorRequest( args, context.repositories, d ); + ArtifactDescriptorRequest descriptorRequest = createArtifactDescriptorRequest( args, repositories, d ); final ArtifactDescriptorResult descriptorResult = - noDescriptor - ? new ArtifactDescriptorResult( descriptorRequest ) - : resolveCachedArtifactDescriptor( args.pool, descriptorRequest, args.session, - context.withDependency( d ), results ); - + getArtifactDescriptorResult( args, results, noDescriptor, d, descriptorRequest ); if ( descriptorResult != null ) { d = d.setArtifact( descriptorResult.getArtifact() ); - int cycleEntry = find( context.parents, d.getArtifact() ); + DependencyNode node = args.nodes.top(); + + int cycleEntry = args.nodes.find( d.getArtifact() ); if ( cycleEntry >= 0 ) { - results.addCycle( context.parents, cycleEntry, d ); - DependencyNode cycleNode = context.parents.get( cycleEntry ); + results.addCycle( args.nodes, cycleEntry, d ); + DependencyNode cycleNode = args.nodes.get( cycleEntry ); if ( cycleNode.getDependency() != null ) { DefaultDependencyNode child = - createDependencyNode( relocations, preManaged, rangeResult, version, d, - descriptorResult, cycleNode ); - context.getParent().getChildren().add( child ); + createDependencyNode( relocations, preManaged, rangeResult, version, d, descriptorResult, + cycleNode ); + node.getChildren().add( child ); continue; } } @@ -435,8 +447,8 @@ public class DefaultDependencyCollector originalArtifact.getGroupId().equals( d.getArtifact().getGroupId() ) && originalArtifact.getArtifactId().equals( d.getArtifact().getArtifactId() ); - processDependency( args, results, context.withDependency( d ), descriptorResult.getRelocations(), - disableVersionManagementSubsequently ); + processDependency( args, results, repositories, depSelector, depManager, depTraverser, verFilter, d, + descriptorResult.getRelocations(), disableVersionManagementSubsequently ); return; } else @@ -444,72 +456,69 @@ public class DefaultDependencyCollector d = args.pool.intern( d.setArtifact( args.pool.intern( d.getArtifact() ) ) ); List<RemoteRepository> repos = - getRemoteRepositories( rangeResult.getRepository( version ), context.repositories ); + getRemoteRepositories( rangeResult.getRepository( version ), repositories ); DefaultDependencyNode child = createDependencyNode( relocations, preManaged, rangeResult, version, d, descriptorResult.getAliases(), repos, args.request.getRequestContext() ); - context.getParent().getChildren().add( child ); + node.getChildren().add( child ); boolean recurse = traverse && !descriptorResult.getDependencies().isEmpty(); if ( recurse ) { - doRecurse( args, context.withDependency( d ), descriptorResult, child ); + doRecurse( args, results, repositories, depSelector, depManager, depTraverser, verFilter, d, + descriptorResult, child ); } } } else { + DependencyNode node = args.nodes.top(); List<RemoteRepository> repos = - getRemoteRepositories( rangeResult.getRepository( version ), context.repositories ); + getRemoteRepositories( rangeResult.getRepository( version ), repositories ); DefaultDependencyNode child = createDependencyNode( relocations, preManaged, rangeResult, version, d, null, repos, args.request.getRequestContext() ); - context.getParent().getChildren().add( child ); + node.getChildren().add( child ); } } } @SuppressWarnings( "checkstyle:parameternumber" ) - private void doRecurse( Args args, DependencyProcessingContext parentContext, + private void doRecurse( Args args, Results results, List<RemoteRepository> repositories, + DependencySelector depSelector, DependencyManager depManager, + DependencyTraverser depTraverser, VersionFilter verFilter, Dependency d, ArtifactDescriptorResult descriptorResult, DefaultDependencyNode child ) { DefaultDependencyCollectionContext context = args.collectionContext; - context.set( parentContext.dependency, descriptorResult.getManagedDependencies() ); + context.set( d, descriptorResult.getManagedDependencies() ); - DependencySelector childSelector = - parentContext.depSelector != null ? parentContext.depSelector.deriveChildSelector( context ) : null; - DependencyManager childManager = - parentContext.depManager != null ? parentContext.depManager.deriveChildManager( context ) : null; - DependencyTraverser childTraverser = - parentContext.depTraverser != null ? parentContext.depTraverser.deriveChildTraverser( context ) : null; - VersionFilter childFilter = - parentContext.verFilter != null ? parentContext.verFilter.deriveChildFilter( context ) : null; + DependencySelector childSelector = depSelector != null ? depSelector.deriveChildSelector( context ) : null; + DependencyManager childManager = depManager != null ? depManager.deriveChildManager( context ) : null; + DependencyTraverser childTraverser = depTraverser != null ? depTraverser.deriveChildTraverser( context ) : null; + VersionFilter childFilter = verFilter != null ? verFilter.deriveChildFilter( context ) : null; final List<RemoteRepository> childRepos = - args.ignoreRepos - ? parentContext.repositories - : remoteRepositoryManager.aggregateRepositories( args.session, parentContext.repositories, - descriptorResult.getRepositories(), true ); + args.ignoreRepos + ? repositories + : remoteRepositoryManager.aggregateRepositories( args.session, repositories, + descriptorResult.getRepositories(), true ); Object key = - args.pool.toKey( parentContext.dependency.getArtifact(), childRepos, childSelector, childManager, - childTraverser, childFilter ); + args.pool.toKey( d.getArtifact(), childRepos, childSelector, childManager, childTraverser, childFilter ); List<DependencyNode> children = args.pool.getChildren( key ); if ( children == null ) { args.pool.putChildren( key, child.getChildren() ); - List<DependencyNode> parents = new ArrayList<>( parentContext.parents ); - parents.add( child ); - for ( Dependency dependency : descriptorResult.getDependencies() ) - { - args.dependencyProcessingQueue.add( - new DependencyProcessingContext( childSelector, childManager, childTraverser, childFilter, - childRepos, descriptorResult.getManagedDependencies(), parents, dependency ) ); - } + args.nodes.push( child ); + + process( args, results, descriptorResult.getDependencies(), childRepos, childSelector, childManager, + childTraverser, childFilter ); + + args.nodes.pop(); } else { @@ -517,11 +526,20 @@ public class DefaultDependencyCollector } } + private ArtifactDescriptorResult getArtifactDescriptorResult( Args args, Results results, boolean noDescriptor, + Dependency d, + ArtifactDescriptorRequest descriptorRequest ) + { + return noDescriptor + ? new ArtifactDescriptorResult( descriptorRequest ) + : resolveCachedArtifactDescriptor( args.pool, descriptorRequest, args.session, d, results, args ); + + } + private ArtifactDescriptorResult resolveCachedArtifactDescriptor( DataPool pool, ArtifactDescriptorRequest descriptorRequest, - RepositorySystemSession session, - DependencyProcessingContext context, - Results results ) + RepositorySystemSession session, Dependency d, + Results results, Args args ) { Object key = pool.toKey( descriptorRequest ); ArtifactDescriptorResult descriptorResult = pool.getDescriptor( key, descriptorRequest ); @@ -534,7 +552,7 @@ public class DefaultDependencyCollector } catch ( ArtifactDescriptorException e ) { - results.addException( context.dependency, e, context.parents ); + results.addException( d, e, args.nodes ); pool.putDescriptor( key, e ); return null; } @@ -689,7 +707,7 @@ public class DefaultDependencyCollector final DataPool pool; - final Queue<DependencyProcessingContext> dependencyProcessingQueue = new ArrayDeque<>(); + final NodeStack nodes; final DefaultDependencyCollectionContext collectionContext; @@ -697,7 +715,7 @@ public class DefaultDependencyCollector final CollectRequest request; - Args( RepositorySystemSession session, RequestTrace trace, DataPool pool, + Args( RepositorySystemSession session, RequestTrace trace, DataPool pool, NodeStack nodes, DefaultDependencyCollectionContext collectionContext, DefaultVersionFilterContext versionContext, CollectRequest request ) { @@ -707,6 +725,7 @@ public class DefaultDependencyCollector this.premanagedState = ConfigUtils.getBoolean( session, false, DependencyManagerUtils.CONFIG_PROP_VERBOSE ); this.trace = trace; this.pool = pool; + this.nodes = nodes; this.collectionContext = collectionContext; this.versionContext = versionContext; } @@ -734,7 +753,7 @@ public class DefaultDependencyCollector maxCycles = ConfigUtils.getInteger( session, CONFIG_PROP_MAX_CYCLES_DEFAULT, CONFIG_PROP_MAX_CYCLES ); } - public void addException( Dependency dependency, Exception e, List<DependencyNode> nodes ) + public void addException( Dependency dependency, Exception e, NodeStack nodes ) { if ( maxExceptions < 0 || result.getExceptions().size() < maxExceptions ) { @@ -742,13 +761,13 @@ public class DefaultDependencyCollector if ( errorPath == null ) { StringBuilder buffer = new StringBuilder( 256 ); - for ( DependencyNode node : nodes ) + for ( int i = 0; i < nodes.size(); i++ ) { if ( buffer.length() > 0 ) { buffer.append( " -> " ); } - Dependency dep = node.getDependency(); + Dependency dep = nodes.get( i ).getDependency(); if ( dep != null ) { buffer.append( dep.getArtifact() ); @@ -764,11 +783,11 @@ public class DefaultDependencyCollector } } - public void addCycle( List<DependencyNode> nodes, int cycleEntry, Dependency dependency ) + public void addCycle( NodeStack nodes, int cycleEntry, Dependency dependency ) { if ( maxCycles < 0 || result.getCycles().size() < maxCycles ) { - result.addCycle( new DefaultDependencyCycle( nodes, cycleEntry, dependency ) ); + result.addCycle( new DfDependencyCycle( nodes, cycleEntry, dependency ) ); } } diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCycle.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/df/DfDependencyCycle.java similarity index 57% rename from maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCycle.java rename to maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/df/DfDependencyCycle.java index dd1565c..b0ff519 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCycle.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/df/DfDependencyCycle.java @@ -1,4 +1,4 @@ -package org.eclipse.aether.internal.impl.collect; +package org.eclipse.aether.internal.impl.collect.df; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -23,16 +23,15 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.graph.Dependency; import org.eclipse.aether.graph.DependencyCycle; import org.eclipse.aether.graph.DependencyNode; import org.eclipse.aether.util.artifact.ArtifactIdUtils; /** - * @see DefaultDependencyCollector + * @see DfDependencyCollector */ -final class DefaultDependencyCycle +final class DfDependencyCycle implements DependencyCycle { @@ -40,7 +39,7 @@ final class DefaultDependencyCycle private final int cycleEntry; - DefaultDependencyCycle( List<DependencyNode> nodes, int cycleEntry, Dependency dependency ) + DfDependencyCycle( NodeStack nodes, int cycleEntry, Dependency dependency ) { // skip root node unless it actually has a dependency or is considered the cycle entry (due to its label) int offset = ( cycleEntry > 0 && nodes.get( 0 ).getDependency() == null ) ? 1 : 0; @@ -70,58 +69,6 @@ final class DefaultDependencyCycle return dependencies.subList( cycleEntry, dependencies.size() ); } - /** - * Searches for a node associated with the given artifact. A version of the artifact is not considered during the - * search. - * - * @param nodes a list representing single path in the dependency graph. First element is the root. - * @param artifact to find among the parent nodes. - * @return the index of the node furthest from the root and associated with the given artifact, or {@literal -1} if - * there is no such node. - */ - public static int find( List<DependencyNode> nodes, Artifact artifact ) - { - - for ( int i = nodes.size() - 1; i >= 0; i-- ) - { - DependencyNode node = nodes.get( i ); - - Artifact a = node.getArtifact(); - if ( a == null ) - { - break; - } - - if ( !a.getArtifactId().equals( artifact.getArtifactId() ) ) - { - continue; - } - if ( !a.getGroupId().equals( artifact.getGroupId() ) ) - { - continue; - } - if ( !a.getExtension().equals( artifact.getExtension() ) ) - { - continue; - } - if ( !a.getClassifier().equals( artifact.getClassifier() ) ) - { - continue; - } - /* - * NOTE: While a:1 and a:2 are technically different artifacts, we want to consider the path a:2 -> b:2 -> - * a:1 a cycle in the current context. The artifacts themselves might not form a cycle but their producing - * projects surely do. Furthermore, conflict resolution will always have to consider a:1 a loser (otherwise - * its ancestor a:2 would get pruned and so would a:1) so there is no point in building the sub graph of - * a:1. - */ - - return i; - } - - return -1; - } - @Override public String toString() { diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/df/NodeStack.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/df/NodeStack.java new file mode 100644 index 0000000..81123c1 --- /dev/null +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/collect/df/NodeStack.java @@ -0,0 +1,127 @@ +package org.eclipse.aether.internal.impl.collect.df; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.Arrays; + +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.graph.DependencyNode; + +/** + * @see DfDependencyCollector + */ +final class NodeStack +{ + + @SuppressWarnings( {"unchecked", "checkstyle:magicnumber" } ) + // CHECKSTYLE_OFF: MagicNumber + private DependencyNode[] nodes = new DependencyNode[96]; + // CHECKSTYLE_ON: MagicNumber + + private int size; + + public DependencyNode top() + { + if ( size <= 0 ) + { + throw new IllegalStateException( "stack empty" ); + } + return nodes[size - 1]; + } + + public void push( DependencyNode node ) + { + if ( size >= nodes.length ) + { + DependencyNode[] tmp = new DependencyNode[size + 64]; + System.arraycopy( nodes, 0, tmp, 0, nodes.length ); + nodes = tmp; + } + nodes[size++] = node; + } + + public void pop() + { + if ( size <= 0 ) + { + throw new IllegalStateException( "stack empty" ); + } + size--; + } + + public int find( Artifact artifact ) + { + for ( int i = size - 1; i >= 0; i-- ) + { + DependencyNode node = nodes[i]; + + Artifact a = node.getArtifact(); + if ( a == null ) + { + break; + } + + if ( !a.getArtifactId().equals( artifact.getArtifactId() ) ) + { + continue; + } + if ( !a.getGroupId().equals( artifact.getGroupId() ) ) + { + continue; + } + if ( !a.getExtension().equals( artifact.getExtension() ) ) + { + continue; + } + if ( !a.getClassifier().equals( artifact.getClassifier() ) ) + { + continue; + } + /* + * NOTE: While a:1 and a:2 are technically different artifacts, we want to consider the path a:2 -> b:2 -> + * a:1 a cycle in the current context. The artifacts themselves might not form a cycle but their producing + * projects surely do. Furthermore, conflict resolution will always have to consider a:1 a loser (otherwise + * its ancestor a:2 would get pruned and so would a:1) so there is no point in building the sub graph of + * a:1. + */ + + return i; + } + + return -1; + } + + public int size() + { + return size; + } + + public DependencyNode get( int index ) + { + return nodes[index]; + } + + @Override + public String toString() + { + return Arrays.toString( nodes ); + } + +} diff --git a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectorTest.java b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/bf/BfDependencyCollectorTest.java similarity index 99% copy from maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectorTest.java copy to maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/bf/BfDependencyCollectorTest.java index 5d4c2aa..fcae807 100644 --- a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectorTest.java +++ b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/bf/BfDependencyCollectorTest.java @@ -1,4 +1,4 @@ -package org.eclipse.aether.internal.impl.collect; +package org.eclipse.aether.internal.impl.collect.bf; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -18,14 +18,6 @@ package org.eclipse.aether.internal.impl.collect; * specific language governing permissions and limitations * under the License. */ -import static java.util.Objects.requireNonNull; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import java.io.IOException; import java.util.ArrayList; @@ -73,12 +65,21 @@ import org.eclipse.aether.util.graph.version.HighestVersionFilter; import org.junit.Before; import org.junit.Test; +import static java.util.Objects.requireNonNull; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + /** */ -public class DefaultDependencyCollectorTest +public class BfDependencyCollectorTest { - private DefaultDependencyCollector collector; + private BfDependencyCollector collector; private DefaultRepositorySystemSession session; @@ -106,7 +107,7 @@ public class DefaultDependencyCollectorTest { session = TestUtils.newSession(); - collector = new DefaultDependencyCollector(); + collector = new BfDependencyCollector(); collector.setArtifactDescriptorReader( newReader( "" ) ); collector.setVersionRangeResolver( new StubVersionRangeResolver() ); collector.setRemoteRepositoryManager( new StubRemoteRepositoryManager() ); diff --git a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCycleTest.java b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/bf/BfDependencyCycleTest.java similarity index 90% copy from maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCycleTest.java copy to maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/bf/BfDependencyCycleTest.java index 0a382f8..a1be7c9 100644 --- a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCycleTest.java +++ b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/bf/BfDependencyCycleTest.java @@ -1,4 +1,4 @@ -package org.eclipse.aether.internal.impl.collect; +package org.eclipse.aether.internal.impl.collect.bf; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,6 +19,9 @@ package org.eclipse.aether.internal.impl.collect; * under the License. */ +import java.util.ArrayList; +import java.util.List; + import org.eclipse.aether.artifact.DefaultArtifact; import org.eclipse.aether.graph.DefaultDependencyNode; import org.eclipse.aether.graph.Dependency; @@ -26,12 +29,9 @@ import org.eclipse.aether.graph.DependencyCycle; import org.eclipse.aether.graph.DependencyNode; import org.junit.Test; -import java.util.ArrayList; -import java.util.List; - import static org.junit.Assert.assertEquals; -public class DefaultDependencyCycleTest +public class BfDependencyCycleTest { private static final Dependency FOO_DEPENDENCY = new Dependency( new DefaultArtifact( "group-id:foo:1.0" ), "test" ); private static final Dependency BAR_DEPENDENCY = new Dependency( new DefaultArtifact( "group-id:bar:1.0" ), "test" ); @@ -41,7 +41,7 @@ public class DefaultDependencyCycleTest { List<DependencyNode> nodes = new ArrayList<>(); nodes.add( new DefaultDependencyNode( FOO_DEPENDENCY ) ); - DependencyCycle cycle = new DefaultDependencyCycle( nodes, 1, BAR_DEPENDENCY ); + DependencyCycle cycle = new BfDependencyCycle( nodes, 1, BAR_DEPENDENCY ); assertEquals( "group-id:foo:jar -> group-id:bar:jar", cycle.toString() ); } diff --git a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectorTest.java b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/df/DfDependencyCollectorTest.java similarity index 99% rename from maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectorTest.java rename to maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/df/DfDependencyCollectorTest.java index 5d4c2aa..61d6e09 100644 --- a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCollectorTest.java +++ b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/df/DfDependencyCollectorTest.java @@ -1,4 +1,4 @@ -package org.eclipse.aether.internal.impl.collect; +package org.eclipse.aether.internal.impl.collect.df; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -18,14 +18,6 @@ package org.eclipse.aether.internal.impl.collect; * specific language governing permissions and limitations * under the License. */ -import static java.util.Objects.requireNonNull; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import java.io.IOException; import java.util.ArrayList; @@ -58,6 +50,7 @@ import org.eclipse.aether.impl.ArtifactDescriptorReader; import org.eclipse.aether.internal.impl.IniArtifactDescriptorReader; import org.eclipse.aether.internal.impl.StubRemoteRepositoryManager; import org.eclipse.aether.internal.impl.StubVersionRangeResolver; +import org.eclipse.aether.internal.impl.collect.DefaultDependencyCollector; import org.eclipse.aether.internal.test.util.DependencyGraphParser; import org.eclipse.aether.internal.test.util.TestUtils; import org.eclipse.aether.repository.RemoteRepository; @@ -73,12 +66,21 @@ import org.eclipse.aether.util.graph.version.HighestVersionFilter; import org.junit.Before; import org.junit.Test; +import static java.util.Objects.requireNonNull; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + /** */ -public class DefaultDependencyCollectorTest +public class DfDependencyCollectorTest { - private DefaultDependencyCollector collector; + private DfDependencyCollector collector; private DefaultRepositorySystemSession session; @@ -106,7 +108,7 @@ public class DefaultDependencyCollectorTest { session = TestUtils.newSession(); - collector = new DefaultDependencyCollector(); + collector = new DfDependencyCollector(); collector.setArtifactDescriptorReader( newReader( "" ) ); collector.setVersionRangeResolver( new StubVersionRangeResolver() ); collector.setRemoteRepositoryManager( new StubRemoteRepositoryManager() ); diff --git a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCycleTest.java b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/df/DfDependencyCycleTest.java similarity index 78% rename from maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCycleTest.java rename to maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/df/DfDependencyCycleTest.java index 0a382f8..0cc8a7d 100644 --- a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/DefaultDependencyCycleTest.java +++ b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/collect/df/DfDependencyCycleTest.java @@ -1,4 +1,4 @@ -package org.eclipse.aether.internal.impl.collect; +package org.eclipse.aether.internal.impl.collect.df; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -23,15 +23,11 @@ import org.eclipse.aether.artifact.DefaultArtifact; import org.eclipse.aether.graph.DefaultDependencyNode; import org.eclipse.aether.graph.Dependency; import org.eclipse.aether.graph.DependencyCycle; -import org.eclipse.aether.graph.DependencyNode; import org.junit.Test; -import java.util.ArrayList; -import java.util.List; - import static org.junit.Assert.assertEquals; -public class DefaultDependencyCycleTest +public class DfDependencyCycleTest { private static final Dependency FOO_DEPENDENCY = new Dependency( new DefaultArtifact( "group-id:foo:1.0" ), "test" ); private static final Dependency BAR_DEPENDENCY = new Dependency( new DefaultArtifact( "group-id:bar:1.0" ), "test" ); @@ -39,9 +35,10 @@ public class DefaultDependencyCycleTest @Test public void testToString() { - List<DependencyNode> nodes = new ArrayList<>(); - nodes.add( new DefaultDependencyNode( FOO_DEPENDENCY ) ); - DependencyCycle cycle = new DefaultDependencyCycle( nodes, 1, BAR_DEPENDENCY ); + org.eclipse.aether.internal.impl.collect.df.NodeStack + nodeStack = new org.eclipse.aether.internal.impl.collect.df.NodeStack(); + nodeStack.push( new DefaultDependencyNode( FOO_DEPENDENCY ) ); + DependencyCycle cycle = new DfDependencyCycle( nodeStack, 1, BAR_DEPENDENCY ); assertEquals( "group-id:foo:jar -> group-id:bar:jar", cycle.toString() ); }