View Javadoc
1   /*
2    * Licensed under the Apache License, Version 2.0 (the "License");
3    * you may not use this file except in compliance with the License.
4    * You may obtain a copy of the License at
5    *
6    * http://www.apache.org/licenses/LICENSE-2.0
7    *
8    * Unless required by applicable law or agreed to in writing, software
9    * distributed under the License is distributed on an "AS IS" BASIS,
10   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11   * See the License for the specific language governing permissions and
12   * limitations under the License.
13   */
14  
15  package org.basepom.mojo.repack;
16  
17  import static com.google.common.base.Preconditions.checkNotNull;
18  
19  /**
20   * Basic glob matcher that supports '?' and '*'. Does not support char escaping in the pattern or direct char matches.
21   * <p>
22   * Inspired by wildmat.c
23   */
24  final class Wildcard {
25  
26      private Wildcard() {
27          throw new AssertionError("Wildcard can not be instantiated");
28      }
29  
30      static boolean wildcardMatch(String pattern, String value) {
31          checkNotNull(pattern, "pattern is null");
32          checkNotNull(value, "value is null");
33  
34          // empty pattern only matches empty value
35          if (pattern.isEmpty()) {
36              return value.isEmpty();
37          }
38  
39          // just wildcard is a quick check
40          if (pattern.equals("*")) {
41              return true;
42          }
43  
44          if (value.isEmpty()) {
45              return false;
46          }
47  
48          return doGlobMatch(pattern, value);
49      }
50  
51      static boolean doGlobMatch(String pattern, String value) {
52          int valueIndex = 0;
53          int patternIndex = 0;
54          int patternLength = pattern.length();
55          int valueLength = value.length();
56  
57          for (; patternIndex < patternLength; valueIndex++, patternIndex++) {
58              char patternChar = pattern.charAt(patternIndex);
59  
60              // if the value ends but there is anything but a wildcard left,
61              // it is not a match.
62              if (valueIndex == valueLength && patternChar != '*') {
63                  return false;
64              }
65  
66              switch (patternChar) {
67                  case '*':
68                      // coalesce multiple stars
69                      do {
70                          // last character
71                          if (patternIndex + 1 == patternLength) {
72                              return true;
73                          }
74                          patternIndex++;
75                          // coalesce multiple stars
76                      } while (pattern.charAt(patternIndex) == '*');
77  
78                      for (; valueIndex < valueLength; valueIndex++) {
79                          boolean matched = doGlobMatch(value.substring(valueIndex), pattern.substring(patternIndex));
80                          if (matched) {
81                              return true;
82                          }
83                      }
84                      return false;
85                  case '?':
86                      continue; // for(
87                  default:
88                      if (value.charAt(valueIndex) != patternChar) {
89                          return false;
90                      }
91              }
92          }
93  
94          return valueIndex == valueLength;
95      }
96  }