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 */
021
022import java.util.ArrayList;
023import java.util.HashMap;
024import java.util.List;
025import java.util.Map;
026
027import org.apache.maven.artifact.Artifact;
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
032/**
033 * @author Brian Fox
034 *
035 */
036public class DependencyVersionMap
037    implements DependencyNodeVisitor
038{
039    private boolean uniqueVersions;
040
041    private Map<String, List<DependencyNode>> idsToNode;
042
043    public DependencyVersionMap( Log log )
044    {
045        idsToNode = new HashMap<String, List<DependencyNode>>();
046    }
047    
048    public void setUniqueVersions( boolean uniqueVersions )
049    {
050        this.uniqueVersions = uniqueVersions;
051    }
052
053    @Override
054    public boolean visit( DependencyNode node )
055    {
056        addDependency( node );
057        return !containsConflicts( node );
058    }
059
060    @Override
061    public boolean endVisit( DependencyNode node )
062    {
063        return true;
064    }
065
066    private String constructKey( DependencyNode node )
067    {
068        return constructKey( node.getArtifact() );
069    }
070
071    private String constructKey( Artifact artifact )
072    {
073        return artifact.getGroupId() + ":" + artifact.getArtifactId();
074    }
075
076    public void addDependency( DependencyNode node )
077    {
078        String key = constructKey( node );
079        List<DependencyNode> nodes = idsToNode.get( key );
080        if ( nodes == null )
081        {
082            nodes = new ArrayList<DependencyNode>();
083            idsToNode.put( key, nodes );
084        }
085        nodes.add( node );
086    }
087    
088    private String getVersion( Artifact artifact )
089    {
090        return uniqueVersions ? artifact.getVersion() : artifact.getBaseVersion();
091    }
092
093    private boolean containsConflicts( DependencyNode node )
094    {
095        return containsConflicts( node.getArtifact() );
096    }
097
098    private boolean containsConflicts( Artifact artifact )
099    {
100        return containsConflicts( idsToNode.get( constructKey( artifact ) ) );
101    }
102
103    private boolean containsConflicts( List<DependencyNode> nodes )
104    {
105        String version = null;
106        for ( DependencyNode node : nodes )
107        {
108            if ( version == null )
109            {
110                version = getVersion( node.getArtifact() );
111            }
112            else
113            {
114                if ( version.compareTo( getVersion( node.getArtifact() ) ) != 0 )
115                {
116                    return true;
117                }
118            }
119        }
120        return false;
121    }
122
123    public List<List<DependencyNode>> getConflictedVersionNumbers()
124    {
125        List<List<DependencyNode>> output = new ArrayList<List<DependencyNode>>();
126        for ( List<DependencyNode> nodes : idsToNode.values() )
127        {
128            if ( containsConflicts( nodes ) )
129            {
130                output.add( nodes );
131            }
132        }
133        return output;
134    }
135}