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 }