From 80cadf4b910cd3f8b649342ef84477c6b24be4c2 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Mon, 24 Jan 2022 21:10:09 +0100 Subject: [PATCH] [MSHARED-1071] Drop maven 3.0 compatibility, Maven 3.2.5, Injects --- pom.xml | 53 +- src/it/settings.xml | 6 +- src/it/setup-extension/pom.xml | 6 +- src/it/setup-plugin/pom.xml | 12 +- .../graph/internal/ArtifactKey.java | 72 - .../DefaultDependencyCollectorBuilder.java | 264 +++- .../DefaultDependencyGraphBuilder.java | 174 ++- ...ava => DirectScopeDependencySelector.java} | 12 +- .../graph/internal/ExceptionHandler.java | 30 - .../dependency/graph/internal/Invoker.java | 97 -- .../Maven31DependencyCollectorBuilder.java | 315 ---- .../Maven31DependencyGraphBuilder.java | 199 --- .../Maven3DependencyCollectorBuilder.java | 322 ---- .../Maven3DependencyGraphBuilder.java | 155 -- .../VerboseJavaScopeSelector.java | 2 +- .../internal/maven30/ConflictIdSorter.java | 370 ----- .../internal/maven30/ConflictResolver.java | 1314 ----------------- .../maven30/ExclusionDependencySelector.java | 228 --- .../internal/maven30/JavaScopeDeriver.java | 72 - .../internal/maven30/JavaScopeSelector.java | 102 -- .../Maven3DirectScopeDependencySelector.java | 132 -- .../maven30/NearestVersionSelector.java | 176 --- .../maven30/SimpleOptionalitySelector.java | 64 - .../maven30/VerboseJavaScopeSelector.java | 64 - src/site/apt/index.apt.vm | 8 +- 25 files changed, 373 insertions(+), 3876 deletions(-) delete mode 100644 src/main/java/org/apache/maven/shared/dependency/graph/internal/ArtifactKey.java rename src/main/java/org/apache/maven/shared/dependency/graph/internal/{maven31/Maven31DirectScopeDependencySelector.java => DirectScopeDependencySelector.java} (89%) delete mode 100644 src/main/java/org/apache/maven/shared/dependency/graph/internal/ExceptionHandler.java delete mode 100644 src/main/java/org/apache/maven/shared/dependency/graph/internal/Invoker.java delete mode 100644 src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven31DependencyCollectorBuilder.java delete mode 100644 src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven31DependencyGraphBuilder.java delete mode 100644 src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven3DependencyCollectorBuilder.java delete mode 100644 src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven3DependencyGraphBuilder.java rename src/main/java/org/apache/maven/shared/dependency/graph/internal/{maven31 => }/VerboseJavaScopeSelector.java (97%) delete mode 100644 src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/ConflictIdSorter.java delete mode 100644 src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/ConflictResolver.java delete mode 100644 src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/ExclusionDependencySelector.java delete mode 100644 src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/JavaScopeDeriver.java delete mode 100644 src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/JavaScopeSelector.java delete mode 100644 src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/Maven3DirectScopeDependencySelector.java delete mode 100644 src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/NearestVersionSelector.java delete mode 100644 src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/SimpleOptionalitySelector.java delete mode 100644 src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/VerboseJavaScopeSelector.java diff --git a/pom.xml b/pom.xml index f55a76d..35d6f9f 100644 --- a/pom.xml +++ b/pom.xml @@ -56,6 +56,8 @@ 8 + 3.2.5 + 1.0.0.v20140518 2022-05-14T10:50:43Z @@ -69,51 +71,38 @@ org.apache.maven maven-core - 3.0.5 - - - org.codehaus.plexus - plexus-component-annotations - true - - - org.sonatype.aether - aether-api - 1.13.1 - true + ${mavenVersion} + provided org.eclipse.aether aether-api - 1.1.0 - true + ${resolverVersion} + provided org.eclipse.aether aether-util - 1.1.0 - - - org.eclipse.aether - aether-api - - + ${resolverVersion} + + + org.slf4j + slf4j-api + 1.7.36 + + + javax.inject + javax.inject + 1 + true - org.codehaus.plexus - plexus-component-metadata - 2.1.1 - - - - generate-metadata - - - + org.eclipse.sisu + sisu-maven-plugin org.apache.rat @@ -128,7 +117,7 @@ - check + rat-check check diff --git a/src/it/settings.xml b/src/it/settings.xml index c8f77f0..543ff45 100644 --- a/src/it/settings.xml +++ b/src/it/settings.xml @@ -23,9 +23,6 @@ under the License. it-repo - - true - local.central @@ -52,4 +49,7 @@ under the License. + + it-repo + diff --git a/src/it/setup-extension/pom.xml b/src/it/setup-extension/pom.xml index f71bd43..1d8fa19 100644 --- a/src/it/setup-extension/pom.xml +++ b/src/it/setup-extension/pom.xml @@ -35,17 +35,13 @@ UTF-8 - 3.0.4 - - - org.apache.maven maven-core - ${maven.version} + @mavenVersion@ provided diff --git a/src/it/setup-plugin/pom.xml b/src/it/setup-plugin/pom.xml index 1a0098a..005835c 100644 --- a/src/it/setup-plugin/pom.xml +++ b/src/it/setup-plugin/pom.xml @@ -37,13 +37,7 @@ org.apache.maven.plugins maven-plugin-plugin - 3.6.1 - - - default-descriptor - process-classes - - + @maven.plugin.tools.version@ @@ -57,13 +51,13 @@ org.apache.maven.plugin-tools maven-plugin-annotations - 3.5.2 + @maven.plugin.tools.version@ provided org.apache.maven maven-core - 3.0.5 + @mavenVersion@ provided diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/ArtifactKey.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/ArtifactKey.java deleted file mode 100644 index 40f9f3c..0000000 --- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/ArtifactKey.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.apache.maven.shared.dependency.graph.internal; - -/* - * 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.Objects; - -import org.apache.maven.project.MavenProject; - -/** - * Uniquely defines an artifact by groupId, artifactId and version. - */ -final class ArtifactKey -{ - private final String groupId; - private final String artifactId; - private final String version; - private final int hashCode; - - ArtifactKey( String groupId, String artifactId, String version ) - { - this.groupId = groupId; - this.artifactId = artifactId; - this.version = version; - this.hashCode = Objects.hash( groupId, artifactId, version ); - } - - ArtifactKey( MavenProject project ) - { - this( project.getGroupId(), project.getArtifactId(), project.getVersion() ); - } - - @Override - public boolean equals( Object o ) - { - if ( this == o ) - { - return true; - } - - if ( !( o instanceof ArtifactKey ) ) - { - return false; - } - - ArtifactKey that = (ArtifactKey) o; - - return artifactId.equals( that.artifactId ) && groupId.equals( that.groupId ) && version.equals( that.version ); - } - - @Override - public int hashCode() - { - return hashCode; - } -} diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/DefaultDependencyCollectorBuilder.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/DefaultDependencyCollectorBuilder.java index cddf101..5b0218d 100644 --- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/DefaultDependencyCollectorBuilder.java +++ b/src/main/java/org/apache/maven/shared/dependency/graph/internal/DefaultDependencyCollectorBuilder.java @@ -19,92 +19,262 @@ * under the License. */ +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.inject.Inject; +import javax.inject.Named; + +import org.apache.maven.RepositoryUtils; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; -import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.Dependency; import org.apache.maven.project.MavenProject; import org.apache.maven.project.ProjectBuildingRequest; import org.apache.maven.shared.dependency.graph.DependencyCollectorBuilder; import org.apache.maven.shared.dependency.graph.DependencyCollectorBuilderException; import org.apache.maven.shared.dependency.graph.DependencyNode; -import org.codehaus.plexus.PlexusConstants; -import org.codehaus.plexus.PlexusContainer; -import org.codehaus.plexus.component.annotations.Component; -import org.codehaus.plexus.component.repository.exception.ComponentLookupException; -import org.codehaus.plexus.context.Context; -import org.codehaus.plexus.context.ContextException; -import org.codehaus.plexus.logging.AbstractLogEnabled; -import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable; +import org.eclipse.aether.DefaultRepositorySystemSession; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.ArtifactTypeRegistry; +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.DependencySelector; +import org.eclipse.aether.graph.DependencyVisitor; +import org.eclipse.aether.graph.Exclusion; +import org.eclipse.aether.util.artifact.JavaScopes; +import org.eclipse.aether.util.graph.manager.DependencyManagerUtils; +import org.eclipse.aether.util.graph.selector.AndDependencySelector; +import org.eclipse.aether.util.graph.selector.ExclusionDependencySelector; +import org.eclipse.aether.util.graph.selector.OptionalDependencySelector; +import org.eclipse.aether.util.graph.transformer.ConflictResolver; +import org.eclipse.aether.util.graph.transformer.JavaScopeDeriver; +import org.eclipse.aether.util.graph.transformer.NearestVersionSelector; +import org.eclipse.aether.util.graph.transformer.SimpleOptionalitySelector; +import org.eclipse.aether.util.graph.visitor.TreeDependencyVisitor; +import org.eclipse.aether.version.VersionConstraint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * Default project dependency raw dependency collector API, providing an abstraction layer against Maven 3 and Maven - * 3.1+ particular Aether implementations. + * Project dependency raw dependency collector API, abstracting Maven 3.1+'s Aether implementation. * * @author Gabriel Belingueres * @since 3.1.0 */ -@Component( role = DependencyCollectorBuilder.class ) +@Named public class DefaultDependencyCollectorBuilder - extends AbstractLogEnabled - implements DependencyCollectorBuilder, Contextualizable + implements DependencyCollectorBuilder { - protected PlexusContainer container; + private static final Logger LOGGER = LoggerFactory.getLogger( DefaultDependencyCollectorBuilder.class ); + + private final RepositorySystem repositorySystem; + + @Inject + public DefaultDependencyCollectorBuilder( RepositorySystem repositorySystem ) + { + this.repositorySystem = repositorySystem; + } @Override public DependencyNode collectDependencyGraph( ProjectBuildingRequest buildingRequest, ArtifactFilter filter ) throws DependencyCollectorBuilderException { + DefaultRepositorySystemSession session = null; try { - String hint = isMaven31() ? "maven31" : "maven3"; + MavenProject project = buildingRequest.getProject(); - DependencyCollectorBuilder effectiveGraphBuilder = - (DependencyCollectorBuilder) container.lookup( DependencyCollectorBuilder.class.getCanonicalName(), - hint ); + Artifact projectArtifact = project.getArtifact(); + List remoteArtifactRepositories = project.getRemoteArtifactRepositories(); - if ( getLogger().isDebugEnabled() ) - { - MavenProject project = buildingRequest.getProject(); + RepositorySystemSession repositorySession = buildingRequest.getRepositorySession(); + + session = new DefaultRepositorySystemSession( repositorySession ); + + DependencyGraphTransformer transformer = + new ConflictResolver( new NearestVersionSelector(), new VerboseJavaScopeSelector(), + new SimpleOptionalitySelector(), new JavaScopeDeriver() ); + session.setDependencyGraphTransformer( transformer ); - getLogger().debug( "building " + hint + " RAW dependency tree for " + project.getId() + " with " - + effectiveGraphBuilder.getClass().getSimpleName() ); + DependencySelector depFilter = + new AndDependencySelector( new DirectScopeDependencySelector( JavaScopes.TEST ), + new DirectScopeDependencySelector( JavaScopes.PROVIDED ), + new OptionalDependencySelector(), + new ExclusionDependencySelector() ); + session.setDependencySelector( depFilter ); + + session.setConfigProperty( ConflictResolver.CONFIG_PROP_VERBOSE, true ); + session.setConfigProperty( DependencyManagerUtils.CONFIG_PROP_VERBOSE, true ); + + org.eclipse.aether.artifact.Artifact aetherArtifact = RepositoryUtils.toArtifact( projectArtifact ); + + List aetherRepos = + RepositoryUtils.toRepos( remoteArtifactRepositories ); + + CollectRequest collectRequest = new CollectRequest(); + collectRequest.setRootArtifact( aetherArtifact ); + collectRequest.setRepositories( aetherRepos ); + + org.eclipse.aether.artifact.ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry(); + collectDependencyList( collectRequest, project, stereotypes ); + collectManagedDependencyList( collectRequest, project, stereotypes ); + + CollectResult collectResult = repositorySystem.collectDependencies( session, collectRequest ); + + org.eclipse.aether.graph.DependencyNode rootNode = collectResult.getRoot(); + + if ( LOGGER.isDebugEnabled() ) + { + logTree( rootNode ); } - return effectiveGraphBuilder.collectDependencyGraph( buildingRequest, filter ); + return buildDependencyNode( null, rootNode, projectArtifact, filter ); } - catch ( ComponentLookupException e ) + catch ( DependencyCollectionException e ) { - throw new DependencyCollectorBuilderException( e.getMessage(), e ); + throw new DependencyCollectorBuilderException( "Could not collect dependencies: " + e.getResult(), e ); + } + finally + { + if ( session != null ) + { + session.setReadOnly(); + } } } - /** - * @return true if the current Maven version is Maven 3.1. - */ - protected static boolean isMaven31() + private void logTree( org.eclipse.aether.graph.DependencyNode rootNode ) { - try + // print the node tree with its associated data Map + rootNode.accept( new TreeDependencyVisitor( new DependencyVisitor() { - Class repoSessionClass = MavenSession.class.getMethod( "getRepositorySession" ).getReturnType(); - - return "org.eclipse.aether.RepositorySystemSession".equals( repoSessionClass.getName() ); + String indent = ""; + + @Override + public boolean visitEnter( org.eclipse.aether.graph.DependencyNode dependencyNode ) + { + LOGGER.debug( "{}Aether node: {} data map: {}", indent, dependencyNode, dependencyNode.getData() ); + indent += " "; + return true; + } + + @Override + public boolean visitLeave( org.eclipse.aether.graph.DependencyNode dependencyNode ) + { + indent = indent.substring( 0, indent.length() - 4 ); + return true; + } + } ) ); + } + + private void collectManagedDependencyList( CollectRequest collectRequest, MavenProject project, + ArtifactTypeRegistry stereotypes ) + { + if ( project.getDependencyManagement() != null ) + { + for ( Dependency dependency : project.getDependencyManagement().getDependencies() ) + { + org.eclipse.aether.graph.Dependency aetherDep = RepositoryUtils.toDependency( dependency, stereotypes ); + collectRequest.addManagedDependency( aetherDep ); + } } - catch ( NoSuchMethodException e ) + } + + private void collectDependencyList( CollectRequest collectRequest, MavenProject project, + org.eclipse.aether.artifact.ArtifactTypeRegistry stereotypes ) + { + for ( Dependency dependency : project.getDependencies() ) { - throw new IllegalStateException( "Cannot determine return type of MavenSession.getRepositorySession" ); + org.eclipse.aether.graph.Dependency aetherDep = RepositoryUtils.toDependency( dependency, stereotypes ); + collectRequest.addDependency( aetherDep ); } } - /** - * Injects the Plexus content. - * - * @param context Plexus context to inject. - * @throws ContextException if the PlexusContainer could not be located. - */ - @Override - public void contextualize( Context context ) - throws ContextException + private Artifact getDependencyArtifact( org.eclipse.aether.graph.Dependency dep ) + { + org.eclipse.aether.artifact.Artifact artifact = dep.getArtifact(); + + Artifact mavenArtifact = RepositoryUtils.toArtifact( artifact ); + mavenArtifact.setScope( dep.getScope() ); + mavenArtifact.setOptional( dep.isOptional() ); + + return mavenArtifact; + } + + private DependencyNode buildDependencyNode( DependencyNode parent, org.eclipse.aether.graph.DependencyNode node, + Artifact artifact, ArtifactFilter filter ) { - container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY ); + String premanagedVersion = DependencyManagerUtils.getPremanagedVersion( node ); + String premanagedScope = DependencyManagerUtils.getPremanagedScope( node ); + + Boolean optional = null; + if ( node.getDependency() != null ) + { + optional = node.getDependency().isOptional(); + } + + List exclusions = null; + if ( node.getDependency() != null ) + { + exclusions = new ArrayList<>( node.getDependency().getExclusions().size() ); + for ( Exclusion exclusion : node.getDependency().getExclusions() ) + { + org.apache.maven.model.Exclusion modelExclusion = new org.apache.maven.model.Exclusion(); + modelExclusion.setGroupId( exclusion.getGroupId() ); + modelExclusion.setArtifactId( exclusion.getArtifactId() ); + exclusions.add( modelExclusion ); + } + } + + org.eclipse.aether.graph.DependencyNode winner = + (org.eclipse.aether.graph.DependencyNode) node.getData().get( ConflictResolver.NODE_DATA_WINNER ); + String winnerVersion = null; + String ignoredScope = null; + if ( winner != null ) + { + winnerVersion = winner.getArtifact().getBaseVersion(); + } + else + { + ignoredScope = (String) node.getData().get( VerboseJavaScopeSelector.REDUCED_SCOPE ); + } + + ConflictData data = new ConflictData( winnerVersion, ignoredScope ); + + VerboseDependencyNode current = + new VerboseDependencyNode( parent, artifact, premanagedVersion, premanagedScope, + getVersionSelectedFromRange( node.getVersionConstraint() ), optional, + exclusions, data ); + + List nodes = new ArrayList<>( node.getChildren().size() ); + for ( org.eclipse.aether.graph.DependencyNode child : node.getChildren() ) + { + Artifact childArtifact = getDependencyArtifact( child.getDependency() ); + + if ( ( filter == null ) || filter.include( childArtifact ) ) + { + nodes.add( buildDependencyNode( current, child, childArtifact, filter ) ); + } + } + + current.setChildren( Collections.unmodifiableList( nodes ) ); + + return current; } + private String getVersionSelectedFromRange( VersionConstraint constraint ) + { + if ( ( constraint == null ) || ( constraint.getVersion() != null ) ) + { + return null; + } + + return constraint.getRange().toString(); + } } diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/DefaultDependencyGraphBuilder.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/DefaultDependencyGraphBuilder.java index 84f27f3..599f5a5 100644 --- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/DefaultDependencyGraphBuilder.java +++ b/src/main/java/org/apache/maven/shared/dependency/graph/internal/DefaultDependencyGraphBuilder.java @@ -19,40 +19,57 @@ * under the License. */ +import static org.eclipse.aether.util.graph.manager.DependencyManagerUtils.NODE_DATA_PREMANAGED_VERSION; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.inject.Inject; +import javax.inject.Named; + +import org.apache.maven.RepositoryUtils; +import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; -import org.apache.maven.execution.MavenSession; +import org.apache.maven.project.DefaultDependencyResolutionRequest; +import org.apache.maven.project.DependencyResolutionException; +import org.apache.maven.project.DependencyResolutionRequest; +import org.apache.maven.project.DependencyResolutionResult; import org.apache.maven.project.MavenProject; import org.apache.maven.project.ProjectBuildingRequest; +import org.apache.maven.project.ProjectDependenciesResolver; import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder; import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException; import org.apache.maven.shared.dependency.graph.DependencyNode; -import org.codehaus.plexus.PlexusConstants; -import org.codehaus.plexus.PlexusContainer; -import org.codehaus.plexus.component.annotations.Component; -import org.codehaus.plexus.component.repository.exception.ComponentLookupException; -import org.codehaus.plexus.context.Context; -import org.codehaus.plexus.context.ContextException; -import org.codehaus.plexus.logging.AbstractLogEnabled; -import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable; +import org.eclipse.aether.DefaultRepositorySystemSession; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.graph.DependencyFilter; +import org.eclipse.aether.graph.Exclusion; +import org.eclipse.aether.util.graph.manager.DependencyManagerUtils; +import org.eclipse.aether.version.VersionConstraint; /** - * Default dependency graph builder that detects current Maven version to delegate to either Maven 3.0 or 3.1+ specific - * code. + * Wrapper around Eclipse Aether dependency resolver, used in Maven 3.1. * - * @see Maven3DependencyGraphBuilder - * @see Maven31DependencyGraphBuilder + * @see ProjectDependenciesResolver * @author Hervé Boutemy - * @since 2.0 + * @since 2.1 */ -@Component( role = DependencyGraphBuilder.class ) +@Named public class DefaultDependencyGraphBuilder - extends AbstractLogEnabled - implements DependencyGraphBuilder, Contextualizable + implements DependencyGraphBuilder { - protected PlexusContainer container; + private final ProjectDependenciesResolver resolver; + + @Inject + public DefaultDependencyGraphBuilder( ProjectDependenciesResolver resolver ) + { + this.resolver = resolver; + } /** - * Builds a dependency graph. + * Builds the dependency graph for Maven 3.1+. * * @param buildingRequest the buildingRequest * @param filter artifact filter (can be null) @@ -63,56 +80,105 @@ public class DefaultDependencyGraphBuilder public DependencyNode buildDependencyGraph( ProjectBuildingRequest buildingRequest, ArtifactFilter filter ) throws DependencyGraphBuilderException { - try + MavenProject project = buildingRequest.getProject(); + + RepositorySystemSession session = buildingRequest.getRepositorySession(); + + if ( Boolean.TRUE != session.getConfigProperties().get( NODE_DATA_PREMANAGED_VERSION ) ) { - String hint = isMaven31() ? "maven31" : "maven3"; + DefaultRepositorySystemSession newSession = new DefaultRepositorySystemSession( session ); + newSession.setConfigProperty( NODE_DATA_PREMANAGED_VERSION, true ); + session = newSession; + } - DependencyGraphBuilder effectiveGraphBuilder = - (DependencyGraphBuilder) container.lookup( DependencyGraphBuilder.class.getCanonicalName(), hint ); - - if ( getLogger().isDebugEnabled() ) - { - MavenProject project = buildingRequest.getProject(); - - getLogger().debug( "building " + hint + " dependency graph for " + project.getId() + " with " - + effectiveGraphBuilder.getClass().getSimpleName() ); - } + final DependencyResolutionRequest request = new DefaultDependencyResolutionRequest(); + request.setMavenProject( project ); + request.setRepositorySession( session ); + // only download the poms, not the artifacts + DependencyFilter collectFilter = ( node, parents ) -> false; + request.setResolutionFilter( collectFilter ); + + final DependencyResolutionResult result = resolveDependencies( request ); - return effectiveGraphBuilder.buildDependencyGraph( buildingRequest, filter ); + org.eclipse.aether.graph.DependencyNode graph = result.getDependencyGraph(); + + return buildDependencyNode( null, graph, project.getArtifact(), filter ); + } + + private DependencyResolutionResult resolveDependencies( DependencyResolutionRequest request ) + throws DependencyGraphBuilderException + { + try + { + return resolver.resolve( request ); } - catch ( ComponentLookupException e ) + catch ( DependencyResolutionException e ) { - throw new DependencyGraphBuilderException( e.getMessage(), e ); + throw new DependencyGraphBuilderException( "Could not resolve following dependencies: " + + e.getResult().getUnresolvedDependencies(), e ); } } - /** - * @return true if the current Maven version is Maven 3.1. - */ - protected static boolean isMaven31() + private Artifact getDependencyArtifact( Dependency dep ) { - try + org.eclipse.aether.artifact.Artifact artifact = dep.getArtifact(); + + Artifact mavenArtifact = RepositoryUtils.toArtifact( artifact ); + + mavenArtifact.setScope( dep.getScope() ); + mavenArtifact.setOptional( dep.isOptional() ); + + return mavenArtifact; + } + + private DependencyNode buildDependencyNode( DependencyNode parent, org.eclipse.aether.graph.DependencyNode node, + Artifact artifact, ArtifactFilter filter ) + { + String premanagedVersion = DependencyManagerUtils.getPremanagedVersion( node ); + String premanagedScope = DependencyManagerUtils.getPremanagedScope( node ); + + List exclusions = null; + Boolean optional = null; + if ( node.getDependency() != null ) { - Class repoSessionClass = MavenSession.class.getMethod( "getRepositorySession" ).getReturnType(); - - return "org.eclipse.aether.RepositorySystemSession".equals( repoSessionClass.getName() ); + exclusions = new ArrayList<>( node.getDependency().getExclusions().size() ); + for ( Exclusion exclusion : node.getDependency().getExclusions() ) + { + org.apache.maven.model.Exclusion modelExclusion = new org.apache.maven.model.Exclusion(); + modelExclusion.setGroupId( exclusion.getGroupId() ); + modelExclusion.setArtifactId( exclusion.getArtifactId() ); + exclusions.add( modelExclusion ); + } } - catch ( NoSuchMethodException e ) + + DefaultDependencyNode current = + new DefaultDependencyNode( parent, artifact, premanagedVersion, premanagedScope, + getVersionSelectedFromRange( node.getVersionConstraint() ), + optional, exclusions ); + + List nodes = new ArrayList<>( node.getChildren().size() ); + for ( org.eclipse.aether.graph.DependencyNode child : node.getChildren() ) { - throw new IllegalStateException( "Cannot determine return type of MavenSession.getRepositorySession" ); + Artifact childArtifact = getDependencyArtifact( child.getDependency() ); + + if ( ( filter == null ) || filter.include( childArtifact ) ) + { + nodes.add( buildDependencyNode( current, child, childArtifact, filter ) ); + } } + + current.setChildren( Collections.unmodifiableList( nodes ) ); + + return current; } - /** - * Injects the Plexus content. - * - * @param context Plexus context to inject. - * @throws ContextException if the PlexusContainer could not be located. - */ - @Override - public void contextualize( Context context ) - throws ContextException + private String getVersionSelectedFromRange( VersionConstraint constraint ) { - container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY ); + if ( ( constraint == null ) || ( constraint.getVersion() != null ) ) + { + return null; + } + + return constraint.getRange().toString(); } } diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven31/Maven31DirectScopeDependencySelector.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/DirectScopeDependencySelector.java similarity index 89% rename from src/main/java/org/apache/maven/shared/dependency/graph/internal/maven31/Maven31DirectScopeDependencySelector.java rename to src/main/java/org/apache/maven/shared/dependency/graph/internal/DirectScopeDependencySelector.java index 1ae4cbd..2e6fc0a 100644 --- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven31/Maven31DirectScopeDependencySelector.java +++ b/src/main/java/org/apache/maven/shared/dependency/graph/internal/DirectScopeDependencySelector.java @@ -1,4 +1,4 @@ -package org.apache.maven.shared.dependency.graph.internal.maven31; +package org.apache.maven.shared.dependency.graph.internal; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -31,7 +31,7 @@ * @author Gabriel Belingueres * @since 3.1.0 */ -public class Maven31DirectScopeDependencySelector +public class DirectScopeDependencySelector implements DependencySelector { @@ -39,12 +39,12 @@ public class Maven31DirectScopeDependencySelector private final int depth; - public Maven31DirectScopeDependencySelector( String scope ) + public DirectScopeDependencySelector( String scope ) { this( scope, 0 ); } - private Maven31DirectScopeDependencySelector( String scope, int depth ) + private DirectScopeDependencySelector( String scope, int depth ) { if ( scope == null ) { @@ -82,7 +82,7 @@ public DependencySelector deriveChildSelector( DependencyCollectionContext conte return this; } - return new Maven31DirectScopeDependencySelector( scope, depth + 1 ); + return new DirectScopeDependencySelector( scope, depth + 1 ); } @Override @@ -110,7 +110,7 @@ public boolean equals( Object obj ) { return false; } - Maven31DirectScopeDependencySelector other = (Maven31DirectScopeDependencySelector) obj; + DirectScopeDependencySelector other = (DirectScopeDependencySelector) obj; if ( depth != other.depth ) { return false; diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/ExceptionHandler.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/ExceptionHandler.java deleted file mode 100644 index 2dd86cc..0000000 --- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/ExceptionHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.apache.maven.shared.dependency.graph.internal; - -/* - * 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. - */ - -/** - * - * - * @param - */ -interface ExceptionHandler -{ - T create( String message, Exception exception ); -} diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/Invoker.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/Invoker.java deleted file mode 100644 index 8cc8851..0000000 --- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/Invoker.java +++ /dev/null @@ -1,97 +0,0 @@ -package org.apache.maven.shared.dependency.graph.internal; - -/* - * 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.apache.maven.shared.dependency.graph.DependencyGraphBuilderException; - -/** - * Invokes method on objects using reflection. - */ -final class Invoker -{ - private Invoker() - { - // do not instantiate - } - - static Object invoke( Object object, String method, ExceptionHandler exceptionHandler ) - throws T - { - return invoke( object.getClass(), object, method, exceptionHandler ); - } - - static Object invoke( Class objectClazz, Object object, String method, - ExceptionHandler exceptionHandler ) - throws T - { - try - { - return objectClazz.getMethod( method ).invoke( object ); - } - catch ( ReflectiveOperationException e ) - { - throw exceptionHandler.create( e.getMessage(), e ); - } - } - - static Object invoke( Object object, String method, Class clazz, Object arg ) - throws DependencyGraphBuilderException - { - try - { - final Class objectClazz = object.getClass(); - return objectClazz.getMethod( method, clazz ).invoke( object, arg ); - } - catch ( ReflectiveOperationException e ) - { - throw new DependencyGraphBuilderException( e.getMessage(), e ); - } - } - - static Object invoke( Class objectClazz, String staticMethod, - Class argClazz, Object arg, - ExceptionHandler exceptionHandler ) - throws T - { - try - { - return objectClazz.getMethod( staticMethod, argClazz ).invoke( null, arg ); - } - catch ( ReflectiveOperationException e ) - { - throw exceptionHandler.create( e.getMessage(), e ); - } - } - - static Object invoke( Class objectClazz, String staticMethod, Class argClazz1, - Class argClazz2, Object arg1, Object arg2, - ExceptionHandler exceptionHandler ) - throws T - { - try - { - return objectClazz.getMethod( staticMethod, argClazz1, argClazz2 ).invoke( null, arg1, arg2 ); - } - catch ( ReflectiveOperationException e ) - { - throw exceptionHandler.create( e.getMessage(), e ); - } - } -} diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven31DependencyCollectorBuilder.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven31DependencyCollectorBuilder.java deleted file mode 100644 index 037a7a3..0000000 --- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven31DependencyCollectorBuilder.java +++ /dev/null @@ -1,315 +0,0 @@ -package org.apache.maven.shared.dependency.graph.internal; - -/* - * 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.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.apache.maven.RepositoryUtils; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.resolver.filter.ArtifactFilter; -import org.apache.maven.model.Dependency; -import org.apache.maven.project.MavenProject; -import org.apache.maven.project.ProjectBuildingRequest; -import org.apache.maven.shared.dependency.graph.DependencyCollectorBuilder; -import org.apache.maven.shared.dependency.graph.DependencyCollectorBuilderException; -import org.apache.maven.shared.dependency.graph.DependencyNode; -import org.apache.maven.shared.dependency.graph.internal.maven31.Maven31DirectScopeDependencySelector; -import org.apache.maven.shared.dependency.graph.internal.maven31.VerboseJavaScopeSelector; -import org.codehaus.plexus.component.annotations.Component; -import org.codehaus.plexus.component.annotations.Requirement; -import org.codehaus.plexus.logging.AbstractLogEnabled; -import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.RepositorySystem; -import org.eclipse.aether.artifact.ArtifactTypeRegistry; -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.DependencySelector; -import org.eclipse.aether.graph.DependencyVisitor; -import org.eclipse.aether.graph.Exclusion; -import org.eclipse.aether.util.artifact.JavaScopes; -import org.eclipse.aether.util.graph.manager.DependencyManagerUtils; -import org.eclipse.aether.util.graph.selector.AndDependencySelector; -import org.eclipse.aether.util.graph.selector.ExclusionDependencySelector; -import org.eclipse.aether.util.graph.selector.OptionalDependencySelector; -import org.eclipse.aether.util.graph.transformer.ConflictResolver; -import org.eclipse.aether.util.graph.transformer.JavaScopeDeriver; -import org.eclipse.aether.util.graph.transformer.NearestVersionSelector; -import org.eclipse.aether.util.graph.transformer.SimpleOptionalitySelector; -import org.eclipse.aether.util.graph.visitor.TreeDependencyVisitor; -import org.eclipse.aether.version.VersionConstraint; - -/** - * Project dependency raw dependency collector API, abstracting Maven 3.1+'s Aether implementation. - * - * @author Gabriel Belingueres - * @since 3.1.0 - */ -@Component( role = DependencyCollectorBuilder.class, hint = "maven31" ) -public class Maven31DependencyCollectorBuilder - extends AbstractLogEnabled - implements DependencyCollectorBuilder -{ - @Requirement - private RepositorySystem repositorySystem; - - private final ExceptionHandler exceptionHandler; - - public Maven31DependencyCollectorBuilder() - { - this.exceptionHandler = DependencyCollectorBuilderException::new; - } - - @Override - public DependencyNode collectDependencyGraph( ProjectBuildingRequest buildingRequest, ArtifactFilter filter ) - throws DependencyCollectorBuilderException - { - DefaultRepositorySystemSession session = null; - try - { - MavenProject project = buildingRequest.getProject(); - - Artifact projectArtifact = project.getArtifact(); - List remoteArtifactRepositories = project.getRemoteArtifactRepositories(); - - DefaultRepositorySystemSession repositorySession = - (DefaultRepositorySystemSession) Invoker.invoke( buildingRequest, "getRepositorySession", - exceptionHandler ); - - session = new DefaultRepositorySystemSession( repositorySession ); - - DependencyGraphTransformer transformer = - new ConflictResolver( new NearestVersionSelector(), new VerboseJavaScopeSelector(), - new SimpleOptionalitySelector(), new JavaScopeDeriver() ); - session.setDependencyGraphTransformer( transformer ); - - DependencySelector depFilter = - new AndDependencySelector( new Maven31DirectScopeDependencySelector( JavaScopes.TEST ), - new Maven31DirectScopeDependencySelector( JavaScopes.PROVIDED ), - new OptionalDependencySelector(), - new ExclusionDependencySelector() ); - session.setDependencySelector( depFilter ); - - session.setConfigProperty( ConflictResolver.CONFIG_PROP_VERBOSE, true ); - session.setConfigProperty( DependencyManagerUtils.CONFIG_PROP_VERBOSE, true ); - - org.eclipse.aether.artifact.Artifact aetherArtifact = - (org.eclipse.aether.artifact.Artifact) Invoker.invoke( RepositoryUtils.class, "toArtifact", - Artifact.class, projectArtifact, - exceptionHandler ); - - @SuppressWarnings( "unchecked" ) - List aetherRepos = - (List) Invoker.invoke( RepositoryUtils.class, "toRepos", - List.class, - remoteArtifactRepositories, - exceptionHandler ); - - CollectRequest collectRequest = new CollectRequest(); - collectRequest.setRootArtifact( aetherArtifact ); - collectRequest.setRepositories( aetherRepos ); - - org.eclipse.aether.artifact.ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry(); - collectDependencyList( collectRequest, project, stereotypes ); - collectManagedDependencyList( collectRequest, project, stereotypes ); - - CollectResult collectResult = repositorySystem.collectDependencies( session, collectRequest ); - - org.eclipse.aether.graph.DependencyNode rootNode = collectResult.getRoot(); - - if ( getLogger().isDebugEnabled() ) - { - logTree( rootNode ); - } - - return buildDependencyNode( null, rootNode, projectArtifact, filter ); - } - catch ( DependencyCollectionException e ) - { - throw new DependencyCollectorBuilderException( "Could not collect dependencies: " + e.getResult(), e ); - } - finally - { - if ( session != null ) - { - session.setReadOnly(); - } - } - } - - private void logTree( org.eclipse.aether.graph.DependencyNode rootNode ) - { - // print the node tree with its associated data Map - rootNode.accept( new TreeDependencyVisitor( new DependencyVisitor() - { - String indent = ""; - - @Override - public boolean visitEnter( org.eclipse.aether.graph.DependencyNode dependencyNode ) - { - getLogger().debug( indent + "Aether node: " + dependencyNode + " data map: " - + dependencyNode.getData() ); - indent += " "; - return true; - } - - @Override - public boolean visitLeave( org.eclipse.aether.graph.DependencyNode dependencyNode ) - { - indent = indent.substring( 0, indent.length() - 4 ); - return true; - } - } ) ); - } - - private void collectManagedDependencyList( CollectRequest collectRequest, MavenProject project, - ArtifactTypeRegistry stereotypes ) - throws DependencyCollectorBuilderException - { - if ( project.getDependencyManagement() != null ) - { - for ( Dependency dependency : project.getDependencyManagement().getDependencies() ) - { - org.eclipse.aether.graph.Dependency aetherDep = toAetherDependency( stereotypes, dependency ); - collectRequest.addManagedDependency( aetherDep ); - } - } - } - - private void collectDependencyList( CollectRequest collectRequest, MavenProject project, - org.eclipse.aether.artifact.ArtifactTypeRegistry stereotypes ) - throws DependencyCollectorBuilderException - { - for ( Dependency dependency : project.getDependencies() ) - { - org.eclipse.aether.graph.Dependency aetherDep = toAetherDependency( stereotypes, dependency ); - collectRequest.addDependency( aetherDep ); - } - } - - // CHECKSTYLE_OFF: LineLength - private org.eclipse.aether.graph.Dependency toAetherDependency( org.eclipse.aether.artifact.ArtifactTypeRegistry stereotypes, - Dependency dependency ) - throws DependencyCollectorBuilderException - { - return (org.eclipse.aether.graph.Dependency) Invoker.invoke( RepositoryUtils.class, "toDependency", - Dependency.class, - ArtifactTypeRegistry.class, - dependency, stereotypes, exceptionHandler ); - } - // CHECKSTYLE_ON: LineLength - - private Artifact getDependencyArtifact( org.eclipse.aether.graph.Dependency dep ) - { - org.eclipse.aether.artifact.Artifact artifact = dep.getArtifact(); - - try - { - Artifact mavenArtifact = - (Artifact) Invoker.invoke( RepositoryUtils.class, "toArtifact", - org.eclipse.aether.artifact.Artifact.class, artifact, exceptionHandler ); - - mavenArtifact.setScope( dep.getScope() ); - mavenArtifact.setOptional( dep.isOptional() ); - - return mavenArtifact; - } - catch ( DependencyCollectorBuilderException e ) - { - // ReflectionException should not happen - throw new RuntimeException( e.getMessage(), e ); - } - } - - private DependencyNode buildDependencyNode( DependencyNode parent, org.eclipse.aether.graph.DependencyNode node, - Artifact artifact, ArtifactFilter filter ) - { - String premanagedVersion = DependencyManagerUtils.getPremanagedVersion( node ); - String premanagedScope = DependencyManagerUtils.getPremanagedScope( node ); - - Boolean optional = null; - if ( node.getDependency() != null ) - { - optional = node.getDependency().isOptional(); - } - - List exclusions = null; - if ( node.getDependency() != null ) - { - exclusions = new ArrayList<>( node.getDependency().getExclusions().size() ); - for ( Exclusion exclusion : node.getDependency().getExclusions() ) - { - org.apache.maven.model.Exclusion modelExclusion = new org.apache.maven.model.Exclusion(); - modelExclusion.setGroupId( exclusion.getGroupId() ); - modelExclusion.setArtifactId( exclusion.getArtifactId() ); - exclusions.add( modelExclusion ); - } - } - - org.eclipse.aether.graph.DependencyNode winner = - (org.eclipse.aether.graph.DependencyNode) node.getData().get( ConflictResolver.NODE_DATA_WINNER ); - String winnerVersion = null; - String ignoredScope = null; - if ( winner != null ) - { - winnerVersion = winner.getArtifact().getBaseVersion(); - } - else - { - ignoredScope = (String) node.getData().get( VerboseJavaScopeSelector.REDUCED_SCOPE ); - } - - ConflictData data = new ConflictData( winnerVersion, ignoredScope ); - - VerboseDependencyNode current = - new VerboseDependencyNode( parent, artifact, premanagedVersion, premanagedScope, - getVersionSelectedFromRange( node.getVersionConstraint() ), optional, - exclusions, data ); - - List nodes = new ArrayList<>( node.getChildren().size() ); - for ( org.eclipse.aether.graph.DependencyNode child : node.getChildren() ) - { - Artifact childArtifact = getDependencyArtifact( child.getDependency() ); - - if ( ( filter == null ) || filter.include( childArtifact ) ) - { - nodes.add( buildDependencyNode( current, child, childArtifact, filter ) ); - } - } - - current.setChildren( Collections.unmodifiableList( nodes ) ); - - return current; - } - - private String getVersionSelectedFromRange( VersionConstraint constraint ) - { - if ( ( constraint == null ) || ( constraint.getVersion() != null ) ) - { - return null; - } - - return constraint.getRange().toString(); - } -} diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven31DependencyGraphBuilder.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven31DependencyGraphBuilder.java deleted file mode 100644 index bdecb91..0000000 --- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven31DependencyGraphBuilder.java +++ /dev/null @@ -1,199 +0,0 @@ -package org.apache.maven.shared.dependency.graph.internal; - -/* - * 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 static org.eclipse.aether.util.graph.manager.DependencyManagerUtils.NODE_DATA_PREMANAGED_VERSION; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.apache.maven.RepositoryUtils; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.resolver.filter.ArtifactFilter; -import org.apache.maven.project.DefaultDependencyResolutionRequest; -import org.apache.maven.project.DependencyResolutionException; -import org.apache.maven.project.DependencyResolutionRequest; -import org.apache.maven.project.DependencyResolutionResult; -import org.apache.maven.project.MavenProject; -import org.apache.maven.project.ProjectBuildingRequest; -import org.apache.maven.project.ProjectDependenciesResolver; -import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder; -import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException; -import org.apache.maven.shared.dependency.graph.DependencyNode; -import org.codehaus.plexus.component.annotations.Component; -import org.codehaus.plexus.component.annotations.Requirement; -import org.codehaus.plexus.logging.AbstractLogEnabled; -import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.RepositorySystemSession; -import org.eclipse.aether.graph.Dependency; -import org.eclipse.aether.graph.DependencyFilter; -import org.eclipse.aether.graph.Exclusion; -import org.eclipse.aether.util.graph.manager.DependencyManagerUtils; -import org.eclipse.aether.version.VersionConstraint; - -/** - * Wrapper around Eclipse Aether dependency resolver, used in Maven 3.1. - * - * @see ProjectDependenciesResolver - * @author Hervé Boutemy - * @since 2.1 - */ -@Component( role = DependencyGraphBuilder.class, hint = "maven31" ) -public class Maven31DependencyGraphBuilder - extends AbstractLogEnabled - implements DependencyGraphBuilder -{ - @Requirement - private ProjectDependenciesResolver resolver; - - private final ExceptionHandler exceptionHandler; - - public Maven31DependencyGraphBuilder() - { - this.exceptionHandler = DependencyGraphBuilderException::new; - } - - /** - * Builds the dependency graph for Maven 3.1+. - * - * @param buildingRequest the buildingRequest - * @param filter artifact filter (can be null) - * @return DependencyNode containing the dependency graph. - * @throws DependencyGraphBuilderException if some of the dependencies could not be resolved. - */ - @Override - public DependencyNode buildDependencyGraph( ProjectBuildingRequest buildingRequest, ArtifactFilter filter ) - throws DependencyGraphBuilderException - { - MavenProject project = buildingRequest.getProject(); - - RepositorySystemSession session = - (RepositorySystemSession) Invoker.invoke( buildingRequest, "getRepositorySession", exceptionHandler ); - - - if ( Boolean.TRUE != session.getConfigProperties().get( NODE_DATA_PREMANAGED_VERSION ) ) - { - DefaultRepositorySystemSession newSession = new DefaultRepositorySystemSession( session ); - newSession.setConfigProperty( NODE_DATA_PREMANAGED_VERSION, true ); - session = newSession; - } - - final DependencyResolutionRequest request = new DefaultDependencyResolutionRequest(); - request.setMavenProject( project ); - Invoker.invoke( request, "setRepositorySession", RepositorySystemSession.class, session ); - // only download the poms, not the artifacts - DependencyFilter collectFilter = ( node, parents ) -> false; - Invoker.invoke( request, "setResolutionFilter", DependencyFilter.class, collectFilter ); - - final DependencyResolutionResult result = resolveDependencies( request ); - org.eclipse.aether.graph.DependencyNode graph = - (org.eclipse.aether.graph.DependencyNode) Invoker.invoke( DependencyResolutionResult.class, result, - "getDependencyGraph", exceptionHandler ); - - return buildDependencyNode( null, graph, project.getArtifact(), filter ); - } - - private DependencyResolutionResult resolveDependencies( DependencyResolutionRequest request ) - throws DependencyGraphBuilderException - { - try - { - return resolver.resolve( request ); - } - catch ( DependencyResolutionException e ) - { - throw new DependencyGraphBuilderException( "Could not resolve following dependencies: " - + e.getResult().getUnresolvedDependencies(), e ); - } - } - - private Artifact getDependencyArtifact( Dependency dep ) - { - org.eclipse.aether.artifact.Artifact artifact = dep.getArtifact(); - - try - { - Artifact mavenArtifact = (Artifact) Invoker.invoke( RepositoryUtils.class, "toArtifact", - org.eclipse.aether.artifact.Artifact.class, artifact, exceptionHandler ); - - mavenArtifact.setScope( dep.getScope() ); - mavenArtifact.setOptional( dep.isOptional() ); - - return mavenArtifact; - } - catch ( DependencyGraphBuilderException e ) - { - // ReflectionException should not happen - throw new RuntimeException( e.getMessage(), e ); - } - } - - private DependencyNode buildDependencyNode( DependencyNode parent, org.eclipse.aether.graph.DependencyNode node, - Artifact artifact, ArtifactFilter filter ) - { - String premanagedVersion = DependencyManagerUtils.getPremanagedVersion( node ); - String premanagedScope = DependencyManagerUtils.getPremanagedScope( node ); - - List exclusions = null; - Boolean optional = null; - if ( node.getDependency() != null ) - { - exclusions = new ArrayList<>( node.getDependency().getExclusions().size() ); - for ( Exclusion exclusion : node.getDependency().getExclusions() ) - { - org.apache.maven.model.Exclusion modelExclusion = new org.apache.maven.model.Exclusion(); - modelExclusion.setGroupId( exclusion.getGroupId() ); - modelExclusion.setArtifactId( exclusion.getArtifactId() ); - exclusions.add( modelExclusion ); - } - } - - DefaultDependencyNode current = - new DefaultDependencyNode( parent, artifact, premanagedVersion, premanagedScope, - getVersionSelectedFromRange( node.getVersionConstraint() ), - optional, exclusions ); - - List nodes = new ArrayList<>( node.getChildren().size() ); - for ( org.eclipse.aether.graph.DependencyNode child : node.getChildren() ) - { - Artifact childArtifact = getDependencyArtifact( child.getDependency() ); - - if ( ( filter == null ) || filter.include( childArtifact ) ) - { - nodes.add( buildDependencyNode( current, child, childArtifact, filter ) ); - } - } - - current.setChildren( Collections.unmodifiableList( nodes ) ); - - return current; - } - - private String getVersionSelectedFromRange( VersionConstraint constraint ) - { - if ( ( constraint == null ) || ( constraint.getVersion() != null ) ) - { - return null; - } - - return constraint.getRange().toString(); - } -} diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven3DependencyCollectorBuilder.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven3DependencyCollectorBuilder.java deleted file mode 100644 index 6dce3a9..0000000 --- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven3DependencyCollectorBuilder.java +++ /dev/null @@ -1,322 +0,0 @@ -package org.apache.maven.shared.dependency.graph.internal; - -/* - * 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.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.apache.maven.RepositoryUtils; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.resolver.filter.ArtifactFilter; -import org.apache.maven.model.Dependency; -import org.apache.maven.project.MavenProject; -import org.apache.maven.project.ProjectBuildingRequest; -import org.apache.maven.shared.dependency.graph.DependencyCollectorBuilder; -import org.apache.maven.shared.dependency.graph.DependencyCollectorBuilderException; -import org.apache.maven.shared.dependency.graph.DependencyNode; -import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver; -import org.apache.maven.shared.dependency.graph.internal.maven30.JavaScopeDeriver; -import org.apache.maven.shared.dependency.graph.internal.maven30.Maven3DirectScopeDependencySelector; -import org.apache.maven.shared.dependency.graph.internal.maven30.NearestVersionSelector; -import org.apache.maven.shared.dependency.graph.internal.maven30.SimpleOptionalitySelector; -import org.apache.maven.shared.dependency.graph.internal.maven30.VerboseJavaScopeSelector; -import org.codehaus.plexus.component.annotations.Component; -import org.codehaus.plexus.component.annotations.Requirement; -import org.codehaus.plexus.logging.AbstractLogEnabled; -import org.sonatype.aether.RepositorySystem; -import org.sonatype.aether.RepositorySystemSession; -import org.sonatype.aether.artifact.ArtifactTypeRegistry; -import org.sonatype.aether.collection.CollectRequest; -import org.sonatype.aether.collection.CollectResult; -import org.sonatype.aether.collection.DependencyCollectionException; -import org.sonatype.aether.collection.DependencyGraphTransformer; -import org.sonatype.aether.collection.DependencySelector; -import org.sonatype.aether.graph.DependencyVisitor; -import org.sonatype.aether.graph.Exclusion; -import org.sonatype.aether.util.DefaultRepositorySystemSession; -import org.sonatype.aether.util.artifact.JavaScopes; -import org.sonatype.aether.util.graph.TreeDependencyVisitor; -import org.sonatype.aether.util.graph.selector.AndDependencySelector; -import org.sonatype.aether.util.graph.selector.ExclusionDependencySelector; -import org.sonatype.aether.util.graph.selector.OptionalDependencySelector; -import org.sonatype.aether.version.VersionConstraint; - -/** - * Project dependency raw dependency collector API, abstracting Maven 3's Aether implementation. - * - * @author Gabriel Belingueres - * @since 3.1.0 - */ -@Component( role = DependencyCollectorBuilder.class, hint = "maven3" ) -public class Maven3DependencyCollectorBuilder - extends AbstractLogEnabled - implements DependencyCollectorBuilder -{ - @Requirement - private RepositorySystem repositorySystem; - - private final ExceptionHandler exceptionHandler; - - public Maven3DependencyCollectorBuilder() - { - this.exceptionHandler = DependencyCollectorBuilderException::new; - } - - @Override - public DependencyNode collectDependencyGraph( ProjectBuildingRequest buildingRequest, ArtifactFilter filter ) - throws DependencyCollectorBuilderException - { - try - { - MavenProject project = buildingRequest.getProject(); - - Artifact projectArtifact = project.getArtifact(); - List remoteArtifactRepositories = project.getRemoteArtifactRepositories(); - - // throws ClassCastException (classloading issues?) - // DefaultRepositorySystemSession repositorySystemSession = - // (DefaultRepositorySystemSession) Invoker.invoke( buildingRequest, "getRepositorySession" ); - RepositorySystemSession repositorySystemSession = buildingRequest.getRepositorySession(); - - DefaultRepositorySystemSession session = new DefaultRepositorySystemSession( repositorySystemSession ); - - DependencyGraphTransformer transformer = - new ConflictResolver( new NearestVersionSelector(), new VerboseJavaScopeSelector(), - new SimpleOptionalitySelector(), new JavaScopeDeriver() ); - session.setDependencyGraphTransformer( transformer ); - - DependencySelector depFilter = - new AndDependencySelector( new Maven3DirectScopeDependencySelector( JavaScopes.TEST ), - new Maven3DirectScopeDependencySelector( JavaScopes.PROVIDED ), - new OptionalDependencySelector(), - new ExclusionDependencySelector() ); - session.setDependencySelector( depFilter ); - - session.setConfigProperty( ConflictResolver.CONFIG_PROP_VERBOSE, true ); - session.setConfigProperty( "aether.dependencyManager.verbose", true ); - - org.sonatype.aether.artifact.Artifact aetherArtifact = - (org.sonatype.aether.artifact.Artifact) Invoker.invoke( RepositoryUtils.class, "toArtifact", - Artifact.class, projectArtifact, - exceptionHandler ); - - @SuppressWarnings( "unchecked" ) - List aetherRepos = - (List) Invoker.invoke( RepositoryUtils.class, - "toRepos", List.class, - remoteArtifactRepositories, - exceptionHandler ); - - CollectRequest collectRequest = new CollectRequest(); - collectRequest.setRoot( new org.sonatype.aether.graph.Dependency( aetherArtifact, "" ) ); - collectRequest.setRepositories( aetherRepos ); - - org.sonatype.aether.artifact.ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry(); - collectDependencyList( collectRequest, project, stereotypes ); - collectManagedDependencyList( collectRequest, project, stereotypes ); - - CollectResult collectResult = repositorySystem.collectDependencies( session, collectRequest ); - - org.sonatype.aether.graph.DependencyNode rootNode = collectResult.getRoot(); - - if ( getLogger().isDebugEnabled() ) - { - logTree( rootNode ); - } - - return buildDependencyNode( null, rootNode, projectArtifact, filter ); - } - catch ( DependencyCollectionException e ) - { - throw new DependencyCollectorBuilderException( "Could not collect dependencies: " + e.getResult(), e ); - } - } - - private void logTree( org.sonatype.aether.graph.DependencyNode rootNode ) - { - // print the node tree with its associated data Map - rootNode.accept( new TreeDependencyVisitor( new DependencyVisitor() - { - String indent = ""; - - @Override - public boolean visitEnter( org.sonatype.aether.graph.DependencyNode dependencyNode ) - { - StringBuilder sb = new StringBuilder(); - sb.append( indent ).append( "Aether node: " ).append( dependencyNode ); - if ( !dependencyNode.getData().isEmpty() ) - { - sb.append( "data map: " ).append( dependencyNode.getData() ); - } - if ( dependencyNode.getPremanagedVersion() != null && !dependencyNode.getPremanagedVersion().isEmpty() ) - { - sb.append( "Premanaged.version: " ).append( dependencyNode.getPremanagedVersion() ); - } - if ( dependencyNode.getPremanagedScope() != null && !dependencyNode.getPremanagedScope().isEmpty() ) - { - sb.append( "Premanaged.scope: " ).append( dependencyNode.getPremanagedScope() ); - } - getLogger().debug( sb.toString() ); - indent += " "; - return true; - } - - @Override - public boolean visitLeave( org.sonatype.aether.graph.DependencyNode dependencyNode ) - { - indent = indent.substring( 0, indent.length() - 4 ); - return true; - } - } ) ); - } - - private void collectManagedDependencyList( CollectRequest collectRequest, MavenProject project, - ArtifactTypeRegistry stereotypes ) - throws DependencyCollectorBuilderException - { - if ( project.getDependencyManagement() != null ) - { - for ( Dependency dependency : project.getDependencyManagement().getDependencies() ) - { - org.sonatype.aether.graph.Dependency aetherDep = toAetherDependency( stereotypes, dependency ); - collectRequest.addManagedDependency( aetherDep ); - } - } - } - - private void collectDependencyList( CollectRequest collectRequest, MavenProject project, - org.sonatype.aether.artifact.ArtifactTypeRegistry stereotypes ) - throws DependencyCollectorBuilderException - { - for ( Dependency dependency : project.getDependencies() ) - { - org.sonatype.aether.graph.Dependency aetherDep = toAetherDependency( stereotypes, dependency ); - collectRequest.addDependency( aetherDep ); - } - } - - // CHECKSTYLE_OFF: LineLength - private org.sonatype.aether.graph.Dependency toAetherDependency( org.sonatype.aether.artifact.ArtifactTypeRegistry stereotypes, - Dependency dependency ) - throws DependencyCollectorBuilderException - { - return (org.sonatype.aether.graph.Dependency) Invoker.invoke( RepositoryUtils.class, "toDependency", - Dependency.class, - ArtifactTypeRegistry.class, - dependency, stereotypes, exceptionHandler ); - } - // CHECKSTYLE_ON: LineLength - - private Artifact getDependencyArtifact( org.sonatype.aether.graph.Dependency dep ) - { - org.sonatype.aether.artifact.Artifact artifact = dep.getArtifact(); - - try - { - Artifact mavenArtifact = - (Artifact) Invoker.invoke( RepositoryUtils.class, "toArtifact", - org.sonatype.aether.artifact.Artifact.class, artifact, exceptionHandler ); - - mavenArtifact.setScope( dep.getScope() ); - mavenArtifact.setOptional( dep.isOptional() ); - - return mavenArtifact; - } - catch ( DependencyCollectorBuilderException e ) - { - // ReflectionException should not happen - throw new RuntimeException( e.getMessage(), e ); - } - } - - private DependencyNode buildDependencyNode( DependencyNode parent, org.sonatype.aether.graph.DependencyNode node, - Artifact artifact, ArtifactFilter filter ) - { - String premanagedVersion = node.getPremanagedVersion(); - String premanagedScope = node.getPremanagedScope(); - - Boolean optional = null; - if ( node.getDependency() != null ) - { - optional = node.getDependency().isOptional(); - } - - List exclusions = null; - if ( node.getDependency() != null ) - { - exclusions = new ArrayList<>( node.getDependency().getExclusions().size() ); - for ( Exclusion exclusion : node.getDependency().getExclusions() ) - { - org.apache.maven.model.Exclusion modelExclusion = new org.apache.maven.model.Exclusion(); - modelExclusion.setGroupId( exclusion.getGroupId() ); - modelExclusion.setArtifactId( exclusion.getArtifactId() ); - exclusions.add( modelExclusion ); - } - } - - org.sonatype.aether.graph.DependencyNode winner = - (org.sonatype.aether.graph.DependencyNode) node.getData().get( ConflictResolver.NODE_DATA_WINNER ); - String winnerVersion = null; - String ignoredScope = null; - if ( winner != null ) - { - winnerVersion = winner.getVersion().toString(); - } - else - { - ignoredScope = (String) node.getData().get( VerboseJavaScopeSelector.REDUCED_SCOPE ); - } - - ConflictData data = new ConflictData( winnerVersion, ignoredScope ); - - VerboseDependencyNode current = - new VerboseDependencyNode( parent, artifact, premanagedVersion, premanagedScope, - getVersionSelectedFromRange( node.getVersionConstraint() ), optional, exclusions, - data ); - - List nodes = new ArrayList<>( node.getChildren().size() ); - for ( org.sonatype.aether.graph.DependencyNode child : node.getChildren() ) - { - Artifact childArtifact = getDependencyArtifact( child.getDependency() ); - - if ( ( filter == null ) || filter.include( childArtifact ) ) - { - nodes.add( buildDependencyNode( current, child, childArtifact, filter ) ); - } - } - - current.setChildren( Collections.unmodifiableList( nodes ) ); - - return current; - } - - private String getVersionSelectedFromRange( VersionConstraint constraint ) - { - if ( ( constraint == null ) || ( constraint.getVersion() != null ) || ( constraint.getRanges().isEmpty() ) ) - { - return null; - } - - return constraint.getRanges().iterator().next().toString(); - } - -} diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven3DependencyGraphBuilder.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven3DependencyGraphBuilder.java deleted file mode 100644 index 2ec8f94..0000000 --- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven3DependencyGraphBuilder.java +++ /dev/null @@ -1,155 +0,0 @@ -package org.apache.maven.shared.dependency.graph.internal; - -/* - * 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.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.apache.maven.RepositoryUtils; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.resolver.filter.ArtifactFilter; -import org.apache.maven.project.DefaultDependencyResolutionRequest; -import org.apache.maven.project.DependencyResolutionException; -import org.apache.maven.project.DependencyResolutionRequest; -import org.apache.maven.project.DependencyResolutionResult; -import org.apache.maven.project.MavenProject; -import org.apache.maven.project.ProjectBuildingRequest; -import org.apache.maven.project.ProjectDependenciesResolver; -import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder; -import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException; -import org.apache.maven.shared.dependency.graph.DependencyNode; -import org.codehaus.plexus.component.annotations.Component; -import org.codehaus.plexus.component.annotations.Requirement; -import org.codehaus.plexus.logging.AbstractLogEnabled; -import org.sonatype.aether.graph.DependencyFilter; -import org.sonatype.aether.graph.Dependency; -import org.sonatype.aether.version.VersionConstraint; - -/** - * Wrapper around Maven 3 dependency resolver. - * - * @see ProjectDependenciesResolver - * @author Hervé Boutemy - * @since 2.0 - */ -@Component( role = DependencyGraphBuilder.class, hint = "maven3" ) -public class Maven3DependencyGraphBuilder - extends AbstractLogEnabled - implements DependencyGraphBuilder -{ - @Requirement - private ProjectDependenciesResolver resolver; - - /** - * Builds the dependency graph for Maven 3. - * - * @param buildingRequest the buildingRequest - * @param filter artifact filter (can be null) - * @return DependencyNode containing the dependency graph. - * @throws DependencyGraphBuilderException if some of the dependencies could not be resolved. - */ - @Override - public DependencyNode buildDependencyGraph( ProjectBuildingRequest buildingRequest, ArtifactFilter filter ) - throws DependencyGraphBuilderException - { - MavenProject project = buildingRequest.getProject(); - - DependencyResolutionRequest request = - new DefaultDependencyResolutionRequest( project, buildingRequest.getRepositorySession() ); - - // only download the poms, not the artifacts - DependencyFilter collectFilter = ( node, parents ) -> false; - request.setResolutionFilter( collectFilter ); - - DependencyResolutionResult result = resolveDependencies( request ); - - return buildDependencyNode( null, result.getDependencyGraph(), project.getArtifact(), filter ); - } - - private DependencyResolutionResult resolveDependencies( DependencyResolutionRequest request ) - throws DependencyGraphBuilderException - { - try - { - return resolver.resolve( request ); - } - catch ( DependencyResolutionException e ) - { - throw new DependencyGraphBuilderException( "Could not resolve following dependencies: " - + e.getResult().getUnresolvedDependencies(), e ); - } - } - - private Artifact getDependencyArtifact( Dependency dep ) - { - Artifact mavenArtifact = RepositoryUtils.toArtifact( dep.getArtifact() ); - - mavenArtifact.setScope( dep.getScope() ); - mavenArtifact.setOptional( dep.isOptional() ); - - return mavenArtifact; - } - - private DependencyNode buildDependencyNode( DependencyNode parent, org.sonatype.aether.graph.DependencyNode node, - Artifact artifact, ArtifactFilter filter ) - { - DefaultDependencyNode current = - new DefaultDependencyNode( parent, artifact, - null /* node.getPremanagedVersion() */, - null /* node.getPremanagedScope() */, - getVersionSelectedFromRange( node.getVersionConstraint() ) ); - - List nodes = new ArrayList<>( node.getChildren().size() ); - for ( org.sonatype.aether.graph.DependencyNode child : node.getChildren() ) - { - Artifact childArtifact = getDependencyArtifact( child.getDependency() ); - - if ( ( filter == null ) || filter.include( childArtifact ) ) - { - nodes.add( buildDependencyNode( current, child, childArtifact, filter ) ); - } - } - - current.setChildren( Collections.unmodifiableList( nodes ) ); - - return current; - } - - private String getVersionSelectedFromRange( VersionConstraint constraint ) - { - if ( ( constraint == null ) || ( constraint.getVersion() != null ) ) - { - return null; - } - - StringBuilder sb = new StringBuilder(); - for ( org.sonatype.aether.version.VersionRange range : constraint.getRanges() ) - { - if ( sb.length() > 0 ) - { - sb.append( ',' ); - } - sb.append( range ); - } - - return sb.toString(); - } -} diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven31/VerboseJavaScopeSelector.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/VerboseJavaScopeSelector.java similarity index 97% rename from src/main/java/org/apache/maven/shared/dependency/graph/internal/maven31/VerboseJavaScopeSelector.java rename to src/main/java/org/apache/maven/shared/dependency/graph/internal/VerboseJavaScopeSelector.java index bcc9c66..b5cd5ee 100644 --- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven31/VerboseJavaScopeSelector.java +++ b/src/main/java/org/apache/maven/shared/dependency/graph/internal/VerboseJavaScopeSelector.java @@ -1,4 +1,4 @@ -package org.apache.maven.shared.dependency.graph.internal.maven31; +package org.apache.maven.shared.dependency.graph.internal; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/ConflictIdSorter.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/ConflictIdSorter.java deleted file mode 100644 index 35cb5a8..0000000 --- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/ConflictIdSorter.java +++ /dev/null @@ -1,370 +0,0 @@ -package org.apache.maven.shared.dependency.graph.internal.maven30; - -/* - * 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.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.sonatype.aether.RepositoryException; -import org.sonatype.aether.collection.DependencyGraphTransformationContext; -import org.sonatype.aether.collection.DependencyGraphTransformer; -import org.sonatype.aether.graph.DependencyNode; -import org.sonatype.aether.util.graph.transformer.ConflictMarker; -import org.sonatype.aether.util.graph.transformer.TransformationContextKeys; - -/** - * This class is a copy of their homonymous in the Eclipse Aether library, adapted to work with Sonatype Aether. - * - * @author Gabriel Belingueres - * @since 3.1.0 - */ -public final class ConflictIdSorter - implements DependencyGraphTransformer -{ - - public DependencyNode transformGraph( DependencyNode node, DependencyGraphTransformationContext context ) - throws RepositoryException - { - Map conflictIds = (Map) context.get( TransformationContextKeys.CONFLICT_IDS ); - if ( conflictIds == null ) - { - ConflictMarker marker = new ConflictMarker(); - marker.transformGraph( node, context ); - - conflictIds = (Map) context.get( TransformationContextKeys.CONFLICT_IDS ); - } - -// @SuppressWarnings( "unchecked" ) -// Map stats = (Map) context.get( TransformationContextKeys.STATS ); -// long time1 = System.currentTimeMillis(); - - Map ids = new LinkedHashMap<>( 256 ); - - // CHECKSTYLE_OFF: AvoidNestedBlocks - { - ConflictId id = null; - Object key = conflictIds.get( node ); - if ( key != null ) - { - id = new ConflictId( key, 0 ); - ids.put( key, id ); - } - - Map visited = new IdentityHashMap<>( conflictIds.size() ); - - buildConflitIdDAG( ids, node, id, 0, visited, conflictIds ); - } - // CHECKSTYLE_NO: AvoidNestedBlocks - -// long time2 = System.currentTimeMillis(); - - topsortConflictIds( ids.values(), context ); -// int cycles = topsortConflictIds( ids.values(), context ); - -// if ( stats != null ) -// { -// long time3 = System.currentTimeMillis(); -// stats.put( "ConflictIdSorter.graphTime", time2 - time1 ); -// stats.put( "ConflictIdSorter.topsortTime", time3 - time2 ); -// stats.put( "ConflictIdSorter.conflictIdCount", ids.size() ); -// stats.put( "ConflictIdSorter.conflictIdCycleCount", cycles ); -// } - - return node; - } - - private void buildConflitIdDAG( Map ids, DependencyNode node, ConflictId id, int depth, - Map visited, Map conflictIds ) - { - if ( visited.put( node, Boolean.TRUE ) != null ) - { - return; - } - - depth++; - - for ( DependencyNode child : node.getChildren() ) - { - Object key = conflictIds.get( child ); - ConflictId childId = ids.get( key ); - if ( childId == null ) - { - childId = new ConflictId( key, depth ); - ids.put( key, childId ); - } - else - { - childId.pullup( depth ); - } - - if ( id != null ) - { - id.add( childId ); - } - - buildConflitIdDAG( ids, child, childId, depth, visited, conflictIds ); - } - } - - private int topsortConflictIds( Collection conflictIds, DependencyGraphTransformationContext context ) - { - List sorted = new ArrayList<>( conflictIds.size() ); - - RootQueue roots = new RootQueue( conflictIds.size() / 2 ); - for ( ConflictId id : conflictIds ) - { - if ( id.inDegree <= 0 ) - { - roots.add( id ); - } - } - - processRoots( sorted, roots ); - - boolean cycle = sorted.size() < conflictIds.size(); - - while ( sorted.size() < conflictIds.size() ) - { - // cycle -> deal gracefully with nodes still having positive in-degree - - ConflictId nearest = null; - for ( ConflictId id : conflictIds ) - { - if ( id.inDegree <= 0 ) - { - continue; - } - if ( nearest == null || id.minDepth < nearest.minDepth - || ( id.minDepth == nearest.minDepth && id.inDegree < nearest.inDegree ) ) - { - nearest = id; - } - } - - nearest.inDegree = 0; - roots.add( nearest ); - - processRoots( sorted, roots ); - } - - Collection> cycles = Collections.emptySet(); - if ( cycle ) - { - cycles = findCycles( conflictIds ); - } - - context.put( TransformationContextKeys.SORTED_CONFLICT_IDS, sorted ); - context.put( TransformationContextKeys.CYCLIC_CONFLICT_IDS, cycles ); - - return cycles.size(); - } - - private void processRoots( List sorted, RootQueue roots ) - { - while ( !roots.isEmpty() ) - { - ConflictId root = roots.remove(); - - sorted.add( root.key ); - - for ( ConflictId child : root.children ) - { - child.inDegree--; - if ( child.inDegree == 0 ) - { - roots.add( child ); - } - } - } - } - - private Collection> findCycles( Collection conflictIds ) - { - Collection> cycles = new HashSet<>(); - - Map stack = new HashMap<>( 128 ); - Map visited = new IdentityHashMap<>( conflictIds.size() ); - for ( ConflictId id : conflictIds ) - { - findCycles( id, visited, stack, cycles ); - } - - return cycles; - } - - private void findCycles( ConflictId id, Map visited, Map stack, - Collection> cycles ) - { - Integer depth = stack.put( id.key, stack.size() ); - if ( depth != null ) - { - stack.put( id.key, depth ); - Collection cycle = new HashSet<>(); - for ( Map.Entry entry : stack.entrySet() ) - { - if ( entry.getValue() >= depth ) - { - cycle.add( entry.getKey() ); - } - } - cycles.add( cycle ); - } - else - { - if ( visited.put( id, Boolean.TRUE ) == null ) - { - for ( ConflictId childId : id.children ) - { - findCycles( childId, visited, stack, cycles ); - } - } - stack.remove( id.key ); - } - } - - static final class ConflictId - { - - final Object key; - - Collection children = Collections.emptySet(); - - int inDegree; - - int minDepth; - - ConflictId( Object key, int depth ) - { - this.key = key; - this.minDepth = depth; - } - - public void add( ConflictId child ) - { - if ( children.isEmpty() ) - { - children = new HashSet<>(); - } - if ( children.add( child ) ) - { - child.inDegree++; - } - } - - public void pullup( int depth ) - { - if ( depth < minDepth ) - { - minDepth = depth; - depth++; - for ( ConflictId child : children ) - { - child.pullup( depth ); - } - } - } - - @Override - public boolean equals( Object obj ) - { - if ( this == obj ) - { - return true; - } - else if ( !( obj instanceof ConflictId ) ) - { - return false; - } - ConflictId that = (ConflictId) obj; - return this.key.equals( that.key ); - } - - @Override - public int hashCode() - { - return key.hashCode(); - } - - @Override - public String toString() - { - return key + " @ " + minDepth + " <" + inDegree; - } - - } - - static final class RootQueue - { - - private int nextOut; - - private int nextIn; - - private ConflictId[] ids; - - RootQueue( int capacity ) - { - ids = new ConflictId[capacity + 16]; - } - - boolean isEmpty() - { - return nextOut >= nextIn; - } - - void add( ConflictId id ) - { - if ( nextOut >= nextIn && nextOut > 0 ) - { - nextIn -= nextOut; - nextOut = 0; - } - if ( nextIn >= ids.length ) - { - ConflictId[] tmp = new ConflictId[ids.length + ids.length / 2 + 16]; - System.arraycopy( ids, nextOut, tmp, 0, nextIn - nextOut ); - ids = tmp; - nextIn -= nextOut; - nextOut = 0; - } - int i; - for ( i = nextIn - 1; i >= nextOut && id.minDepth < ids[i].minDepth; i-- ) - { - ids[i + 1] = ids[i]; - } - ids[i + 1] = id; - nextIn++; - } - - ConflictId remove() - { - return ids[nextOut++]; - } - - } - -} diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/ConflictResolver.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/ConflictResolver.java deleted file mode 100644 index 329c028..0000000 --- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/ConflictResolver.java +++ /dev/null @@ -1,1314 +0,0 @@ -package org.apache.maven.shared.dependency.graph.internal.maven30; - -/* - * 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.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; - -import org.sonatype.aether.RepositoryException; -import org.sonatype.aether.artifact.Artifact; -import org.sonatype.aether.collection.DependencyGraphTransformationContext; -import org.sonatype.aether.collection.DependencyGraphTransformer; -import org.sonatype.aether.graph.Dependency; -import org.sonatype.aether.graph.DependencyNode; -import org.sonatype.aether.util.ConfigUtils; -import org.sonatype.aether.util.graph.DefaultDependencyNode; -import org.sonatype.aether.util.graph.transformer.TransformationContextKeys; - -/** - * This class is a copy of their homonymous in the Eclipse Aether library, adapted to work with Sonatype Aether. - * - * @author Gabriel Belingueres - * @since 3.1.0 - */ -public final class ConflictResolver - implements DependencyGraphTransformer -{ - - /** - * The key in the repository session's {@link org.sonatype.aether.RepositorySystemSession#getConfigProperties() - * configuration properties} used to store a {@link Boolean} flag controlling the transformer's verbose mode. - */ - public static final String CONFIG_PROP_VERBOSE = "aether.conflictResolver.verbose"; - - /** - * The key in the dependency node's {@link DependencyNode#getData() custom data} under which a reference to the - * {@link DependencyNode} which has won the conflict is stored. - */ - public static final String NODE_DATA_WINNER = "conflict.winner"; - - /** - * The key in the dependency node's {@link DependencyNode#getData() custom data} under which the scope of the - * dependency before scope derivation and conflict resolution is stored. - */ - public static final String NODE_DATA_ORIGINAL_SCOPE = "conflict.originalScope"; - - /** - * The key in the dependency node's {@link DependencyNode#getData() custom data} under which the optional flag of - * the dependency before derivation and conflict resolution is stored. - */ - public static final String NODE_DATA_ORIGINAL_OPTIONALITY = "conflict.originalOptionality"; - - private final VersionSelector versionSelector; - - private final ScopeSelector scopeSelector; - - private final ScopeDeriver scopeDeriver; - - private final OptionalitySelector optionalitySelector; - - /** - * Creates a new conflict resolver instance with the specified hooks. - * - * @param versionSelector The version selector to use, must not be {@code null}. - * @param scopeSelector The scope selector to use, must not be {@code null}. - * @param optionalitySelector The optionality selector ot use, must not be {@code null}. - * @param scopeDeriver The scope deriver to use, must not be {@code null}. - */ - public ConflictResolver( VersionSelector versionSelector, ScopeSelector scopeSelector, - OptionalitySelector optionalitySelector, ScopeDeriver scopeDeriver ) - { - if ( versionSelector == null ) - { - throw new IllegalArgumentException( "version selector not specified" ); - } - this.versionSelector = versionSelector; - if ( scopeSelector == null ) - { - throw new IllegalArgumentException( "scope selector not specified" ); - } - this.scopeSelector = scopeSelector; - if ( scopeDeriver == null ) - { - throw new IllegalArgumentException( "scope deriver not specified" ); - } - this.scopeDeriver = scopeDeriver; - if ( optionalitySelector == null ) - { - throw new IllegalArgumentException( "optionality selector not specified" ); - } - this.optionalitySelector = optionalitySelector; - } - - public DependencyNode transformGraph( DependencyNode node, DependencyGraphTransformationContext context ) - throws RepositoryException - { - List sortedConflictIds = (List) context.get( TransformationContextKeys.SORTED_CONFLICT_IDS ); - if ( sortedConflictIds == null ) - { - ConflictIdSorter sorter = new ConflictIdSorter(); - sorter.transformGraph( node, context ); - - sortedConflictIds = (List) context.get( TransformationContextKeys.SORTED_CONFLICT_IDS ); - } - -// @SuppressWarnings( "unchecked" ) -// Map stats = (Map) context.get( TransformationContextKeys.STATS ); -// long time1 = System.currentTimeMillis(); - - @SuppressWarnings( "unchecked" ) - Collection> conflictIdCycles = - (Collection>) context.get( TransformationContextKeys.CYCLIC_CONFLICT_IDS ); - if ( conflictIdCycles == null ) - { - throw new RepositoryException( "conflict id cycles have not been identified" ); - } - - Map conflictIds = (Map) context.get( TransformationContextKeys.CONFLICT_IDS ); - if ( conflictIds == null ) - { - throw new RepositoryException( "conflict groups have not been identified" ); - } - - Map> cyclicPredecessors = new HashMap<>(); - for ( Collection cycle : conflictIdCycles ) - { - for ( Object conflictId : cycle ) - { - Collection predecessors = - cyclicPredecessors.computeIfAbsent( conflictId, k -> new HashSet<>() ); - predecessors.addAll( cycle ); - } - } - - State state = new State( node, conflictIds, sortedConflictIds.size(), context ); - for ( Iterator it = sortedConflictIds.iterator(); it.hasNext(); ) - { - Object conflictId = it.next(); - - // reset data structures for next graph walk - state.prepare( conflictId, cyclicPredecessors.get( conflictId ) ); - - // find nodes with the current conflict id and while walking the graph (more deeply), nuke leftover losers - gatherConflictItems( node, state ); - - // now that we know the min depth of the parents, update depth of conflict items - state.finish(); - - // earlier runs might have nuked all parents of the current conflict id, so it might not exist anymore - if ( !state.items.isEmpty() ) - { - ConflictContext ctx = state.conflictCtx; - state.versionSelector.selectVersion( ctx ); - if ( ctx.winner == null ) - { - throw new RepositoryException( "conflict resolver did not select winner among " + state.items ); - } - DependencyNode winner = ctx.winner.node; - - state.scopeSelector.selectScope( ctx ); - if ( state.verbose ) - { - winner.setData( NODE_DATA_ORIGINAL_SCOPE, winner.getDependency().getScope() ); - } - winner.setScope( ctx.scope ); - - state.optionalitySelector.selectOptionality( ctx ); - if ( state.verbose ) - { - winner.setData( NODE_DATA_ORIGINAL_OPTIONALITY, winner.getDependency().isOptional() ); - } - winner.getDependency().setOptional( ctx.optional ); -// winner.setOptional( ctx.optional ); - - removeLosers( state ); - } - - // record the winner so we can detect leftover losers during future graph walks - state.winner(); - - // in case of cycles, trigger final graph walk to ensure all leftover losers are gone - if ( !it.hasNext() && !conflictIdCycles.isEmpty() && state.conflictCtx.winner != null ) - { - DependencyNode winner = state.conflictCtx.winner.node; - state.prepare( state, null ); - gatherConflictItems( winner, state ); - } - } - -// if ( stats != null ) -// { -// long time2 = System.currentTimeMillis(); -// stats.put( "ConflictResolver.totalTime", time2 - time1 ); -// stats.put( "ConflictResolver.conflictItemCount", state.totalConflictItems ); -// } - - return node; - } - - private boolean gatherConflictItems( DependencyNode node, State state ) - throws RepositoryException - { - Object conflictId = state.conflictIds.get( node ); - if ( state.currentId.equals( conflictId ) ) - { - // found it, add conflict item (if not already done earlier by another path) - state.add( node ); - // we don't recurse here so we might miss losers beneath us, those will be nuked during future walks below - } - else if ( state.loser( node, conflictId ) ) - { - // found a leftover loser (likely in a cycle) of an already processed conflict id, tell caller to nuke it - return false; - } - else if ( state.push( node, conflictId ) ) - { - // found potential parent, no cycle and not visisted before with the same derived scope, so recurse - for ( Iterator it = node.getChildren().iterator(); it.hasNext(); ) - { - DependencyNode child = it.next(); - if ( !gatherConflictItems( child, state ) ) - { - it.remove(); - } - } - state.pop(); - } - return true; - } - - private void removeLosers( State state ) - { - ConflictItem winner = state.conflictCtx.winner; - List previousParent = null; - ListIterator childIt = null; - boolean conflictVisualized = false; - for ( ConflictItem item : state.items ) - { - if ( item == winner ) - { - continue; - } - if ( item.parent != previousParent ) - { - childIt = item.parent.listIterator(); - previousParent = item.parent; - conflictVisualized = false; - } - while ( childIt.hasNext() ) - { - DependencyNode child = childIt.next(); - if ( child == item.node ) - { - if ( state.verbose && !conflictVisualized && item.parent != winner.parent ) - { - conflictVisualized = true; - DependencyNode loser = new DefaultDependencyNode( child ); - loser.setData( NODE_DATA_WINNER, winner.node ); - loser.setData( NODE_DATA_ORIGINAL_SCOPE, loser.getDependency().getScope() ); - loser.setData( NODE_DATA_ORIGINAL_OPTIONALITY, loser.getDependency().isOptional() ); - loser.setScope( item.getScopes().iterator().next() ); -// loser.setChildren( Collections.emptyList() ); - childIt.set( loser ); - } - else - { - childIt.remove(); - } - break; - } - } - } - // there might still be losers beneath the winner (e.g. in case of cycles) - // those will be nuked during future graph walks when we include the winner in the recursion - } - - static final class NodeInfo - { - - /** - * The smallest depth at which the node was seen, used for "the" depth of its conflict items. - */ - int minDepth; - - /** - * The set of derived scopes the node was visited with, used to check whether an already seen node needs to be - * revisited again in context of another scope. To conserve memory, we start with {@code String} and update to - * {@code Set} if needed. - */ - Object derivedScopes; - - /** - * The set of derived optionalities the node was visited with, used to check whether an already seen node needs - * to be revisited again in context of another optionality. To conserve memory, encoded as bit field (bit 0 -> - * optional=false, bit 1 -> optional=true). - */ - int derivedOptionalities; - - /** - * The conflict items which are immediate children of the node, used to easily update those conflict items after - * a new parent scope/optionality was encountered. - */ - List children; - - static final int CHANGE_SCOPE = 0x01; - - static final int CHANGE_OPTIONAL = 0x02; - - private static final int OPT_FALSE = 0x01; - - private static final int OPT_TRUE = 0x02; - - NodeInfo( int depth, String derivedScope, boolean optional ) - { - minDepth = depth; - derivedScopes = derivedScope; - derivedOptionalities = optional ? OPT_TRUE : OPT_FALSE; - } - - @SuppressWarnings( "unchecked" ) - int update( int depth, String derivedScope, boolean optional ) - { - if ( depth < minDepth ) - { - minDepth = depth; - } - int changes; - if ( derivedScopes.equals( derivedScope ) ) - { - changes = 0; - } - else if ( derivedScopes instanceof Collection ) - { - changes = ( (Collection) derivedScopes ).add( derivedScope ) ? CHANGE_SCOPE : 0; - } - else - { - Collection scopes = new HashSet<>(); - scopes.add( (String) derivedScopes ); - scopes.add( derivedScope ); - derivedScopes = scopes; - changes = CHANGE_SCOPE; - } - int bit = optional ? OPT_TRUE : OPT_FALSE; - if ( ( derivedOptionalities & bit ) == 0 ) - { - derivedOptionalities |= bit; - changes |= CHANGE_OPTIONAL; - } - return changes; - } - - void add( ConflictItem item ) - { - if ( children == null ) - { - children = new ArrayList<>( 1 ); - } - children.add( item ); - } - - } - - final class State - { - - /** - * The conflict id currently processed. - */ - Object currentId; - - /** - * Stats counter. - */ - int totalConflictItems; - - /** - * Flag whether we should keep losers in the graph to enable visualization/troubleshooting of conflicts. - */ - final boolean verbose; - - /** - * A mapping from conflict id to winner node, helps to recognize nodes that have their effective - * scope&optionality set or are leftovers from previous removals. - */ - final Map resolvedIds; - - /** - * The set of conflict ids which could apply to ancestors of nodes with the current conflict id, used to avoid - * recursion early on. This is basically a superset of the key set of resolvedIds, the additional ids account - * for cyclic dependencies. - */ - final Collection potentialAncestorIds; - - /** - * The output from the conflict marker - */ - final Map conflictIds; - - /** - * The conflict items we have gathered so far for the current conflict id. - */ - final List items; - - /** - * The (conceptual) mapping from nodes to extra infos, technically keyed by the node's child list which better - * captures the identity of a node since we're basically concerned with effects towards children. - */ - final Map, NodeInfo> infos; - - /** - * The set of nodes on the DFS stack to detect cycles, technically keyed by the node's child list to match the - * dirty graph structure produced by the dependency collector for cycles. - */ - final Map, Object> stack; - - /** - * The stack of parent nodes. - */ - final List parentNodes; - - /** - * The stack of derived scopes for parent nodes. - */ - final List parentScopes; - - /** - * The stack of derived optional flags for parent nodes. - */ - final List parentOptionals; - - /** - * The stack of node infos for parent nodes, may contain {@code null} which is used to disable creating new - * conflict items when visiting their parent again (conflict items are meant to be unique by parent-node combo). - */ - final List parentInfos; - - /** - * The conflict context passed to the version/scope/optionality selectors, updated as we move along rather than - * recreated to avoid tmp objects. - */ - final ConflictContext conflictCtx; - - /** - * The scope context passed to the scope deriver, updated as we move along rather than recreated to avoid tmp - * objects. - */ - final ScopeContext scopeCtx; - - /** - * The effective version selector, i.e. after initialization. - */ - final VersionSelector versionSelector; - - /** - * The effective scope selector, i.e. after initialization. - */ - final ScopeSelector scopeSelector; - - /** - * The effective scope deriver, i.e. after initialization. - */ - final ScopeDeriver scopeDeriver; - - /** - * The effective optionality selector, i.e. after initialization. - */ - final OptionalitySelector optionalitySelector; - - State( DependencyNode root, Map conflictIds, int conflictIdCount, - DependencyGraphTransformationContext context ) - throws RepositoryException - { - this.conflictIds = conflictIds; - verbose = ConfigUtils.getBoolean( context.getSession(), false, CONFIG_PROP_VERBOSE ); - potentialAncestorIds = new HashSet<>( conflictIdCount * 2 ); - resolvedIds = new HashMap<>( conflictIdCount * 2 ); - items = new ArrayList<>( 256 ); - infos = new IdentityHashMap<>( 64 ); - stack = new IdentityHashMap<>( 64 ); - parentNodes = new ArrayList<>( 64 ); - parentScopes = new ArrayList<>( 64 ); - parentOptionals = new ArrayList<>( 64 ); - parentInfos = new ArrayList<>( 64 ); - conflictCtx = new ConflictContext( root, conflictIds, items ); - scopeCtx = new ScopeContext( null, null ); - versionSelector = ConflictResolver.this.versionSelector.getInstance( root, context ); - scopeSelector = ConflictResolver.this.scopeSelector.getInstance( root, context ); - scopeDeriver = ConflictResolver.this.scopeDeriver.getInstance( root, context ); - optionalitySelector = ConflictResolver.this.optionalitySelector.getInstance( root, context ); - } - - void prepare( Object conflictId, Collection cyclicPredecessors ) - { - currentId = conflictId; - conflictCtx.conflictId = conflictId; - conflictCtx.winner = null; - conflictCtx.scope = null; - conflictCtx.optional = null; - items.clear(); - infos.clear(); - if ( cyclicPredecessors != null ) - { - potentialAncestorIds.addAll( cyclicPredecessors ); - } - } - - void finish() - { - List previousParent = null; - int previousDepth = 0; - totalConflictItems += items.size(); - for ( int i = items.size() - 1; i >= 0; i-- ) - { - ConflictItem item = items.get( i ); - if ( item.parent == previousParent ) - { - item.depth = previousDepth; - } - else if ( item.parent != null ) - { - previousParent = item.parent; - NodeInfo info = infos.get( previousParent ); - previousDepth = info.minDepth + 1; - item.depth = previousDepth; - } - } - potentialAncestorIds.add( currentId ); - } - - void winner() - { - resolvedIds.put( currentId, ( conflictCtx.winner != null ) ? conflictCtx.winner.node : null ); - } - - boolean loser( DependencyNode node, Object conflictId ) - { - DependencyNode winner = resolvedIds.get( conflictId ); - return winner != null && winner != node; - } - - boolean push( DependencyNode node, Object conflictId ) - throws RepositoryException - { - if ( conflictId == null ) - { - if ( node.getDependency() != null ) - { - if ( node.getData().get( NODE_DATA_WINNER ) != null ) - { - return false; - } - throw new RepositoryException( "missing conflict id for node " + node ); - } - } - else if ( !potentialAncestorIds.contains( conflictId ) ) - { - return false; - } - - List graphNode = node.getChildren(); - if ( stack.put( graphNode, Boolean.TRUE ) != null ) - { - return false; - } - - int depth = depth(); - String scope = deriveScope( node, conflictId ); - boolean optional = deriveOptional( node, conflictId ); - NodeInfo info = infos.get( graphNode ); - if ( info == null ) - { - info = new NodeInfo( depth, scope, optional ); - infos.put( graphNode, info ); - parentInfos.add( info ); - parentNodes.add( node ); - parentScopes.add( scope ); - parentOptionals.add( optional ); - } - else - { - int changes = info.update( depth, scope, optional ); - if ( changes == 0 ) - { - stack.remove( graphNode ); - return false; - } - parentInfos.add( null ); // disable creating new conflict items, we update the existing ones below - parentNodes.add( node ); - parentScopes.add( scope ); - parentOptionals.add( optional ); - if ( info.children != null ) - { - if ( ( changes & NodeInfo.CHANGE_SCOPE ) != 0 ) - { - for ( int i = info.children.size() - 1; i >= 0; i-- ) - { - ConflictItem item = info.children.get( i ); - String childScope = deriveScope( item.node, null ); - item.addScope( childScope ); - } - } - if ( ( changes & NodeInfo.CHANGE_OPTIONAL ) != 0 ) - { - for ( int i = info.children.size() - 1; i >= 0; i-- ) - { - ConflictItem item = info.children.get( i ); - boolean childOptional = deriveOptional( item.node, null ); - item.addOptional( childOptional ); - } - } - } - } - - return true; - } - - void pop() - { - int last = parentInfos.size() - 1; - parentInfos.remove( last ); - parentScopes.remove( last ); - parentOptionals.remove( last ); - DependencyNode node = parentNodes.remove( last ); - stack.remove( node.getChildren() ); - } - - void add( DependencyNode node ) - throws RepositoryException - { - DependencyNode parent = parent(); - if ( parent == null ) - { - ConflictItem item = newConflictItem( parent, node ); - items.add( item ); - } - else - { - NodeInfo info = parentInfos.get( parentInfos.size() - 1 ); - if ( info != null ) - { - ConflictItem item = newConflictItem( parent, node ); - info.add( item ); - items.add( item ); - } - } - } - - private ConflictItem newConflictItem( DependencyNode parent, DependencyNode node ) - throws RepositoryException - { - return new ConflictItem( parent, node, deriveScope( node, null ), deriveOptional( node, null ) ); - } - - private int depth() - { - return parentNodes.size(); - } - - private DependencyNode parent() - { - int size = parentNodes.size(); - return ( size <= 0 ) ? null : parentNodes.get( size - 1 ); - } - - private String deriveScope( DependencyNode node, Object conflictId ) - throws RepositoryException - { - if ( node.getPremanagedScope() != null - || ( conflictId != null && resolvedIds.containsKey( conflictId ) ) ) -// if ( ( node.getManagedBits() & DependencyNode.MANAGED_SCOPE ) != 0 -// || ( conflictId != null && resolvedIds.containsKey( conflictId ) ) ) - { - return scope( node.getDependency() ); - } - - int depth = parentNodes.size(); - scopes( depth, node.getDependency() ); - if ( depth > 0 ) - { - scopeDeriver.deriveScope( scopeCtx ); - } - return scopeCtx.derivedScope; - } - - private void scopes( int parent, Dependency child ) - { - scopeCtx.parentScope = ( parent > 0 ) ? parentScopes.get( parent - 1 ) : null; - scopeCtx.derivedScope = scope( child ); - scopeCtx.childScope = scopeCtx.derivedScope; - } - - private String scope( Dependency dependency ) - { - return ( dependency != null ) ? dependency.getScope() : null; - } - - private boolean deriveOptional( DependencyNode node, Object conflictId ) - { - Dependency dep = node.getDependency(); - boolean optional = dep != null && dep.isOptional(); - if ( optional - || ( node.getData().get( NODE_DATA_ORIGINAL_OPTIONALITY ) != null - && (Boolean) node.getData().get( NODE_DATA_ORIGINAL_OPTIONALITY ) ) - || ( conflictId != null && resolvedIds.containsKey( conflictId ) ) ) -// if ( optional || ( node.getManagedBits() & DependencyNode.MANAGED_OPTIONAL ) != 0 -// || ( conflictId != null && resolvedIds.containsKey( conflictId ) ) ) - { - return optional; - } - int depth = parentNodes.size(); - return ( depth > 0 ) ? parentOptionals.get( depth - 1 ) : false; - } - - } - - /** - * A context used to hold information that is relevant for deriving the scope of a child dependency. - * - * @see ScopeDeriver - * This class is not intended to be instantiated by clients in production code, the constructor may - * change without notice and only exists to enable unit testing. - */ - public static final class ScopeContext - { - - String parentScope; - - String childScope; - - String derivedScope; - - /** - * Creates a new scope context with the specified properties. - * - * @param parentScope The scope of the parent dependency, may be {@code null}. - * @param childScope The scope of the child dependency, may be {@code null}. - * This class is not intended to be instantiated by clients in production code, the constructor may - * change without notice and only exists to enable unit testing. - */ - public ScopeContext( String parentScope, String childScope ) - { - this.parentScope = ( parentScope != null ) ? parentScope : ""; - derivedScope = ( childScope != null ) ? childScope : ""; - this.childScope = derivedScope; - } - - /** - * Gets the scope of the parent dependency. This is usually the scope that was derived by earlier invocations of - * the scope deriver. - * - * @return The scope of the parent dependency, never {@code null}. - */ - public String getParentScope() - { - return parentScope; - } - - /** - * Gets the original scope of the child dependency. This is the scope that was declared in the artifact - * descriptor of the parent dependency. - * - * @return The original scope of the child dependency, never {@code null}. - */ - public String getChildScope() - { - return childScope; - } - - /** - * Gets the derived scope of the child dependency. This is initially equal to {@link #getChildScope()} until the - * scope deriver makes changes. - * - * @return The derived scope of the child dependency, never {@code null}. - */ - public String getDerivedScope() - { - return derivedScope; - } - - /** - * Sets the derived scope of the child dependency. - * - * @param derivedScope The derived scope of the dependency, may be {@code null}. - */ - public void setDerivedScope( String derivedScope ) - { - this.derivedScope = ( derivedScope != null ) ? derivedScope : ""; - } - - } - - /** - * A conflicting dependency. - * - * This class is not intended to be instantiated by clients in production code, the constructor may - * change without notice and only exists to enable unit testing. - */ - public static final class ConflictItem - { - - // nodes can share child lists, we care about the unique owner of a child node which is the child list - final List parent; - - // only for debugging/toString() to help identify the parent node(s) - final Artifact artifact; - - final DependencyNode node; - - int depth; - - // we start with String and update to Set if needed - Object scopes; - - // bit field of OPTIONAL_FALSE and OPTIONAL_TRUE - int optionalities; - - /** - * Bit flag indicating whether one or more paths consider the dependency non-optional. - */ - public static final int OPTIONAL_FALSE = 0x01; - - /** - * Bit flag indicating whether one or more paths consider the dependency optional. - */ - public static final int OPTIONAL_TRUE = 0x02; - - ConflictItem( DependencyNode parent, DependencyNode node, String scope, boolean optional ) - { - if ( parent != null ) - { - this.parent = parent.getChildren(); - this.artifact = parent.getDependency().getArtifact(); -// this.artifact = parent.getArtifact(); - } - else - { - this.parent = null; - this.artifact = null; - } - this.node = node; - this.scopes = scope; - this.optionalities = optional ? OPTIONAL_TRUE : OPTIONAL_FALSE; - } - - /** - * Creates a new conflict item with the specified properties. - * - * @param parent The parent node of the conflicting dependency, may be {@code null}. - * @param node The conflicting dependency, must not be {@code null}. - * @param depth The zero-based depth of the conflicting dependency. - * @param optionalities The optionalities the dependency was encountered with, encoded as a bit field consisting - * of {@link ConflictResolver.ConflictItem#OPTIONAL_TRUE} and - * {@link ConflictResolver.ConflictItem#OPTIONAL_FALSE}. - * @param scopes The derived scopes of the conflicting dependency, must not be {@code null}. - * This class is not intended to be instantiated by clients in production code, the constructor may - * change without notice and only exists to enable unit testing. - */ - public ConflictItem( DependencyNode parent, DependencyNode node, int depth, int optionalities, - String... scopes ) - { - this.parent = ( parent != null ) ? parent.getChildren() : null; - this.artifact = ( parent != null ) ? parent.getDependency().getArtifact() : null; -// this.artifact = ( parent != null ) ? parent.getArtifact() : null; - this.node = node; - this.depth = depth; - this.optionalities = optionalities; - this.scopes = Arrays.asList( scopes ); - } - - /** - * Determines whether the specified conflict item is a sibling of this item. - * - * @param item The other conflict item, must not be {@code null}. - * @return {@code true} if the given item has the same parent as this item, {@code false} otherwise. - */ - public boolean isSibling( ConflictItem item ) - { - return parent == item.parent; - } - - /** - * Gets the dependency node involved in the conflict. - * - * @return The involved dependency node, never {@code null}. - */ - public DependencyNode getNode() - { - return node; - } - - /** - * Gets the dependency involved in the conflict, short for {@code getNode.getDependency()}. - * - * @return The involved dependency, never {@code null}. - */ - public Dependency getDependency() - { - return node.getDependency(); - } - - /** - * Gets the zero-based depth at which the conflicting node occurs in the graph. As such, the depth denotes the - * number of parent nodes. If actually multiple paths lead to the node, the return value denotes the smallest - * possible depth. - * - * @return The zero-based depth of the node in the graph. - */ - public int getDepth() - { - return depth; - } - - /** - * Gets the derived scopes of the dependency. In general, the same dependency node could be reached via - * different paths and each path might result in a different derived scope. - * - * @see ScopeDeriver - * @return The (read-only) set of derived scopes of the dependency, never {@code null}. - */ - @SuppressWarnings( "unchecked" ) - public Collection getScopes() - { - if ( scopes instanceof String ) - { - return Collections.singleton( (String) scopes ); - } - return (Collection) scopes; - } - - @SuppressWarnings( "unchecked" ) - void addScope( String scope ) - { - if ( scopes instanceof Collection ) - { - ( (Collection) scopes ).add( scope ); - } - else if ( !scopes.equals( scope ) ) - { - Collection set = new HashSet<>(); - set.add( scopes ); - set.add( scope ); - scopes = set; - } - } - - /** - * Gets the derived optionalities of the dependency. In general, the same dependency node could be reached via - * different paths and each path might result in a different derived optionality. - * - * @return A bit field consisting of {@link ConflictResolver.ConflictItem#OPTIONAL_FALSE} and/or - * {@link ConflictResolver.ConflictItem#OPTIONAL_TRUE} indicating the derived optionalities the - * dependency was encountered with. - */ - public int getOptionalities() - { - return optionalities; - } - - void addOptional( boolean optional ) - { - optionalities |= optional ? OPTIONAL_TRUE : OPTIONAL_FALSE; - } - - @Override - public String toString() - { - return node + " @ " + depth + " < " + artifact; - } - - } - - /** - * A context used to hold information that is relevant for resolving version and scope conflicts. - * - * @see VersionSelector - * @see ScopeSelector - * This class is not intended to be instantiated by clients in production code, the constructor may - * change without notice and only exists to enable unit testing. - */ - public static final class ConflictContext - { - - final DependencyNode root; - - final Map conflictIds; - - final Collection items; - - Object conflictId; - - ConflictItem winner; - - String scope; - - Boolean optional; - - ConflictContext( DependencyNode root, Map conflictIds, Collection items ) - { - this.root = root; - this.conflictIds = conflictIds; - this.items = Collections.unmodifiableCollection( items ); - } - - /** - * Creates a new conflict context. - * - * @param root The root node of the dependency graph, must not be {@code null}. - * @param conflictId The conflict id for the set of conflicting dependencies in this context, must not be - * {@code null}. - * @param conflictIds The mapping from dependency node to conflict id, must not be {@code null}. - * @param items The conflict items in this context, must not be {@code null}. - * This class is not intended to be instantiated by clients in production code, the constructor may - * change without notice and only exists to enable unit testing. - */ - public ConflictContext( DependencyNode root, Object conflictId, Map conflictIds, - Collection items ) - { - this( root, conflictIds, items ); - this.conflictId = conflictId; - } - - /** - * Gets the root node of the dependency graph being transformed. - * - * @return The root node of the dependeny graph, never {@code null}. - */ - public DependencyNode getRoot() - { - return root; - } - - /** - * Determines whether the specified dependency node belongs to this conflict context. - * - * @param node The dependency node to check, must not be {@code null}. - * @return {@code true} if the given node belongs to this conflict context, {@code false} otherwise. - */ - public boolean isIncluded( DependencyNode node ) - { - return conflictId.equals( conflictIds.get( node ) ); - } - - /** - * Gets the collection of conflict items in this context. - * - * @return The (read-only) collection of conflict items in this context, never {@code null}. - */ - public Collection getItems() - { - return items; - } - - /** - * Gets the conflict item which has been selected as the winner among the conflicting dependencies. - * - * @return The winning conflict item or {@code null} if not set yet. - */ - public ConflictItem getWinner() - { - return winner; - } - - /** - * Sets the conflict item which has been selected as the winner among the conflicting dependencies. - * - * @param winner The winning conflict item, may be {@code null}. - */ - public void setWinner( ConflictItem winner ) - { - this.winner = winner; - } - - /** - * Gets the effective scope of the winning dependency. - * - * @return The effective scope of the winning dependency or {@code null} if none. - */ - public String getScope() - { - return scope; - } - - /** - * Sets the effective scope of the winning dependency. - * - * @param scope The effective scope, may be {@code null}. - */ - public void setScope( String scope ) - { - this.scope = scope; - } - - /** - * Gets the effective optional flag of the winning dependency. - * - * @return The effective optional flag or {@code null} if none. - */ - public Boolean getOptional() - { - return optional; - } - - /** - * Sets the effective optional flag of the winning dependency. - * - * @param optional The effective optional flag, may be {@code null}. - */ - public void setOptional( Boolean optional ) - { - this.optional = optional; - } - - @Override - public String toString() - { - return winner + " @ " + scope + " < " + items; - } - - } - - /** - * An extension point of {@link ConflictResolver} that determines the winner among conflicting dependencies. The - * winning node (and its children) will be retained in the dependency graph, the other nodes will get removed. The - * version selector does not need to deal with potential scope conflicts, these will be addressed afterwards by the - * {@link ScopeSelector}. Implementations must be stateless. - */ - public abstract static class VersionSelector - { - - /** - * Retrieves the version selector for use during the specified graph transformation. The conflict resolver calls - * this method once per - * {@link ConflictResolver#transformGraph(DependencyNode, DependencyGraphTransformationContext)} invocation to - * allow implementations to prepare any auxiliary data that is needed for their operation. Given that - * implementations need to be stateless, a new instance needs to be returned to hold such auxiliary data. The - * default implementation simply returns the current instance which is appropriate for implementations which do - * not require auxiliary data. - * - * @param root The root node of the (possibly cyclic!) graph to transform, must not be {@code null}. - * @param context The graph transformation context, must not be {@code null}. - * @return The scope deriver to use for the given graph transformation, never {@code null}. - * @throws RepositoryException If the instance could not be retrieved. - */ - public VersionSelector getInstance( DependencyNode root, DependencyGraphTransformationContext context ) - throws RepositoryException - { - return this; - } - - /** - * Determines the winning node among conflicting dependencies. Implementations will usually iterate - * {@link ConflictContext#getItems()}, inspect {@link ConflictItem#getNode()} and eventually call - * {@link ConflictContext#setWinner(ConflictResolver.ConflictItem)} to deliver the winner. Failure to select a - * winner will automatically fail the entire conflict resolution. - * - * @param context The conflict context, must not be {@code null}. - * @throws RepositoryException If the version selection failed. - */ - public abstract void selectVersion( ConflictContext context ) - throws RepositoryException; - - } - - /** - * An extension point of {@link ConflictResolver} that determines the effective scope of a dependency from a - * potentially conflicting set of {@link ScopeDeriver derived scopes}. The scope selector gets invoked after the - * {@link VersionSelector} has picked the winning node. Implementations must be stateless. - */ - public abstract static class ScopeSelector - { - - /** - * Retrieves the scope selector for use during the specified graph transformation. The conflict resolver calls - * this method once per - * {@link ConflictResolver#transformGraph(DependencyNode, DependencyGraphTransformationContext)} invocation to - * allow implementations to prepare any auxiliary data that is needed for their operation. Given that - * implementations need to be stateless, a new instance needs to be returned to hold such auxiliary data. The - * default implementation simply returns the current instance which is appropriate for implementations which do - * not require auxiliary data. - * - * @param root The root node of the (possibly cyclic!) graph to transform, must not be {@code null}. - * @param context The graph transformation context, must not be {@code null}. - * @return The scope selector to use for the given graph transformation, never {@code null}. - * @throws RepositoryException If the instance could not be retrieved. - */ - public ScopeSelector getInstance( DependencyNode root, DependencyGraphTransformationContext context ) - throws RepositoryException - { - return this; - } - - /** - * Determines the effective scope of the dependency given by {@link ConflictContext#getWinner()}. - * Implementations will usually iterate {@link ConflictContext#getItems()}, inspect - * {@link ConflictItem#getScopes()} and eventually call {@link ConflictContext#setScope(String)} to deliver the - * effective scope. - * - * @param context The conflict context, must not be {@code null}. - * @throws RepositoryException If the scope selection failed. - */ - public abstract void selectScope( ConflictContext context ) - throws RepositoryException; - - } - - /** - * An extension point of {@link ConflictResolver} that determines the scope of a dependency in relation to the scope - * of its parent. Implementations must be stateless. - */ - public abstract static class ScopeDeriver - { - - /** - * Retrieves the scope deriver for use during the specified graph transformation. The conflict resolver calls - * this method once per - * {@link ConflictResolver#transformGraph(DependencyNode, DependencyGraphTransformationContext)} invocation to - * allow implementations to prepare any auxiliary data that is needed for their operation. Given that - * implementations need to be stateless, a new instance needs to be returned to hold such auxiliary data. The - * default implementation simply returns the current instance which is appropriate for implementations which do - * not require auxiliary data. - * - * @param root The root node of the (possibly cyclic!) graph to transform, must not be {@code null}. - * @param context The graph transformation context, must not be {@code null}. - * @return The scope deriver to use for the given graph transformation, never {@code null}. - * @throws RepositoryException If the instance could not be retrieved. - */ - public ScopeDeriver getInstance( DependencyNode root, DependencyGraphTransformationContext context ) - throws RepositoryException - { - return this; - } - - /** - * Determines the scope of a dependency in relation to the scope of its parent. Implementors need to call - * {@link ScopeContext#setDerivedScope(String)} to deliver the result of their calculation. If said method is - * not invoked, the conflict resolver will assume the scope of the child dependency remains unchanged. - * - * @param context The scope context, must not be {@code null}. - * @throws RepositoryException If the scope deriviation failed. - */ - public abstract void deriveScope( ScopeContext context ) - throws RepositoryException; - - } - - /** - * An extension point of {@link ConflictResolver} that determines the effective optional flag of a dependency from a - * potentially conflicting set of derived optionalities. The optionality selector gets invoked after the - * {@link VersionSelector} has picked the winning node. Implementations must be stateless. - */ - public abstract static class OptionalitySelector - { - - /** - * Retrieves the optionality selector for use during the specified graph transformation. The conflict resolver - * calls this method once per - * {@link ConflictResolver#transformGraph(DependencyNode, DependencyGraphTransformationContext)} invocation to - * allow implementations to prepare any auxiliary data that is needed for their operation. Given that - * implementations need to be stateless, a new instance needs to be returned to hold such auxiliary data. The - * default implementation simply returns the current instance which is appropriate for implementations which do - * not require auxiliary data. - * - * @param root The root node of the (possibly cyclic!) graph to transform, must not be {@code null}. - * @param context The graph transformation context, must not be {@code null}. - * @return The optionality selector to use for the given graph transformation, never {@code null}. - * @throws RepositoryException If the instance could not be retrieved. - */ - public OptionalitySelector getInstance( DependencyNode root, DependencyGraphTransformationContext context ) - throws RepositoryException - { - return this; - } - - /** - * Determines the effective optional flag of the dependency given by {@link ConflictContext#getWinner()}. - * Implementations will usually iterate {@link ConflictContext#getItems()}, inspect - * {@link ConflictItem#getOptionalities()} and eventually call {@link ConflictContext#setOptional(Boolean)} to - * deliver the effective optional flag. - * - * @param context The conflict context, must not be {@code null}. - * @throws RepositoryException If the optionality selection failed. - */ - public abstract void selectOptionality( ConflictContext context ) - throws RepositoryException; - - } - -} diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/ExclusionDependencySelector.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/ExclusionDependencySelector.java deleted file mode 100644 index 2808595..0000000 --- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/ExclusionDependencySelector.java +++ /dev/null @@ -1,228 +0,0 @@ -package org.apache.maven.shared.dependency.graph.internal.maven30; - -/* - * 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 java.util.Collection; -import java.util.Comparator; -import java.util.TreeSet; - -import org.sonatype.aether.artifact.Artifact; -import org.sonatype.aether.collection.DependencyCollectionContext; -import org.sonatype.aether.collection.DependencySelector; -import org.sonatype.aether.graph.Dependency; -import org.sonatype.aether.graph.Exclusion; - -/** - * This class is a copy of their homonymous in the Eclipse Aether library, adapted to work with Sonatype Aether. - * - * @author Gabriel Belingueres - * @since 3.1.0 - */ -public class ExclusionDependencySelector - implements DependencySelector -{ - - // sorted and dupe-free array, faster to iterate than LinkedHashSet - private final Exclusion[] exclusions; - - private int hashCode; - - /** - * Creates a new selector without any exclusions. - */ - public ExclusionDependencySelector() - { - this.exclusions = new Exclusion[0]; - } - - /** - * Creates a new selector with the specified exclusions. - * - * @param exclusions The exclusions, may be {@code null}. - */ - public ExclusionDependencySelector( Collection exclusions ) - { - if ( exclusions != null && !exclusions.isEmpty() ) - { - TreeSet sorted = new TreeSet<>( ExclusionComparator.INSTANCE ); - sorted.addAll( exclusions ); - this.exclusions = sorted.toArray( new Exclusion[0] ); - } - else - { - this.exclusions = new Exclusion[0]; - } - } - - private ExclusionDependencySelector( Exclusion[] exclusions ) - { - this.exclusions = exclusions; - } - - public boolean selectDependency( Dependency dependency ) - { - Artifact artifact = dependency.getArtifact(); - for ( Exclusion exclusion : exclusions ) - { - if ( matches( exclusion, artifact ) ) - { - return false; - } - } - return true; - } - - private boolean matches( Exclusion exclusion, Artifact artifact ) - { - if ( !matches( exclusion.getArtifactId(), artifact.getArtifactId() ) ) - { - return false; - } - if ( !matches( exclusion.getGroupId(), artifact.getGroupId() ) ) - { - return false; - } - if ( !matches( exclusion.getExtension(), artifact.getExtension() ) ) - { - return false; - } - if ( !matches( exclusion.getClassifier(), artifact.getClassifier() ) ) - { - return false; - } - return true; - } - - private boolean matches( String pattern, String value ) - { - return "*".equals( pattern ) || pattern.equals( value ); - } - - public DependencySelector deriveChildSelector( DependencyCollectionContext context ) - { - Dependency dependency = context.getDependency(); - Collection exclusions = ( dependency != null ) ? dependency.getExclusions() : null; - if ( exclusions == null || exclusions.isEmpty() ) - { - return this; - } - - Exclusion[] merged = this.exclusions; - int count = merged.length; - for ( Exclusion exclusion : exclusions ) - { - int index = Arrays.binarySearch( merged, exclusion, ExclusionComparator.INSTANCE ); - if ( index < 0 ) - { - index = -( index + 1 ); - if ( count >= merged.length ) - { - Exclusion[] tmp = new Exclusion[merged.length + exclusions.size()]; - System.arraycopy( merged, 0, tmp, 0, index ); - tmp[index] = exclusion; - System.arraycopy( merged, index, tmp, index + 1, count - index ); - merged = tmp; - } - else - { - System.arraycopy( merged, index, merged, index + 1, count - index ); - merged[index] = exclusion; - } - count++; - } - } - if ( merged == this.exclusions ) - { - return this; - } - if ( merged.length != count ) - { - Exclusion[] tmp = new Exclusion[count]; - System.arraycopy( merged, 0, tmp, 0, count ); - merged = tmp; - } - - return new ExclusionDependencySelector( merged ); - } - - @Override - public boolean equals( Object obj ) - { - if ( this == obj ) - { - return true; - } - else if ( null == obj || !getClass().equals( obj.getClass() ) ) - { - return false; - } - - ExclusionDependencySelector that = (ExclusionDependencySelector) obj; - return Arrays.equals( exclusions, that.exclusions ); - } - - @Override - public int hashCode() - { - if ( hashCode == 0 ) - { - int hash = getClass().hashCode(); - hash = hash * 31 + Arrays.hashCode( exclusions ); - hashCode = hash; - } - return hashCode; - } - - private static class ExclusionComparator - implements Comparator - { - - static final ExclusionComparator INSTANCE = new ExclusionComparator(); - - public int compare( Exclusion e1, Exclusion e2 ) - { - if ( e1 == null ) - { - return ( e2 == null ) ? 0 : 1; - } - else if ( e2 == null ) - { - return -1; - } - int rel = e1.getArtifactId().compareTo( e2.getArtifactId() ); - if ( rel == 0 ) - { - rel = e1.getGroupId().compareTo( e2.getGroupId() ); - if ( rel == 0 ) - { - rel = e1.getExtension().compareTo( e2.getExtension() ); - if ( rel == 0 ) - { - rel = e1.getClassifier().compareTo( e2.getClassifier() ); - } - } - } - return rel; - } - - } - -} diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/JavaScopeDeriver.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/JavaScopeDeriver.java deleted file mode 100644 index d35abf0..0000000 --- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/JavaScopeDeriver.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.apache.maven.shared.dependency.graph.internal.maven30; - -/* - * 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.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ScopeContext; -import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ScopeDeriver; -import org.sonatype.aether.RepositoryException; -import org.sonatype.aether.util.artifact.JavaScopes; - -/** - * This class is a copy of their homonymous in the Eclipse Aether library, adapted to work with Sonatype Aether. - * - * @author Gabriel Belingueres - * @since 3.1.0 - */ -public class JavaScopeDeriver - extends ScopeDeriver -{ - - @Override - public void deriveScope( ScopeContext context ) - throws RepositoryException - { - context.setDerivedScope( getDerivedScope( context.getParentScope(), context.getChildScope() ) ); - } - - private String getDerivedScope( String parentScope, String childScope ) - { - String derivedScope; - - if ( JavaScopes.SYSTEM.equals( childScope ) || JavaScopes.TEST.equals( childScope ) ) - { - derivedScope = childScope; - } - else if ( parentScope == null || parentScope.length() <= 0 || JavaScopes.COMPILE.equals( parentScope ) ) - { - derivedScope = childScope; - } - else if ( JavaScopes.TEST.equals( parentScope ) || JavaScopes.RUNTIME.equals( parentScope ) ) - { - derivedScope = parentScope; - } - else if ( JavaScopes.SYSTEM.equals( parentScope ) || JavaScopes.PROVIDED.equals( parentScope ) ) - { - derivedScope = JavaScopes.PROVIDED; - } - else - { - derivedScope = JavaScopes.RUNTIME; - } - - return derivedScope; - } - -} diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/JavaScopeSelector.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/JavaScopeSelector.java deleted file mode 100644 index 1950a92..0000000 --- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/JavaScopeSelector.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.apache.maven.shared.dependency.graph.internal.maven30; - -/* - * 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.Collection; -import java.util.HashSet; -import java.util.Set; - -import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ConflictContext; -import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ConflictItem; -import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ScopeSelector; -import org.sonatype.aether.RepositoryException; -import org.sonatype.aether.util.artifact.JavaScopes; - -/** - * This class is a copy of their homonymous in the Eclipse Aether library, adapted to work with Sonatype Aether. - * - * @author Gabriel Belingueres - * @since 3.1.0 - */ -public final class JavaScopeSelector - extends ScopeSelector -{ - - @Override - public void selectScope( ConflictContext context ) - throws RepositoryException - { - String scope = context.getWinner().getDependency().getScope(); - if ( !JavaScopes.SYSTEM.equals( scope ) ) - { - scope = chooseEffectiveScope( context.getItems() ); - } - context.setScope( scope ); - } - - private String chooseEffectiveScope( Collection items ) - { - Set scopes = new HashSet<>(); - for ( ConflictItem item : items ) - { - if ( item.getDepth() <= 1 ) - { - return item.getDependency().getScope(); - } - scopes.addAll( item.getScopes() ); - } - return chooseEffectiveScope( scopes ); - } - - private String chooseEffectiveScope( Set scopes ) - { - if ( scopes.size() > 1 ) - { - scopes.remove( JavaScopes.SYSTEM ); - } - - String effectiveScope = ""; - - if ( scopes.size() == 1 ) - { - effectiveScope = scopes.iterator().next(); - } - else if ( scopes.contains( JavaScopes.COMPILE ) ) - { - effectiveScope = JavaScopes.COMPILE; - } - else if ( scopes.contains( JavaScopes.RUNTIME ) ) - { - effectiveScope = JavaScopes.RUNTIME; - } - else if ( scopes.contains( JavaScopes.PROVIDED ) ) - { - effectiveScope = JavaScopes.PROVIDED; - } - else if ( scopes.contains( JavaScopes.TEST ) ) - { - effectiveScope = JavaScopes.TEST; - } - - return effectiveScope; - } - - -} diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/Maven3DirectScopeDependencySelector.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/Maven3DirectScopeDependencySelector.java deleted file mode 100644 index 9373b90..0000000 --- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/Maven3DirectScopeDependencySelector.java +++ /dev/null @@ -1,132 +0,0 @@ -package org.apache.maven.shared.dependency.graph.internal.maven30; - -/* - * 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.sonatype.aether.collection.DependencyCollectionContext; -import org.sonatype.aether.collection.DependencySelector; -import org.sonatype.aether.graph.Dependency; - -/** - * A dependency selector that excludes dependencies of an specific Scope which occur beyond level one of the dependency - * graph. - * - * @see Dependency#getScope() - * @author Gabriel Belingueres - * @since 3.1.0 - */ -public class Maven3DirectScopeDependencySelector - implements DependencySelector -{ - - private final String scope; - - private final int depth; - - public Maven3DirectScopeDependencySelector( String scope ) - { - this( scope, 0 ); - } - - private Maven3DirectScopeDependencySelector( String scope, int depth ) - { - if ( scope == null ) - { - throw new IllegalArgumentException( "scope is null!" ); - } - this.scope = scope; - this.depth = depth; - } - - /** - * Decides whether the specified dependency should be included in the dependency graph. - * - * @param dependency The dependency to check, must not be {@code null}. - * @return {@code false} if the dependency should be excluded from the children of the current node, {@code true} - * otherwise. - */ - @Override - public boolean selectDependency( Dependency dependency ) - { - return depth < 2 || !scope.equals( dependency.getScope() ); - } - - /** - * Derives a dependency selector for the specified collection context. When calculating the child selector, - * implementors are strongly advised to simply return the current instance if nothing changed to help save memory. - * - * @param context The dependency collection context, must not be {@code null}. - * @return The dependency selector for the target node, must not be {@code null}. - */ - @Override - public DependencySelector deriveChildSelector( DependencyCollectionContext context ) - { - if ( depth >= 2 ) - { - return this; - } - - return new Maven3DirectScopeDependencySelector( scope, depth + 1 ); - } - - @Override - public int hashCode() - { - final int prime = 31; - int result = 1; - result = prime * result + depth; - result = prime * result + ( ( scope == null ) ? 0 : scope.hashCode() ); - return result; - } - - @Override - public boolean equals( Object obj ) - { - if ( this == obj ) - { - return true; - } - if ( obj == null ) - { - return false; - } - if ( getClass() != obj.getClass() ) - { - return false; - } - Maven3DirectScopeDependencySelector other = (Maven3DirectScopeDependencySelector) obj; - if ( depth != other.depth ) - { - return false; - } - if ( scope == null ) - { - if ( other.scope != null ) - { - return false; - } - } - else if ( !scope.equals( other.scope ) ) - { - return false; - } - return true; - } - -} diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/NearestVersionSelector.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/NearestVersionSelector.java deleted file mode 100644 index 31af5b8..0000000 --- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/NearestVersionSelector.java +++ /dev/null @@ -1,176 +0,0 @@ -package org.apache.maven.shared.dependency.graph.internal.maven30; - -/* - * 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.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; - -import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ConflictContext; -import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ConflictItem; -import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.VersionSelector; -import org.sonatype.aether.RepositoryException; -import org.sonatype.aether.collection.UnsolvableVersionConflictException; -import org.sonatype.aether.graph.DependencyFilter; -import org.sonatype.aether.graph.DependencyNode; -import org.sonatype.aether.util.graph.PathRecordingDependencyVisitor; -import org.sonatype.aether.version.Version; -import org.sonatype.aether.version.VersionConstraint; - -/** - * This class is a copy of their homonymous in the Eclipse Aether library, adapted to work with Sonatype Aether. - * - * @author Gabriel Belingueres - * @since 3.1.0 - */ -public final class NearestVersionSelector - extends VersionSelector -{ - - @Override - public void selectVersion( ConflictContext context ) - throws RepositoryException - { - ConflictGroup group = new ConflictGroup(); - for ( ConflictItem item : context.getItems() ) - { - DependencyNode node = item.getNode(); - VersionConstraint constraint = node.getVersionConstraint(); - - boolean backtrack = false; - boolean hardConstraint = !constraint.getRanges().isEmpty(); -// boolean hardConstraint = constraint.getRange() != null; - - if ( hardConstraint ) - { - if ( group.constraints.add( constraint ) ) - { - if ( group.winner != null && !constraint.containsVersion( group.winner.getNode().getVersion() ) ) - { - backtrack = true; - } - } - } - - if ( isAcceptable( group, node.getVersion() ) ) - { - group.candidates.add( item ); - - if ( backtrack ) - { - backtrack( group, context ); - } - else if ( group.winner == null || isNearer( item, group.winner ) ) - { - group.winner = item; - } - } - else if ( backtrack ) - { - backtrack( group, context ); - } - } - context.setWinner( group.winner ); - } - - private void backtrack( ConflictGroup group, ConflictContext context ) - throws UnsolvableVersionConflictException - { - group.winner = null; - - for ( Iterator it = group.candidates.iterator(); it.hasNext(); ) - { - ConflictItem candidate = it.next(); - - if ( !isAcceptable( group, candidate.getNode().getVersion() ) ) - { - it.remove(); - } - else if ( group.winner == null || isNearer( candidate, group.winner ) ) - { - group.winner = candidate; - } - } - - if ( group.winner == null ) - { - throw newFailure( context ); - } - } - - private boolean isAcceptable( ConflictGroup group, Version version ) - { - for ( VersionConstraint constraint : group.constraints ) - { - if ( !constraint.containsVersion( version ) ) - { - return false; - } - } - return true; - } - - private boolean isNearer( ConflictItem item1, ConflictItem item2 ) - { - if ( item1.isSibling( item2 ) ) - { - return item1.getNode().getVersion().compareTo( item2.getNode().getVersion() ) > 0; - } - else - { - return item1.getDepth() < item2.getDepth(); - } - } - - private UnsolvableVersionConflictException newFailure( final ConflictContext context ) - { - DependencyFilter filter = ( node, parents ) -> context.isIncluded( node ); - PathRecordingDependencyVisitor visitor = new PathRecordingDependencyVisitor( filter ); - context.getRoot().accept( visitor ); - return new UnsolvableVersionConflictException( visitor.getPaths(), context.conflictId ); -// return new UnsolvableVersionConflictException( visitor.getPaths() ); - } - - static final class ConflictGroup - { - - final Collection constraints; - - final Collection candidates; - - ConflictItem winner; - - ConflictGroup() - { - constraints = new HashSet<>(); - candidates = new ArrayList<>( 64 ); - } - - @Override - public String toString() - { - return String.valueOf( winner ); - } - - } - - -} diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/SimpleOptionalitySelector.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/SimpleOptionalitySelector.java deleted file mode 100644 index d63df0b..0000000 --- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/SimpleOptionalitySelector.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.apache.maven.shared.dependency.graph.internal.maven30; - -/* - * 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.Collection; - -import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ConflictContext; -import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ConflictItem; -import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.OptionalitySelector; -import org.sonatype.aether.RepositoryException; - -/** - * This class is a copy of their homonymous in the Eclipse Aether library, adapted to work with Sonatype Aether. - * - * @author Gabriel Belingueres - * @since 3.1.0 - */ -public class SimpleOptionalitySelector - extends OptionalitySelector -{ - - @Override - public void selectOptionality( ConflictContext context ) - throws RepositoryException - { - boolean optional = chooseEffectiveOptionality( context.getItems() ); - context.setOptional( optional ); - } - - private boolean chooseEffectiveOptionality( Collection items ) - { - boolean optional = true; - for ( ConflictItem item : items ) - { - if ( item.getDepth() <= 1 ) - { - return item.getDependency().isOptional(); - } - if ( ( item.getOptionalities() & ConflictItem.OPTIONAL_FALSE ) != 0 ) - { - optional = false; - } - } - return optional; - } - -} \ No newline at end of file diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/VerboseJavaScopeSelector.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/VerboseJavaScopeSelector.java deleted file mode 100644 index 85b660d..0000000 --- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/VerboseJavaScopeSelector.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.apache.maven.shared.dependency.graph.internal.maven30; - -/* - * 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 java.util.Comparator; -import java.util.List; - -import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ConflictContext; -import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ScopeSelector; -import org.sonatype.aether.RepositoryException; - -/** - * A JavaScopeSelector that keeps track of reduced scopes - * - */ -public class VerboseJavaScopeSelector extends ScopeSelector -{ - public static final String REDUCED_SCOPE = "REDUCED_SCOPE"; - - private final ScopeSelector scopeSelector = new JavaScopeSelector(); - - @Override - public void selectScope( ConflictContext context ) - throws RepositoryException - { - scopeSelector.selectScope( context ); - - context.getItems().stream() - .flatMap( i -> i.getScopes().stream() ) - .distinct() - .max( new ScopeComparator() ) - .filter( s -> s != context.getScope() ) - .ifPresent( s -> context.getWinner().getNode().setData( REDUCED_SCOPE, s ) ); - } - - static class ScopeComparator implements Comparator - { - List orderedScopes = Arrays.asList( "compile", "runtime", "provided", "test" ); - - @Override - public int compare( String lhs, String rhs ) - { - return orderedScopes.indexOf( rhs ) - orderedScopes.indexOf( lhs ); - } - } -} diff --git a/src/site/apt/index.apt.vm b/src/site/apt/index.apt.vm index 7cbf0fe..23b98ef 100644 --- a/src/site/apt/index.apt.vm +++ b/src/site/apt/index.apt.vm @@ -30,10 +30,4 @@ ${project.name} A tree-based API for resolution of Maven project dependencies. - Component entry point is <<<{{{./apidocs/org/apache/maven/shared/dependency/graph/DependencyGraphBuilder.html}DependencyGraphBuilder}}>>>, - which will delegate to appropriate implementation for either Maven 2, Maven 3.0.x or Maven 3.1.x. - - Older Maven 2-specific component entry point is - <<<{{{./apidocs/org/apache/maven/shared/dependency/tree/DependencyTreeBuilder.html}DependencyTreeBuilder}}>>>, - which is consistent with Maven 2 even when used with Maven 3, which can cause inconsistent results between resolved list (consistent - with Maven 3) and resolved tree (consistent with Maven 2): see {{{https://issues.apache.org/jira/browse/MSHARED-167}MSHARED-167}}. + Component entry point is <<<{{{./apidocs/org/apache/maven/shared/dependency/graph/DependencyGraphBuilder.html}DependencyGraphBuilder}}>>>.