001package org.apache.maven.plugins.enforcer.utils;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021import java.util.ArrayList;
022import java.util.HashMap;
023import java.util.List;
024import java.util.Map;
025
026import org.apache.maven.artifact.Artifact;
027import org.apache.maven.artifact.ArtifactUtils;
028import org.apache.maven.plugin.logging.Log;
029import org.apache.maven.shared.dependency.tree.DependencyNode;
030import org.apache.maven.shared.dependency.tree.traversal.DependencyNodeVisitor;
031
032public class DependencyVersionMap
033    implements DependencyNodeVisitor
034{
035    private Log log;
036    
037    private boolean uniqueVersions;
038
039    private Map<String, List<DependencyNode>> idsToNode;
040
041    public DependencyVersionMap( Log log )
042    {
043        this.log = log;
044        idsToNode = new HashMap<String, List<DependencyNode>>();
045    }
046    
047    public void setUniqueVersions( boolean uniqueVersions )
048    {
049        this.uniqueVersions = uniqueVersions;
050    }
051
052    public boolean visit( DependencyNode node )
053    {
054        addDependency( node );
055        return !containsConflicts( node );
056    }
057
058    public boolean endVisit( DependencyNode node )
059    {
060        return true;
061    }
062
063    private String constructKey( DependencyNode node )
064    {
065        return constructKey( node.getArtifact() );
066    }
067
068    private String constructKey( Artifact artifact )
069    {
070        return artifact.getGroupId() + ":" + artifact.getArtifactId();
071    }
072
073    public void addDependency( DependencyNode node )
074    {
075        String key = constructKey( node );
076        List<DependencyNode> nodes = idsToNode.get( key );
077        if ( nodes == null )
078        {
079            nodes = new ArrayList<DependencyNode>();
080            idsToNode.put( key, nodes );
081        }
082        nodes.add( node );
083    }
084    
085    private String getVersion( Artifact artifact )
086    {
087        return uniqueVersions ? artifact.getVersion() : artifact.getBaseVersion();
088    }
089
090    private boolean containsConflicts( DependencyNode node )
091    {
092        return containsConflicts( node.getArtifact() );
093    }
094
095    private boolean containsConflicts( Artifact artifact )
096    {
097        return containsConflicts( idsToNode.get( constructKey( artifact ) ) );
098    }
099
100    private boolean containsConflicts( List<DependencyNode> nodes )
101    {
102        String version = null;
103        for ( DependencyNode node : nodes )
104        {
105            if ( version == null )
106            {
107                version = getVersion( node.getArtifact() );
108            }
109            else
110            {
111                if ( version.compareTo( getVersion( node.getArtifact() ) ) != 0 )
112                {
113                    return true;
114                }
115            }
116        }
117        return false;
118    }
119
120    public List<List<DependencyNode>> getConflictedVersionNumbers()
121    {
122        List<List<DependencyNode>> output = new ArrayList<List<DependencyNode>>();
123        for ( List<DependencyNode> nodes : idsToNode.values() )
124        {
125            if ( containsConflicts( nodes ) )
126            {
127                output.add( nodes );
128            }
129        }
130        return output;
131    }
132}