diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/Node.java b/api/maven-api-core/src/main/java/org/apache/maven/api/Node.java
index 4d41444109ab..247cc4798390 100644
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/Node.java
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Node.java
@@ -33,7 +33,7 @@
* Represents a dependency node within a Maven project's dependency collector.
*
* @since 4.0.0
- * @see org.apache.maven.api.services.DependencyCollectorResult#getRoot()
+ * @see org.apache.maven.api.services.DependencyResolverResult#getRoot()
*/
@Experimental
@Immutable
diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java b/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java
index 31aeb06b7b8c..720bb85e475d 100644
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java
@@ -496,25 +496,25 @@ Artifact createArtifact(
boolean isVersionSnapshot(@Nonnull String version);
/**
- * Shortcut for {@code getService(DependencyCollector.class).collect(...)}
+ * Shortcut for {@code getService(DependencyResolver.class).collect(...)}
*
* @param artifact artifact for which to get the dependencies, including transitive ones
* @return root node of the dependency graph for the given artifact
*
- * @see org.apache.maven.api.services.DependencyCollector#collect(Session, Artifact)
- * @throws org.apache.maven.api.services.DependencyCollectorException if the dependency collection failed
+ * @see org.apache.maven.api.services.DependencyResolver#collect(Session, Artifact)
+ * @throws org.apache.maven.api.services.DependencyResolverException if the dependency collection failed
*/
@Nonnull
Node collectDependencies(@Nonnull Artifact artifact);
/**
- * Shortcut for {@code getService(DependencyCollector.class).collect(...)}
+ * Shortcut for {@code getService(DependencyResolver.class).collect(...)}
*
* @param project project for which to get the dependencies, including transitive ones
* @return root node of the dependency graph for the given project
*
- * @see org.apache.maven.api.services.DependencyCollector#collect(Session, Project)
- * @throws org.apache.maven.api.services.DependencyCollectorException if the dependency collection failed
+ * @see org.apache.maven.api.services.DependencyResolver#collect(Session, Project)
+ * @throws org.apache.maven.api.services.DependencyResolverException if the dependency collection failed
*/
@Nonnull
Node collectDependencies(@Nonnull Project project);
@@ -524,13 +524,13 @@ Artifact createArtifact(
* only concerned about determining the coordinates of the transitive dependencies and does not actually resolve the
* artifact files.
*
- * Shortcut for {@code getService(DependencyCollector.class).resolve(...)}
+ * Shortcut for {@code getService(DependencyResolver.class).resolve(...)}
*
* @param dependency dependency for which to get transitive dependencies
* @return root node of the dependency graph for the given artifact
*
- * @see org.apache.maven.api.services.DependencyCollector#collect(Session, DependencyCoordinate)
- * @throws org.apache.maven.api.services.DependencyCollectorException if the dependency collection failed
+ * @see org.apache.maven.api.services.DependencyResolver#collect(Session, DependencyCoordinate)
+ * @throws org.apache.maven.api.services.DependencyResolverException if the dependency collection failed
*/
@Nonnull
Node collectDependencies(@Nonnull DependencyCoordinate dependency);
diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyCollector.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyCollector.java
deleted file mode 100644
index 788fd67c8ce8..000000000000
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyCollector.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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.
- */
-package org.apache.maven.api.services;
-
-import org.apache.maven.api.Artifact;
-import org.apache.maven.api.DependencyCoordinate;
-import org.apache.maven.api.Project;
-import org.apache.maven.api.Service;
-import org.apache.maven.api.Session;
-import org.apache.maven.api.annotations.Experimental;
-import org.apache.maven.api.annotations.Nonnull;
-
-/**
- * The DependencyCollector service can be used to collect dependencies
- * for a given artifact and builds a graph of them.
- * The dependencies collection mechanism will not download any artifacts,
- * and only the pom files will be downloaded.
- *
- * @since 4.0.0
- */
-@Experimental
-public interface DependencyCollector extends Service {
-
- /**
- * Collects the transitive dependencies and builds a dependency graph.
- * Note that this operation is only concerned about determining the coordinates of the
- * transitive dependencies and does not actually resolve the artifact files.
- *
- * @param request the dependency collection request, must not be {@code null}
- * @return the collection result, never {@code null}
- * @throws DependencyCollectorException if the dependency tree could not be built
- * @throws IllegalArgumentException if an argument is null or invalid
- *
- * @see DependencyCollector#collect(Session, Project)
- * @see DependencyCollector#collect(Session, DependencyCoordinate)
- * @see DependencyCollector#collect(Session, Artifact)
- */
- @Nonnull
- DependencyCollectorResult collect(@Nonnull DependencyCollectorRequest request);
-
- /**
- * Collects the transitive dependencies of some artifacts and builds a dependency graph. Note that this operation is
- * only concerned about determining the coordinates of the transitive dependencies and does not actually resolve the
- * artifact files.
- *
- * @param session the {@link Session}, must not be {@code null}
- * @param root the Maven Dependency, must not be {@code null}
- * @return the collection result, never {@code null}
- * @throws DependencyCollectorException if the dependency tree could not be built
- * @throws IllegalArgumentException if an argument is null or invalid
- * @see #collect(DependencyCollectorRequest)
- */
- @Nonnull
- default DependencyCollectorResult collect(@Nonnull Session session, @Nonnull DependencyCoordinate root) {
- return collect(DependencyCollectorRequest.build(session, root));
- }
-
- /**
- * Collects the transitive dependencies of some artifacts and builds a dependency graph. Note that this operation is
- * only concerned about determining the coordinates of the transitive dependencies and does not actually resolve the
- * artifact files.
- *
- * @param session the {@link Session}, must not be {@code null}
- * @param project the {@link Project}, must not be {@code null}
- * @return the collection result, never {@code null}
- * @throws DependencyCollectorException if the dependency tree could not be built
- * @throws IllegalArgumentException if an argument is null or invalid
- * @see #collect(DependencyCollectorRequest)
- */
- @Nonnull
- default DependencyCollectorResult collect(@Nonnull Session session, @Nonnull Project project) {
- return collect(DependencyCollectorRequest.build(session, project));
- }
-
- /**
- * Collects the transitive dependencies of some artifacts and builds a dependency graph. Note that this operation is
- * only concerned about determining the coordinates of the transitive dependencies and does not actually resolve the
- * artifact files.
- *
- * @param session the {@link Session}, must not be {@code null}
- * @param artifact the {@link Artifact}, must not be {@code null}
- * @return the collection result, never {@code null}
- * @throws DependencyCollectorException if the dependency tree could not be built
- * @throws IllegalArgumentException if an argument is null or invalid
- * @see #collect(DependencyCollectorRequest)
- */
- @Nonnull
- default DependencyCollectorResult collect(@Nonnull Session session, @Nonnull Artifact artifact) {
- return collect(DependencyCollectorRequest.build(session, artifact));
- }
-}
diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyCollectorException.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyCollectorException.java
deleted file mode 100644
index 466c40ec9b39..000000000000
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyCollectorException.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.
- */
-package org.apache.maven.api.services;
-
-import org.apache.maven.api.annotations.Experimental;
-
-/**
- * Thrown in case of bad artifact descriptors, version ranges or other
- * issues encountered during calculation of the dependency graph.
- *
- * @since 4.0.0
- */
-@Experimental
-public class DependencyCollectorException extends MavenException {
- /**
- *
- */
- private static final long serialVersionUID = -3134726259840210686L;
-
- /**
- * @param message the message you would give for the exception
- * @param cause the cause which is related to the message
- */
- public DependencyCollectorException(String message, Throwable cause) {
- super(message, cause);
- }
-}
diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyCollectorRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyCollectorRequest.java
deleted file mode 100644
index ebaa10b09eb4..000000000000
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyCollectorRequest.java
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * 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.
- */
-package org.apache.maven.api.services;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
-
-import org.apache.maven.api.Artifact;
-import org.apache.maven.api.DependencyCoordinate;
-import org.apache.maven.api.Project;
-import org.apache.maven.api.Session;
-import org.apache.maven.api.annotations.Experimental;
-import org.apache.maven.api.annotations.Immutable;
-import org.apache.maven.api.annotations.Nonnull;
-import org.apache.maven.api.annotations.NotThreadSafe;
-import org.apache.maven.api.annotations.Nullable;
-
-import static org.apache.maven.api.services.BaseRequest.nonNull;
-
-/**
- * A request to collect the transitive dependencies and to build a dependency graph from them. There are three ways to
- * create a dependency graph. First, only the root dependency can be given. Second, a root dependency and direct
- * dependencies can be specified in which case the specified direct dependencies are merged with the direct dependencies
- * retrieved from the artifact descriptor of the root dependency. And last, only direct dependencies can be specified in
- * which case the root node of the resulting graph has no associated dependency.
- *
- * @since 4.0.0
- * @see DependencyCollector#collect(DependencyCollectorRequest)
- */
-@Experimental
-@Immutable
-public interface DependencyCollectorRequest {
-
- @Nonnull
- Session getSession();
-
- Optional getProject();
-
- @Nonnull
- Optional getRootArtifact();
-
- @Nonnull
- Optional getRoot();
-
- @Nonnull
- Collection getDependencies();
-
- @Nonnull
- Collection getManagedDependencies();
-
- boolean getVerbose();
-
- @Nonnull
- static DependencyCollectorRequest build(@Nonnull Session session, Artifact root) {
- return builder()
- .session(nonNull(session, "session cannot be null"))
- .rootArtifact(nonNull(root, "root cannot be null"))
- .build();
- }
-
- @Nonnull
- static DependencyCollectorRequest build(@Nonnull Session session, @Nonnull DependencyCoordinate root) {
- return builder()
- .session(nonNull(session, "session cannot be null"))
- .root(nonNull(root, "root cannot be null"))
- .build();
- }
-
- @Nonnull
- static DependencyCollectorRequest build(@Nonnull Session session, @Nonnull Project project) {
- return builder()
- .session(nonNull(session, "session cannot be null"))
- .project(nonNull(project, "project cannot be null"))
- .build();
- }
-
- @Nonnull
- static DependencyCollectorRequestBuilder builder() {
- return new DependencyCollectorRequestBuilder();
- }
-
- @NotThreadSafe
- class DependencyCollectorRequestBuilder {
-
- Session session;
- Project project;
- Artifact rootArtifact;
- DependencyCoordinate root;
- List dependencies = Collections.emptyList();
- List managedDependencies = Collections.emptyList();
- boolean verbose;
-
- DependencyCollectorRequestBuilder() {}
-
- @Nonnull
- public DependencyCollectorRequestBuilder session(@Nonnull Session session) {
- this.session = session;
- return this;
- }
-
- @Nonnull
- public DependencyCollectorRequestBuilder project(@Nullable Project project) {
- this.project = project;
- return this;
- }
-
- /**
- * Sets the root artifact for the dependency graph.
- * This must not be confused with {@link #root(DependencyCoordinate)}: The root dependency, like any
- * other specified dependency, will be subject to dependency collection/resolution, i.e. should have an artifact
- * descriptor and a corresponding artifact file. The root artifact on the other hand is only used
- * as a label for the root node of the graph in case no root dependency was specified. As such, the configured
- * root artifact is ignored if {@link #root(DependencyCoordinate)} has been set.
- *
- * @param rootArtifact the root artifact for the dependency graph, may be {@code null}
- * @return this request for chaining, never {@code null}
- */
- @Nonnull
- public DependencyCollectorRequestBuilder rootArtifact(@Nullable Artifact rootArtifact) {
- this.rootArtifact = rootArtifact;
- return this;
- }
-
- /**
- * @param root The root dependency
- * @return this request for chaining, never {@code null}
- */
- @Nonnull
- public DependencyCollectorRequestBuilder root(@Nonnull DependencyCoordinate root) {
- this.root = root;
- return this;
- }
-
- /**
- * Sets the direct dependencies. If both a root dependency and direct dependencies are given in the request, the
- * direct dependencies from the request will be merged with the direct dependencies from the root dependency's
- * artifact descriptor, giving higher priority to the dependencies from the request.
- *
- * @param dependencies the direct dependencies, may be {@code null}
- * @return this request for chaining, never {@code null}
- */
- @Nonnull
- public DependencyCollectorRequestBuilder dependencies(@Nullable List dependencies) {
- this.dependencies = (dependencies != null) ? dependencies : Collections.emptyList();
- return this;
- }
-
- /**
- * Adds the specified direct dependency.
- *
- * @param dependency the dependency to add, may be {@code null}
- * @return this request for chaining, never {@code null}
- */
- @Nonnull
- public DependencyCollectorRequestBuilder dependency(@Nullable DependencyCoordinate dependency) {
- if (dependency != null) {
- if (this.dependencies.isEmpty()) {
- this.dependencies = new ArrayList<>();
- }
- this.dependencies.add(dependency);
- }
- return this;
- }
-
- /**
- * Sets the dependency management to apply to transitive dependencies. To clarify, this management does not
- * apply to
- * the direct dependencies of the root node.
- *
- * @param managedDependencies the dependency management, may be {@code null}
- * @return this request for chaining, never {@code null}
- */
- @Nonnull
- public DependencyCollectorRequestBuilder managedDependencies(
- @Nullable List managedDependencies) {
- this.managedDependencies = (managedDependencies != null) ? managedDependencies : Collections.emptyList();
- return this;
- }
-
- /**
- * Adds the specified managed dependency.
- *
- * @param managedDependency The managed dependency to add, may be {@code null} in which case the call
- * will have no effect.
- * @return this request for chaining, never {@code null}
- */
- @Nonnull
- public DependencyCollectorRequestBuilder managedDependency(@Nullable DependencyCoordinate managedDependency) {
- if (managedDependency != null) {
- if (this.managedDependencies.isEmpty()) {
- this.managedDependencies = new ArrayList<>();
- }
- this.managedDependencies.add(managedDependency);
- }
- return this;
- }
-
- /**
- * Specifies that the collection should be verbose.
- *
- * @param verbose whether the collection should be verbose or not
- * @return this request for chaining, never {@code null}
- */
- @Nonnull
- public DependencyCollectorRequestBuilder verbose(boolean verbose) {
- this.verbose = verbose;
- return this;
- }
-
- @Nonnull
- public DependencyCollectorRequest build() {
- return new DefaultDependencyCollectorRequest(
- session, project, rootArtifact, root, dependencies, managedDependencies, verbose);
- }
-
- static class DefaultDependencyCollectorRequest extends BaseRequest implements DependencyCollectorRequest {
- private final Project project;
- private final Artifact rootArtifact;
- private final DependencyCoordinate root;
- private final Collection dependencies;
- private final Collection managedDependencies;
- private final boolean verbose;
-
- /**
- * Creates a request with the specified properties.
- *
- * @param session {@link Session}
- * @param rootArtifact The root dependency whose transitive dependencies should be collected, may be {@code
- * null}.
- */
- DefaultDependencyCollectorRequest(
- @Nonnull Session session,
- @Nullable Project project,
- @Nullable Artifact rootArtifact,
- @Nullable DependencyCoordinate root,
- @Nonnull Collection dependencies,
- @Nonnull Collection managedDependencies,
- boolean verbose) {
- super(session);
- this.project = project;
- this.rootArtifact = rootArtifact;
- this.root = root;
- this.dependencies = unmodifiable(nonNull(dependencies, "dependencies cannot be null"));
- this.managedDependencies =
- unmodifiable(nonNull(managedDependencies, "managedDependencies cannot be null"));
- this.verbose = verbose;
- }
-
- @Nonnull
- @Override
- public Optional getProject() {
- return Optional.ofNullable(project);
- }
-
- @Nonnull
- @Override
- public Optional getRootArtifact() {
- return Optional.ofNullable(rootArtifact);
- }
-
- @Nonnull
- @Override
- public Optional getRoot() {
- return Optional.ofNullable(root);
- }
-
- @Nonnull
- @Override
- public Collection getDependencies() {
- return dependencies;
- }
-
- @Nonnull
- @Override
- public Collection getManagedDependencies() {
- return managedDependencies;
- }
-
- @Override
- public boolean getVerbose() {
- return verbose;
- }
-
- @Nonnull
- @Override
- public String toString() {
- return getRoot() + " -> " + getDependencies();
- }
- }
- }
-}
diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyCollectorResult.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyCollectorResult.java
deleted file mode 100644
index 77b6350390ae..000000000000
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyCollectorResult.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.
- */
-package org.apache.maven.api.services;
-
-import java.util.List;
-
-import org.apache.maven.api.Node;
-import org.apache.maven.api.annotations.Experimental;
-import org.apache.maven.api.annotations.Nonnull;
-import org.apache.maven.api.annotations.Nullable;
-
-/**
- * The result of a dependency collection request.
- *
- * @since 4.0.0
- * @see DependencyCollector#collect(DependencyCollectorRequest)
- */
-@Experimental
-public interface DependencyCollectorResult {
- /**
- * Gets the exceptions that occurred while building the dependency graph.
- *
- * @return the exceptions that occurred, never {@code null}
- */
- @Nonnull
- List getExceptions();
-
- /**
- * Gets the root node of the dependency graph.
- *
- * @return the root node of the dependency graph or {@code null} if none
- */
- @Nullable
- Node getRoot();
-}
diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolver.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolver.java
index 9fefbc4cda7c..95feaa1925f2 100644
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolver.java
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolver.java
@@ -20,6 +20,7 @@
import java.util.List;
+import org.apache.maven.api.Artifact;
import org.apache.maven.api.DependencyCoordinate;
import org.apache.maven.api.Node;
import org.apache.maven.api.PathScope;
@@ -35,55 +36,165 @@
@Experimental
public interface DependencyResolver extends Service {
- List flatten(Session session, Node node, PathScope scope) throws DependencyResolverException;
+ /**
+ * Collects the transitive dependencies of some artifacts and builds a dependency graph. Note that this operation is
+ * only concerned about determining the coordinates of the transitive dependencies and does not actually resolve the
+ * artifact files.
+ *
+ * @param session the {@link Session}, must not be {@code null}
+ * @param root the Maven Dependency, must not be {@code null}
+ * @return the collection result, never {@code null}
+ * @throws DependencyResolverException if the dependency tree could not be built
+ * @throws IllegalArgumentException if an argument is null or invalid
+ * @see #collect(DependencyResolverRequest)
+ */
+ @Nonnull
+ default DependencyResolverResult collect(@Nonnull Session session, @Nonnull DependencyCoordinate root) {
+ return collect(DependencyResolverRequest.build(session, DependencyResolverRequest.RequestType.COLLECT, root));
+ }
/**
- * This method collects, flattens and resolves the dependencies.
+ * Collects the transitive dependencies of some artifacts and builds a dependency graph. Note that this operation is
+ * only concerned about determining the coordinates of the transitive dependencies and does not actually resolve the
+ * artifact files.
*
- * @param request the request to resolve
- * @return the result of the resolution
- * @throws DependencyCollectorException
- * @throws DependencyResolverException
- * @throws ArtifactResolverException
+ * @param session the {@link Session}, must not be {@code null}
+ * @param project the {@link Project}, must not be {@code null}
+ * @return the collection result, never {@code null}
+ * @throws DependencyResolverException if the dependency tree could not be built
+ * @throws IllegalArgumentException if an argument is null or invalid
+ * @see #collect(DependencyResolverRequest)
+ */
+ @Nonnull
+ default DependencyResolverResult collect(@Nonnull Session session, @Nonnull Project project) {
+ return collect(
+ DependencyResolverRequest.build(session, DependencyResolverRequest.RequestType.COLLECT, project));
+ }
+
+ /**
+ * Collects the transitive dependencies of some artifacts and builds a dependency graph. Note that this operation is
+ * only concerned about determining the coordinates of the transitive dependencies and does not actually resolve the
+ * artifact files.
*
- * @see DependencyCollector#collect(DependencyCollectorRequest)
- * @see #flatten(Session, Node, PathScope)
- * @see ArtifactResolver#resolve(ArtifactResolverRequest)
+ * @param session the {@link Session}, must not be {@code null}
+ * @param artifact the {@link Artifact}, must not be {@code null}
+ * @return the collection result, never {@code null}
+ * @throws DependencyResolverException if the dependency tree could not be built
+ * @throws IllegalArgumentException if an argument is null or invalid
+ * @see #collect(DependencyResolverRequest)
*/
- DependencyResolverResult resolve(DependencyResolverRequest request)
- throws DependencyCollectorException, DependencyResolverException, ArtifactResolverException;
+ @Nonnull
+ default DependencyResolverResult collect(@Nonnull Session session, @Nonnull Artifact artifact) {
+ return collect(
+ DependencyResolverRequest.build(session, DependencyResolverRequest.RequestType.COLLECT, artifact));
+ }
+
+ /**
+ * Collects the transitive dependencies and builds a dependency graph.
+ * Note that this operation is only concerned about determining the coordinates of the
+ * transitive dependencies and does not actually resolve the artifact files.
+ *
+ * @param request the dependency collection request, must not be {@code null}
+ * @return the collection result, never {@code null}
+ * @throws DependencyResolverException if the dependency tree could not be built
+ * @throws IllegalArgumentException if an argument is null or invalid
+ *
+ * @see DependencyResolver#collect(Session, Project)
+ * @see DependencyResolver#collect(Session, DependencyCoordinate)
+ * @see DependencyResolver#collect(Session, Artifact)
+ */
+ @Nonnull
+ default DependencyResolverResult collect(@Nonnull DependencyResolverRequest request) {
+ if (request.getRequestType() != DependencyResolverRequest.RequestType.COLLECT) {
+ throw new IllegalArgumentException("requestType should be COLLECT when calling collect()");
+ }
+ return resolve(request);
+ }
+
+ /**
+ * Flattens a list of nodes.
+ *
+ * @param session
+ * @param node
+ * @param scope
+ * @return
+ * @throws DependencyResolverException
+ */
+ List flatten(Session session, Node node, PathScope scope) throws DependencyResolverException;
+
+ @Nonnull
+ default DependencyResolverResult flatten(@Nonnull Session session, @Nonnull Project project) {
+ return flatten(
+ DependencyResolverRequest.build(session, DependencyResolverRequest.RequestType.FLATTEN, project));
+ }
+
+ @Nonnull
+ default DependencyResolverResult flatten(
+ @Nonnull Session session, @Nonnull Project project, @Nonnull PathScope scope) {
+ return flatten(DependencyResolverRequest.build(
+ session, DependencyResolverRequest.RequestType.FLATTEN, project, scope));
+ }
+
+ @Nonnull
+ default DependencyResolverResult flatten(@Nonnull DependencyResolverRequest request) {
+ if (request.getRequestType() != DependencyResolverRequest.RequestType.FLATTEN) {
+ throw new IllegalArgumentException("requestType should be FLATTEN when calling flatten()");
+ }
+ return resolve(request);
+ }
@Nonnull
default DependencyResolverResult resolve(@Nonnull Session session, @Nonnull Project project) {
- return resolve(DependencyResolverRequest.build(session, project));
+ return resolve(
+ DependencyResolverRequest.build(session, DependencyResolverRequest.RequestType.RESOLVE, project));
}
@Nonnull
default DependencyResolverResult resolve(
@Nonnull Session session, @Nonnull Project project, @Nonnull PathScope scope) {
- return resolve(DependencyResolverRequest.build(session, project, scope));
+ return resolve(DependencyResolverRequest.build(
+ session, DependencyResolverRequest.RequestType.RESOLVE, project, scope));
}
@Nonnull
default DependencyResolverResult resolve(@Nonnull Session session, @Nonnull DependencyCoordinate dependency) {
- return resolve(DependencyResolverRequest.build(session, dependency));
+ return resolve(
+ DependencyResolverRequest.build(session, DependencyResolverRequest.RequestType.RESOLVE, dependency));
}
@Nonnull
default DependencyResolverResult resolve(
@Nonnull Session session, @Nonnull DependencyCoordinate dependency, @Nonnull PathScope scope) {
- return resolve(DependencyResolverRequest.build(session, dependency, scope));
+ return resolve(DependencyResolverRequest.build(
+ session, DependencyResolverRequest.RequestType.RESOLVE, dependency, scope));
}
@Nonnull
default DependencyResolverResult resolve(
@Nonnull Session session, @Nonnull List dependencies) {
- return resolve(DependencyResolverRequest.build(session, dependencies));
+ return resolve(
+ DependencyResolverRequest.build(session, DependencyResolverRequest.RequestType.RESOLVE, dependencies));
}
@Nonnull
default DependencyResolverResult resolve(
@Nonnull Session session, @Nonnull List dependencies, @Nonnull PathScope scope) {
- return resolve(DependencyResolverRequest.build(session, dependencies, scope));
+ return resolve(DependencyResolverRequest.build(
+ session, DependencyResolverRequest.RequestType.RESOLVE, dependencies, scope));
}
+
+ /**
+ * This method collects, flattens and resolves the dependencies.
+ *
+ * @param request the request to resolve
+ * @return the result of the resolution
+ * @throws DependencyResolverException
+ * @throws ArtifactResolverException
+ *
+ * @see DependencyResolver#collect(DependencyResolverRequest)
+ * @see #flatten(Session, Node, PathScope)
+ * @see ArtifactResolver#resolve(ArtifactResolverRequest)
+ */
+ DependencyResolverResult resolve(DependencyResolverRequest request)
+ throws DependencyResolverException, ArtifactResolverException;
}
diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolverRequest.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolverRequest.java
index 2f410a8a303f..dfc7760fc7cc 100644
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolverRequest.java
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolverRequest.java
@@ -18,8 +18,11 @@
*/
package org.apache.maven.api.services;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
+import java.util.Optional;
import java.util.function.Predicate;
import org.apache.maven.api.Artifact;
@@ -30,14 +33,54 @@
import org.apache.maven.api.Project;
import org.apache.maven.api.Session;
import org.apache.maven.api.annotations.Experimental;
+import org.apache.maven.api.annotations.Immutable;
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.annotations.NotThreadSafe;
import org.apache.maven.api.annotations.Nullable;
+/**
+ * A request to collect the transitive dependencies and to build a dependency graph from them. There are three ways to
+ * create a dependency graph. First, only the root dependency can be given. Second, a root dependency and direct
+ * dependencies can be specified in which case the specified direct dependencies are merged with the direct dependencies
+ * retrieved from the artifact descriptor of the root dependency. And last, only direct dependencies can be specified in
+ * which case the root node of the resulting graph has no associated dependency.
+ *
+ * @since 4.0.0
+ */
@Experimental
-public interface DependencyResolverRequest extends DependencyCollectorRequest {
+@Immutable
+public interface DependencyResolverRequest {
+
+ enum RequestType {
+ COLLECT,
+ FLATTEN,
+ RESOLVE
+ }
+
+ @Nonnull
+ Session getSession();
+
+ @Nonnull
+ RequestType getRequestType();
+
+ @Nonnull
+ Optional getProject();
+
+ @Nonnull
+ Optional getRootArtifact();
+
+ @Nonnull
+ Optional getRoot();
@Nonnull
+ Collection getDependencies();
+
+ @Nonnull
+ Collection getManagedDependencies();
+
+ boolean getVerbose();
+
+ @Nullable
PathScope getPathScope();
/**
@@ -48,6 +91,7 @@ public interface DependencyResolverRequest extends DependencyCollectorRequest {
*
* @return a filter for the types of path (class-path, module-path, …) accepted by the tool
*/
+ @Nullable
Predicate getPathTypeFilter();
@Nonnull
@@ -56,119 +100,202 @@ static DependencyResolverRequestBuilder builder() {
}
@Nonnull
- static DependencyResolverRequest build(Session session, Project project) {
- return build(session, project, PathScope.MAIN_RUNTIME);
+ static DependencyResolverRequest build(Session session, RequestType requestType, Artifact rootArtifact) {
+ return new DependencyResolverRequestBuilder()
+ .session(session)
+ .requestType(requestType)
+ .rootArtifact(rootArtifact)
+ .pathScope(PathScope.MAIN_RUNTIME)
+ .build();
}
@Nonnull
- static DependencyResolverRequest build(Session session, Project project, PathScope scope) {
+ static DependencyResolverRequest build(Session session, RequestType requestType, Project project) {
+ return build(session, requestType, project, PathScope.MAIN_RUNTIME);
+ }
+
+ @Nonnull
+ static DependencyResolverRequest build(Session session, RequestType requestType, Project project, PathScope scope) {
return new DependencyResolverRequestBuilder()
.session(session)
+ .requestType(requestType)
.project(project)
.pathScope(scope)
.build();
}
@Nonnull
- static DependencyResolverRequest build(Session session, DependencyCoordinate dependency) {
- return build(session, dependency, PathScope.MAIN_RUNTIME);
+ static DependencyResolverRequest build(Session session, RequestType requestType, DependencyCoordinate dependency) {
+ return build(session, requestType, dependency, PathScope.MAIN_RUNTIME);
}
@Nonnull
- static DependencyResolverRequest build(Session session, DependencyCoordinate dependency, PathScope scope) {
+ static DependencyResolverRequest build(
+ Session session, RequestType requestType, DependencyCoordinate dependency, PathScope scope) {
return new DependencyResolverRequestBuilder()
.session(session)
+ .requestType(requestType)
.dependency(dependency)
.pathScope(scope)
.build();
}
@Nonnull
- static DependencyResolverRequest build(Session session, List dependencies) {
- return build(session, dependencies, PathScope.MAIN_RUNTIME);
+ static DependencyResolverRequest build(
+ Session session, RequestType requestType, List dependencies) {
+ return build(session, requestType, dependencies, PathScope.MAIN_RUNTIME);
}
@Nonnull
- static DependencyResolverRequest build(Session session, List dependencies, PathScope scope) {
+ static DependencyResolverRequest build(
+ Session session, RequestType requestType, List dependencies, PathScope scope) {
return new DependencyResolverRequestBuilder()
.session(session)
+ .requestType(requestType)
.dependencies(dependencies)
.pathScope(scope)
.build();
}
@NotThreadSafe
- class DependencyResolverRequestBuilder extends DependencyCollectorRequestBuilder {
+ class DependencyResolverRequestBuilder {
+
+ Session session;
+ RequestType requestType;
+ Project project;
+ Artifact rootArtifact;
+ DependencyCoordinate root;
+ List dependencies = Collections.emptyList();
+ List managedDependencies = Collections.emptyList();
+ boolean verbose;
PathScope pathScope;
-
Predicate pathTypeFilter;
+ DependencyResolverRequestBuilder() {}
+
@Nonnull
- @Override
public DependencyResolverRequestBuilder session(@Nonnull Session session) {
- super.session(session);
+ this.session = session;
+ return this;
+ }
+
+ @Nonnull
+ public DependencyResolverRequestBuilder requestType(@Nonnull RequestType requestType) {
+ this.requestType = requestType;
return this;
}
@Nonnull
- @Override
public DependencyResolverRequestBuilder project(@Nullable Project project) {
- super.project(project);
+ this.project = project;
return this;
}
+ /**
+ * Sets the root artifact for the dependency graph.
+ * This must not be confused with {@link #root(DependencyCoordinate)}: The root dependency, like any
+ * other specified dependency, will be subject to dependency collection/resolution, i.e. should have an artifact
+ * descriptor and a corresponding artifact file. The root artifact on the other hand is only used
+ * as a label for the root node of the graph in case no root dependency was specified. As such, the configured
+ * root artifact is ignored if {@link #root(DependencyCoordinate)} has been set.
+ *
+ * @param rootArtifact the root artifact for the dependency graph, may be {@code null}
+ * @return this request for chaining, never {@code null}
+ */
@Nonnull
- @Override
public DependencyResolverRequestBuilder rootArtifact(@Nullable Artifact rootArtifact) {
- super.rootArtifact(rootArtifact);
+ this.rootArtifact = rootArtifact;
return this;
}
+ /**
+ * @param root The root dependency
+ * @return this request for chaining, never {@code null}
+ */
@Nonnull
- @Override
- public DependencyResolverRequestBuilder root(@Nullable DependencyCoordinate root) {
- super.root(root);
+ public DependencyResolverRequestBuilder root(@Nonnull DependencyCoordinate root) {
+ this.root = root;
return this;
}
+ /**
+ * Sets the direct dependencies. If both a root dependency and direct dependencies are given in the request, the
+ * direct dependencies from the request will be merged with the direct dependencies from the root dependency's
+ * artifact descriptor, giving higher priority to the dependencies from the request.
+ *
+ * @param dependencies the direct dependencies, may be {@code null}
+ * @return this request for chaining, never {@code null}
+ */
@Nonnull
- @Override
public DependencyResolverRequestBuilder dependencies(@Nullable List dependencies) {
- super.dependencies(dependencies);
+ this.dependencies = (dependencies != null) ? dependencies : Collections.emptyList();
return this;
}
+ /**
+ * Adds the specified direct dependency.
+ *
+ * @param dependency the dependency to add, may be {@code null}
+ * @return this request for chaining, never {@code null}
+ */
@Nonnull
- @Override
public DependencyResolverRequestBuilder dependency(@Nullable DependencyCoordinate dependency) {
- super.dependency(dependency);
+ if (dependency != null) {
+ if (this.dependencies.isEmpty()) {
+ this.dependencies = new ArrayList<>();
+ }
+ this.dependencies.add(dependency);
+ }
return this;
}
+ /**
+ * Sets the dependency management to apply to transitive dependencies. To clarify, this management does not
+ * apply to
+ * the direct dependencies of the root node.
+ *
+ * @param managedDependencies the dependency management, may be {@code null}
+ * @return this request for chaining, never {@code null}
+ */
@Nonnull
- @Override
public DependencyResolverRequestBuilder managedDependencies(
@Nullable List managedDependencies) {
- super.managedDependencies(managedDependencies);
+ this.managedDependencies = (managedDependencies != null) ? managedDependencies : Collections.emptyList();
return this;
}
+ /**
+ * Adds the specified managed dependency.
+ *
+ * @param managedDependency The managed dependency to add, may be {@code null} in which case the call
+ * will have no effect.
+ * @return this request for chaining, never {@code null}
+ */
@Nonnull
- @Override
public DependencyResolverRequestBuilder managedDependency(@Nullable DependencyCoordinate managedDependency) {
- super.managedDependency(managedDependency);
+ if (managedDependency != null) {
+ if (this.managedDependencies.isEmpty()) {
+ this.managedDependencies = new ArrayList<>();
+ }
+ this.managedDependencies.add(managedDependency);
+ }
return this;
}
+ /**
+ * Specifies that the collection should be verbose.
+ *
+ * @param verbose whether the collection should be verbose or not
+ * @return this request for chaining, never {@code null}
+ */
@Nonnull
- @Override
public DependencyResolverRequestBuilder verbose(boolean verbose) {
- super.verbose(verbose);
+ this.verbose = verbose;
return this;
}
@Nonnull
- public DependencyResolverRequestBuilder pathScope(@Nonnull PathScope pathScope) {
+ public DependencyResolverRequestBuilder pathScope(@Nullable PathScope pathScope) {
this.pathScope = pathScope;
return this;
}
@@ -200,10 +327,11 @@ public DependencyResolverRequestBuilder pathTypeFilter(@Nonnull Collection dependencies;
+ private final Collection managedDependencies;
+ private final boolean verbose;
private final PathScope pathScope;
-
private final Predicate pathTypeFilter;
+ /**
+ * Creates a request with the specified properties.
+ *
+ * @param session {@link Session}
+ * @param rootArtifact The root dependency whose transitive dependencies should be collected, may be {@code
+ * null}.
+ */
DefaultDependencyResolverRequest(
- Session session,
- Project project,
- Artifact rootArtifact,
- DependencyCoordinate root,
- Collection dependencies,
- Collection managedDependencies,
+ @Nonnull Session session,
+ @Nonnull RequestType requestType,
+ @Nullable Project project,
+ @Nullable Artifact rootArtifact,
+ @Nullable DependencyCoordinate root,
+ @Nonnull Collection dependencies,
+ @Nonnull Collection managedDependencies,
boolean verbose,
- PathScope pathScope,
- Predicate pathTypeFilter) {
- super(session, project, rootArtifact, root, dependencies, managedDependencies, verbose);
- this.pathScope = nonNull(pathScope, "pathScope cannot be null");
+ @Nullable PathScope pathScope,
+ @Nullable Predicate pathTypeFilter) {
+ super(session);
+ this.requestType = nonNull(requestType, "requestType cannot be null");
+ this.project = project;
+ this.rootArtifact = rootArtifact;
+ this.root = root;
+ this.dependencies = unmodifiable(nonNull(dependencies, "dependencies cannot be null"));
+ this.managedDependencies =
+ unmodifiable(nonNull(managedDependencies, "managedDependencies cannot be null"));
+ this.verbose = verbose;
+ this.pathScope = pathScope;
this.pathTypeFilter = (pathTypeFilter != null) ? pathTypeFilter : (t) -> true;
- if (verbose) {
- throw new IllegalArgumentException("verbose cannot be true for resolving dependencies");
+ if (verbose && requestType != RequestType.COLLECT) {
+ throw new IllegalArgumentException("verbose cannot only be true when collecting dependencies");
}
}
@Nonnull
+ @Override
+ public RequestType getRequestType() {
+ return requestType;
+ }
+
+ @Nonnull
+ @Override
+ public Optional getProject() {
+ return Optional.ofNullable(project);
+ }
+
+ @Nonnull
+ @Override
+ public Optional getRootArtifact() {
+ return Optional.ofNullable(rootArtifact);
+ }
+
+ @Nonnull
+ @Override
+ public Optional getRoot() {
+ return Optional.ofNullable(root);
+ }
+
+ @Nonnull
+ @Override
+ public Collection getDependencies() {
+ return dependencies;
+ }
+
+ @Nonnull
+ @Override
+ public Collection getManagedDependencies() {
+ return managedDependencies;
+ }
+
+ @Override
+ public boolean getVerbose() {
+ return verbose;
+ }
+
@Override
public PathScope getPathScope() {
return pathScope;
@@ -248,6 +437,12 @@ public PathScope getPathScope() {
public Predicate getPathTypeFilter() {
return pathTypeFilter;
}
+
+ @Nonnull
+ @Override
+ public String toString() {
+ return getRoot() + " -> " + getDependencies();
+ }
}
}
}
diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolverResult.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolverResult.java
index 9579ad6d17ad..e7ab86d01105 100644
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolverResult.java
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolverResult.java
@@ -29,9 +29,32 @@
import org.apache.maven.api.PathType;
import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.annotations.Nonnull;
+import org.apache.maven.api.annotations.Nullable;
+/**
+ * The result of a dependency resolution request.
+ *
+ * @since 4.0.0
+ * @see DependencyResolver#resolve(DependencyResolverRequest)
+ */
@Experimental
-public interface DependencyResolverResult extends DependencyCollectorResult {
+public interface DependencyResolverResult {
+
+ /**
+ * Gets the exceptions that occurred while building the dependency graph.
+ *
+ * @return the exceptions that occurred, never {@code null}
+ */
+ @Nonnull
+ List getExceptions();
+
+ /**
+ * Gets the root node of the dependency graph.
+ *
+ * @return the root node of the dependency graph or {@code null} if none
+ */
+ @Nullable
+ Node getRoot();
/**
* The ordered list of the flattened dependency nodes.
diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ProjectBuilderResult.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ProjectBuilderResult.java
index 348be6135b96..2247aa7b2edf 100644
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/ProjectBuilderResult.java
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ProjectBuilderResult.java
@@ -75,5 +75,5 @@ public interface ProjectBuilderResult {
* @return the result of the dependency resolution for the project
*/
@Nonnull
- Optional getDependencyResolverResult();
+ Optional getDependencyResolverResult();
}
diff --git a/maven-api-impl/src/main/java/org/apache/maven/internal/impl/AbstractSession.java b/maven-api-impl/src/main/java/org/apache/maven/internal/impl/AbstractSession.java
index 464941d23cfc..d8a3a10f5748 100644
--- a/maven-api-impl/src/main/java/org/apache/maven/internal/impl/AbstractSession.java
+++ b/maven-api-impl/src/main/java/org/apache/maven/internal/impl/AbstractSession.java
@@ -596,39 +596,41 @@ public DependencyCoordinate createDependencyCoordinate(@Nonnull Dependency depen
}
/**
- * Shortcut for getService(DependencyCollector.class).collect(...)
+ * Shortcut for getService(DependencyResolver.class).collect(...)
*
- * @throws DependencyCollectorException if the dependency collection failed
- * @see DependencyCollector#collect(Session, Artifact)
+ * @throws DependencyResolverException if the dependency collection failed
+ * @see DependencyResolver#collect(Session, Artifact)
*/
@Nonnull
@Override
public Node collectDependencies(@Nonnull Artifact artifact) {
- return getService(DependencyCollector.class).collect(this, artifact).getRoot();
+ return getService(DependencyResolver.class).collect(this, artifact).getRoot();
}
/**
- * Shortcut for getService(DependencyCollector.class).collect(...)
+ * Shortcut for getService(DependencyResolver.class).collect(...)
*
- * @throws DependencyCollectorException if the dependency collection failed
- * @see DependencyCollector#collect(Session, Project)
+ * @throws DependencyResolverException if the dependency collection failed
+ * @see DependencyResolver#collect(Session, Project)
*/
@Nonnull
@Override
public Node collectDependencies(@Nonnull Project project) {
- return getService(DependencyCollector.class).collect(this, project).getRoot();
+ return getService(DependencyResolver.class).collect(this, project).getRoot();
}
/**
- * Shortcut for getService(DependencyCollector.class).collect(...)
+ * Shortcut for getService(DependencyResolver.class).collect(...)
*
- * @throws DependencyCollectorException if the dependency collection failed
- * @see DependencyCollector#collect(Session, DependencyCoordinate)
+ * @throws DependencyResolverException if the dependency collection failed
+ * @see DependencyResolver#collect(Session, DependencyCoordinate)
*/
@Nonnull
@Override
public Node collectDependencies(@Nonnull DependencyCoordinate dependency) {
- return getService(DependencyCollector.class).collect(this, dependency).getRoot();
+ Node root =
+ getService(DependencyResolver.class).collect(this, dependency).getRoot();
+ return root.getChildren().iterator().next();
}
@Nonnull
@@ -662,6 +664,7 @@ public Map> resolveDependencies(
return getService(DependencyResolver.class)
.resolve(DependencyResolverRequest.builder()
.session(this)
+ .requestType(DependencyResolverRequest.RequestType.RESOLVE)
.dependency(dependency)
.pathScope(scope)
.pathTypeFilter(desiredTypes)
@@ -675,6 +678,7 @@ public Map> resolveDependencies(
return getService(DependencyResolver.class)
.resolve(DependencyResolverRequest.builder()
.session(this)
+ .requestType(DependencyResolverRequest.RequestType.RESOLVE)
.project(project)
.pathScope(scope)
.pathTypeFilter(desiredTypes)
diff --git a/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultDependencyCollector.java b/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultDependencyCollector.java
deleted file mode 100644
index bd63ca128087..000000000000
--- a/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultDependencyCollector.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * 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.
- */
-package org.apache.maven.internal.impl;
-
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.maven.api.Artifact;
-import org.apache.maven.api.DependencyCoordinate;
-import org.apache.maven.api.Node;
-import org.apache.maven.api.Project;
-import org.apache.maven.api.RemoteRepository;
-import org.apache.maven.api.annotations.Nonnull;
-import org.apache.maven.api.di.Named;
-import org.apache.maven.api.di.Singleton;
-import org.apache.maven.api.services.DependencyCollector;
-import org.apache.maven.api.services.DependencyCollectorException;
-import org.apache.maven.api.services.DependencyCollectorRequest;
-import org.apache.maven.api.services.DependencyCollectorResult;
-import org.apache.maven.api.services.ProjectManager;
-import org.eclipse.aether.DefaultRepositorySystemSession;
-import org.eclipse.aether.RepositorySystemSession;
-import org.eclipse.aether.collection.CollectRequest;
-import org.eclipse.aether.collection.CollectResult;
-import org.eclipse.aether.collection.DependencyCollectionException;
-import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
-import org.eclipse.aether.util.graph.transformer.ConflictResolver;
-
-import static org.apache.maven.internal.impl.Utils.nonNull;
-
-@Named
-@Singleton
-public class DefaultDependencyCollector implements DependencyCollector {
-
- @Nonnull
- @Override
- public DependencyCollectorResult collect(@Nonnull DependencyCollectorRequest request)
- throws DependencyCollectorException, IllegalArgumentException {
- nonNull(request, "request");
- InternalSession session = InternalSession.from(request.getSession());
-
- Artifact rootArtifact;
- DependencyCoordinate root;
- Collection dependencies;
- Collection managedDependencies;
- List remoteRepositories;
- if (request.getProject().isPresent()) {
- Project project = request.getProject().get();
- rootArtifact = project.getPomArtifact();
- root = null;
- dependencies = project.getDependencies();
- managedDependencies = project.getManagedDependencies();
- remoteRepositories = session.getService(ProjectManager.class).getRemoteProjectRepositories(project);
- } else {
- rootArtifact = request.getRootArtifact().orElse(null);
- root = request.getRoot().orElse(null);
- dependencies = request.getDependencies();
- managedDependencies = request.getManagedDependencies();
- remoteRepositories = session.getRemoteRepositories();
- }
- CollectRequest collectRequest = new CollectRequest()
- .setRootArtifact(rootArtifact != null ? session.toArtifact(rootArtifact) : null)
- .setRoot(root != null ? session.toDependency(root, false) : null)
- .setDependencies(session.toDependencies(dependencies, false))
- .setManagedDependencies(session.toDependencies(managedDependencies, true))
- .setRepositories(session.toRepositories(remoteRepositories));
-
- RepositorySystemSession systemSession = session.getSession();
- if (request.getVerbose()) {
- systemSession = new DefaultRepositorySystemSession(systemSession)
- .setConfigProperty(ConflictResolver.CONFIG_PROP_VERBOSE, true)
- .setConfigProperty(DependencyManagerUtils.CONFIG_PROP_VERBOSE, true);
- }
-
- try {
- final CollectResult result =
- session.getRepositorySystem().collectDependencies(systemSession, collectRequest);
- return new DependencyCollectorResult() {
- @Override
- public List getExceptions() {
- return result.getExceptions();
- }
-
- @Override
- public Node getRoot() {
- return session.getNode(result.getRoot(), request.getVerbose());
- }
- };
- } catch (DependencyCollectionException e) {
- throw new DependencyCollectorException("Unable to collect dependencies", e);
- }
- }
-}
diff --git a/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolver.java b/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolver.java
new file mode 100644
index 000000000000..1105c2ab5da6
--- /dev/null
+++ b/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolver.java
@@ -0,0 +1,182 @@
+/*
+ * 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.
+ */
+package org.apache.maven.internal.impl;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import org.apache.maven.api.*;
+import org.apache.maven.api.Artifact;
+import org.apache.maven.api.ArtifactCoordinate;
+import org.apache.maven.api.Dependency;
+import org.apache.maven.api.Node;
+import org.apache.maven.api.PathType;
+import org.apache.maven.api.Session;
+import org.apache.maven.api.annotations.Nonnull;
+import org.apache.maven.api.di.Named;
+import org.apache.maven.api.di.Singleton;
+import org.apache.maven.api.services.*;
+import org.eclipse.aether.DefaultRepositorySystemSession;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.collection.CollectRequest;
+import org.eclipse.aether.collection.CollectResult;
+import org.eclipse.aether.collection.DependencyCollectionException;
+import org.eclipse.aether.graph.DependencyFilter;
+import org.eclipse.aether.graph.DependencyNode;
+import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
+import org.eclipse.aether.util.graph.transformer.ConflictResolver;
+
+import static org.apache.maven.internal.impl.Utils.cast;
+import static org.apache.maven.internal.impl.Utils.map;
+import static org.apache.maven.internal.impl.Utils.nonNull;
+
+@Named
+@Singleton
+public class DefaultDependencyResolver implements DependencyResolver {
+
+ @Nonnull
+ @Override
+ public DependencyResolverResult collect(@Nonnull DependencyResolverRequest request)
+ throws DependencyResolverException, IllegalArgumentException {
+ nonNull(request, "request");
+ InternalSession session = InternalSession.from(request.getSession());
+
+ Artifact rootArtifact;
+ DependencyCoordinate root;
+ Collection dependencies;
+ Collection managedDependencies;
+ List remoteRepositories;
+ if (request.getProject().isPresent()) {
+ Project project = request.getProject().get();
+ rootArtifact = project.getPomArtifact();
+ root = null;
+ dependencies = project.getDependencies();
+ managedDependencies = project.getManagedDependencies();
+ remoteRepositories = session.getService(ProjectManager.class).getRemoteProjectRepositories(project);
+ } else {
+ rootArtifact = request.getRootArtifact().orElse(null);
+ root = request.getRoot().orElse(null);
+ dependencies = request.getDependencies();
+ managedDependencies = request.getManagedDependencies();
+ remoteRepositories = session.getRemoteRepositories();
+ }
+ CollectRequest collectRequest = new CollectRequest()
+ .setRootArtifact(rootArtifact != null ? session.toArtifact(rootArtifact) : null)
+ .setRoot(root != null ? session.toDependency(root, false) : null)
+ .setDependencies(session.toDependencies(dependencies, false))
+ .setManagedDependencies(session.toDependencies(managedDependencies, true))
+ .setRepositories(session.toRepositories(remoteRepositories));
+
+ RepositorySystemSession systemSession = session.getSession();
+ if (request.getVerbose()) {
+ systemSession = new DefaultRepositorySystemSession(systemSession)
+ .setConfigProperty(ConflictResolver.CONFIG_PROP_VERBOSE, true)
+ .setConfigProperty(DependencyManagerUtils.CONFIG_PROP_VERBOSE, true);
+ }
+
+ try {
+ final CollectResult result =
+ session.getRepositorySystem().collectDependencies(systemSession, collectRequest);
+ return new DefaultDependencyResolverResult(
+ null, result.getExceptions(), session.getNode(result.getRoot(), request.getVerbose()), 0);
+ } catch (DependencyCollectionException e) {
+ throw new DependencyResolverException("Unable to collect dependencies", e);
+ }
+ }
+
+ @Override
+ public List flatten(Session s, Node node, PathScope scope) throws DependencyResolverException {
+ InternalSession session = InternalSession.from(s);
+ DependencyNode root = cast(AbstractNode.class, node, "node").getDependencyNode();
+ List dependencies = session.getRepositorySystem()
+ .flattenDependencyNodes(session.getSession(), root, getScopeDependencyFilter(scope));
+ dependencies.remove(root);
+ return map(dependencies, session::getNode);
+ }
+
+ private static DependencyFilter getScopeDependencyFilter(PathScope scope) {
+ Set scopes =
+ scope.dependencyScopes().stream().map(DependencyScope::id).collect(Collectors.toSet());
+ return (n, p) -> {
+ org.eclipse.aether.graph.Dependency d = n.getDependency();
+ return d == null || scopes.contains(d.getScope());
+ };
+ }
+
+ /**
+ * Collects, flattens and resolves the dependencies.
+ *
+ * @param request the request to resolve
+ * @return the result of the resolution
+ */
+ @Override
+ public DependencyResolverResult resolve(DependencyResolverRequest request)
+ throws DependencyResolverException, DependencyResolverException, ArtifactResolverException {
+ InternalSession session =
+ InternalSession.from(nonNull(request, "request").getSession());
+ DependencyResolverResult result;
+ DependencyResolverResult collectorResult = collect(request);
+ if (request.getRequestType() == DependencyResolverRequest.RequestType.COLLECT) {
+ result = collectorResult;
+ } else {
+ List nodes = flatten(session, collectorResult.getRoot(), request.getPathScope());
+ List coordinates = nodes.stream()
+ .map(Node::getDependency)
+ .filter(Objects::nonNull)
+ .map(Artifact::toCoordinate)
+ .collect(Collectors.toList());
+ Predicate filter = request.getPathTypeFilter();
+ if (request.getRequestType() == DependencyResolverRequest.RequestType.FLATTEN) {
+ DefaultDependencyResolverResult flattenResult = new DefaultDependencyResolverResult(
+ null, collectorResult.getExceptions(), collectorResult.getRoot(), nodes.size());
+ for (Node node : nodes) {
+ flattenResult.addNode(node);
+ }
+ result = flattenResult;
+ } else {
+ PathModularizationCache cache = new PathModularizationCache(); // TODO: should be project-wide cache.
+ DefaultDependencyResolverResult resolverResult = new DefaultDependencyResolverResult(
+ cache, collectorResult.getExceptions(), collectorResult.getRoot(), nodes.size());
+ Map artifacts = session.resolveArtifacts(coordinates);
+ for (Node node : nodes) {
+ Dependency d = node.getDependency();
+ Path path = (d != null) ? artifacts.get(d) : null;
+ try {
+ resolverResult.addDependency(node, d, filter, path);
+ } catch (IOException e) {
+ throw cannotReadModuleInfo(path, e);
+ }
+ }
+ result = resolverResult;
+ }
+ }
+ return result;
+ }
+
+ private static DependencyResolverException cannotReadModuleInfo(final Path path, final IOException cause) {
+ return new DependencyResolverException("Cannot read module information of " + path, cause);
+ }
+}
diff --git a/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolverResult.java b/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolverResult.java
index baf7b44424ae..ffad2adab514 100644
--- a/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolverResult.java
+++ b/maven-api-impl/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolverResult.java
@@ -94,7 +94,7 @@ class DefaultDependencyResolverResult implements DependencyResolverResult {
/**
* Creates an initially empty result. Callers should add path elements by calls
- * to {@link #addDependency(Node, Dependency, Predicate, Path, PathModularizationCache)}.
+ * to {@link #addDependency(Node, Dependency, Predicate, Path)}.
*
* @param cache cache of module information about each dependency
* @param exceptions the exceptions that occurred while building the dependency graph
@@ -201,6 +201,15 @@ void addOutputDirectory(Path main, Path test) throws IOException {
}
}
+ /**
+ * Adds a dependency node to the result.
+ *
+ * @param node the dependency node
+ */
+ void addNode(Node node) {
+ nodes.add(node);
+ }
+
/**
* Adds a dependency to the result. This method populates the {@link #nodes}, {@link #paths},
* {@link #dispatchedPaths} and {@link #dependencies} collections with the given arguments.
diff --git a/maven-api-impl/src/test/java/org/apache/maven/internal/impl/standalone/ApiRunner.java b/maven-api-impl/src/test/java/org/apache/maven/internal/impl/standalone/ApiRunner.java
index b6e2bbc815da..750aa9c084e6 100644
--- a/maven-api-impl/src/test/java/org/apache/maven/internal/impl/standalone/ApiRunner.java
+++ b/maven-api-impl/src/test/java/org/apache/maven/internal/impl/standalone/ApiRunner.java
@@ -85,7 +85,7 @@ public static Session createSession() {
injector.bindImplicit(DefaultArtifactInstaller.class);
injector.bindImplicit(DefaultArtifactResolver.class);
injector.bindImplicit(DefaultChecksumAlgorithmService.class);
- injector.bindImplicit(DefaultDependencyCollector.class);
+ injector.bindImplicit(DefaultDependencyResolver.class);
injector.bindImplicit(DefaultDependencyCoordinateFactory.class);
injector.bindImplicit(DefaultLocalRepositoryManager.class);
injector.bindImplicit(DefaultMessageBuilderFactory.class);
diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolver.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolver.java
deleted file mode 100644
index 254ee13f06f8..000000000000
--- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolver.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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.
- */
-package org.apache.maven.internal.impl;
-
-import javax.inject.Named;
-import javax.inject.Singleton;
-
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-import org.apache.maven.api.*;
-import org.apache.maven.api.Artifact;
-import org.apache.maven.api.ArtifactCoordinate;
-import org.apache.maven.api.Dependency;
-import org.apache.maven.api.Node;
-import org.apache.maven.api.PathType;
-import org.apache.maven.api.Session;
-import org.apache.maven.api.services.*;
-import org.eclipse.aether.graph.DependencyFilter;
-import org.eclipse.aether.graph.DependencyNode;
-
-import static org.apache.maven.internal.impl.Utils.cast;
-import static org.apache.maven.internal.impl.Utils.map;
-import static org.apache.maven.internal.impl.Utils.nonNull;
-
-@Named
-@Singleton
-public class DefaultDependencyResolver implements DependencyResolver {
-
- @Override
- public List flatten(Session s, Node node, PathScope scope) throws DependencyResolverException {
- InternalSession session = InternalSession.from(s);
- DependencyNode root = cast(AbstractNode.class, node, "node").getDependencyNode();
- List dependencies = session.getRepositorySystem()
- .flattenDependencyNodes(session.getSession(), root, getScopeDependencyFilter(scope));
- dependencies.remove(root);
- return map(dependencies, session::getNode);
- }
-
- private static DependencyFilter getScopeDependencyFilter(PathScope scope) {
- Set scopes =
- scope.dependencyScopes().stream().map(DependencyScope::id).collect(Collectors.toSet());
- return (n, p) -> {
- org.eclipse.aether.graph.Dependency d = n.getDependency();
- return d == null || scopes.contains(d.getScope());
- };
- }
-
- /**
- * Collects, flattens and resolves the dependencies.
- *
- * @param request the request to resolve
- * @return the result of the resolution
- */
- @Override
- public DependencyResolverResult resolve(DependencyResolverRequest request)
- throws DependencyCollectorException, DependencyResolverException, ArtifactResolverException {
- InternalSession session =
- InternalSession.from(nonNull(request, "request").getSession());
- Predicate filter = request.getPathTypeFilter();
- PathModularizationCache cache = new PathModularizationCache(); // TODO: should be project-wide cache.
- DependencyCollectorResult collectorResult =
- session.getService(DependencyCollector.class).collect(request);
- List nodes = flatten(session, collectorResult.getRoot(), request.getPathScope());
- List coordinates = nodes.stream()
- .map(Node::getDependency)
- .filter(Objects::nonNull)
- .map(Artifact::toCoordinate)
- .collect(Collectors.toList());
- Map artifacts = session.resolveArtifacts(coordinates);
- DefaultDependencyResolverResult result = new DefaultDependencyResolverResult(
- cache, collectorResult.getExceptions(), collectorResult.getRoot(), nodes.size());
- for (Node node : nodes) {
- Dependency d = node.getDependency();
- Path path = (d != null) ? artifacts.get(d) : null;
- try {
- result.addDependency(node, d, filter, path);
- } catch (IOException e) {
- throw cannotReadModuleInfo(path, e);
- }
- }
- return result;
- }
-
- private static DependencyResolverException cannotReadModuleInfo(final Path path, final IOException cause) {
- return new DependencyResolverException("Cannot read module information of " + path, cause);
- }
-}
diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectBuilder.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectBuilder.java
index d785dad9f82f..cbc2e0afd782 100644
--- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectBuilder.java
+++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectBuilder.java
@@ -31,11 +31,10 @@
import java.util.List;
import java.util.Optional;
-import org.apache.maven.api.Node;
import org.apache.maven.api.Project;
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.services.BuilderProblem;
-import org.apache.maven.api.services.DependencyCollectorResult;
+import org.apache.maven.api.services.DependencyResolverResult;
import org.apache.maven.api.services.ProjectBuilder;
import org.apache.maven.api.services.ProjectBuilderException;
import org.apache.maven.api.services.ProjectBuilderRequest;
@@ -170,19 +169,10 @@ public Severity getSeverity() {
@Nonnull
@Override
- public Optional getDependencyResolverResult() {
+ public Optional getDependencyResolverResult() {
return Optional.ofNullable(res.getDependencyResolutionResult())
- .map(r -> new DependencyCollectorResult() {
- @Override
- public List getExceptions() {
- return r.getCollectionErrors();
- }
-
- @Override
- public Node getRoot() {
- return session.getNode(r.getDependencyGraph());
- }
- });
+ .map(r -> new DefaultDependencyResolverResult(
+ null, r.getCollectionErrors(), session.getNode(r.getDependencyGraph()), 0));
}
};
} catch (ProjectBuildingException e) {
diff --git a/maven-core/src/main/resources/META-INF/maven/org.apache.maven.api.di.Inject b/maven-core/src/main/resources/META-INF/maven/org.apache.maven.api.di.Inject
index 285f768d41fb..dbbc28f99d1e 100644
--- a/maven-core/src/main/resources/META-INF/maven/org.apache.maven.api.di.Inject
+++ b/maven-core/src/main/resources/META-INF/maven/org.apache.maven.api.di.Inject
@@ -11,8 +11,8 @@ org.apache.maven.internal.impl.DefaultArtifactFactory
org.apache.maven.internal.impl.DefaultArtifactInstaller
org.apache.maven.internal.impl.DefaultArtifactResolver
org.apache.maven.internal.impl.DefaultChecksumAlgorithmService
-org.apache.maven.internal.impl.DefaultDependencyCollector
org.apache.maven.internal.impl.DefaultDependencyCoordinateFactory
+org.apache.maven.internal.impl.DefaultDependencyResolver
org.apache.maven.internal.impl.DefaultLocalRepositoryManager
org.apache.maven.internal.impl.DefaultMessageBuilderFactory
org.apache.maven.internal.impl.DefaultModelUrlNormalizer