001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.maven.enforcer.rules.utils; 020 021import java.util.Collection; 022import java.util.Set; 023import java.util.stream.Collectors; 024 025import org.apache.commons.lang3.StringUtils; 026import org.apache.maven.RepositoryUtils; 027import org.apache.maven.artifact.Artifact; 028import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; 029import org.apache.maven.enforcer.rule.api.EnforcerRuleException; 030import org.eclipse.aether.graph.DependencyNode; 031 032import static java.util.Optional.ofNullable; 033 034/** 035 * 036 * @author Robert Scholte 037 * @since 3.0.0 038 */ 039public final class ArtifactUtils { 040 041 /** 042 * Converts {@link DependencyNode} to {@link Artifact}; in comparison 043 * to {@link RepositoryUtils#toArtifact(org.eclipse.aether.artifact.Artifact)}, this method 044 * assigns {@link Artifact#getScope()} and {@link Artifact#isOptional()} based on 045 * the dependency information from the node. 046 * 047 * @param node {@link DependencyNode} to convert to {@link Artifact} 048 * @return target artifact 049 */ 050 public static Artifact toArtifact(DependencyNode node) { 051 Artifact artifact = RepositoryUtils.toArtifact(node.getArtifact()); 052 ofNullable(node.getDependency()).ifPresent(dependency -> { 053 ofNullable(dependency.getScope()).ifPresent(artifact::setScope); 054 artifact.setOptional(dependency.isOptional()); 055 }); 056 return artifact; 057 } 058 059 /** 060 * Returns a subset of dependency artifacts that match the given collection of patterns 061 * 062 * @param dependencies dependency artifacts to match against patterns 063 * @param patterns patterns to match against the artifacts 064 * @return a set containing artifacts matching one of the patterns or <code>null</code> 065 * @throws EnforcerRuleException the enforcer rule exception 066 */ 067 public static Set<Artifact> filterDependencyArtifacts(Set<Artifact> dependencies, Collection<String> patterns) 068 throws EnforcerRuleException { 069 try { 070 return ofNullable(patterns) 071 .map(collection -> collection.stream() 072 .map(p -> p.split(":")) 073 .map(StringUtils::stripAll) 074 .map(arr -> String.join(":", arr)) 075 .flatMap(pattern -> 076 dependencies.stream().filter(artifact -> compareDependency(pattern, artifact))) 077 .collect(Collectors.toSet())) 078 .orElse(null); 079 } catch (IllegalArgumentException e) { 080 if (e.getCause() instanceof InvalidVersionSpecificationException) { 081 throw new EnforcerRuleException(e.getMessage()); 082 } 083 throw e; 084 } 085 } 086 087 /** 088 * Checks if the given dependency artifact matches the given collection of patterns 089 * 090 * @param artifact dependency artifact to match against patterns 091 * @param patterns patterns to match against the artifacts 092 * @return {@code true} if the given artifact matches the set of patterns 093 */ 094 public static boolean matchDependencyArtifact(Artifact artifact, Collection<String> patterns) { 095 try { 096 return ofNullable(patterns) 097 .map(collection -> collection.stream() 098 .map(p -> p.split(":")) 099 .map(StringUtils::stripAll) 100 .map(arr -> String.join(":", arr)) 101 .anyMatch(pattern -> compareDependency(pattern, artifact))) 102 .orElse(false); 103 } catch (IllegalArgumentException e) { 104 if (e.getCause() instanceof InvalidVersionSpecificationException) { 105 throw new IllegalArgumentException(e.getMessage()); 106 } 107 throw e; 108 } 109 } 110 111 /** 112 * Compares the given pattern against the given artifact. The pattern should follow the format 113 * <code>groupId:artifactId:version:type:scope:classifier</code>. 114 * 115 * @param pattern The pattern to compare the artifact with. 116 * @param artifact the artifact 117 * @return <code>true</code> if the artifact matches one of the patterns 118 */ 119 public static boolean compareDependency(String pattern, Artifact artifact) { 120 return new ArtifactMatcher.Pattern(pattern).match(artifact); 121 } 122}