Package org.apache.maven.archiva.dependency.graph.tasks

Source Code of org.apache.maven.archiva.dependency.graph.tasks.RefineConflictsVisitor$DistantNodeLocationPredicate

package org.apache.maven.archiva.dependency.graph.tasks;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.comparators.ReverseComparator;
import org.apache.commons.collections.functors.NotPredicate;
import org.apache.commons.collections.list.TypedList;
import org.apache.maven.archiva.common.utils.VersionComparator;
import org.apache.maven.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.dependency.graph.DependencyGraphKeys;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
import org.apache.maven.archiva.dependency.graph.DependencyGraphUtils;
import org.apache.maven.archiva.dependency.graph.walk.BaseVisitor;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphVisitor;
import org.apache.maven.archiva.model.ArtifactReference;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* RefineConflictsVisitor
*
* @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
* @version $Id: RefineConflictsVisitor.java 562485 2007-08-03 14:44:15Z joakime $
*/
public class RefineConflictsVisitor
    extends BaseVisitor
    implements DependencyGraphVisitor
{
    class DepthComparator
        implements Comparator
    {
        public int compare( Object obj0, Object obj1 )
        {
            NodeLocation nodeLoc0 = (NodeLocation) obj0;
            NodeLocation nodeLoc1 = (NodeLocation) obj1;

            return nodeLoc0.depth - nodeLoc1.depth;
        }
    }

    class NodeLocation
    {
        public ArtifactReference artifact;

        public DependencyGraphEdge edge;

        public int depth;

        public NodeLocation( ArtifactReference artifact, DependencyGraphEdge edge, int depth )
        {
            this.artifact = artifact;
            this.edge = edge;
            this.depth = depth;
        }
    }

    class NodeLocationPredicate
        implements Predicate
    {
        private ArtifactReference artifact;

        public NodeLocationPredicate( ArtifactReference artifact )
        {
            this.artifact = artifact;
        }

        public NodeLocationPredicate( DependencyGraphNode node )
        {
            this( node.getArtifact() );
        }

        public boolean evaluate( Object object )
        {
            boolean satisfies = false;

            if ( object instanceof NodeLocation )
            {
                NodeLocation nodeloc = (NodeLocation) object;
                satisfies = nodeloc.artifact.equals( artifact );
            }

            return satisfies;
        }

    }

    class NodeLocationVersionComparator
        implements Comparator
    {
        public int compare( Object o1, Object o2 )
        {
            if ( o1 == null && o2 == null )
            {
                return 0;
            }

            if ( o1 == null && o2 != null )
            {
                return 1;
            }

            if ( o1 != null && o2 == null )
            {
                return -1;
            }

            if ( ( o1 instanceof NodeLocation ) && ( o2 instanceof NodeLocation ) )
            {
                String version1 = ( (NodeLocation) o1 ).artifact.getVersion();
                String version2 = ( (NodeLocation) o2 ).artifact.getVersion();

                VersionComparator.getInstance().compare( version1, version2 );
            }

            return 0;
        }
    }

    class DistantNodeLocationPredicate
        implements Predicate
    {
        private int cutoff;

        public DistantNodeLocationPredicate( int distantCutoff )
        {
            this.cutoff = distantCutoff;
        }

        public boolean evaluate( Object object )
        {
            boolean satisfies = false;

            if ( object instanceof NodeLocation )
            {
                NodeLocation nodeloc = (NodeLocation) object;
                satisfies = ( nodeloc.depth >= this.cutoff );
            }

            return satisfies;
        }
    }

    private List conflictingArtifacts;

    private Map foundNodesMap = new HashMap();

    private int currentDepth = 0;

    private DependencyGraph currentGraph;

    public RefineConflictsVisitor()
    {
        conflictingArtifacts = TypedList.decorate( new ArrayList(), ArtifactReference.class );
    }

    public void discoverGraph( DependencyGraph graph )
    {
        super.discoverGraph( graph );
        this.currentGraph = graph;
        this.foundNodesMap.clear();
    }

    public void discoverNode( DependencyGraphNode node )
    {
        super.discoverNode( node );

        currentDepth++;

        List edgesFrom = currentGraph.getEdgesFrom( node );
        Iterator it = edgesFrom.iterator();
        while ( it.hasNext() )
        {
            DependencyGraphEdge edge = (DependencyGraphEdge) it.next();
            if ( this.conflictingArtifacts.contains( edge.getNodeTo() ) )
            {
                String nodeKey = DependencyGraphKeys.toKey( edge.getNodeTo() );
                // Check for existing NodeLocation with same key
                NodeLocation nodeloc = (NodeLocation) this.foundNodesMap.get( nodeKey );

                if ( ( nodeloc == null ) || ( currentDepth < nodeloc.depth ) )
                {
                    nodeloc = new NodeLocation( edge.getNodeTo(), edge, currentDepth );
                    this.foundNodesMap.put( nodeKey, nodeloc );
                }
            }
        }
    }

    public void finishGraph( DependencyGraph graph )
    {
        super.finishGraph( graph );

        if ( MapUtils.isEmpty( this.foundNodesMap ) )
        {
            return;
        }

        // Find winning node.
        ArtifactReference winningArtifact = findWinningArtifact( this.foundNodesMap.values() );
        DependencyGraphNode winningNode = graph.getNode( winningArtifact );

        // Gather up Losing Nodes.
        Set losingNodes = new HashSet();
        Predicate losersPredicate = NotPredicate.getInstance( new NodeLocationPredicate( winningArtifact ) );
        CollectionUtils.select( this.foundNodesMap.values(), losersPredicate, losingNodes );

        // Swing losing nodes to winning node.
        Iterator it = losingNodes.iterator();
        while ( it.hasNext() )
        {
            NodeLocation losingNodeLoc = (NodeLocation) it.next();
            DependencyGraphNode losingNode = graph.getNode( losingNodeLoc.artifact );
            DependencyGraphUtils.collapseNodes( graph, losingNode, winningNode );
        }
    }

    private ArtifactReference findWinningArtifact( Collection nodes )
    {
        List remainingNodes = new ArrayList();
        remainingNodes.addAll( nodes );

        /* .\ Filter by Depth \.____________________________________________________ */

        // Sort by depth.
        Collections.sort( remainingNodes, new DepthComparator() );

        // Determine 'closest' node depth.
        NodeLocation nearestNode = (NodeLocation) remainingNodes.get( 0 );
        int nearest = nearestNode.depth;

        // Filter out distant nodes.
        Predicate distantLocations = new DistantNodeLocationPredicate( nearest );
        CollectionUtils.filter( remainingNodes, distantLocations );

        // Do we have 1 node left?
        if ( remainingNodes.size() == 1 )
        {
            // A winner!
            NodeLocation nodeloc = (NodeLocation) remainingNodes.get( 0 );
            return nodeloc.artifact;
        }

        /* .\ Filter by Newest Version \.___________________________________________ */

        // We have 2 or more nodes that are equal distance from the root.
        // Determine which one is 'newest' based on version id.
        Collections.sort( remainingNodes, new ReverseComparator( new NodeLocationVersionComparator() ) );

        NodeLocation nodeloc = (NodeLocation) remainingNodes.get( 0 );
        return nodeloc.artifact;
    }

    public void finishNode( DependencyGraphNode node )
    {
        super.finishNode( node );
        currentDepth--;
    }

    public List getConflictingArtifacts()
    {
        return conflictingArtifacts;
    }

    public void addAllConflictingArtifacts( Collection nodes )
    {
        this.conflictingArtifacts.addAll( nodes );
    }

    public void resetConflictingArtifacts()
    {
        this.conflictingArtifacts.clear();
    }
}
TOP

Related Classes of org.apache.maven.archiva.dependency.graph.tasks.RefineConflictsVisitor$DistantNodeLocationPredicate

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.