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.HashSet;
023import java.util.List;
024import java.util.Set;
025
026import org.apache.commons.lang3.StringUtils;
027import org.apache.maven.artifact.Artifact;
028import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
029import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
030import org.apache.maven.plugins.enforcer.utils.ArtifactMatcher.Pattern;
031import org.apache.maven.shared.dependency.graph.DependencyNode;
032
033/**
034 * 
035 * @author Robert Scholte
036 * @since 3.0.0
037 */
038public final class ArtifactUtils
039{
040    private ArtifactUtils()
041    {
042    }
043
044    public static Set<Artifact> getAllDescendants( DependencyNode node )
045    {
046        Set<Artifact> children = null;
047        if ( node.getChildren() != null )
048        {
049            children = new HashSet<>();
050            for ( DependencyNode depNode : node.getChildren() )
051            {
052                children.add( depNode.getArtifact() );
053                Set<Artifact> subNodes = getAllDescendants( depNode );
054                if ( subNodes != null )
055                {
056                    children.addAll( subNodes );
057                }
058            }
059        }
060        return children;
061    }
062
063    /**
064     * Checks the set of dependencies against the list of patterns.
065     * 
066     * @param thePatterns the patterns
067     * @param dependencies the dependencies
068     * @return a set containing artifacts matching one of the patterns or <code>null</code>
069     * @throws EnforcerRuleException the enforcer rule exception
070     */
071    public static Set<Artifact> checkDependencies( Set<Artifact> dependencies, List<String> thePatterns )
072        throws EnforcerRuleException
073    {
074        Set<Artifact> foundMatches = null;
075    
076        if ( thePatterns != null && thePatterns.size() > 0 )
077        {
078    
079            for ( String pattern : thePatterns )
080            {
081                String[] subStrings = pattern.split( ":" );
082                subStrings = StringUtils.stripAll( subStrings );
083                String resultPattern = StringUtils.join( subStrings, ":" );
084    
085                for ( Artifact artifact : dependencies )
086                {
087                    if ( compareDependency( resultPattern, artifact ) )
088                    {
089                        // only create if needed
090                        if ( foundMatches == null )
091                        {
092                            foundMatches = new HashSet<Artifact>();
093                        }
094                        foundMatches.add( artifact );
095                    }
096                }
097            }
098        }
099        return foundMatches;
100    }
101
102    /**
103     * Compares the given pattern against the given artifact. The pattern should follow the format
104     * <code>groupId:artifactId:version:type:scope:classifier</code>.
105     * 
106     * @param pattern The pattern to compare the artifact with.
107     * @param artifact the artifact
108     * @return <code>true</code> if the artifact matches one of the patterns
109     * @throws EnforcerRuleException the enforcer rule exception
110     */
111    private static boolean compareDependency( String pattern, Artifact artifact )
112        throws EnforcerRuleException
113    {
114    
115        ArtifactMatcher.Pattern am = new Pattern( pattern );
116        boolean result;
117        try
118        {
119            result = am.match( artifact );
120        }
121        catch ( InvalidVersionSpecificationException e )
122        {
123            throw new EnforcerRuleException( "Invalid Version Range: ", e );
124        }
125    
126        return result;
127    }
128
129}