|
@@ -46,7 +46,7 @@ public class IgnoreList {
|
46
|
46
|
*
|
47
|
47
|
* @param items Items to add to this RegexStringList
|
48
|
48
|
*/
|
49
|
|
- public IgnoreList(final List<String> items) {
|
|
49
|
+ public IgnoreList(final Iterable<String> items) {
|
50
|
50
|
addAll(items);
|
51
|
51
|
}
|
52
|
52
|
|
|
@@ -70,7 +70,7 @@ public class IgnoreList {
|
70
|
70
|
*
|
71
|
71
|
* @param patterns A list of patterns to be added
|
72
|
72
|
*/
|
73
|
|
- public void addAll(final List<String> patterns) {
|
|
73
|
+ public void addAll(final Iterable<String> patterns) {
|
74
|
74
|
for (String pattern : patterns) {
|
75
|
75
|
add(pattern);
|
76
|
76
|
}
|
|
@@ -82,7 +82,7 @@ public class IgnoreList {
|
82
|
82
|
* @param position Position in the list to remove
|
83
|
83
|
*/
|
84
|
84
|
public void remove(final int position) {
|
85
|
|
- if (position < this.count()) {
|
|
85
|
+ if (position < count()) {
|
86
|
86
|
ignoreInfo.remove(position);
|
87
|
87
|
}
|
88
|
88
|
}
|
|
@@ -102,8 +102,8 @@ public class IgnoreList {
|
102
|
102
|
* @throws PatternSyntaxException if one of the items in the list is an invalid regex
|
103
|
103
|
*/
|
104
|
104
|
public int matches(final String check) throws PatternSyntaxException {
|
105
|
|
- for (int i = 0; i < this.count(); ++i) {
|
106
|
|
- if (check.matches("(?i)" + this.get(i))) {
|
|
105
|
+ for (int i = 0; i < count(); i++) {
|
|
106
|
+ if (check.matches("(?i)" + get(i))) {
|
107
|
107
|
return i;
|
108
|
108
|
}
|
109
|
109
|
}
|
|
@@ -120,11 +120,7 @@ public class IgnoreList {
|
120
|
120
|
*/
|
121
|
121
|
public boolean matches(final int position, final String check) throws
|
122
|
122
|
PatternSyntaxException {
|
123
|
|
- if (position < this.count()) {
|
124
|
|
- return check.matches("(?i)" + this.get(position));
|
125
|
|
- } else {
|
126
|
|
- return false;
|
127
|
|
- }
|
|
123
|
+ return position < count() && check.matches("(?i)" + get(position));
|
128
|
124
|
}
|
129
|
125
|
|
130
|
126
|
/**
|
|
@@ -134,7 +130,7 @@ public class IgnoreList {
|
134
|
130
|
* @return String showing the pattern. ("" if position isn't valid)
|
135
|
131
|
*/
|
136
|
132
|
public String get(final int position) {
|
137
|
|
- if (position < this.count()) {
|
|
133
|
+ if (position < count()) {
|
138
|
134
|
return ignoreInfo.get(position);
|
139
|
135
|
} else {
|
140
|
136
|
return "";
|
|
@@ -148,7 +144,7 @@ public class IgnoreList {
|
148
|
144
|
* @param pattern New pattern
|
149
|
145
|
*/
|
150
|
146
|
public void set(final int position, final String pattern) {
|
151
|
|
- if (position < this.count()) {
|
|
147
|
+ if (position < count()) {
|
152
|
148
|
ignoreInfo.set(position, pattern);
|
153
|
149
|
}
|
154
|
150
|
}
|
|
@@ -220,62 +216,87 @@ public class IgnoreList {
|
220
|
216
|
protected static String regexToSimple(final String regex)
|
221
|
217
|
throws UnsupportedOperationException {
|
222
|
218
|
final StringBuilder res = new StringBuilder(regex.length());
|
223
|
|
- boolean escaped = false;
|
224
|
|
- boolean inchar = false;
|
|
219
|
+ final ConversionState state = new ConversionState();
|
225
|
220
|
|
226
|
221
|
for (char part : regex.toCharArray()) {
|
227
|
|
- if (inchar) {
|
228
|
|
- inchar = false;
|
229
|
|
-
|
230
|
|
- if (part == '*') {
|
231
|
|
- res.append(part);
|
232
|
|
- continue;
|
233
|
|
- } else {
|
234
|
|
- res.append('?');
|
235
|
|
- }
|
236
|
|
- }
|
237
|
|
-
|
238
|
|
- if (escaped) {
|
239
|
|
- if (part == '?' || part == '*') {
|
240
|
|
- throw new UnsupportedOperationException("Cannot convert to"
|
241
|
|
- + " simple expression: ? or * is escaped.");
|
242
|
|
- }
|
243
|
|
-
|
244
|
|
- res.append(part);
|
245
|
|
- escaped = false;
|
246
|
|
- } else if (part == '\\') {
|
247
|
|
- escaped = true;
|
248
|
|
- } else if (part == '.') {
|
249
|
|
- inchar = true;
|
250
|
|
- } else if (part == '.' || part == '^' || part == '$' || part
|
251
|
|
- == '['
|
252
|
|
- || part == ']' || part == '\\' || part == '(' || part == ')'
|
253
|
|
- || part == '{' || part == '}' || part == '|' || part == '+'
|
254
|
|
- || part == '*' || part == '?') {
|
255
|
|
- throw new UnsupportedOperationException("Cannot convert to"
|
256
|
|
- + " simple expression: unescaped special char: " + part);
|
|
222
|
+ if (state.getAndResetLastCharWasDot()) {
|
|
223
|
+ handleCharFollowingDot(state, res, part);
|
|
224
|
+ } else if (state.getAndResetEscaped()) {
|
|
225
|
+ handleEscapedChar(res, part);
|
257
|
226
|
} else {
|
258
|
|
- res.append(part);
|
|
227
|
+ handleNormalChar(state, res, part);
|
259
|
228
|
}
|
260
|
229
|
}
|
261
|
230
|
|
262
|
|
- if (escaped) {
|
|
231
|
+ if (state.getAndResetEscaped()) {
|
263
|
232
|
throw new UnsupportedOperationException("Cannot convert to "
|
264
|
233
|
+ "simple expression: trailing backslash");
|
265
|
|
- } else if (inchar) {
|
|
234
|
+ } else if (state.getAndResetLastCharWasDot()) {
|
266
|
235
|
res.append('?');
|
267
|
236
|
}
|
268
|
237
|
|
269
|
238
|
return res.toString();
|
270
|
239
|
}
|
271
|
240
|
|
|
241
|
+ /**
|
|
242
|
+ * Handles a single char that was preceded by a '.' when converting from a regex.
|
|
243
|
+ *
|
|
244
|
+ * @param state The current state of conversion.
|
|
245
|
+ * @param builder The builder to append data to.
|
|
246
|
+ * @param character The character in question.
|
|
247
|
+ */
|
|
248
|
+ private static void handleCharFollowingDot(final ConversionState state,
|
|
249
|
+ final StringBuilder builder, final char character) {
|
|
250
|
+ if (character == '*') {
|
|
251
|
+ builder.append('*');
|
|
252
|
+ } else {
|
|
253
|
+ builder.append('?');
|
|
254
|
+ handleNormalChar(state, builder, character);
|
|
255
|
+ }
|
|
256
|
+ }
|
|
257
|
+
|
|
258
|
+ /**
|
|
259
|
+ * Handles a single char that was escaped when converting from a regex.
|
|
260
|
+ *
|
|
261
|
+ * @param builder The builder to append data to.
|
|
262
|
+ * @param character The character in question.
|
|
263
|
+ */
|
|
264
|
+ private static void handleEscapedChar(final StringBuilder builder, final char character) {
|
|
265
|
+ if (character == '?' || character == '*') {
|
|
266
|
+ throw new UnsupportedOperationException("Cannot convert to"
|
|
267
|
+ + " simple expression: ? or * is escaped.");
|
|
268
|
+ }
|
|
269
|
+
|
|
270
|
+ builder.append(character);
|
|
271
|
+ }
|
|
272
|
+
|
|
273
|
+ /**
|
|
274
|
+ * Handles a single normal character when converting from a regex.
|
|
275
|
+ *
|
|
276
|
+ * @param state The current state of conversion.
|
|
277
|
+ * @param builder The builder to append data to.
|
|
278
|
+ * @param character The character in question.
|
|
279
|
+ */
|
|
280
|
+ private static void handleNormalChar(final ConversionState state,
|
|
281
|
+ final StringBuilder builder, final char character) {
|
|
282
|
+ if (character == '\\') {
|
|
283
|
+ state.setEscaped();
|
|
284
|
+ } else if (character == '.') {
|
|
285
|
+ state.setLastCharWasDot();
|
|
286
|
+ } else if ("^$[](){}|+*?".indexOf(character) > -1) {
|
|
287
|
+ throw new UnsupportedOperationException("Cannot convert to"
|
|
288
|
+ + " simple expression: unescaped special char: " + character);
|
|
289
|
+ } else {
|
|
290
|
+ builder.append(character);
|
|
291
|
+ }
|
|
292
|
+ }
|
|
293
|
+
|
272
|
294
|
/**
|
273
|
295
|
* Converts a simple expression to a regular expression.
|
274
|
296
|
*
|
275
|
297
|
* @param regex The simple expression to be converted
|
276
|
298
|
* @return A corresponding regular expression
|
277
|
299
|
*/
|
278
|
|
- @SuppressWarnings("fallthrough")
|
279
|
300
|
protected static String simpleToRegex(final String regex) {
|
280
|
301
|
final StringBuilder res = new StringBuilder(regex.length());
|
281
|
302
|
|
|
@@ -293,14 +314,14 @@ public class IgnoreList {
|
293
|
314
|
case '}':
|
294
|
315
|
case '|':
|
295
|
316
|
case '+':
|
296
|
|
- res.append('\\');
|
297
|
|
- res.append(part);
|
|
317
|
+ res.append('\\').append(part);
|
298
|
318
|
break;
|
299
|
319
|
case '?':
|
300
|
320
|
res.append('.');
|
301
|
321
|
break;
|
302
|
322
|
case '*':
|
303
|
|
- res.append('.');
|
|
323
|
+ res.append(".*");
|
|
324
|
+ break;
|
304
|
325
|
default:
|
305
|
326
|
res.append(part);
|
306
|
327
|
break;
|
|
@@ -309,4 +330,35 @@ public class IgnoreList {
|
309
|
330
|
|
310
|
331
|
return res.toString();
|
311
|
332
|
}
|
|
333
|
+
|
|
334
|
+ /**
|
|
335
|
+ * Utility class to represent state while converting a regex to a simple form.
|
|
336
|
+ */
|
|
337
|
+ private static final class ConversionState {
|
|
338
|
+
|
|
339
|
+ private boolean escaped;
|
|
340
|
+ private boolean lastCharWasDot;
|
|
341
|
+
|
|
342
|
+ public boolean getAndResetLastCharWasDot() {
|
|
343
|
+ final boolean oldValue = lastCharWasDot;
|
|
344
|
+ lastCharWasDot = false;
|
|
345
|
+ return oldValue;
|
|
346
|
+ }
|
|
347
|
+
|
|
348
|
+ public void setLastCharWasDot() {
|
|
349
|
+ lastCharWasDot = true;
|
|
350
|
+ }
|
|
351
|
+
|
|
352
|
+ public boolean getAndResetEscaped() {
|
|
353
|
+ final boolean oldValue = escaped;
|
|
354
|
+ escaped = false;
|
|
355
|
+ return oldValue;
|
|
356
|
+ }
|
|
357
|
+
|
|
358
|
+ public void setEscaped() {
|
|
359
|
+ escaped = true;
|
|
360
|
+ }
|
|
361
|
+
|
|
362
|
+ }
|
|
363
|
+
|
312
|
364
|
}
|