This is an automated email from the ASF dual-hosted git repository.
cstamas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-resolver.git
The following commit(s) were added to refs/heads/master by this push:
new b8e9f9f8 [MRESOLVER-461] Cleanup in dep managers (#402)
b8e9f9f8 is described below
commit b8e9f9f88712ef7f25ae11618fc452d77e60591e
Author: Tamas Cservenak <[email protected]>
AuthorDate: Wed Dec 20 12:13:08 2023 +0100
[MRESOLVER-461] Cleanup in dep managers (#402)
3 of them were almost same.
* default: derives to infinity, always applies
* transitive: derives to infinity, applies after depth>=2
* classic: derives until depth>=2, applies after depth>=2
Note: "derives" means picks up depMgt from currently processed node. Hence,
classic ignores all depMgt in graph coming from transitive dependencies.
depth=1 is root (ie. project), depth=2 are first level deps (those listed in
POM), etc.
Added UT to cover all 3 of them with all aspects as well.
---
https://issues.apache.org/jira/browse/MRESOLVER-461
---
...Manager.java => AbstractDependencyManager.java} | 105 ++++----
.../graph/manager/ClassicDependencyManager.java | 271 +++------------------
.../graph/manager/DefaultDependencyManager.java | 259 +++-----------------
.../graph/manager/TransitiveDependencyManager.java | 263 +++-----------------
.../manager/ClassicDependencyManagerTest.java | 75 ------
.../util/graph/manager/DependencyManagerTest.java | 248 +++++++++++++++++++
6 files changed, 421 insertions(+), 800 deletions(-)
diff --git
a/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/ClassicDependencyManager.java
b/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/AbstractDependencyManager.java
similarity index 79%
copy from
maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/ClassicDependencyManager.java
copy to
maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/AbstractDependencyManager.java
index 19917376..5cf7ebb3 100644
---
a/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/ClassicDependencyManager.java
+++
b/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/AbstractDependencyManager.java
@@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
+import java.util.Objects;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.ArtifactProperties;
@@ -36,59 +37,87 @@ import org.eclipse.aether.util.artifact.JavaScopes;
import static java.util.Objects.requireNonNull;
/**
- * A dependency manager that mimics the way Maven 2.x works.
+ * A dependency manager support class.
+ *
+ * @since 2.0.0
*/
-public final class ClassicDependencyManager implements DependencyManager {
+public abstract class AbstractDependencyManager implements DependencyManager {
+
+ protected final int depth;
- private final int depth;
+ protected final int deriveUntil;
- private final Map<Object, String> managedVersions;
+ protected final int applyFrom;
- private final Map<Object, String> managedScopes;
+ protected final Map<Object, String> managedVersions;
- private final Map<Object, Boolean> managedOptionals;
+ protected final Map<Object, String> managedScopes;
- private final Map<Object, String> managedLocalPaths;
+ protected final Map<Object, Boolean> managedOptionals;
- private final Map<Object, Collection<Exclusion>> managedExclusions;
+ protected final Map<Object, String> managedLocalPaths;
- private int hashCode;
+ protected final Map<Object, Collection<Exclusion>> managedExclusions;
+
+ private final int hashCode;
/**
* Creates a new dependency manager without any management information.
*/
- public ClassicDependencyManager() {
+ protected AbstractDependencyManager(int deriveUntil, int applyFrom) {
this(
0,
- Collections.<Object, String>emptyMap(),
- Collections.<Object, String>emptyMap(),
- Collections.<Object, Boolean>emptyMap(),
- Collections.<Object, String>emptyMap(),
- Collections.<Object, Collection<Exclusion>>emptyMap());
+ deriveUntil,
+ applyFrom,
+ Collections.emptyMap(),
+ Collections.emptyMap(),
+ Collections.emptyMap(),
+ Collections.emptyMap(),
+ Collections.emptyMap());
}
- private ClassicDependencyManager(
+ @SuppressWarnings("checkstyle:ParameterNumber")
+ protected AbstractDependencyManager(
int depth,
+ int deriveUntil,
+ int applyFrom,
Map<Object, String> managedVersions,
Map<Object, String> managedScopes,
Map<Object, Boolean> managedOptionals,
Map<Object, String> managedLocalPaths,
Map<Object, Collection<Exclusion>> managedExclusions) {
this.depth = depth;
+ this.deriveUntil = deriveUntil;
+ this.applyFrom = applyFrom;
this.managedVersions = managedVersions;
this.managedScopes = managedScopes;
this.managedOptionals = managedOptionals;
this.managedLocalPaths = managedLocalPaths;
this.managedExclusions = managedExclusions;
+
+ this.hashCode = Objects.hash(
+ depth,
+ deriveUntil,
+ applyFrom,
+ managedVersions,
+ managedScopes,
+ managedOptionals,
+ managedLocalPaths,
+ managedExclusions);
}
+ protected abstract DependencyManager newInstance(
+ Map<Object, String> managedVersions,
+ Map<Object, String> managedScopes,
+ Map<Object, Boolean> managedOptionals,
+ Map<Object, String> managedLocalPaths,
+ Map<Object, Collection<Exclusion>> managedExclusions);
+
+ @Override
public DependencyManager deriveChildManager(DependencyCollectionContext
context) {
requireNonNull(context, "context cannot be null");
- if (depth >= 2) {
+ if (depth >= deriveUntil) {
return this;
- } else if (depth == 1) {
- return new ClassicDependencyManager(
- depth + 1, managedVersions, managedScopes,
managedOptionals, managedLocalPaths, managedExclusions);
}
Map<Object, String> managedVersions = this.managedVersions;
@@ -99,7 +128,7 @@ public final class ClassicDependencyManager implements
DependencyManager {
for (Dependency managedDependency : context.getManagedDependencies()) {
Artifact artifact = managedDependency.getArtifact();
- Object key = getKey(artifact);
+ Object key = new Key(artifact);
String version = artifact.getVersion();
if (!version.isEmpty() && !managedVersions.containsKey(key)) {
@@ -143,17 +172,16 @@ public final class ClassicDependencyManager implements
DependencyManager {
}
}
- return new ClassicDependencyManager(
- depth + 1, managedVersions, managedScopes, managedOptionals,
managedLocalPaths, managedExclusions);
+ return newInstance(managedVersions, managedScopes, managedOptionals,
managedLocalPaths, managedExclusions);
}
+ @Override
public DependencyManagement manageDependency(Dependency dependency) {
requireNonNull(dependency, "dependency cannot be null");
DependencyManagement management = null;
+ Object key = new Key(dependency.getArtifact());
- Object key = getKey(dependency.getArtifact());
-
- if (depth >= 2) {
+ if (depth >= applyFrom) {
String version = managedVersions.get(key);
if (version != null) {
management = new DependencyManagement();
@@ -212,10 +240,6 @@ public final class ClassicDependencyManager implements
DependencyManager {
return management;
}
- private Object getKey(Artifact a) {
- return new Key(a);
- }
-
@Override
public boolean equals(Object obj) {
if (this == obj) {
@@ -224,8 +248,10 @@ public final class ClassicDependencyManager implements
DependencyManager {
return false;
}
- ClassicDependencyManager that = (ClassicDependencyManager) obj;
+ AbstractDependencyManager that = (AbstractDependencyManager) obj;
return depth == that.depth
+ && deriveUntil == that.deriveUntil
+ && applyFrom == that.applyFrom
&& managedVersions.equals(that.managedVersions)
&& managedScopes.equals(that.managedScopes)
&& managedOptionals.equals(that.managedOptionals)
@@ -234,19 +260,10 @@ public final class ClassicDependencyManager implements
DependencyManager {
@Override
public int hashCode() {
- if (hashCode == 0) {
- int hash = 17;
- hash = hash * 31 + depth;
- hash = hash * 31 + managedVersions.hashCode();
- hash = hash * 31 + managedScopes.hashCode();
- hash = hash * 31 + managedOptionals.hashCode();
- hash = hash * 31 + managedExclusions.hashCode();
- hashCode = hash;
- }
return hashCode;
}
- static class Key {
+ protected static class Key {
private final Artifact artifact;
@@ -254,11 +271,7 @@ public final class ClassicDependencyManager implements
DependencyManager {
Key(Artifact artifact) {
this.artifact = artifact;
-
- int hash = 17;
- hash = hash * 31 + artifact.getGroupId().hashCode();
- hash = hash * 31 + artifact.getArtifactId().hashCode();
- hashCode = hash;
+ this.hashCode = Objects.hash(artifact.getGroupId(),
artifact.getArtifactId());
}
@Override
diff --git
a/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/ClassicDependencyManager.java
b/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/ClassicDependencyManager.java
index 19917376..afde36ed 100644
---
a/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/ClassicDependencyManager.java
+++
b/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/ClassicDependencyManager.java
@@ -19,265 +19,72 @@
package org.eclipse.aether.util.graph.manager;
import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
import java.util.Map;
-import org.eclipse.aether.artifact.Artifact;
-import org.eclipse.aether.artifact.ArtifactProperties;
import org.eclipse.aether.collection.DependencyCollectionContext;
-import org.eclipse.aether.collection.DependencyManagement;
import org.eclipse.aether.collection.DependencyManager;
-import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.graph.Exclusion;
-import org.eclipse.aether.util.artifact.JavaScopes;
-
-import static java.util.Objects.requireNonNull;
/**
- * A dependency manager that mimics the way Maven 2.x works.
+ * A dependency manager that mimics the way Maven 2.x works. This manager was
used throughout all Maven 3.x versions.
+ * <p>
+ * This manager has {@code deriveUntil=2} and {@code applyFrom=2}.
*/
-public final class ClassicDependencyManager implements DependencyManager {
-
- private final int depth;
-
- private final Map<Object, String> managedVersions;
-
- private final Map<Object, String> managedScopes;
-
- private final Map<Object, Boolean> managedOptionals;
-
- private final Map<Object, String> managedLocalPaths;
-
- private final Map<Object, Collection<Exclusion>> managedExclusions;
-
- private int hashCode;
-
+public final class ClassicDependencyManager extends AbstractDependencyManager {
/**
* Creates a new dependency manager without any management information.
*/
public ClassicDependencyManager() {
- this(
- 0,
- Collections.<Object, String>emptyMap(),
- Collections.<Object, String>emptyMap(),
- Collections.<Object, Boolean>emptyMap(),
- Collections.<Object, String>emptyMap(),
- Collections.<Object, Collection<Exclusion>>emptyMap());
+ super(2, 2);
}
+ @SuppressWarnings("checkstyle:ParameterNumber")
private ClassicDependencyManager(
int depth,
+ int deriveUntil,
+ int applyFrom,
Map<Object, String> managedVersions,
Map<Object, String> managedScopes,
Map<Object, Boolean> managedOptionals,
Map<Object, String> managedLocalPaths,
Map<Object, Collection<Exclusion>> managedExclusions) {
- this.depth = depth;
- this.managedVersions = managedVersions;
- this.managedScopes = managedScopes;
- this.managedOptionals = managedOptionals;
- this.managedLocalPaths = managedLocalPaths;
- this.managedExclusions = managedExclusions;
- }
-
- public DependencyManager deriveChildManager(DependencyCollectionContext
context) {
- requireNonNull(context, "context cannot be null");
- if (depth >= 2) {
- return this;
- } else if (depth == 1) {
- return new ClassicDependencyManager(
- depth + 1, managedVersions, managedScopes,
managedOptionals, managedLocalPaths, managedExclusions);
- }
-
- Map<Object, String> managedVersions = this.managedVersions;
- Map<Object, String> managedScopes = this.managedScopes;
- Map<Object, Boolean> managedOptionals = this.managedOptionals;
- Map<Object, String> managedLocalPaths = this.managedLocalPaths;
- Map<Object, Collection<Exclusion>> managedExclusions =
this.managedExclusions;
-
- for (Dependency managedDependency : context.getManagedDependencies()) {
- Artifact artifact = managedDependency.getArtifact();
- Object key = getKey(artifact);
-
- String version = artifact.getVersion();
- if (!version.isEmpty() && !managedVersions.containsKey(key)) {
- if (managedVersions == this.managedVersions) {
- managedVersions = new HashMap<>(this.managedVersions);
- }
- managedVersions.put(key, version);
- }
-
- String scope = managedDependency.getScope();
- if (!scope.isEmpty() && !managedScopes.containsKey(key)) {
- if (managedScopes == this.managedScopes) {
- managedScopes = new HashMap<>(this.managedScopes);
- }
- managedScopes.put(key, scope);
- }
-
- Boolean optional = managedDependency.getOptional();
- if (optional != null && !managedOptionals.containsKey(key)) {
- if (managedOptionals == this.managedOptionals) {
- managedOptionals = new HashMap<>(this.managedOptionals);
- }
- managedOptionals.put(key, optional);
- }
-
- String localPath =
managedDependency.getArtifact().getProperty(ArtifactProperties.LOCAL_PATH,
null);
- if (localPath != null && !managedLocalPaths.containsKey(key)) {
- if (managedLocalPaths == this.managedLocalPaths) {
- managedLocalPaths = new HashMap<>(this.managedLocalPaths);
- }
- managedLocalPaths.put(key, localPath);
- }
-
- Collection<Exclusion> exclusions =
managedDependency.getExclusions();
- if (!exclusions.isEmpty()) {
- if (managedExclusions == this.managedExclusions) {
- managedExclusions = new HashMap<>(this.managedExclusions);
- }
- Collection<Exclusion> managed =
managedExclusions.computeIfAbsent(key, k -> new LinkedHashSet<>());
- managed.addAll(exclusions);
- }
- }
-
- return new ClassicDependencyManager(
- depth + 1, managedVersions, managedScopes, managedOptionals,
managedLocalPaths, managedExclusions);
- }
-
- public DependencyManagement manageDependency(Dependency dependency) {
- requireNonNull(dependency, "dependency cannot be null");
- DependencyManagement management = null;
-
- Object key = getKey(dependency.getArtifact());
-
- if (depth >= 2) {
- String version = managedVersions.get(key);
- if (version != null) {
- management = new DependencyManagement();
- management.setVersion(version);
- }
-
- String scope = managedScopes.get(key);
- if (scope != null) {
- if (management == null) {
- management = new DependencyManagement();
- }
- management.setScope(scope);
-
- if (!JavaScopes.SYSTEM.equals(scope)
- &&
dependency.getArtifact().getProperty(ArtifactProperties.LOCAL_PATH, null) !=
null) {
- Map<String, String> properties =
- new
HashMap<>(dependency.getArtifact().getProperties());
- properties.remove(ArtifactProperties.LOCAL_PATH);
- management.setProperties(properties);
- }
- }
-
- if ((JavaScopes.SYSTEM.equals(scope))
- || (scope == null &&
JavaScopes.SYSTEM.equals(dependency.getScope()))) {
- String localPath = managedLocalPaths.get(key);
- if (localPath != null) {
- if (management == null) {
- management = new DependencyManagement();
- }
- Map<String, String> properties =
- new
HashMap<>(dependency.getArtifact().getProperties());
- properties.put(ArtifactProperties.LOCAL_PATH, localPath);
- management.setProperties(properties);
- }
- }
-
- Boolean optional = managedOptionals.get(key);
- if (optional != null) {
- if (management == null) {
- management = new DependencyManagement();
- }
- management.setOptional(optional);
- }
- }
-
- Collection<Exclusion> exclusions = managedExclusions.get(key);
- if (exclusions != null) {
- if (management == null) {
- management = new DependencyManagement();
- }
- Collection<Exclusion> result = new
LinkedHashSet<>(dependency.getExclusions());
- result.addAll(exclusions);
- management.setExclusions(result);
- }
-
- return management;
- }
-
- private Object getKey(Artifact a) {
- return new Key(a);
+ super(
+ depth,
+ deriveUntil,
+ applyFrom,
+ managedVersions,
+ managedScopes,
+ managedOptionals,
+ managedLocalPaths,
+ managedExclusions);
}
@Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- } else if (null == obj || !getClass().equals(obj.getClass())) {
- return false;
+ public DependencyManager deriveChildManager(DependencyCollectionContext
context) {
+ // MNG-4720: Maven2 backward compatibility
+ // Removing this IF makes one IT fail here (read comment above):
+ //
https://github.com/apache/maven-integration-testing/blob/b4e8fd52b99a058336f9c7c5ec44fdbc1427759c/core-it-suite/src/test/java/org/apache/maven/it/MavenITmng4720DependencyManagementExclusionMergeTest.java#L67
+ if (depth == 1) {
+ return newInstance(managedVersions, managedScopes,
managedOptionals, managedLocalPaths, managedExclusions);
}
-
- ClassicDependencyManager that = (ClassicDependencyManager) obj;
- return depth == that.depth
- && managedVersions.equals(that.managedVersions)
- && managedScopes.equals(that.managedScopes)
- && managedOptionals.equals(that.managedOptionals)
- && managedExclusions.equals(that.managedExclusions);
+ return super.deriveChildManager(context);
}
@Override
- public int hashCode() {
- if (hashCode == 0) {
- int hash = 17;
- hash = hash * 31 + depth;
- hash = hash * 31 + managedVersions.hashCode();
- hash = hash * 31 + managedScopes.hashCode();
- hash = hash * 31 + managedOptionals.hashCode();
- hash = hash * 31 + managedExclusions.hashCode();
- hashCode = hash;
- }
- return hashCode;
- }
-
- static class Key {
-
- private final Artifact artifact;
-
- private final int hashCode;
-
- Key(Artifact artifact) {
- this.artifact = artifact;
-
- int hash = 17;
- hash = hash * 31 + artifact.getGroupId().hashCode();
- hash = hash * 31 + artifact.getArtifactId().hashCode();
- hashCode = hash;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- } else if (!(obj instanceof Key)) {
- return false;
- }
- Key that = (Key) obj;
- return
artifact.getArtifactId().equals(that.artifact.getArtifactId())
- && artifact.getGroupId().equals(that.artifact.getGroupId())
- &&
artifact.getExtension().equals(that.artifact.getExtension())
- &&
artifact.getClassifier().equals(that.artifact.getClassifier());
- }
-
- @Override
- public int hashCode() {
- return hashCode;
- }
+ protected DependencyManager newInstance(
+ Map<Object, String> managedVersions,
+ Map<Object, String> managedScopes,
+ Map<Object, Boolean> managedOptionals,
+ Map<Object, String> managedLocalPaths,
+ Map<Object, Collection<Exclusion>> managedExclusions) {
+ return new ClassicDependencyManager(
+ depth + 1,
+ deriveUntil,
+ applyFrom,
+ managedVersions,
+ managedScopes,
+ managedOptionals,
+ managedLocalPaths,
+ managedExclusions);
}
}
diff --git
a/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/DefaultDependencyManager.java
b/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/DefaultDependencyManager.java
index 332a3622..f76b2a44 100644
---
a/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/DefaultDependencyManager.java
+++
b/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/DefaultDependencyManager.java
@@ -19,22 +19,10 @@
package org.eclipse.aether.util.graph.manager;
import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
import java.util.Map;
-import java.util.Objects;
-import org.eclipse.aether.artifact.Artifact;
-import org.eclipse.aether.artifact.ArtifactProperties;
-import org.eclipse.aether.collection.DependencyCollectionContext;
-import org.eclipse.aether.collection.DependencyManagement;
import org.eclipse.aether.collection.DependencyManager;
-import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.graph.Exclusion;
-import org.eclipse.aether.util.artifact.JavaScopes;
-
-import static java.util.Objects.requireNonNull;
/**
* A dependency manager managing dependencies on all levels supporting
transitive dependency management.
@@ -42,229 +30,56 @@ import static java.util.Objects.requireNonNull;
* <b>Note:</b>Unlike the {@code ClassicDependencyManager} and the {@code
TransitiveDependencyManager} this
* implementation applies management also on the first level. This is
considered the resolver's default behaviour.
* It ignores all management overrides supported by the {@code
MavenModelBuilder}.
- * </p>
+ * <p>
+ * This manager has {@code deriveUntil=Integer.MAX_VALUE} and {@code
applyFrom=0}.
*
* @author Christian Schulte
* @since 1.4.0
*/
-public final class DefaultDependencyManager implements DependencyManager {
-
- private final Map<Object, String> managedVersions;
-
- private final Map<Object, String> managedScopes;
-
- private final Map<Object, Boolean> managedOptionals;
-
- private final Map<Object, String> managedLocalPaths;
-
- private final Map<Object, Collection<Exclusion>> managedExclusions;
-
- private int hashCode;
-
+public final class DefaultDependencyManager extends AbstractDependencyManager {
/**
* Creates a new dependency manager without any management information.
*/
public DefaultDependencyManager() {
- this(
- Collections.<Object, String>emptyMap(),
- Collections.<Object, String>emptyMap(),
- Collections.<Object, Boolean>emptyMap(),
- Collections.<Object, String>emptyMap(),
- Collections.<Object, Collection<Exclusion>>emptyMap());
+ super(Integer.MAX_VALUE, 0);
}
+ @SuppressWarnings("checkstyle:ParameterNumber")
private DefaultDependencyManager(
- final Map<Object, String> managedVersions,
- final Map<Object, String> managedScopes,
- final Map<Object, Boolean> managedOptionals,
- final Map<Object, String> managedLocalPaths,
- final Map<Object, Collection<Exclusion>> managedExclusions) {
- super();
- this.managedVersions = managedVersions;
- this.managedScopes = managedScopes;
- this.managedOptionals = managedOptionals;
- this.managedLocalPaths = managedLocalPaths;
- this.managedExclusions = managedExclusions;
- }
-
- public DependencyManager deriveChildManager(final
DependencyCollectionContext context) {
- requireNonNull(context, "context cannot be null");
- Map<Object, String> versions = this.managedVersions;
- Map<Object, String> scopes = this.managedScopes;
- Map<Object, Boolean> optionals = this.managedOptionals;
- Map<Object, String> localPaths = this.managedLocalPaths;
- Map<Object, Collection<Exclusion>> exclusions = this.managedExclusions;
-
- for (Dependency managedDependency : context.getManagedDependencies()) {
- Artifact artifact = managedDependency.getArtifact();
- Object key = getKey(artifact);
-
- String version = artifact.getVersion();
- if (!version.isEmpty() && !versions.containsKey(key)) {
- if (versions == this.managedVersions) {
- versions = new HashMap<>(this.managedVersions);
- }
- versions.put(key, version);
- }
-
- String scope = managedDependency.getScope();
- if (!scope.isEmpty() && !scopes.containsKey(key)) {
- if (scopes == this.managedScopes) {
- scopes = new HashMap<>(this.managedScopes);
- }
- scopes.put(key, scope);
- }
-
- Boolean optional = managedDependency.getOptional();
- if (optional != null && !optionals.containsKey(key)) {
- if (optionals == this.managedOptionals) {
- optionals = new HashMap<>(this.managedOptionals);
- }
- optionals.put(key, optional);
- }
-
- String localPath =
managedDependency.getArtifact().getProperty(ArtifactProperties.LOCAL_PATH,
null);
- if (localPath != null && !localPaths.containsKey(key)) {
- if (localPaths == this.managedLocalPaths) {
- localPaths = new HashMap<>(this.managedLocalPaths);
- }
- localPaths.put(key, localPath);
- }
-
- if (!managedDependency.getExclusions().isEmpty()) {
- if (exclusions == this.managedExclusions) {
- exclusions = new HashMap<>(this.managedExclusions);
- }
- Collection<Exclusion> managed =
exclusions.computeIfAbsent(key, k -> new LinkedHashSet<>());
- managed.addAll(managedDependency.getExclusions());
- }
- }
-
- return new DefaultDependencyManager(versions, scopes, optionals,
localPaths, exclusions);
- }
-
- public DependencyManagement manageDependency(Dependency dependency) {
- requireNonNull(dependency, "dependency cannot be null");
- DependencyManagement management = null;
-
- Object key = getKey(dependency.getArtifact());
-
- String version = managedVersions.get(key);
- if (version != null) {
- management = new DependencyManagement();
- management.setVersion(version);
- }
-
- String scope = managedScopes.get(key);
- if (scope != null) {
- if (management == null) {
- management = new DependencyManagement();
- }
- management.setScope(scope);
-
- if (!JavaScopes.SYSTEM.equals(scope)
- &&
dependency.getArtifact().getProperty(ArtifactProperties.LOCAL_PATH, null) !=
null) {
- Map<String, String> properties =
- new
HashMap<>(dependency.getArtifact().getProperties());
-
- properties.remove(ArtifactProperties.LOCAL_PATH);
- management.setProperties(properties);
- }
- }
-
- if ((scope != null && JavaScopes.SYSTEM.equals(scope))
- || (scope == null &&
JavaScopes.SYSTEM.equals(dependency.getScope()))) {
- String localPath = managedLocalPaths.get(key);
- if (localPath != null) {
- if (management == null) {
- management = new DependencyManagement();
- }
-
- Map<String, String> properties =
- new
HashMap<>(dependency.getArtifact().getProperties());
-
- properties.put(ArtifactProperties.LOCAL_PATH, localPath);
- management.setProperties(properties);
- }
- }
-
- Boolean optional = managedOptionals.get(key);
- if (optional != null) {
- if (management == null) {
- management = new DependencyManagement();
- }
- management.setOptional(optional);
- }
-
- Collection<Exclusion> exclusions = managedExclusions.get(key);
- if (exclusions != null) {
- if (management == null) {
- management = new DependencyManagement();
- }
- Collection<Exclusion> result = new
LinkedHashSet<>(dependency.getExclusions());
- result.addAll(exclusions);
- management.setExclusions(result);
- }
-
- return management;
- }
-
- private Object getKey(Artifact a) {
- return new Key(a);
+ int depth,
+ int deriveUntil,
+ int applyFrom,
+ Map<Object, String> managedVersions,
+ Map<Object, String> managedScopes,
+ Map<Object, Boolean> managedOptionals,
+ Map<Object, String> managedLocalPaths,
+ Map<Object, Collection<Exclusion>> managedExclusions) {
+ super(
+ depth,
+ deriveUntil,
+ applyFrom,
+ managedVersions,
+ managedScopes,
+ managedOptionals,
+ managedLocalPaths,
+ managedExclusions);
}
@Override
- public boolean equals(final Object obj) {
- boolean equal = obj instanceof DefaultDependencyManager;
-
- if (equal) {
- final DefaultDependencyManager that = (DefaultDependencyManager)
obj;
- equal = Objects.equals(managedVersions, that.managedVersions)
- && Objects.equals(managedScopes, that.managedScopes)
- && Objects.equals(managedOptionals, that.managedOptionals)
- && Objects.equals(managedExclusions,
that.managedExclusions);
- }
-
- return equal;
- }
-
- @Override
- public int hashCode() {
- if (hashCode == 0) {
- hashCode = Objects.hash(managedVersions, managedScopes,
managedOptionals, managedExclusions);
- }
- return hashCode;
- }
-
- static class Key {
-
- private final Artifact artifact;
-
- private final int hashCode;
-
- Key(final Artifact artifact) {
- this.artifact = artifact;
- this.hashCode = Objects.hash(artifact.getGroupId(),
artifact.getArtifactId());
- }
-
- @Override
- public boolean equals(final Object obj) {
- boolean equal = obj instanceof Key;
-
- if (equal) {
- final Key that = (Key) obj;
- return Objects.equals(artifact.getArtifactId(),
that.artifact.getArtifactId())
- && Objects.equals(artifact.getGroupId(),
that.artifact.getGroupId())
- && Objects.equals(artifact.getExtension(),
that.artifact.getExtension())
- && Objects.equals(artifact.getClassifier(),
that.artifact.getClassifier());
- }
-
- return false;
- }
-
- @Override
- public int hashCode() {
- return this.hashCode;
- }
+ protected DependencyManager newInstance(
+ Map<Object, String> managedVersions,
+ Map<Object, String> managedScopes,
+ Map<Object, Boolean> managedOptionals,
+ Map<Object, String> managedLocalPaths,
+ Map<Object, Collection<Exclusion>> managedExclusions) {
+ return new DefaultDependencyManager(
+ depth + 1,
+ deriveUntil,
+ applyFrom,
+ managedVersions,
+ managedScopes,
+ managedOptionals,
+ managedLocalPaths,
+ managedExclusions);
}
}
diff --git
a/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/TransitiveDependencyManager.java
b/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/TransitiveDependencyManager.java
index 9e691239..e1ec3304 100644
---
a/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/TransitiveDependencyManager.java
+++
b/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/TransitiveDependencyManager.java
@@ -19,251 +19,64 @@
package org.eclipse.aether.util.graph.manager;
import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
import java.util.Map;
-import java.util.Objects;
-import org.eclipse.aether.artifact.Artifact;
-import org.eclipse.aether.artifact.ArtifactProperties;
-import org.eclipse.aether.collection.DependencyCollectionContext;
-import org.eclipse.aether.collection.DependencyManagement;
import org.eclipse.aether.collection.DependencyManager;
-import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.graph.Exclusion;
-import org.eclipse.aether.util.artifact.JavaScopes;
-
-import static java.util.Objects.requireNonNull;
/**
* A dependency manager managing transitive dependencies supporting transitive
dependency management.
+ * <p>
+ * This manager is similar to "classic", it has {@code
deriveUntil=Integer.MAX_VALUE} (unlike 2 as in "classic") and
+ * {@code applyFrom=2}.
*
* @author Christian Schulte
* @since 1.4.0
*/
-public final class TransitiveDependencyManager implements DependencyManager {
-
- private final Map<Object, String> managedVersions;
-
- private final Map<Object, String> managedScopes;
-
- private final Map<Object, Boolean> managedOptionals;
-
- private final Map<Object, String> managedLocalPaths;
-
- private final Map<Object, Collection<Exclusion>> managedExclusions;
-
- private final int depth;
-
- private int hashCode;
-
+public final class TransitiveDependencyManager extends
AbstractDependencyManager {
/**
* Creates a new dependency manager without any management information.
*/
public TransitiveDependencyManager() {
- this(
- 0,
- Collections.<Object, String>emptyMap(),
- Collections.<Object, String>emptyMap(),
- Collections.<Object, Boolean>emptyMap(),
- Collections.<Object, String>emptyMap(),
- Collections.<Object, Collection<Exclusion>>emptyMap());
+ super(Integer.MAX_VALUE, 2);
}
+ @SuppressWarnings("checkstyle:ParameterNumber")
private TransitiveDependencyManager(
- final int depth,
- final Map<Object, String> managedVersions,
- final Map<Object, String> managedScopes,
- final Map<Object, Boolean> managedOptionals,
- final Map<Object, String> managedLocalPaths,
- final Map<Object, Collection<Exclusion>> managedExclusions) {
- super();
- this.depth = depth;
- this.managedVersions = managedVersions;
- this.managedScopes = managedScopes;
- this.managedOptionals = managedOptionals;
- this.managedLocalPaths = managedLocalPaths;
- this.managedExclusions = managedExclusions;
- }
-
- public DependencyManager deriveChildManager(final
DependencyCollectionContext context) {
- requireNonNull(context, "context cannot be null");
- Map<Object, String> versions = managedVersions;
- Map<Object, String> scopes = managedScopes;
- Map<Object, Boolean> optionals = managedOptionals;
- Map<Object, String> localPaths = managedLocalPaths;
- Map<Object, Collection<Exclusion>> exclusions = managedExclusions;
-
- for (Dependency managedDependency : context.getManagedDependencies()) {
- Artifact artifact = managedDependency.getArtifact();
- Object key = getKey(artifact);
-
- String version = artifact.getVersion();
- if (!version.isEmpty() && !versions.containsKey(key)) {
- if (versions == managedVersions) {
- versions = new HashMap<>(managedVersions);
- }
- versions.put(key, version);
- }
-
- String scope = managedDependency.getScope();
- if (!scope.isEmpty() && !scopes.containsKey(key)) {
- if (scopes == this.managedScopes) {
- scopes = new HashMap<>(this.managedScopes);
- }
- scopes.put(key, scope);
- }
-
- Boolean optional = managedDependency.getOptional();
- if (optional != null && !optionals.containsKey(key)) {
- if (optionals == managedOptionals) {
- optionals = new HashMap<>(managedOptionals);
- }
- optionals.put(key, optional);
- }
-
- String localPath =
managedDependency.getArtifact().getProperty(ArtifactProperties.LOCAL_PATH,
null);
- if (localPath != null && !localPaths.containsKey(key)) {
- if (localPaths == this.managedLocalPaths) {
- localPaths = new HashMap<>(managedLocalPaths);
- }
- localPaths.put(key, localPath);
- }
-
- if (!managedDependency.getExclusions().isEmpty()) {
- if (exclusions == managedExclusions) {
- exclusions = new HashMap<>(managedExclusions);
- }
- Collection<Exclusion> managed =
exclusions.computeIfAbsent(key, k -> new LinkedHashSet<>());
- managed.addAll(managedDependency.getExclusions());
- }
- }
-
- return new TransitiveDependencyManager(depth + 1, versions, scopes,
optionals, localPaths, exclusions);
- }
-
- public DependencyManagement manageDependency(Dependency dependency) {
- requireNonNull(dependency, "dependency cannot be null");
- DependencyManagement management = null;
-
- Object key = getKey(dependency.getArtifact());
-
- if (depth >= 2) {
- String version = managedVersions.get(key);
- if (version != null) {
- management = new DependencyManagement();
- management.setVersion(version);
- }
-
- String scope = managedScopes.get(key);
- if (scope != null) {
- if (management == null) {
- management = new DependencyManagement();
- }
- management.setScope(scope);
-
- if (!JavaScopes.SYSTEM.equals(scope)
- &&
dependency.getArtifact().getProperty(ArtifactProperties.LOCAL_PATH, null) !=
null) {
- Map<String, String> properties =
- new
HashMap<>(dependency.getArtifact().getProperties());
- properties.remove(ArtifactProperties.LOCAL_PATH);
- management.setProperties(properties);
- }
- }
-
- if ((JavaScopes.SYSTEM.equals(scope))
- || (scope == null &&
JavaScopes.SYSTEM.equals(dependency.getScope()))) {
- String localPath = managedLocalPaths.get(key);
- if (localPath != null) {
- if (management == null) {
- management = new DependencyManagement();
- }
- Map<String, String> properties =
- new
HashMap<>(dependency.getArtifact().getProperties());
- properties.put(ArtifactProperties.LOCAL_PATH, localPath);
- management.setProperties(properties);
- }
- }
-
- Boolean optional = managedOptionals.get(key);
- if (optional != null) {
- if (management == null) {
- management = new DependencyManagement();
- }
- management.setOptional(optional);
- }
- }
-
- Collection<Exclusion> exclusions = managedExclusions.get(key);
- if (exclusions != null) {
- if (management == null) {
- management = new DependencyManagement();
- }
- Collection<Exclusion> result = new
LinkedHashSet<>(dependency.getExclusions());
- result.addAll(exclusions);
- management.setExclusions(result);
- }
-
- return management;
- }
-
- private Object getKey(Artifact a) {
- return new Key(a);
+ int depth,
+ int deriveUntil,
+ int applyFrom,
+ Map<Object, String> managedVersions,
+ Map<Object, String> managedScopes,
+ Map<Object, Boolean> managedOptionals,
+ Map<Object, String> managedLocalPaths,
+ Map<Object, Collection<Exclusion>> managedExclusions) {
+ super(
+ depth,
+ deriveUntil,
+ applyFrom,
+ managedVersions,
+ managedScopes,
+ managedOptionals,
+ managedLocalPaths,
+ managedExclusions);
}
@Override
- public boolean equals(final Object obj) {
- boolean equal = obj instanceof TransitiveDependencyManager;
-
- if (equal) {
- final TransitiveDependencyManager that =
(TransitiveDependencyManager) obj;
- return depth == that.depth
- && Objects.equals(managedVersions, that.managedVersions)
- && Objects.equals(managedScopes, that.managedScopes)
- && Objects.equals(managedOptionals, that.managedOptionals)
- && Objects.equals(managedExclusions,
that.managedExclusions);
- }
-
- return false;
- }
-
- @Override
- public int hashCode() {
- if (hashCode == 0) {
- hashCode = Objects.hash(depth, managedVersions, managedScopes,
managedOptionals, managedExclusions);
- }
- return hashCode;
- }
-
- static class Key {
- private final Artifact artifact;
-
- private final int hashCode;
-
- Key(final Artifact artifact) {
- this.artifact = artifact;
- this.hashCode = Objects.hash(artifact.getGroupId(),
artifact.getArtifactId());
- }
-
- @Override
- public boolean equals(final Object obj) {
- boolean equal = obj instanceof Key;
-
- if (equal) {
- final Key that = (Key) obj;
- return Objects.equals(artifact.getArtifactId(),
that.artifact.getArtifactId())
- && Objects.equals(artifact.getGroupId(),
that.artifact.getGroupId())
- && Objects.equals(artifact.getExtension(),
that.artifact.getExtension())
- && Objects.equals(artifact.getClassifier(),
that.artifact.getClassifier());
- }
-
- return false;
- }
-
- @Override
- public int hashCode() {
- return this.hashCode;
- }
+ protected DependencyManager newInstance(
+ Map<Object, String> managedVersions,
+ Map<Object, String> managedScopes,
+ Map<Object, Boolean> managedOptionals,
+ Map<Object, String> managedLocalPaths,
+ Map<Object, Collection<Exclusion>> managedExclusions) {
+ return new TransitiveDependencyManager(
+ depth + 1,
+ deriveUntil,
+ applyFrom,
+ managedVersions,
+ managedScopes,
+ managedOptionals,
+ managedLocalPaths,
+ managedExclusions);
}
}
diff --git
a/maven-resolver-util/src/test/java/org/eclipse/aether/util/graph/manager/ClassicDependencyManagerTest.java
b/maven-resolver-util/src/test/java/org/eclipse/aether/util/graph/manager/ClassicDependencyManagerTest.java
deleted file mode 100644
index 2db88c09..00000000
---
a/maven-resolver-util/src/test/java/org/eclipse/aether/util/graph/manager/ClassicDependencyManagerTest.java
+++ /dev/null
@@ -1,75 +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.eclipse.aether.util.graph.manager;
-
-import java.util.Arrays;
-
-import org.eclipse.aether.RepositorySystemSession;
-import org.eclipse.aether.artifact.Artifact;
-import org.eclipse.aether.artifact.DefaultArtifact;
-import org.eclipse.aether.collection.DependencyCollectionContext;
-import org.eclipse.aether.collection.DependencyManagement;
-import org.eclipse.aether.collection.DependencyManager;
-import org.eclipse.aether.graph.Dependency;
-import org.eclipse.aether.internal.test.util.TestUtils;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-public class ClassicDependencyManagerTest {
-
- private final Artifact A = new DefaultArtifact("test", "a", "", "");
-
- private final Artifact A1 = new DefaultArtifact("test", "a", "", "1");
-
- private final Artifact B = new DefaultArtifact("test", "b", "", "");
-
- private final Artifact B1 = new DefaultArtifact("test", "b", "", "1");
-
- private RepositorySystemSession session;
-
- private DependencyCollectionContext newContext(Dependency...
managedDependencies) {
- return TestUtils.newCollectionContext(session, null,
Arrays.asList(managedDependencies));
- }
-
- @BeforeEach
- void setUp() {
- session = TestUtils.newSession();
- }
-
- @Test
- void testManageOptional() {
- DependencyManager manager = new ClassicDependencyManager();
-
- manager = manager.deriveChildManager(newContext(new Dependency(A,
null, null), new Dependency(B, null, true)));
- DependencyManagement mngt;
- mngt = manager.manageDependency(new Dependency(A1, null));
- assertNull(mngt);
- mngt = manager.manageDependency(new Dependency(B1, null));
- assertNull(mngt);
-
- manager = manager.deriveChildManager(newContext());
- mngt = manager.manageDependency(new Dependency(A1, null));
- assertNull(mngt);
- mngt = manager.manageDependency(new Dependency(B1, null));
- assertNotNull(mngt);
- assertEquals(Boolean.TRUE, mngt.getOptional());
- }
-}
diff --git
a/maven-resolver-util/src/test/java/org/eclipse/aether/util/graph/manager/DependencyManagerTest.java
b/maven-resolver-util/src/test/java/org/eclipse/aether/util/graph/manager/DependencyManagerTest.java
new file mode 100644
index 00000000..f2aab830
--- /dev/null
+++
b/maven-resolver-util/src/test/java/org/eclipse/aether/util/graph/manager/DependencyManagerTest.java
@@ -0,0 +1,248 @@
+/*
+ * 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.eclipse.aether.util.graph.manager;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.artifact.DefaultArtifact;
+import org.eclipse.aether.collection.DependencyCollectionContext;
+import org.eclipse.aether.collection.DependencyManagement;
+import org.eclipse.aether.collection.DependencyManager;
+import org.eclipse.aether.graph.Dependency;
+import org.eclipse.aether.graph.Exclusion;
+import org.eclipse.aether.internal.test.util.TestUtils;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * UT for {@link DependencyManager} implementations.
+ */
+public class DependencyManagerTest {
+
+ private final Artifact A1 = new DefaultArtifact("test", "a", "", "1");
+
+ private final Artifact A2 = new DefaultArtifact("test", "a", "", "2");
+
+ private final Artifact B1 = new DefaultArtifact("test", "b", "", "1");
+
+ private final Artifact C1 = new DefaultArtifact("test", "c", "", "1");
+
+ private final Artifact D1 = new DefaultArtifact("test", "d", "", "1");
+
+ private final Artifact E1 = new DefaultArtifact("test", "e", "", "1");
+
+ private final Artifact E2 = new DefaultArtifact("test", "e", "", "2");
+
+ private final Exclusion EXCLUSION = new Exclusion("test", "excluded",
null, null);
+
+ private RepositorySystemSession session;
+
+ private DependencyCollectionContext newContext(Dependency...
managedDependencies) {
+ return TestUtils.newCollectionContext(session, null,
Arrays.asList(managedDependencies));
+ }
+
+ @BeforeEach
+ void setUp() {
+ session = TestUtils.newSession();
+ }
+
+ @Test
+ void testClassic() {
+ DependencyManager manager = new ClassicDependencyManager();
+ DependencyManagement mngt;
+
+ // depth=1: only exclusion applied, nothing more
+ manager = manager.deriveChildManager(newContext(
+ new Dependency(A2, null, null),
+ new Dependency(B1, null, true),
+ new Dependency(C1, "newscope", null),
+ new Dependency(D1, null, null,
Collections.singleton(EXCLUSION))));
+ mngt = manager.manageDependency(new Dependency(A1, null));
+ assertNull(mngt);
+ mngt = manager.manageDependency(new Dependency(B1, null));
+ assertNull(mngt);
+ mngt = manager.manageDependency(new Dependency(C1, null));
+ assertNull(mngt);
+ mngt = manager.manageDependency(new Dependency(D1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getExclusions(), Collections.singleton(EXCLUSION));
+ mngt = manager.manageDependency(new Dependency(E1, null));
+ assertNull(mngt);
+
+ // depth=2: all applied
+ manager = manager.deriveChildManager(newContext());
+ mngt = manager.manageDependency(new Dependency(A1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getVersion(), A2.getVersion());
+ mngt = manager.manageDependency(new Dependency(B1, null));
+ assertNotNull(mngt);
+ assertEquals(Boolean.TRUE, mngt.getOptional());
+ mngt = manager.manageDependency(new Dependency(C1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getScope(), "newscope");
+ mngt = manager.manageDependency(new Dependency(D1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getExclusions(), Collections.singleton(EXCLUSION));
+ mngt = manager.manageDependency(new Dependency(E1, null));
+ assertNull(mngt);
+
+ // depth=3: all existing applied, new depMgt ignored, carried on only
what we have so far
+ manager = manager.deriveChildManager(newContext(new Dependency(E2,
null, null)));
+ mngt = manager.manageDependency(new Dependency(A1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getVersion(), A2.getVersion());
+ mngt = manager.manageDependency(new Dependency(B1, null));
+ assertNotNull(mngt);
+ assertEquals(Boolean.TRUE, mngt.getOptional());
+ mngt = manager.manageDependency(new Dependency(C1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getScope(), "newscope");
+ mngt = manager.manageDependency(new Dependency(D1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getExclusions(), Collections.singleton(EXCLUSION));
+ mngt = manager.manageDependency(new Dependency(E1, null));
+ assertNull(mngt);
+ }
+
+ @Test
+ void testTransitive() {
+ DependencyManager manager = new TransitiveDependencyManager();
+ DependencyManagement mngt;
+
+ // depth=1: only exclusion applied, nothing more
+ manager = manager.deriveChildManager(newContext(
+ new Dependency(A2, null, null),
+ new Dependency(B1, null, true),
+ new Dependency(C1, "newscope", null),
+ new Dependency(D1, null, null,
Collections.singleton(EXCLUSION))));
+ mngt = manager.manageDependency(new Dependency(A1, null));
+ assertNull(mngt);
+ mngt = manager.manageDependency(new Dependency(B1, null));
+ assertNull(mngt);
+ mngt = manager.manageDependency(new Dependency(C1, null));
+ assertNull(mngt);
+ mngt = manager.manageDependency(new Dependency(D1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getExclusions(), Collections.singleton(EXCLUSION));
+ mngt = manager.manageDependency(new Dependency(E1, null));
+ assertNull(mngt);
+
+ // depth=2: all applied
+ manager = manager.deriveChildManager(newContext());
+ mngt = manager.manageDependency(new Dependency(A1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getVersion(), A2.getVersion());
+ mngt = manager.manageDependency(new Dependency(B1, null));
+ assertNotNull(mngt);
+ assertEquals(Boolean.TRUE, mngt.getOptional());
+ mngt = manager.manageDependency(new Dependency(C1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getScope(), "newscope");
+ mngt = manager.manageDependency(new Dependency(D1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getExclusions(), Collections.singleton(EXCLUSION));
+ mngt = manager.manageDependency(new Dependency(E1, null));
+ assertNull(mngt);
+
+ // depth=3: all existing applied, new depMgt processed, carried on
+ manager = manager.deriveChildManager(newContext(new Dependency(E2,
null, null)));
+ mngt = manager.manageDependency(new Dependency(A1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getVersion(), A2.getVersion());
+ mngt = manager.manageDependency(new Dependency(B1, null));
+ assertNotNull(mngt);
+ assertEquals(Boolean.TRUE, mngt.getOptional());
+ mngt = manager.manageDependency(new Dependency(C1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getScope(), "newscope");
+ mngt = manager.manageDependency(new Dependency(D1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getExclusions(), Collections.singleton(EXCLUSION));
+ mngt = manager.manageDependency(new Dependency(E1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getVersion(), E2.getVersion());
+ }
+
+ @Test
+ void testDefault() {
+ DependencyManager manager = new DefaultDependencyManager();
+ DependencyManagement mngt;
+
+ // depth=1: all applied
+ manager = manager.deriveChildManager(newContext(
+ new Dependency(A2, null, null),
+ new Dependency(B1, null, true),
+ new Dependency(C1, "newscope", null),
+ new Dependency(D1, null, null,
Collections.singleton(EXCLUSION))));
+ mngt = manager.manageDependency(new Dependency(A1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getVersion(), A2.getVersion());
+ mngt = manager.manageDependency(new Dependency(B1, null));
+ assertNotNull(mngt);
+ assertEquals(Boolean.TRUE, mngt.getOptional());
+ mngt = manager.manageDependency(new Dependency(C1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getScope(), "newscope");
+ mngt = manager.manageDependency(new Dependency(D1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getExclusions(), Collections.singleton(EXCLUSION));
+ mngt = manager.manageDependency(new Dependency(E1, null));
+ assertNull(mngt);
+
+ // depth=2: all applied
+ manager = manager.deriveChildManager(newContext());
+ mngt = manager.manageDependency(new Dependency(A1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getVersion(), A2.getVersion());
+ mngt = manager.manageDependency(new Dependency(B1, null));
+ assertNotNull(mngt);
+ assertEquals(Boolean.TRUE, mngt.getOptional());
+ mngt = manager.manageDependency(new Dependency(C1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getScope(), "newscope");
+ mngt = manager.manageDependency(new Dependency(D1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getExclusions(), Collections.singleton(EXCLUSION));
+ mngt = manager.manageDependency(new Dependency(E1, null));
+ assertNull(mngt);
+
+ // depth=3: all existing applied, new depMgt processed, carried on
+ manager = manager.deriveChildManager(newContext(new Dependency(E2,
null, null)));
+ mngt = manager.manageDependency(new Dependency(A1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getVersion(), A2.getVersion());
+ mngt = manager.manageDependency(new Dependency(B1, null));
+ assertNotNull(mngt);
+ assertEquals(Boolean.TRUE, mngt.getOptional());
+ mngt = manager.manageDependency(new Dependency(C1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getScope(), "newscope");
+ mngt = manager.manageDependency(new Dependency(D1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getExclusions(), Collections.singleton(EXCLUSION));
+ mngt = manager.manageDependency(new Dependency(E1, null));
+ assertNotNull(mngt);
+ assertEquals(mngt.getVersion(), E2.getVersion());
+ }
+}