1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.dbunit.dataset.filter;
22
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 import java.util.Set;
27 import java.util.HashSet;
28 import java.util.Iterator;
29
30
31
32
33
34
35 class PatternMatcher
36 {
37
38
39
40
41 private static final Logger logger = LoggerFactory.getLogger(PatternMatcher.class);
42
43 private final Set _acceptedNames = new HashSet();
44 private final Set _acceptedPatterns = new HashSet();
45
46
47
48
49
50
51
52 public void addPattern(String patternName)
53 {
54 logger.debug("addPattern(patternName={}) - start", patternName);
55
56 if (patternName.indexOf("*") != -1 || patternName.indexOf("?") != -1)
57 {
58 _acceptedPatterns.add(patternName);
59 }
60 else
61 {
62 _acceptedNames.add(patternName.toUpperCase());
63 }
64 }
65
66 public boolean isEmpty()
67 {
68 logger.debug("isEmpty() - start");
69
70 if (_acceptedNames.isEmpty() && _acceptedPatterns.isEmpty())
71 {
72 return true;
73 }
74
75 return false;
76 }
77
78 public boolean accept(String name)
79 {
80 logger.debug("accept(name={}) - start", name);
81
82 if (_acceptedNames.contains(name.toUpperCase()))
83 {
84 return true;
85 }
86
87 if (_acceptedPatterns.size() > 0)
88 {
89 for (Iterator it = _acceptedPatterns.iterator(); it.hasNext();)
90 {
91 String pattern = (String)it.next();
92 if (match(pattern, name, false))
93 {
94 return true;
95 }
96 }
97 }
98
99 return false;
100 }
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 private boolean match(String pattern, String str, boolean isCaseSensitive)
116 {
117 if(logger.isDebugEnabled())
118 logger.debug("match(pattern={}, str={}, isCaseSensitive={}) - start",
119 new Object[]{pattern, str, String.valueOf(isCaseSensitive)});
120
121
122
123 char[] patArr = pattern.toCharArray();
124 char[] strArr = str.toCharArray();
125 int patIdxStart = 0;
126 int patIdxEnd = patArr.length - 1;
127 int strIdxStart = 0;
128 int strIdxEnd = strArr.length - 1;
129 char ch;
130
131 boolean containsStar = false;
132 for (int i = 0; i < patArr.length; i++)
133 {
134 if (patArr[i] == '*')
135 {
136 containsStar = true;
137 break;
138 }
139 }
140
141 if (!containsStar)
142 {
143
144 if (patIdxEnd != strIdxEnd)
145 {
146 return false;
147 }
148 for (int i = 0; i <= patIdxEnd; i++)
149 {
150 ch = patArr[i];
151 if (ch != '?')
152 {
153 if (isCaseSensitive && ch != strArr[i])
154 {
155 return false;
156 }
157 if (!isCaseSensitive && Character.toUpperCase(ch) !=
158 Character.toUpperCase(strArr[i]))
159 {
160 return false;
161 }
162 }
163 }
164 return true;
165 }
166
167 if (patIdxEnd == 0)
168 {
169 return true;
170 }
171
172
173 while ((ch = patArr[patIdxStart]) != '*' && strIdxStart <= strIdxEnd)
174 {
175 if (ch != '?')
176 {
177 if (isCaseSensitive && ch != strArr[strIdxStart])
178 {
179 return false;
180 }
181 if (!isCaseSensitive && Character.toUpperCase(ch) !=
182 Character.toUpperCase(strArr[strIdxStart]))
183 {
184 return false;
185 }
186 }
187 patIdxStart++;
188 strIdxStart++;
189 }
190 if (strIdxStart > strIdxEnd)
191 {
192
193
194 for (int i = patIdxStart; i <= patIdxEnd; i++)
195 {
196 if (patArr[i] != '*')
197 {
198 return false;
199 }
200 }
201 return true;
202 }
203
204
205 while ((ch = patArr[patIdxEnd]) != '*' && strIdxStart <= strIdxEnd)
206 {
207 if (ch != '?')
208 {
209 if (isCaseSensitive && ch != strArr[strIdxEnd])
210 {
211 return false;
212 }
213 if (!isCaseSensitive && Character.toUpperCase(ch) !=
214 Character.toUpperCase(strArr[strIdxEnd]))
215 {
216 return false;
217 }
218 }
219 patIdxEnd--;
220 strIdxEnd--;
221 }
222 if (strIdxStart > strIdxEnd)
223 {
224
225
226 for (int i = patIdxStart; i <= patIdxEnd; i++)
227 {
228 if (patArr[i] != '*')
229 {
230 return false;
231 }
232 }
233 return true;
234 }
235
236
237
238 while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd)
239 {
240 int patIdxTmp = -1;
241 for (int i = patIdxStart + 1; i <= patIdxEnd; i++)
242 {
243 if (patArr[i] == '*')
244 {
245 patIdxTmp = i;
246 break;
247 }
248 }
249 if (patIdxTmp == patIdxStart + 1)
250 {
251
252 patIdxStart++;
253 continue;
254 }
255
256
257 int patLength = (patIdxTmp - patIdxStart - 1);
258 int strLength = (strIdxEnd - strIdxStart + 1);
259 int foundIdx = -1;
260 strLoop:
261 for (int i = 0; i <= strLength - patLength; i++)
262 {
263 for (int j = 0; j < patLength; j++)
264 {
265 ch = patArr[patIdxStart + j + 1];
266 if (ch != '?')
267 {
268 if (isCaseSensitive && ch != strArr[strIdxStart + i + j])
269 {
270 continue strLoop;
271 }
272 if (!isCaseSensitive && Character.toUpperCase(ch) !=
273 Character.toUpperCase(strArr[strIdxStart + i + j]))
274 {
275 continue strLoop;
276 }
277 }
278 }
279
280 foundIdx = strIdxStart + i;
281 break;
282 }
283
284 if (foundIdx == -1)
285 {
286 return false;
287 }
288
289 patIdxStart = patIdxTmp;
290 strIdxStart = foundIdx + patLength;
291 }
292
293
294
295 for (int i = patIdxStart; i <= patIdxEnd; i++)
296 {
297 if (patArr[i] != '*')
298 {
299 return false;
300 }
301 }
302 return true;
303 }
304
305
306 public String toString()
307 {
308 final StringBuilder sb = new StringBuilder();
309 sb.append(getClass().getName()).append("[");
310 sb.append("_acceptedNames=").append(_acceptedNames);
311 sb.append(", _acceptedPatterns=").append(_acceptedPatterns);
312 sb.append("]");
313 return sb.toString();
314 }
315
316
317 }