1 package org.codehaus.mojo.wagon.shared;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 import java.util.StringTokenizer;
19 import java.util.Vector;
20
21
22
23
24 public final class SelectorUtils {
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 public static boolean matchPatternStart(String pattern, String str) {
40 return matchPatternStart(pattern, str, true);
41 }
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 public static boolean matchPatternStart(String pattern, String str, boolean isCaseSensitive) {
59
60
61
62
63 if (str.startsWith("/") != pattern.startsWith("/")) {
64 return false;
65 }
66
67 Vector<?> patDirs = tokenizePath(pattern);
68 Vector<?> strDirs = tokenizePath(str);
69
70 int patIdxStart = 0;
71 int patIdxEnd = patDirs.size() - 1;
72 int strIdxStart = 0;
73 int strIdxEnd = strDirs.size() - 1;
74
75
76 while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
77 String patDir = (String) patDirs.elementAt(patIdxStart);
78 if (patDir.equals("**")) {
79 break;
80 }
81 if (!match(patDir, (String) strDirs.elementAt(strIdxStart), isCaseSensitive)) {
82 return false;
83 }
84 patIdxStart++;
85 strIdxStart++;
86 }
87
88 if (strIdxStart > strIdxEnd) {
89
90 return true;
91 } else if (patIdxStart > patIdxEnd) {
92
93 return false;
94 } else {
95
96
97 return true;
98 }
99 }
100
101
102
103
104
105
106
107
108
109
110
111 public static boolean matchPath(String pattern, String str) {
112 return matchPath(pattern, str, true);
113 }
114
115
116
117
118
119
120
121
122
123
124
125
126
127 public static boolean matchPath(String pattern, String str, boolean isCaseSensitive) {
128
129
130
131
132 if (str.startsWith("/") != pattern.startsWith("/")) {
133 return false;
134 }
135
136 Vector<?> patDirs = tokenizePath(pattern);
137 Vector<?> strDirs = tokenizePath(str);
138
139 int patIdxStart = 0;
140 int patIdxEnd = patDirs.size() - 1;
141 int strIdxStart = 0;
142 int strIdxEnd = strDirs.size() - 1;
143
144
145 while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
146 String patDir = (String) patDirs.elementAt(patIdxStart);
147 if (patDir.equals("**")) {
148 break;
149 }
150 if (!match(patDir, (String) strDirs.elementAt(strIdxStart), isCaseSensitive)) {
151 patDirs = null;
152 strDirs = null;
153 return false;
154 }
155 patIdxStart++;
156 strIdxStart++;
157 }
158 if (strIdxStart > strIdxEnd) {
159
160 for (int i = patIdxStart; i <= patIdxEnd; i++) {
161 if (!patDirs.elementAt(i).equals("**")) {
162 patDirs = null;
163 strDirs = null;
164 return false;
165 }
166 }
167 return true;
168 } else {
169 if (patIdxStart > patIdxEnd) {
170
171 patDirs = null;
172 strDirs = null;
173 return false;
174 }
175 }
176
177
178 while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
179 String patDir = (String) patDirs.elementAt(patIdxEnd);
180 if (patDir.equals("**")) {
181 break;
182 }
183 if (!match(patDir, (String) strDirs.elementAt(strIdxEnd), isCaseSensitive)) {
184 patDirs = null;
185 strDirs = null;
186 return false;
187 }
188 patIdxEnd--;
189 strIdxEnd--;
190 }
191 if (strIdxStart > strIdxEnd) {
192
193 for (int i = patIdxStart; i <= patIdxEnd; i++) {
194 if (!patDirs.elementAt(i).equals("**")) {
195 patDirs = null;
196 strDirs = null;
197 return false;
198 }
199 }
200 return true;
201 }
202
203 while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
204 int patIdxTmp = -1;
205 for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
206 if (patDirs.elementAt(i).equals("**")) {
207 patIdxTmp = i;
208 break;
209 }
210 }
211 if (patIdxTmp == patIdxStart + 1) {
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267 public static boolean match(String pattern, String str) {
268 return match(pattern, str, true);
269 }
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286 public static boolean match(String pattern, String str, boolean isCaseSensitive) {
287 char[] patArr = pattern.toCharArray();
288 char[] strArr = str.toCharArray();
289 int patIdxStart = 0;
290 int patIdxEnd = patArr.length - 1;
291 int strIdxStart = 0;
292 int strIdxEnd = strArr.length - 1;
293 char ch;
294
295 boolean containsStar = false;
296 for (int i = 0; i < patArr.length; i++) {
297 if (patArr[i] == '*') {
298 containsStar = true;
299 break;
300 }
301 }
302
303 if (!containsStar) {
304
305 if (patIdxEnd != strIdxEnd) {
306 return false;
307 }
308 for (int i = 0; i <= patIdxEnd; i++) {
309 ch = patArr[i];
310 if (ch != '?' && !equals(ch, strArr[i], isCaseSensitive)) {
311 return false;
312 }
313 }
314 return true;
315 }
316
317 if (patIdxEnd == 0) {
318 return true;
319 }
320
321
322 while ((ch = patArr[patIdxStart]) != '*' && strIdxStart <= strIdxEnd) {
323 if (ch != '?' && !equals(ch, strArr[strIdxStart], isCaseSensitive)) {
324 return false;
325 }
326 patIdxStart++;
327 strIdxStart++;
328 }
329 if (strIdxStart > strIdxEnd) {
330
331
332 for (int i = patIdxStart; i <= patIdxEnd; i++) {
333 if (patArr[i] != '*') {
334 return false;
335 }
336 }
337 return true;
338 }
339
340
341 while ((ch = patArr[patIdxEnd]) != '*' && strIdxStart <= strIdxEnd) {
342 if (ch != '?' && !equals(ch, strArr[strIdxEnd], isCaseSensitive)) {
343 return false;
344 }
345 patIdxEnd--;
346 strIdxEnd--;
347 }
348 if (strIdxStart > strIdxEnd) {
349
350
351 for (int i = patIdxStart; i <= patIdxEnd; i++) {
352 if (patArr[i] != '*') {
353 return false;
354 }
355 }
356 return true;
357 }
358
359
360
361 while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
362 int patIdxTmp = -1;
363 for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
364 if (patArr[i] == '*') {
365 patIdxTmp = i;
366 break;
367 }
368 }
369 if (patIdxTmp == patIdxStart + 1) {
370
371 patIdxStart++;
372 continue;
373 }
374
375
376 int patLength = (patIdxTmp - patIdxStart - 1);
377 int strLength = (strIdxEnd - strIdxStart + 1);
378 int foundIdx = -1;
379 strLoop: for (int i = 0; i <= strLength - patLength; i++) {
380 for (int j = 0; j < patLength; j++) {
381 ch = patArr[patIdxStart + j + 1];
382 if (ch != '?' && !equals(ch, strArr[strIdxStart + i + j], isCaseSensitive)) {
383 continue strLoop;
384 }
385 }
386
387 foundIdx = strIdxStart + i;
388 break;
389 }
390
391 if (foundIdx == -1) {
392 return false;
393 }
394
395 patIdxStart = patIdxTmp;
396 strIdxStart = foundIdx + patLength;
397 }
398
399
400
401 for (int i = patIdxStart; i <= patIdxEnd; i++) {
402 if (patArr[i] != '*') {
403 return false;
404 }
405 }
406 return true;
407 }
408
409
410
411
412 private static boolean equals(char c1, char c2, boolean isCaseSensitive) {
413 if (c1 == c2) {
414 return true;
415 }
416 if (!isCaseSensitive) {
417
418 if (Character.toUpperCase(c1) == Character.toUpperCase(c2)
419 || Character.toLowerCase(c1) == Character.toLowerCase(c2)) {
420 return true;
421 }
422 }
423 return false;
424 }
425
426
427
428
429
430
431
432
433
434 public static Vector<String> tokenizePath(String path) {
435 Vector<String> ret = new Vector<String>();
436 StringTokenizer st = new StringTokenizer(path, "/");
437 while (st.hasMoreTokens()) {
438 ret.addElement(st.nextToken());
439 }
440 return ret;
441 }
442
443 }