Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 4D641200B97 for ; Sat, 3 Sep 2016 22:23:29 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 4B935160AD0; Sat, 3 Sep 2016 20:23:29 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id A7F73160AD4 for ; Sat, 3 Sep 2016 22:23:27 +0200 (CEST) Received: (qmail 53229 invoked by uid 500); 3 Sep 2016 20:23:25 -0000 Mailing-List: contact commits-help@maven.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@maven.apache.org Delivered-To: mailing list commits@maven.apache.org Received: (qmail 52323 invoked by uid 99); 3 Sep 2016 20:23:25 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 03 Sep 2016 20:23:25 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id C84AFE04D9; Sat, 3 Sep 2016 20:23:24 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: hboutemy@apache.org To: commits@maven.apache.org Date: Sat, 03 Sep 2016 20:23:37 -0000 Message-Id: <95aa5de67eeb436eaab9a7460694d28f@git.apache.org> In-Reply-To: <2cd999b3830b4d988db740ac64710a62@git.apache.org> References: <2cd999b3830b4d988db740ac64710a62@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [14/51] [partial] maven-aether git commit: [MNG-6007] rename Aether to Maven Artifact Resolver archived-at: Sat, 03 Sep 2016 20:23:29 -0000 http://git-wip-us.apache.org/repos/asf/maven-aether/blob/27f8bd73/aether-util/src/main/java/org/eclipse/aether/util/graph/selector/ScopeDependencySelector.java ---------------------------------------------------------------------- diff --git a/aether-util/src/main/java/org/eclipse/aether/util/graph/selector/ScopeDependencySelector.java b/aether-util/src/main/java/org/eclipse/aether/util/graph/selector/ScopeDependencySelector.java deleted file mode 100644 index 2640c42..0000000 --- a/aether-util/src/main/java/org/eclipse/aether/util/graph/selector/ScopeDependencySelector.java +++ /dev/null @@ -1,151 +0,0 @@ -package org.eclipse.aether.util.graph.selector; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.TreeSet; - -import org.eclipse.aether.collection.DependencyCollectionContext; -import org.eclipse.aether.collection.DependencySelector; -import org.eclipse.aether.graph.Dependency; - -/** - * A dependency selector that filters transitive dependencies based on their scope. Direct dependencies are always - * included regardless of their scope. Note: This filter does not assume any relationships between the scopes. - * In particular, the filter is not aware of scopes that logically include other scopes. - * - * @see Dependency#getScope() - */ -public final class ScopeDependencySelector - implements DependencySelector -{ - - private final int depth; - - private final Collection included; - - private final Collection excluded; - - /** - * Creates a new selector using the specified includes and excludes. - * - * @param included The set of scopes to include, may be {@code null} or empty to include any scope. - * @param excluded The set of scopes to exclude, may be {@code null} or empty to exclude no scope. - */ - public ScopeDependencySelector( Collection included, Collection excluded ) - { - super(); - this.depth = 0; - this.included = clone( included ); - this.excluded = clone( excluded ); - } - - private static Collection clone( Collection scopes ) - { - Collection copy; - if ( scopes == null || scopes.isEmpty() ) - { - // checking for null is faster than isEmpty() - copy = null; - } - else - { - copy = new HashSet( scopes ); - if ( copy.size() <= 2 ) - { - // contains() is faster for smallish array (sorted for equals()!) - copy = new ArrayList( new TreeSet( copy ) ); - } - } - return copy; - } - - /** - * Creates a new selector using the specified excludes. - * - * @param excluded The set of scopes to exclude, may be {@code null} or empty to exclude no scope. - */ - public ScopeDependencySelector( String... excluded ) - { - this( null, ( excluded != null ) ? Arrays.asList( excluded ) : null ); - } - - private ScopeDependencySelector( int depth, Collection included, Collection excluded ) - { - super(); - this.depth = depth; - this.included = included; - this.excluded = excluded; - } - - public boolean selectDependency( Dependency dependency ) - { - // depth < 2 == direct dependency - // assert this.depth > 0 : "Unexpected depth."; - return this.depth < 2 - || ( ( included == null || included.contains( dependency.getScope() ) ) - && ( excluded == null || !excluded.contains( dependency.getScope() ) ) ); - - } - - public DependencySelector deriveChildSelector( DependencyCollectionContext context ) - { - // First call is for direct dependencies, successive calls are for transitive dependencies. - return this.depth >= 2 - ? this - : new ScopeDependencySelector( this.depth + 1, this.included, this.excluded ); - - } - - @Override - public boolean equals( Object obj ) - { - if ( this == obj ) - { - return true; - } - else if ( null == obj || !getClass().equals( obj.getClass() ) ) - { - return false; - } - - ScopeDependencySelector that = (ScopeDependencySelector) obj; - return this.depth == that.depth && eq( included, that.included ) && eq( excluded, that.excluded ); - } - - private static boolean eq( T o1, T o2 ) - { - return ( o1 != null ) ? o1.equals( o2 ) : o2 == null; - } - - @Override - public int hashCode() - { - int hash = 17; - hash = hash * 31 + ( this.depth ); - hash = hash * 31 + ( included != null ? included.hashCode() : 0 ); - hash = hash * 31 + ( excluded != null ? excluded.hashCode() : 0 ); - return hash; - } - -} http://git-wip-us.apache.org/repos/asf/maven-aether/blob/27f8bd73/aether-util/src/main/java/org/eclipse/aether/util/graph/selector/StaticDependencySelector.java ---------------------------------------------------------------------- diff --git a/aether-util/src/main/java/org/eclipse/aether/util/graph/selector/StaticDependencySelector.java b/aether-util/src/main/java/org/eclipse/aether/util/graph/selector/StaticDependencySelector.java deleted file mode 100644 index 41ce0e0..0000000 --- a/aether-util/src/main/java/org/eclipse/aether/util/graph/selector/StaticDependencySelector.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.eclipse.aether.util.graph.selector; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import org.eclipse.aether.collection.DependencyCollectionContext; -import org.eclipse.aether.collection.DependencySelector; -import org.eclipse.aether.graph.Dependency; - -/** - * A dependency selector that always includes or excludes dependencies. - */ -public final class StaticDependencySelector - implements DependencySelector -{ - - private final boolean select; - - /** - * Creates a new selector with the specified selection behavior. - * - * @param select {@code true} to select all dependencies, {@code false} to exclude all dependencies. - */ - public StaticDependencySelector( boolean select ) - { - this.select = select; - } - - public boolean selectDependency( Dependency dependency ) - { - return select; - } - - public DependencySelector deriveChildSelector( DependencyCollectionContext context ) - { - return this; - } - - @Override - public boolean equals( Object obj ) - { - if ( this == obj ) - { - return true; - } - else if ( null == obj || !getClass().equals( obj.getClass() ) ) - { - return false; - } - - StaticDependencySelector that = (StaticDependencySelector) obj; - return select == that.select; - } - - @Override - public int hashCode() - { - int hash = getClass().hashCode(); - hash = hash * 31 + ( select ? 1 : 0 ); - return hash; - } - -} http://git-wip-us.apache.org/repos/asf/maven-aether/blob/27f8bd73/aether-util/src/main/java/org/eclipse/aether/util/graph/selector/package-info.java ---------------------------------------------------------------------- diff --git a/aether-util/src/main/java/org/eclipse/aether/util/graph/selector/package-info.java b/aether-util/src/main/java/org/eclipse/aether/util/graph/selector/package-info.java deleted file mode 100644 index 3c3cf3c..0000000 --- a/aether-util/src/main/java/org/eclipse/aether/util/graph/selector/package-info.java +++ /dev/null @@ -1,24 +0,0 @@ -// CHECKSTYLE_OFF: RegexpHeader -/* - * 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. - */ -/** - * Various dependency selectors for building a dependency graph. - */ -package org.eclipse.aether.util.graph.selector; - http://git-wip-us.apache.org/repos/asf/maven-aether/blob/27f8bd73/aether-util/src/main/java/org/eclipse/aether/util/graph/transformer/ChainedDependencyGraphTransformer.java ---------------------------------------------------------------------- diff --git a/aether-util/src/main/java/org/eclipse/aether/util/graph/transformer/ChainedDependencyGraphTransformer.java b/aether-util/src/main/java/org/eclipse/aether/util/graph/transformer/ChainedDependencyGraphTransformer.java deleted file mode 100644 index d7f1771..0000000 --- a/aether-util/src/main/java/org/eclipse/aether/util/graph/transformer/ChainedDependencyGraphTransformer.java +++ /dev/null @@ -1,85 +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 org.eclipse.aether.RepositoryException; -import org.eclipse.aether.collection.DependencyGraphTransformationContext; -import org.eclipse.aether.collection.DependencyGraphTransformer; -import org.eclipse.aether.graph.DependencyNode; - -/** - * A dependency graph transformer that chains other transformers. - */ -public final class ChainedDependencyGraphTransformer - implements DependencyGraphTransformer -{ - - private final DependencyGraphTransformer[] transformers; - - /** - * Creates a new transformer that chains the specified transformers. - * - * @param transformers The transformers to chain, may be {@code null} or empty. - */ - public ChainedDependencyGraphTransformer( DependencyGraphTransformer... transformers ) - { - if ( transformers == null ) - { - this.transformers = new DependencyGraphTransformer[0]; - } - else - { - this.transformers = transformers; - } - } - - /** - * Creates a new transformer that chains the specified transformers or simply returns one of them if the other one - * is {@code null}. - * - * @param transformer1 The first transformer of the chain, may be {@code null}. - * @param transformer2 The second transformer of the chain, may be {@code null}. - * @return The chained transformer or {@code null} if both input transformers are {@code null}. - */ - public static DependencyGraphTransformer newInstance( DependencyGraphTransformer transformer1, - DependencyGraphTransformer transformer2 ) - { - if ( transformer1 == null ) - { - return transformer2; - } - else if ( transformer2 == null ) - { - return transformer1; - } - return new ChainedDependencyGraphTransformer( transformer1, transformer2 ); - } - - public DependencyNode transformGraph( DependencyNode node, DependencyGraphTransformationContext context ) - throws RepositoryException - { - for ( DependencyGraphTransformer transformer : transformers ) - { - node = transformer.transformGraph( node, context ); - } - return node; - } - -} http://git-wip-us.apache.org/repos/asf/maven-aether/blob/27f8bd73/aether-util/src/main/java/org/eclipse/aether/util/graph/transformer/ConflictIdSorter.java ---------------------------------------------------------------------- diff --git a/aether-util/src/main/java/org/eclipse/aether/util/graph/transformer/ConflictIdSorter.java b/aether-util/src/main/java/org/eclipse/aether/util/graph/transformer/ConflictIdSorter.java deleted file mode 100644 index 5cc6432..0000000 --- a/aether-util/src/main/java/org/eclipse/aether/util/graph/transformer/ConflictIdSorter.java +++ /dev/null @@ -1,370 +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.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.aether.RepositoryException; -import org.eclipse.aether.collection.DependencyGraphTransformationContext; -import org.eclipse.aether.collection.DependencyGraphTransformer; -import org.eclipse.aether.graph.DependencyNode; - -/** - * A dependency graph transformer that creates a topological sorting of the conflict ids which have been assigned to the - * dependency nodes. Conflict ids are sorted according to the dependency relation induced by the dependency graph. This - * transformer will query the key {@link TransformationContextKeys#CONFLICT_IDS} in the transformation context for an - * existing mapping of nodes to their conflicts ids. In absence of this map, the transformer will automatically invoke - * the {@link ConflictMarker} to calculate the conflict ids. When this transformer has executed, the transformation - * context holds a {@code List} that denotes the topologically sorted conflict ids. The list will be stored - * using the key {@link TransformationContextKeys#SORTED_CONFLICT_IDS}. In addition, the transformer will store a - * {@code Collection>} using the key {@link TransformationContextKeys#CYCLIC_CONFLICT_IDS} that - * describes cycles among conflict ids. - */ -public final class ConflictIdSorter - implements DependencyGraphTransformer -{ - - public DependencyNode transformGraph( DependencyNode node, DependencyGraphTransformationContext context ) - throws RepositoryException - { - Map conflictIds = (Map) context.get( TransformationContextKeys.CONFLICT_IDS ); - if ( conflictIds == null ) - { - ConflictMarker marker = new ConflictMarker(); - marker.transformGraph( node, context ); - - conflictIds = (Map) context.get( TransformationContextKeys.CONFLICT_IDS ); - } - - @SuppressWarnings( "unchecked" ) - Map stats = (Map) context.get( TransformationContextKeys.STATS ); - long time1 = System.nanoTime(); - - Map ids = new LinkedHashMap( 256 ); - - { - ConflictId id = null; - Object key = conflictIds.get( node ); - if ( key != null ) - { - id = new ConflictId( key, 0 ); - ids.put( key, id ); - } - - Map visited = new IdentityHashMap( conflictIds.size() ); - - buildConflitIdDAG( ids, node, id, 0, visited, conflictIds ); - } - - long time2 = System.nanoTime(); - - int cycles = topsortConflictIds( ids.values(), context ); - - if ( stats != null ) - { - long time3 = System.nanoTime(); - stats.put( "ConflictIdSorter.graphTime", time2 - time1 ); - stats.put( "ConflictIdSorter.topsortTime", time3 - time2 ); - stats.put( "ConflictIdSorter.conflictIdCount", ids.size() ); - stats.put( "ConflictIdSorter.conflictIdCycleCount", cycles ); - } - - return node; - } - - private void buildConflitIdDAG( Map ids, DependencyNode node, ConflictId id, int depth, - Map visited, Map conflictIds ) - { - if ( visited.put( node, Boolean.TRUE ) != null ) - { - return; - } - - depth++; - - for ( DependencyNode child : node.getChildren() ) - { - Object key = conflictIds.get( child ); - ConflictId childId = ids.get( key ); - if ( childId == null ) - { - childId = new ConflictId( key, depth ); - ids.put( key, childId ); - } - else - { - childId.pullup( depth ); - } - - if ( id != null ) - { - id.add( childId ); - } - - buildConflitIdDAG( ids, child, childId, depth, visited, conflictIds ); - } - } - - private int topsortConflictIds( Collection conflictIds, DependencyGraphTransformationContext context ) - { - List sorted = new ArrayList( conflictIds.size() ); - - RootQueue roots = new RootQueue( conflictIds.size() / 2 ); - for ( ConflictId id : conflictIds ) - { - if ( id.inDegree <= 0 ) - { - roots.add( id ); - } - } - - processRoots( sorted, roots ); - - boolean cycle = sorted.size() < conflictIds.size(); - - while ( sorted.size() < conflictIds.size() ) - { - // cycle -> deal gracefully with nodes still having positive in-degree - - ConflictId nearest = null; - for ( ConflictId id : conflictIds ) - { - if ( id.inDegree <= 0 ) - { - continue; - } - if ( nearest == null || id.minDepth < nearest.minDepth - || ( id.minDepth == nearest.minDepth && id.inDegree < nearest.inDegree ) ) - { - nearest = id; - } - } - - nearest.inDegree = 0; - roots.add( nearest ); - - processRoots( sorted, roots ); - } - - Collection> cycles = Collections.emptySet(); - if ( cycle ) - { - cycles = findCycles( conflictIds ); - } - - context.put( TransformationContextKeys.SORTED_CONFLICT_IDS, sorted ); - context.put( TransformationContextKeys.CYCLIC_CONFLICT_IDS, cycles ); - - return cycles.size(); - } - - private void processRoots( List sorted, RootQueue roots ) - { - while ( !roots.isEmpty() ) - { - ConflictId root = roots.remove(); - - sorted.add( root.key ); - - for ( ConflictId child : root.children ) - { - child.inDegree--; - if ( child.inDegree == 0 ) - { - roots.add( child ); - } - } - } - } - - private Collection> findCycles( Collection conflictIds ) - { - Collection> cycles = new HashSet>(); - - Map stack = new HashMap( 128 ); - Map visited = new IdentityHashMap( conflictIds.size() ); - for ( ConflictId id : conflictIds ) - { - findCycles( id, visited, stack, cycles ); - } - - return cycles; - } - - private void findCycles( ConflictId id, Map visited, Map stack, - Collection> cycles ) - { - Integer depth = stack.put( id.key, stack.size() ); - if ( depth != null ) - { - stack.put( id.key, depth ); - Collection cycle = new HashSet(); - for ( Map.Entry entry : stack.entrySet() ) - { - if ( entry.getValue() >= depth ) - { - cycle.add( entry.getKey() ); - } - } - cycles.add( cycle ); - } - else - { - if ( visited.put( id, Boolean.TRUE ) == null ) - { - for ( ConflictId childId : id.children ) - { - findCycles( childId, visited, stack, cycles ); - } - } - stack.remove( id.key ); - } - } - - static final class ConflictId - { - - final Object key; - - Collection children = Collections.emptySet(); - - int inDegree; - - int minDepth; - - public ConflictId( Object key, int depth ) - { - this.key = key; - this.minDepth = depth; - } - - public void add( ConflictId child ) - { - if ( children.isEmpty() ) - { - children = new HashSet(); - } - if ( children.add( child ) ) - { - child.inDegree++; - } - } - - public void pullup( int depth ) - { - if ( depth < minDepth ) - { - minDepth = depth; - depth++; - for ( ConflictId child : children ) - { - child.pullup( depth ); - } - } - } - - @Override - public boolean equals( Object obj ) - { - if ( this == obj ) - { - return true; - } - else if ( !( obj instanceof ConflictId ) ) - { - return false; - } - ConflictId that = (ConflictId) obj; - return this.key.equals( that.key ); - } - - @Override - public int hashCode() - { - return key.hashCode(); - } - - @Override - public String toString() - { - return key + " @ " + minDepth + " <" + inDegree; - } - - } - - static final class RootQueue - { - - private int nextOut; - - private int nextIn; - - private ConflictId[] ids; - - RootQueue( int capacity ) - { - ids = new ConflictId[capacity + 16]; - } - - boolean isEmpty() - { - return nextOut >= nextIn; - } - - void add( ConflictId id ) - { - if ( nextOut >= nextIn && nextOut > 0 ) - { - nextIn -= nextOut; - nextOut = 0; - } - if ( nextIn >= ids.length ) - { - ConflictId[] tmp = new ConflictId[ids.length + ids.length / 2 + 16]; - System.arraycopy( ids, nextOut, tmp, 0, nextIn - nextOut ); - ids = tmp; - nextIn -= nextOut; - nextOut = 0; - } - int i; - for ( i = nextIn - 1; i >= nextOut && id.minDepth < ids[i].minDepth; i-- ) - { - ids[i + 1] = ids[i]; - } - ids[i + 1] = id; - nextIn++; - } - - ConflictId remove() - { - return ids[nextOut++]; - } - - } - -} http://git-wip-us.apache.org/repos/asf/maven-aether/blob/27f8bd73/aether-util/src/main/java/org/eclipse/aether/util/graph/transformer/ConflictMarker.java ---------------------------------------------------------------------- diff --git a/aether-util/src/main/java/org/eclipse/aether/util/graph/transformer/ConflictMarker.java b/aether-util/src/main/java/org/eclipse/aether/util/graph/transformer/ConflictMarker.java deleted file mode 100644 index fe2f5d5..0000000 --- a/aether-util/src/main/java/org/eclipse/aether/util/graph/transformer/ConflictMarker.java +++ /dev/null @@ -1,315 +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.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.Map; -import java.util.Set; - -import org.eclipse.aether.RepositoryException; -import org.eclipse.aether.artifact.Artifact; -import org.eclipse.aether.collection.DependencyGraphTransformationContext; -import org.eclipse.aether.collection.DependencyGraphTransformer; -import org.eclipse.aether.graph.Dependency; -import org.eclipse.aether.graph.DependencyNode; - -/** - * A dependency graph transformer that identifies conflicting dependencies. When this transformer has executed, the - * transformation context holds a {@code Map} where dependency nodes that belong to the same - * conflict group will have an equal conflict identifier. This map is stored using the key - * {@link TransformationContextKeys#CONFLICT_IDS}. - */ -public final class ConflictMarker - implements DependencyGraphTransformer -{ - - /** - * After the execution of this method, every DependencyNode with an attached dependency is member of one conflict - * group. - * - * @see DependencyGraphTransformer#transformGraph(DependencyNode, DependencyGraphTransformationContext) - */ - public DependencyNode transformGraph( DependencyNode node, DependencyGraphTransformationContext context ) - throws RepositoryException - { - @SuppressWarnings( "unchecked" ) - Map stats = (Map) context.get( TransformationContextKeys.STATS ); - long time1 = System.nanoTime(); - - Map nodes = new IdentityHashMap( 1024 ); - Map groups = new HashMap( 1024 ); - - analyze( node, nodes, groups, new int[] { 0 } ); - - long time2 = System.nanoTime(); - - Map conflictIds = mark( nodes.keySet(), groups ); - - context.put( TransformationContextKeys.CONFLICT_IDS, conflictIds ); - - if ( stats != null ) - { - long time3 = System.nanoTime(); - stats.put( "ConflictMarker.analyzeTime", time2 - time1 ); - stats.put( "ConflictMarker.markTime", time3 - time2 ); - stats.put( "ConflictMarker.nodeCount", nodes.size() ); - } - - return node; - } - - private void analyze( DependencyNode node, Map nodes, Map groups, - int[] counter ) - { - if ( nodes.put( node, Boolean.TRUE ) != null ) - { - return; - } - - Set keys = getKeys( node ); - if ( !keys.isEmpty() ) - { - ConflictGroup group = null; - boolean fixMappings = false; - - for ( Object key : keys ) - { - ConflictGroup g = groups.get( key ); - - if ( group != g ) - { - if ( group == null ) - { - Set newKeys = merge( g.keys, keys ); - if ( newKeys == g.keys ) - { - group = g; - break; - } - else - { - group = new ConflictGroup( newKeys, counter[0]++ ); - fixMappings = true; - } - } - else if ( g == null ) - { - fixMappings = true; - } - else - { - Set newKeys = merge( g.keys, group.keys ); - if ( newKeys == g.keys ) - { - group = g; - fixMappings = false; - break; - } - else if ( newKeys != group.keys ) - { - group = new ConflictGroup( newKeys, counter[0]++ ); - fixMappings = true; - } - } - } - } - - if ( group == null ) - { - group = new ConflictGroup( keys, counter[0]++ ); - fixMappings = true; - } - if ( fixMappings ) - { - for ( Object key : group.keys ) - { - groups.put( key, group ); - } - } - } - - for ( DependencyNode child : node.getChildren() ) - { - analyze( child, nodes, groups, counter ); - } - } - - private Set merge( Set keys1, Set keys2 ) - { - int size1 = keys1.size(); - int size2 = keys2.size(); - - if ( size1 < size2 ) - { - if ( keys2.containsAll( keys1 ) ) - { - return keys2; - } - } - else - { - if ( keys1.containsAll( keys2 ) ) - { - return keys1; - } - } - - Set keys = new HashSet(); - keys.addAll( keys1 ); - keys.addAll( keys2 ); - return keys; - } - - private Set getKeys( DependencyNode node ) - { - Set keys; - - Dependency dependency = node.getDependency(); - - if ( dependency == null ) - { - keys = Collections.emptySet(); - } - else - { - Object key = toKey( dependency.getArtifact() ); - - if ( node.getRelocations().isEmpty() && node.getAliases().isEmpty() ) - { - keys = Collections.singleton( key ); - } - else - { - keys = new HashSet(); - keys.add( key ); - - for ( Artifact relocation : node.getRelocations() ) - { - key = toKey( relocation ); - keys.add( key ); - } - - for ( Artifact alias : node.getAliases() ) - { - key = toKey( alias ); - keys.add( key ); - } - } - } - - return keys; - } - - private Map mark( Collection nodes, Map groups ) - { - Map conflictIds = new IdentityHashMap( nodes.size() + 1 ); - - for ( DependencyNode node : nodes ) - { - Dependency dependency = node.getDependency(); - if ( dependency != null ) - { - Object key = toKey( dependency.getArtifact() ); - conflictIds.put( node, groups.get( key ).index ); - } - } - - return conflictIds; - } - - private static Object toKey( Artifact artifact ) - { - return new Key( artifact ); - } - - static class ConflictGroup - { - - final Set keys; - - final int index; - - public ConflictGroup( Set keys, int index ) - { - this.keys = keys; - this.index = index; - } - - @Override - public String toString() - { - return String.valueOf( keys ); - } - - } - - static class Key - { - - private final Artifact artifact; - - public Key( Artifact artifact ) - { - this.artifact = artifact; - } - - @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() - { - int hash = 17; - hash = hash * 31 + artifact.getArtifactId().hashCode(); - hash = hash * 31 + artifact.getGroupId().hashCode(); - hash = hash * 31 + artifact.getClassifier().hashCode(); - hash = hash * 31 + artifact.getExtension().hashCode(); - return hash; - } - - @Override - public String toString() - { - return artifact.getGroupId() + ':' + artifact.getArtifactId() + ':' + artifact.getClassifier() + ':' - + artifact.getExtension(); - } - - } - -}