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.Collection; 023import java.util.LinkedList; 024 025import org.apache.maven.artifact.Artifact; 026import org.apache.maven.artifact.versioning.DefaultArtifactVersion; 027import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; 028import org.apache.maven.artifact.versioning.VersionRange; 029import org.apache.maven.plugins.enforcer.AbstractVersionEnforcer; 030 031/** 032 * This class is used for matching Artifacts against a list of patterns. 033 * 034 * @author Jakub Senko 035 * @see org.apache.maven.plugins.enforcer.BanTransitiveDependencies 036 */ 037public final class ArtifactMatcher 038{ 039 040 public static class Pattern 041 { 042 private String pattern; 043 044 private String[] parts; 045 046 public Pattern( String pattern ) 047 { 048 if ( pattern == null ) 049 { 050 throw new NullPointerException( "pattern" ); 051 } 052 053 this.pattern = pattern; 054 055 parts = pattern.split( ":", 7 ); 056 057 if ( parts.length == 7 ) 058 { 059 throw new IllegalArgumentException( "Pattern contains too many delimiters." ); 060 } 061 062 for ( String part : parts ) 063 { 064 if ( "".equals( part ) ) 065 { 066 throw new IllegalArgumentException( "Pattern or its part is empty." ); 067 } 068 } 069 } 070 071 public boolean match( Artifact artifact ) 072 throws InvalidVersionSpecificationException 073 { 074 if ( artifact == null ) 075 { 076 throw new NullPointerException( "artifact" ); 077 } 078 079 switch ( parts.length ) 080 { 081 case 6: 082 String classifier = artifact.getClassifier(); 083 if ( !matches( parts[5], classifier ) ) 084 { 085 return false; 086 } 087 case 5: 088 String scope = artifact.getScope(); 089 if ( scope == null || scope.equals( "" ) ) 090 { 091 scope = "compile"; 092 } 093 094 if ( !matches( parts[4], scope ) ) 095 { 096 return false; 097 } 098 case 4: 099 String type = artifact.getType(); 100 if ( type == null || type.equals( "" ) ) 101 { 102 type = "jar"; 103 } 104 105 if ( !matches( parts[3], type ) ) 106 { 107 return false; 108 } 109 110 case 3: 111 if ( !matches( parts[2], artifact.getVersion() ) ) 112 { 113 if ( !AbstractVersionEnforcer.containsVersion( VersionRange.createFromVersionSpec( parts[2] ), 114 new DefaultArtifactVersion( 115 artifact.getVersion() ) ) ) 116 { 117 return false; 118 } 119 } 120 121 case 2: 122 if ( !matches( parts[1], artifact.getArtifactId() ) ) 123 { 124 return false; 125 } 126 case 1: 127 if ( !matches( parts[0], artifact.getGroupId() ) ) 128 { 129 return false; 130 } 131 else 132 { 133 return true; 134 } 135 default: 136 throw new AssertionError(); 137 } 138 } 139 140 private boolean matches( String expression, String input ) 141 { 142 String regex = expression.replace( ".", "\\." ).replace( "*", ".*" ).replace( ":", "\\:" ).replace( '?', '.' ); 143 144 return java.util.regex.Pattern.matches( regex , input ); 145 } 146 147 @Override 148 public String toString() 149 { 150 return pattern; 151 } 152 } 153 154 private Collection<Pattern> patterns = new LinkedList<Pattern>(); 155 156 private Collection<Pattern> ignorePatterns = new LinkedList<Pattern>(); 157 158 /** 159 * Construct class by providing patterns as strings. Empty strings are ignored. 160 * 161 * @throws NullPointerException if any of the arguments is null 162 */ 163 public ArtifactMatcher( final Collection<String> patterns, final Collection<String> ignorePatterns ) 164 { 165 if ( patterns == null ) 166 { 167 throw new NullPointerException( "patterns" ); 168 } 169 if ( ignorePatterns == null ) 170 { 171 throw new NullPointerException( "ignorePatterns" ); 172 } 173 for ( String pattern : patterns ) 174 { 175 if ( pattern != null && !"".equals( pattern ) ) 176 { 177 this.patterns.add( new Pattern( pattern ) ); 178 } 179 } 180 181 for ( String ignorePattern : ignorePatterns ) 182 { 183 if ( ignorePattern != null && !"".equals( ignorePattern ) ) 184 { 185 this.ignorePatterns.add( new Pattern( ignorePattern ) ); 186 } 187 } 188 } 189 190 /** 191 * Check if artifact matches patterns. 192 * 193 * @throws InvalidVersionSpecificationException 194 */ 195 public boolean match( Artifact artifact ) 196 throws InvalidVersionSpecificationException 197 { 198 for ( Pattern pattern : patterns ) 199 { 200 if ( pattern.match( artifact ) ) 201 { 202 for ( Pattern ignorePattern : ignorePatterns ) 203 { 204 if ( ignorePattern.match( artifact ) ) 205 { 206 return false; 207 } 208 } 209 return true; 210 } 211 } 212 return false; 213 } 214}