View Javadoc
1   package org.apache.maven.plugins.enforcer.utils;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.artifact.Artifact;
23  import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
24  import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
25  import org.apache.maven.artifact.versioning.VersionRange;
26  import org.apache.maven.plugins.enforcer.AbstractVersionEnforcer;
27  import java.util.Collection;
28  import java.util.LinkedList;
29  
30  /**
31   * This class is used for matching Artifacts against a list of patterns.
32   * 
33   * @author Jakub Senko
34   * @see org.apache.maven.plugins.enforcer.BanTransitiveDependencies
35   */
36  public final class ArtifactMatcher
37  {
38  
39      /**
40       * @author I don't know
41       */
42      public static class Pattern
43      {
44          private String pattern;
45  
46          private String[] parts;
47  
48          public Pattern( String pattern )
49          {
50              if ( pattern == null )
51              {
52                  throw new NullPointerException( "pattern" );
53              }
54  
55              this.pattern = pattern;
56  
57              parts = pattern.split( ":", 7 );
58  
59              if ( parts.length == 7 )
60              {
61                  throw new IllegalArgumentException( "Pattern contains too many delimiters." );
62              }
63  
64              for ( String part : parts )
65              {
66                  if ( "".equals( part ) )
67                  {
68                      throw new IllegalArgumentException( "Pattern or its part is empty." );
69                  }
70              }
71          }
72  
73          public boolean match( Artifact artifact )
74              throws InvalidVersionSpecificationException
75          {
76              if ( artifact == null )
77              {
78                  throw new NullPointerException( "artifact" );
79              }
80  
81              switch ( parts.length )
82              {
83                  case 6:
84                      String classifier = artifact.getClassifier();
85                      if ( !matches( parts[5], classifier ) )
86                      {
87                          return false;
88                      }
89                  case 5:
90                      String scope = artifact.getScope();
91                      if ( scope == null || scope.equals( "" ) )
92                      {
93                          scope = Artifact.SCOPE_COMPILE;
94                      }
95  
96                      if ( !matches( parts[4], scope ) )
97                      {
98                          return false;
99                      }
100                 case 4:
101                     String type = artifact.getType();
102                     if ( type == null || type.equals( "" ) )
103                     {
104                         type = "jar";
105                     }
106 
107                     if ( !matches( parts[3], type ) )
108                     {
109                         return false;
110                     }
111 
112                 case 3:
113                     if ( !matches( parts[2], artifact.getVersion() ) )
114                     {
115                         // CHECKSTYLE_OFF: LineLength
116                         if ( !AbstractVersionEnforcer.containsVersion( VersionRange.createFromVersionSpec( parts[2] ),
117                                                                        new DefaultArtifactVersion(
118                                                                                                    artifact.getVersion() ) ) )
119                         // CHECKSTYLE_ON: LineLength
120                         {
121                             return false;
122                         }
123                     }
124 
125                 case 2:
126                     if ( !matches( parts[1], artifact.getArtifactId() ) )
127                     {
128                         return false;
129                     }
130                 case 1:
131                     return matches( parts[0], artifact.getGroupId() );
132                 default:
133                     throw new AssertionError();
134             }
135         }
136 
137         private boolean matches( String expression, String input )
138         {
139             String regex =
140                 expression.replace( ".", "\\." ).replace( "*", ".*" ).replace( ":", "\\:" ).replace( '?', '.' );
141 
142             // TODO: Check if this can be done better or prevented earlier.
143             if ( input == null )
144             {
145                 input = "";
146             }
147 
148             return java.util.regex.Pattern.matches( regex, input );
149         }
150 
151         @Override
152         public String toString()
153         {
154             return pattern;
155         }
156     }
157 
158     private Collection<Pattern> patterns = new LinkedList<Pattern>();
159 
160     private Collection<Pattern> ignorePatterns = new LinkedList<Pattern>();
161 
162     /**
163      * Construct class by providing patterns as strings. Empty strings are ignored.
164      * 
165      * @throws NullPointerException if any of the arguments is null
166      */
167     public ArtifactMatcher( final Collection<String> patterns, final Collection<String> ignorePatterns )
168     {
169         if ( patterns == null )
170         {
171             throw new NullPointerException( "patterns" );
172         }
173         if ( ignorePatterns == null )
174         {
175             throw new NullPointerException( "ignorePatterns" );
176         }
177         for ( String pattern : patterns )
178         {
179             if ( pattern != null && !"".equals( pattern ) )
180             {
181                 this.patterns.add( new Pattern( pattern ) );
182             }
183         }
184 
185         for ( String ignorePattern : ignorePatterns )
186         {
187             if ( ignorePattern != null && !"".equals( ignorePattern ) )
188             {
189                 this.ignorePatterns.add( new Pattern( ignorePattern ) );
190             }
191         }
192     }
193 
194     /**
195      * Check if artifact matches patterns.
196      * 
197      * @throws InvalidVersionSpecificationException
198      */
199     public boolean match( Artifact artifact )
200         throws InvalidVersionSpecificationException
201     {
202         for ( Pattern pattern : patterns )
203         {
204             if ( pattern.match( artifact ) )
205             {
206                 for ( Pattern ignorePattern : ignorePatterns )
207                 {
208                     if ( ignorePattern.match( artifact ) )
209                     {
210                         return false;
211                     }
212                 }
213                 return true;
214             }
215         }
216         return false;
217     }
218 }