Repository: maven-resolver
Updated Branches:
refs/heads/master e391a27ab -> bec698b6d
Reverted various commits. Due to the way the 'DefaultDependencyCollector'
caches child node lists, there is no way to provide an API for traversing a
graph bottom-up. Parent's share the same child node list objects even when the
child nodes have been resolved from a different parent. The default dependency
collector would need to be rewritten (various caches, performance improvements,
cycle resolution) to make this possible making old issues re-appear.
This effectively reverts commits
468240b7060c80268f75c49b121e9a63ca8d90da
5b69d98e7bce7e49e1af031db59990f22d91526b
0a82c39e821953d43530e4fc3fcf99a6882dfd61
1b4370b1a4e82ce5dfaaea133b40a7fce801fc52
and paritally commit:
1ee92862c67ec98564c4d8be1207355960f1dd5d
Project: http://git-wip-us.apache.org/repos/asf/maven-resolver/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-resolver/commit/bec698b6
Tree: http://git-wip-us.apache.org/repos/asf/maven-resolver/tree/bec698b6
Diff: http://git-wip-us.apache.org/repos/asf/maven-resolver/diff/bec698b6
Branch: refs/heads/master
Commit: bec698b6db1a03cf5c98c79a1b10ed3df4bcb911
Parents: e391a27
Author: Christian Schulte <[email protected]>
Authored: Mon Nov 14 02:11:03 2016 +0100
Committer: Christian Schulte <[email protected]>
Committed: Mon Nov 14 02:11:03 2016 +0100
----------------------------------------------------------------------
.../aether/graph/DefaultDependencyNode.java | 43 +-
.../eclipse/aether/graph/DependencyNode.java | 18 -
.../impl/DefaultDependencyCollector.java | 18 +-
.../test/util/DependencyGraphParser.java | 2 +-
.../transformer/JavaDependencyMediator.java | 389 -------------------
5 files changed, 16 insertions(+), 454 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/bec698b6/maven-resolver-api/src/main/java/org/eclipse/aether/graph/DefaultDependencyNode.java
----------------------------------------------------------------------
diff --git
a/maven-resolver-api/src/main/java/org/eclipse/aether/graph/DefaultDependencyNode.java
b/maven-resolver-api/src/main/java/org/eclipse/aether/graph/DefaultDependencyNode.java
index 2e7288f..7d46891 100644
---
a/maven-resolver-api/src/main/java/org/eclipse/aether/graph/DefaultDependencyNode.java
+++
b/maven-resolver-api/src/main/java/org/eclipse/aether/graph/DefaultDependencyNode.java
@@ -39,8 +39,6 @@ public final class DefaultDependencyNode
implements DependencyNode
{
- private DependencyNode parent;
-
private List<DependencyNode> children;
private Dependency dependency;
@@ -70,7 +68,13 @@ public final class DefaultDependencyNode
*/
public DefaultDependencyNode( Dependency dependency )
{
- this( null, dependency );
+ this.dependency = dependency;
+ artifact = ( dependency != null ) ? dependency.getArtifact() : null;
+ children = new ArrayList<DependencyNode>( 0 );
+ aliases = relocations = Collections.emptyList();
+ repositories = Collections.emptyList();
+ context = "";
+ data = Collections.emptyMap();
}
/**
@@ -83,7 +87,6 @@ public final class DefaultDependencyNode
public DefaultDependencyNode( Artifact artifact )
{
super();
- this.parent = null;
this.artifact = artifact;
children = new ArrayList<DependencyNode>( 0 );
aliases = relocations = Collections.emptyList();
@@ -101,7 +104,6 @@ public final class DefaultDependencyNode
public DefaultDependencyNode( DependencyNode node )
{
super();
- parent = node.getParent();
dependency = node.getDependency();
artifact = node.getArtifact();
children = new ArrayList<DependencyNode>( 0 );
@@ -116,37 +118,6 @@ public final class DefaultDependencyNode
setData( data.isEmpty() ? null : new HashMap<Object, Object>( data ) );
}
- /**
- * Creates a new node with the specified dependency.
- *
- * @param parent The parent node of the node or {@code null}.
- * @param dependency The dependency associated with this node, may be
{@code null} for a root node.
- *
- * @since 1.2
- */
- public DefaultDependencyNode( DependencyNode parent, Dependency dependency
)
- {
- super();
- this.parent = parent;
- this.dependency = dependency;
- artifact = ( dependency != null ) ? dependency.getArtifact() : null;
- children = new ArrayList<DependencyNode>( 0 );
- aliases = relocations = Collections.emptyList();
- repositories = Collections.emptyList();
- context = "";
- data = Collections.emptyMap();
- }
-
- public long getDepth()
- {
- return this.getParent() != null ? this.getParent().getDepth() + 1L :
0L;
- }
-
- public DependencyNode getParent()
- {
- return this.parent;
- }
-
public List<DependencyNode> getChildren()
{
return children;
http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/bec698b6/maven-resolver-api/src/main/java/org/eclipse/aether/graph/DependencyNode.java
----------------------------------------------------------------------
diff --git
a/maven-resolver-api/src/main/java/org/eclipse/aether/graph/DependencyNode.java
b/maven-resolver-api/src/main/java/org/eclipse/aether/graph/DependencyNode.java
index da30124..5a9fc68 100644
---
a/maven-resolver-api/src/main/java/org/eclipse/aether/graph/DependencyNode.java
+++
b/maven-resolver-api/src/main/java/org/eclipse/aether/graph/DependencyNode.java
@@ -77,24 +77,6 @@ public interface DependencyNode
int MANAGED_EXCLUSIONS = 0x10;
/**
- * Gets the depth of the node.
- *
- * @return The depth of the node.
- *
- * @since 1.2
- */
- long getDepth();
-
- /**
- * Gets the parent node of this node.
- *
- * @return The parent node of this node or {@code null}, if this node is
the root of the graph.
- *
- * @since 1.2
- */
- DependencyNode getParent();
-
- /**
* Gets the child nodes of this node. To conserve memory, dependency nodes
with equal dependencies may share the
* same child list instance. Hence clients mutating the child list need to
be aware that these changes might affect
* more than this node. Where this is not desired, the child list should
be copied before mutation if the client
http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/bec698b6/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultDependencyCollector.java
----------------------------------------------------------------------
diff --git
a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultDependencyCollector.java
b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultDependencyCollector.java
index e38cf63..c68eb86 100644
---
a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultDependencyCollector.java
+++
b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultDependencyCollector.java
@@ -420,8 +420,8 @@ public class DefaultDependencyCollector
if ( cycleNode.getDependency() != null )
{
DefaultDependencyNode child =
- createDependencyNode( node, relocations,
preManaged, rangeResult, version, d,
- descriptorResult, cycleNode
);
+ createDependencyNode( relocations, preManaged,
rangeResult, version, d, descriptorResult,
+ cycleNode );
node.getChildren().add( child );
continue;
}
@@ -445,7 +445,7 @@ public class DefaultDependencyCollector
getRemoteRepositories( rangeResult.getRepository(
version ), repositories );
DefaultDependencyNode child =
- createDependencyNode( node, relocations, preManaged,
rangeResult, version, d,
+ createDependencyNode( relocations, preManaged,
rangeResult, version, d,
descriptorResult.getAliases(),
repos, args.request.getRequestContext() );
node.getChildren().add( child );
@@ -464,7 +464,7 @@ public class DefaultDependencyCollector
List<RemoteRepository> repos =
getRemoteRepositories( rangeResult.getRepository( version
), repositories );
DefaultDependencyNode child =
- createDependencyNode( node, relocations, preManaged,
rangeResult, version, d, null, repos,
+ createDependencyNode( relocations, preManaged,
rangeResult, version, d, null, repos,
args.request.getRequestContext() );
node.getChildren().add( child );
}
@@ -553,14 +553,13 @@ public class DefaultDependencyCollector
return descriptorResult;
}
- private static DefaultDependencyNode createDependencyNode( DependencyNode
parent,
- List<Artifact>
relocations,
+ private static DefaultDependencyNode createDependencyNode( List<Artifact>
relocations,
PremanagedDependency preManaged,
VersionRangeResult rangeResult, Version version,
Dependency d,
Collection<Artifact> aliases,
List<RemoteRepository> repos, String requestContext )
{
- DefaultDependencyNode child = new DefaultDependencyNode( parent, d );
+ DefaultDependencyNode child = new DefaultDependencyNode( d );
preManaged.applyTo( child );
child.setRelocations( relocations );
child.setVersionConstraint( rangeResult.getVersionConstraint() );
@@ -571,15 +570,14 @@ public class DefaultDependencyCollector
return child;
}
- private static DefaultDependencyNode createDependencyNode( DependencyNode
parent,
- List<Artifact>
relocations,
+ private static DefaultDependencyNode createDependencyNode( List<Artifact>
relocations,
PremanagedDependency preManaged,
VersionRangeResult rangeResult, Version version,
Dependency d,
ArtifactDescriptorResult descriptorResult,
DependencyNode
cycleNode )
{
DefaultDependencyNode child =
- createDependencyNode( parent, relocations, preManaged,
rangeResult, version, d,
+ createDependencyNode( relocations, preManaged, rangeResult,
version, d,
descriptorResult.getAliases(),
cycleNode.getRepositories(),
cycleNode.getRequestContext() );
http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/bec698b6/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/DependencyGraphParser.java
----------------------------------------------------------------------
diff --git
a/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/DependencyGraphParser.java
b/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/DependencyGraphParser.java
index 67eb20d..0eafb39 100644
---
a/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/DependencyGraphParser.java
+++
b/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/DependencyGraphParser.java
@@ -339,7 +339,7 @@ public class DependencyGraphParser
{
DefaultArtifact artifact = new DefaultArtifact( def.coords,
def.properties );
Dependency dependency = new Dependency( artifact, def.scope,
def.optional );
- node = new DefaultDependencyNode( parent, dependency );
+ node = new DefaultDependencyNode( dependency );
int managedBits = 0;
if ( def.premanagedScope != null )
{
http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/bec698b6/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/transformer/JavaDependencyMediator.java
----------------------------------------------------------------------
diff --git
a/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/transformer/JavaDependencyMediator.java
b/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/transformer/JavaDependencyMediator.java
deleted file mode 100644
index 441b6df..0000000
---
a/maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/transformer/JavaDependencyMediator.java
+++ /dev/null
@@ -1,389 +0,0 @@
-package org.eclipse.aether.util.graph.transformer;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.eclipse.aether.RepositoryException;
-import org.eclipse.aether.collection.DependencyGraphTransformationContext;
-import org.eclipse.aether.collection.DependencyGraphTransformer;
-import org.eclipse.aether.graph.DependencyNode;
-import org.eclipse.aether.util.artifact.JavaScopes;
-
-/**
- * A {@code DependencyGraphTransformer} applying the Maven dependency
mediation mechanism.
- *
- * @author Christian Schulte
- * @since 1.2
- * @see <a
href="http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html">Introduction
to the Dependency Mechanism</a>
- */
-public final class JavaDependencyMediator
- implements DependencyGraphTransformer
-{
-
- private static final Map<String, Integer> APPLICATION_SCOPE_PRIORITIES =
new HashMap<String, Integer>( 5 );
-
- private static final Map<String, Integer> TEST_SCOPE_PRIORITIES = new
HashMap<String, Integer>( 5 );
-
- static
- {
- APPLICATION_SCOPE_PRIORITIES.put( JavaScopes.TEST, 0 );
- APPLICATION_SCOPE_PRIORITIES.put( JavaScopes.RUNTIME, 1 );
- APPLICATION_SCOPE_PRIORITIES.put( JavaScopes.PROVIDED, 2 );
- APPLICATION_SCOPE_PRIORITIES.put( JavaScopes.COMPILE, 3 );
- APPLICATION_SCOPE_PRIORITIES.put( JavaScopes.SYSTEM, 4 );
-
- TEST_SCOPE_PRIORITIES.put( JavaScopes.RUNTIME, 0 );
- TEST_SCOPE_PRIORITIES.put( JavaScopes.PROVIDED, 1 );
- TEST_SCOPE_PRIORITIES.put( JavaScopes.COMPILE, 2 );
- TEST_SCOPE_PRIORITIES.put( JavaScopes.TEST, 3 );
- TEST_SCOPE_PRIORITIES.put( JavaScopes.SYSTEM, 4 );
- }
-
- /**
- * Application scope nodes are prioritized over non application scope
nodes.
- */
- public static final int APPLICATION_SCOPE_PRIORITIZATION = 1 << 1;
-
- /**
- * Test scope nodes are prioritized over non test scope nodes.
- */
- public static final int TEST_SCOPE_PRIORITIZATION = 1 << 2;
-
- /**
- * Nearest wins only strategy. No scopes are prioritized.
- */
- public static final int NO_PRIORITIZATION = 1 << 3;
-
- /**
- * The prioritization to apply.
- */
- private final int prioritization;
-
- /**
- * Creates a new {@code DependencyGraphTransformer}.
- *
- * @param prioritization The prioritization to apply.
- *
- * @see #APPLICATION_SCOPE_PRIORITIZATION
- * @see #TEST_SCOPE_PRIORITIZATION
- * @see #NO_PRIORITIZATION
- */
- public JavaDependencyMediator( final int prioritization )
- {
- super();
- this.prioritization = prioritization;
- }
-
- @Override
- public DependencyNode transformGraph( final DependencyNode node,
- final
DependencyGraphTransformationContext context )
- throws RepositoryException
- {
- DependencyNode result = node;
- result = this.removeNonTransitiveNodes( result );
- result = this.updateTransitiveScopes( result );
-
- for ( ;; )
- {
- if ( this.removeDuplicateNodes( result, result, new
HashMap<ConflictMarker.Key, DependencyNode>( 8192 ),
- new HashMap<DependencyNode,
DependencyNode>( 8192 ) ) )
- {
- break;
- }
- }
-
- return result;
- }
-
- private DependencyNode removeNonTransitiveNodes( final DependencyNode
parent )
- {
- final String parentScope = parent.getDependency() != null
- ? parent.getDependency().getScope() !=
null
- &&
parent.getDependency().getScope().length() >= 0
- ?
parent.getDependency().getScope()
- : JavaScopes.COMPILE
- : null;
-
- for ( final Iterator<DependencyNode> it =
parent.getChildren().iterator(); it.hasNext(); )
- {
- final DependencyNode child = it.next();
-
- recurse:
- {
- if ( parentScope != null )
- {
- String childScope = child.getDependency().getScope() !=
null
- &&
child.getDependency().getScope().length() >= 0
- ? child.getDependency().getScope()
- : JavaScopes.COMPILE;
-
- // Provided and test scopes are non-transitive.
- // Optional dependencies are non-transitive.
- if ( JavaScopes.PROVIDED.equals( childScope )
- || JavaScopes.TEST.equals( childScope )
- || child.getDependency().isOptional() )
- {
- it.remove();
- break recurse;
- }
- }
-
- this.removeNonTransitiveNodes( child );
- }
- }
-
- return parent;
- }
-
- private DependencyNode updateTransitiveScopes( final DependencyNode parent
)
- {
- final String parentScope = parent.getDependency() != null
- ? parent.getDependency().getScope() !=
null
- &&
parent.getDependency().getScope().length() >= 0
- ?
parent.getDependency().getScope()
- : JavaScopes.COMPILE
- : null;
-
- for ( final DependencyNode child : parent.getChildren() )
- {
- if ( parentScope != null )
- {
- String childScope = child.getDependency().getScope() != null
- &&
child.getDependency().getScope().length() >= 0
- ? child.getDependency().getScope()
- : JavaScopes.COMPILE;
-
- if ( ( child.getManagedBits() & DependencyNode.MANAGED_SCOPE )
== 0 )
- {
- // Non-managed child scopes are updated according to the
table in the "Dependency Scope" section
- // of the "Introduction to the Dependency Mechanism"
document.
-
- if ( JavaScopes.PROVIDED.equals( parentScope ) )
- {
- // Compile and runtime become provided.
- if ( JavaScopes.COMPILE.equals( childScope )
- || JavaScopes.RUNTIME.equals( childScope ) )
- {
- childScope = JavaScopes.PROVIDED;
- child.setScope( childScope );
- }
- }
- else if ( JavaScopes.RUNTIME.equals( parentScope ) )
- {
- // Compile becomes runtime.
- if ( JavaScopes.COMPILE.equals( childScope ) )
- {
- childScope = JavaScopes.RUNTIME;
- child.setScope( childScope );
- }
- }
- else if ( JavaScopes.TEST.equals( parentScope ) )
- {
- // Compile and runtime become test.
- if ( JavaScopes.COMPILE.equals( childScope )
- || JavaScopes.RUNTIME.equals( childScope ) )
- {
- childScope = JavaScopes.TEST;
- child.setScope( childScope );
- }
- }
- }
- }
-
- this.updateTransitiveScopes( child );
- }
-
- return parent;
- }
-
- private boolean removeDuplicateNodes( final DependencyNode rootNode,
- final DependencyNode candidateNode,
- final Map<ConflictMarker.Key,
DependencyNode> winnerNodes,
- final Map<DependencyNode,
DependencyNode> looserNodes )
- {
- boolean restart = false;
-
- recurse:
- {
- if ( candidateNode.getDependency() != null )
- {
- final ConflictMarker.Key candidateKey = new
ConflictMarker.Key( candidateNode.getArtifact() );
- final DependencyNode winnerNode = winnerNodes.get(
candidateKey );
-
- if ( winnerNode == null )
- {
- // Conflict not yet seen. Candidate is selected.
- winnerNodes.put( candidateKey, candidateNode );
- }
- else if ( this.isPreferredNode( winnerNode, candidateNode ) )
- {
- // Conflict already seen. Candidate is preferred.
- winnerNodes.put( candidateKey, candidateNode );
- looserNodes.put( candidateNode, winnerNode );
-
- if ( winnerNode.getParent() != null )
- {
- winnerNode.getParent().getChildren().remove(
winnerNode );
- }
- else
- {
- rootNode.getChildren().remove( winnerNode );
- }
-
- final DependencyNode winningChild = getWinningChild(
winnerNode, winnerNodes.values() );
-
- if ( winningChild != null )
- {
- // The node eliminated by the current candidate node
contains a child node which has been
- // selected the winner in a previous iteration. As
that winner is eliminated in this iteration,
- // the former looser needs to be re-added and the
whole transformation re-started (undo and
- // restart). No need to maintain the maps here because
they are thrown away when restarting.
- // Doing it for completeness, however.
- final DependencyNode looserNode = looserNodes.remove(
winningChild ); // Can be get().
-
- if ( looserNode != null )
- {
- if ( looserNode.getParent() != null )
- {
- if (
!looserNode.getParent().getChildren().contains( looserNode ) )
- {
- looserNode.getParent().getChildren().add(
looserNode );
- }
- }
- else if ( !rootNode.getChildren().contains(
looserNode ) )
- {
- rootNode.getChildren().add( looserNode );
- }
-
- // Not needed, but...
- final DependencyNode winner =
- winnerNodes.remove( new ConflictMarker.Key(
looserNode.getArtifact() ) );
-
- if ( winner != null )
- {
- looserNodes.remove( winner );
- }
- }
-
- restart = true;
- break recurse;
- }
- }
- else
- {
- // Conflict already seen. Candidate is not preferred.
- looserNodes.put( winnerNode, candidateNode );
- if ( candidateNode.getParent() != null )
- {
- candidateNode.getParent().getChildren().remove(
candidateNode );
- }
- else
- {
- rootNode.getChildren().remove( candidateNode );
- }
- // No need to inspect children.
- break recurse;
- }
- }
-
- for ( final DependencyNode child : new ArrayList<DependencyNode>(
candidateNode.getChildren() ) )
- {
- if ( !this.removeDuplicateNodes( rootNode, child, winnerNodes,
looserNodes ) )
- {
- restart = true;
- break recurse;
- }
- }
- }
-
- return !restart;
- }
-
- private boolean isPreferredNode( final DependencyNode existing, final
DependencyNode candidate )
- {
- boolean preferred = false;
- Integer p1 = null;
- Integer p2 = null;
- boolean prioritize = true;
-
- if ( this.prioritization == APPLICATION_SCOPE_PRIORITIZATION )
- {
- p1 = APPLICATION_SCOPE_PRIORITIES.get(
existing.getDependency().getScope() );
- p2 = APPLICATION_SCOPE_PRIORITIES.get(
candidate.getDependency().getScope() );
- }
- else if ( this.prioritization == TEST_SCOPE_PRIORITIZATION )
- {
- p1 = TEST_SCOPE_PRIORITIES.get(
existing.getDependency().getScope() );
- p2 = TEST_SCOPE_PRIORITIES.get(
candidate.getDependency().getScope() );
- }
- else if ( this.prioritization == NO_PRIORITIZATION )
- {
- prioritize = false;
- }
- else
- {
- throw new AssertionError( this.prioritization );
- }
-
- final Boolean candidateScopePrioritized = p1 != null && p2 != null ?
p2 > p1 : false;
- final boolean equalPriority =
- existing.getDependency().getScope().equals(
candidate.getDependency().getScope() );
-
- if ( candidate.getDepth() < existing.getDepth() )
- {
- preferred = !prioritize || equalPriority ||
candidateScopePrioritized;
- }
- else if ( candidate.getDepth() == existing.getDepth() )
- {
- preferred = prioritize && !equalPriority &&
candidateScopePrioritized;
- }
-
- return preferred;
- }
-
- private static DependencyNode getWinningChild( final DependencyNode node,
- final
Collection<DependencyNode> winnerNodes )
- {
- DependencyNode winningChild = winnerNodes.contains( node )
- ? node
- : null;
-
- if ( winningChild == null )
- {
- for ( final DependencyNode child : node.getChildren() )
- {
- winningChild = getWinningChild( child, winnerNodes );
-
- if ( winningChild != null )
- {
- break;
- }
- }
- }
-
- return winningChild;
- }
-
-}