1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.filter;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.hadoop.hbase.classification.InterfaceAudience;
24 import org.apache.hadoop.hbase.classification.InterfaceStability;
25 import org.apache.hadoop.hbase.KeyValue;
26 import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
27 import org.apache.hadoop.hbase.util.Bytes;
28
29 import java.lang.reflect.InvocationTargetException;
30 import java.lang.reflect.Method;
31 import java.nio.ByteBuffer;
32 import java.nio.charset.CharacterCodingException;
33 import java.util.ArrayList;
34 import java.util.Collections;
35 import java.util.EmptyStackException;
36 import java.util.HashMap;
37 import java.util.Map;
38 import java.util.Set;
39 import java.util.Stack;
40
41
42
43
44
45
46
47
48
49
50 @InterfaceAudience.Public
51 @InterfaceStability.Stable
52 public class ParseFilter {
53 private static final Log LOG = LogFactory.getLog(ParseFilter.class);
54
55 private static HashMap<ByteBuffer, Integer> operatorPrecedenceHashMap;
56 private static HashMap<String, String> filterHashMap;
57
58 static {
59
60 filterHashMap = new HashMap<String, String>();
61 filterHashMap.put("KeyOnlyFilter", ParseConstants.FILTER_PACKAGE + "." +
62 "KeyOnlyFilter");
63 filterHashMap.put("FirstKeyOnlyFilter", ParseConstants.FILTER_PACKAGE + "." +
64 "FirstKeyOnlyFilter");
65 filterHashMap.put("PrefixFilter", ParseConstants.FILTER_PACKAGE + "." +
66 "PrefixFilter");
67 filterHashMap.put("ColumnPrefixFilter", ParseConstants.FILTER_PACKAGE + "." +
68 "ColumnPrefixFilter");
69 filterHashMap.put("MultipleColumnPrefixFilter", ParseConstants.FILTER_PACKAGE + "." +
70 "MultipleColumnPrefixFilter");
71 filterHashMap.put("ColumnCountGetFilter", ParseConstants.FILTER_PACKAGE + "." +
72 "ColumnCountGetFilter");
73 filterHashMap.put("PageFilter", ParseConstants.FILTER_PACKAGE + "." +
74 "PageFilter");
75 filterHashMap.put("ColumnPaginationFilter", ParseConstants.FILTER_PACKAGE + "." +
76 "ColumnPaginationFilter");
77 filterHashMap.put("InclusiveStopFilter", ParseConstants.FILTER_PACKAGE + "." +
78 "InclusiveStopFilter");
79 filterHashMap.put("TimestampsFilter", ParseConstants.FILTER_PACKAGE + "." +
80 "TimestampsFilter");
81 filterHashMap.put("RowFilter", ParseConstants.FILTER_PACKAGE + "." +
82 "RowFilter");
83 filterHashMap.put("FamilyFilter", ParseConstants.FILTER_PACKAGE + "." +
84 "FamilyFilter");
85 filterHashMap.put("QualifierFilter", ParseConstants.FILTER_PACKAGE + "." +
86 "QualifierFilter");
87 filterHashMap.put("ValueFilter", ParseConstants.FILTER_PACKAGE + "." +
88 "ValueFilter");
89 filterHashMap.put("ColumnRangeFilter", ParseConstants.FILTER_PACKAGE + "." +
90 "ColumnRangeFilter");
91 filterHashMap.put("SingleColumnValueFilter", ParseConstants.FILTER_PACKAGE + "." +
92 "SingleColumnValueFilter");
93 filterHashMap.put("SingleColumnValueExcludeFilter", ParseConstants.FILTER_PACKAGE + "." +
94 "SingleColumnValueExcludeFilter");
95 filterHashMap.put("DependentColumnFilter", ParseConstants.FILTER_PACKAGE + "." +
96 "DependentColumnFilter");
97
98
99 operatorPrecedenceHashMap = new HashMap<ByteBuffer, Integer>();
100 operatorPrecedenceHashMap.put(ParseConstants.SKIP_BUFFER, 1);
101 operatorPrecedenceHashMap.put(ParseConstants.WHILE_BUFFER, 1);
102 operatorPrecedenceHashMap.put(ParseConstants.AND_BUFFER, 2);
103 operatorPrecedenceHashMap.put(ParseConstants.OR_BUFFER, 3);
104 }
105
106
107
108
109
110
111
112 public Filter parseFilterString (String filterString)
113 throws CharacterCodingException {
114 return parseFilterString(Bytes.toBytes(filterString));
115 }
116
117
118
119
120
121
122
123 public Filter parseFilterString (byte [] filterStringAsByteArray)
124 throws CharacterCodingException {
125
126 Stack <ByteBuffer> operatorStack = new Stack<ByteBuffer>();
127
128 Stack <Filter> filterStack = new Stack<Filter>();
129
130 Filter filter = null;
131 for (int i=0; i<filterStringAsByteArray.length; i++) {
132 if (filterStringAsByteArray[i] == ParseConstants.LPAREN) {
133
134 operatorStack.push(ParseConstants.LPAREN_BUFFER);
135 } else if (filterStringAsByteArray[i] == ParseConstants.WHITESPACE ||
136 filterStringAsByteArray[i] == ParseConstants.TAB) {
137
138 continue;
139 } else if (checkForOr(filterStringAsByteArray, i)) {
140
141 i += ParseConstants.OR_ARRAY.length - 1;
142 reduce(operatorStack, filterStack, ParseConstants.OR_BUFFER);
143 operatorStack.push(ParseConstants.OR_BUFFER);
144 } else if (checkForAnd(filterStringAsByteArray, i)) {
145
146 i += ParseConstants.AND_ARRAY.length - 1;
147 reduce(operatorStack, filterStack, ParseConstants.AND_BUFFER);
148 operatorStack.push(ParseConstants.AND_BUFFER);
149 } else if (checkForSkip(filterStringAsByteArray, i)) {
150
151 i += ParseConstants.SKIP_ARRAY.length - 1;
152 reduce(operatorStack, filterStack, ParseConstants.SKIP_BUFFER);
153 operatorStack.push(ParseConstants.SKIP_BUFFER);
154 } else if (checkForWhile(filterStringAsByteArray, i)) {
155
156 i += ParseConstants.WHILE_ARRAY.length - 1;
157 reduce(operatorStack, filterStack, ParseConstants.WHILE_BUFFER);
158 operatorStack.push(ParseConstants.WHILE_BUFFER);
159 } else if (filterStringAsByteArray[i] == ParseConstants.RPAREN) {
160
161 if (operatorStack.empty()) {
162 throw new IllegalArgumentException("Mismatched parenthesis");
163 }
164 ByteBuffer argumentOnTopOfStack = operatorStack.peek();
165 while (!(argumentOnTopOfStack.equals(ParseConstants.LPAREN_BUFFER))) {
166 filterStack.push(popArguments(operatorStack, filterStack));
167 if (operatorStack.empty()) {
168 throw new IllegalArgumentException("Mismatched parenthesis");
169 }
170 argumentOnTopOfStack = operatorStack.pop();
171 }
172 } else {
173
174 byte [] filterSimpleExpression = extractFilterSimpleExpression(filterStringAsByteArray, i);
175 i+= (filterSimpleExpression.length - 1);
176 filter = parseSimpleFilterExpression(filterSimpleExpression);
177 filterStack.push(filter);
178 }
179 }
180
181
182 while (!operatorStack.empty()) {
183 filterStack.push(popArguments(operatorStack, filterStack));
184 }
185 filter = filterStack.pop();
186 if (!filterStack.empty()) {
187 throw new IllegalArgumentException("Incorrect Filter String");
188 }
189 return filter;
190 }
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206 public byte [] extractFilterSimpleExpression (byte [] filterStringAsByteArray,
207 int filterExpressionStartOffset)
208 throws CharacterCodingException {
209 int quoteCount = 0;
210 for (int i=filterExpressionStartOffset; i<filterStringAsByteArray.length; i++) {
211 if (filterStringAsByteArray[i] == ParseConstants.SINGLE_QUOTE) {
212 if (isQuoteUnescaped(filterStringAsByteArray, i)) {
213 quoteCount ++;
214 } else {
215
216 i++;
217 }
218 }
219 if (filterStringAsByteArray[i] == ParseConstants.RPAREN && (quoteCount %2 ) == 0) {
220 byte [] filterSimpleExpression = new byte [i - filterExpressionStartOffset + 1];
221 Bytes.putBytes(filterSimpleExpression, 0, filterStringAsByteArray,
222 filterExpressionStartOffset, i-filterExpressionStartOffset + 1);
223 return filterSimpleExpression;
224 }
225 }
226 throw new IllegalArgumentException("Incorrect Filter String");
227 }
228
229
230
231
232
233
234
235 public Filter parseSimpleFilterExpression (byte [] filterStringAsByteArray)
236 throws CharacterCodingException {
237
238 String filterName = Bytes.toString(getFilterName(filterStringAsByteArray));
239 ArrayList<byte []> filterArguments = getFilterArguments(filterStringAsByteArray);
240 if (!filterHashMap.containsKey(filterName)) {
241 throw new IllegalArgumentException("Filter Name " + filterName + " not supported");
242 }
243 try {
244 filterName = filterHashMap.get(filterName);
245 Class<?> c = Class.forName(filterName);
246 Class<?>[] argTypes = new Class [] {ArrayList.class};
247 Method m = c.getDeclaredMethod("createFilterFromArguments", argTypes);
248 return (Filter) m.invoke(null,filterArguments);
249 } catch (ClassNotFoundException e) {
250 e.printStackTrace();
251 } catch (NoSuchMethodException e) {
252 e.printStackTrace();
253 } catch (IllegalAccessException e) {
254 e.printStackTrace();
255 } catch (InvocationTargetException e) {
256 e.printStackTrace();
257 }
258 throw new IllegalArgumentException("Incorrect filter string " +
259 new String(filterStringAsByteArray));
260 }
261
262
263
264
265
266
267
268 public static byte [] getFilterName (byte [] filterStringAsByteArray) {
269 int filterNameStartIndex = 0;
270 int filterNameEndIndex = 0;
271
272 for (int i=filterNameStartIndex; i<filterStringAsByteArray.length; i++) {
273 if (filterStringAsByteArray[i] == ParseConstants.LPAREN ||
274 filterStringAsByteArray[i] == ParseConstants.WHITESPACE) {
275 filterNameEndIndex = i;
276 break;
277 }
278 }
279
280 if (filterNameEndIndex == 0) {
281 throw new IllegalArgumentException("Incorrect Filter Name");
282 }
283
284 byte [] filterName = new byte[filterNameEndIndex - filterNameStartIndex];
285 Bytes.putBytes(filterName, 0, filterStringAsByteArray, 0,
286 filterNameEndIndex - filterNameStartIndex);
287 return filterName;
288 }
289
290
291
292
293
294
295
296 public static ArrayList<byte []> getFilterArguments (byte [] filterStringAsByteArray) {
297 int argumentListStartIndex = KeyValue.getDelimiter(filterStringAsByteArray, 0,
298 filterStringAsByteArray.length,
299 ParseConstants.LPAREN);
300 if (argumentListStartIndex == -1) {
301 throw new IllegalArgumentException("Incorrect argument list");
302 }
303
304 int argumentStartIndex = 0;
305 int argumentEndIndex = 0;
306 ArrayList<byte []> filterArguments = new ArrayList<byte []>();
307
308 for (int i = argumentListStartIndex + 1; i<filterStringAsByteArray.length; i++) {
309
310 if (filterStringAsByteArray[i] == ParseConstants.WHITESPACE ||
311 filterStringAsByteArray[i] == ParseConstants.COMMA ||
312 filterStringAsByteArray[i] == ParseConstants.RPAREN) {
313 continue;
314 }
315
316
317 if (filterStringAsByteArray[i] == ParseConstants.SINGLE_QUOTE) {
318 argumentStartIndex = i;
319 for (int j = argumentStartIndex+1; j < filterStringAsByteArray.length; j++) {
320 if (filterStringAsByteArray[j] == ParseConstants.SINGLE_QUOTE) {
321 if (isQuoteUnescaped(filterStringAsByteArray,j)) {
322 argumentEndIndex = j;
323 i = j+1;
324 byte [] filterArgument = createUnescapdArgument(filterStringAsByteArray,
325 argumentStartIndex, argumentEndIndex);
326 filterArguments.add(filterArgument);
327 break;
328 } else {
329
330 j++;
331 }
332 } else if (j == filterStringAsByteArray.length - 1) {
333 throw new IllegalArgumentException("Incorrect argument list");
334 }
335 }
336 } else {
337
338 argumentStartIndex = i;
339 for (int j = argumentStartIndex; j < filterStringAsByteArray.length; j++) {
340 if (filterStringAsByteArray[j] == ParseConstants.WHITESPACE ||
341 filterStringAsByteArray[j] == ParseConstants.COMMA ||
342 filterStringAsByteArray[j] == ParseConstants.RPAREN) {
343 argumentEndIndex = j - 1;
344 i = j;
345 byte [] filterArgument = new byte [argumentEndIndex - argumentStartIndex + 1];
346 Bytes.putBytes(filterArgument, 0, filterStringAsByteArray,
347 argumentStartIndex, argumentEndIndex - argumentStartIndex + 1);
348 filterArguments.add(filterArgument);
349 break;
350 } else if (j == filterStringAsByteArray.length - 1) {
351 throw new IllegalArgumentException("Incorrect argument list");
352 }
353 }
354 }
355 }
356 return filterArguments;
357 }
358
359
360
361
362
363
364
365
366 public void reduce(Stack<ByteBuffer> operatorStack,
367 Stack<Filter> filterStack,
368 ByteBuffer operator) {
369 while (!operatorStack.empty() &&
370 !(ParseConstants.LPAREN_BUFFER.equals(operatorStack.peek())) &&
371 hasHigherPriority(operatorStack.peek(), operator)) {
372 filterStack.push(popArguments(operatorStack, filterStack));
373 }
374 }
375
376
377
378
379
380
381
382
383
384 public static Filter popArguments (Stack<ByteBuffer> operatorStack, Stack <Filter> filterStack) {
385 ByteBuffer argumentOnTopOfStack = operatorStack.peek();
386
387 if (argumentOnTopOfStack.equals(ParseConstants.OR_BUFFER)) {
388
389 try {
390 ArrayList<Filter> listOfFilters = new ArrayList<Filter>();
391 while (!operatorStack.empty() && operatorStack.peek().equals(ParseConstants.OR_BUFFER)) {
392 Filter filter = filterStack.pop();
393 listOfFilters.add(0, filter);
394 operatorStack.pop();
395 }
396 Filter filter = filterStack.pop();
397 listOfFilters.add(0, filter);
398 Filter orFilter = new FilterList(FilterList.Operator.MUST_PASS_ONE, listOfFilters);
399 return orFilter;
400 } catch (EmptyStackException e) {
401 throw new IllegalArgumentException("Incorrect input string - an OR needs two filters");
402 }
403
404 } else if (argumentOnTopOfStack.equals(ParseConstants.AND_BUFFER)) {
405
406 try {
407 ArrayList<Filter> listOfFilters = new ArrayList<Filter>();
408 while (!operatorStack.empty() && operatorStack.peek().equals(ParseConstants.AND_BUFFER)) {
409 Filter filter = filterStack.pop();
410 listOfFilters.add(0, filter);
411 operatorStack.pop();
412 }
413 Filter filter = filterStack.pop();
414 listOfFilters.add(0, filter);
415 Filter andFilter = new FilterList(FilterList.Operator.MUST_PASS_ALL, listOfFilters);
416 return andFilter;
417 } catch (EmptyStackException e) {
418 throw new IllegalArgumentException("Incorrect input string - an AND needs two filters");
419 }
420
421 } else if (argumentOnTopOfStack.equals(ParseConstants.SKIP_BUFFER)) {
422
423 try {
424 Filter wrappedFilter = filterStack.pop();
425 Filter skipFilter = new SkipFilter(wrappedFilter);
426 operatorStack.pop();
427 return skipFilter;
428 } catch (EmptyStackException e) {
429 throw new IllegalArgumentException("Incorrect input string - a SKIP wraps a filter");
430 }
431
432 } else if (argumentOnTopOfStack.equals(ParseConstants.WHILE_BUFFER)) {
433
434 try {
435 Filter wrappedFilter = filterStack.pop();
436 Filter whileMatchFilter = new WhileMatchFilter(wrappedFilter);
437 operatorStack.pop();
438 return whileMatchFilter;
439 } catch (EmptyStackException e) {
440 throw new IllegalArgumentException("Incorrect input string - a WHILE wraps a filter");
441 }
442
443 } else if (argumentOnTopOfStack.equals(ParseConstants.LPAREN_BUFFER)) {
444
445 try {
446 Filter filter = filterStack.pop();
447 operatorStack.pop();
448 return filter;
449 } catch (EmptyStackException e) {
450 throw new IllegalArgumentException("Incorrect Filter String");
451 }
452
453 } else {
454 throw new IllegalArgumentException("Incorrect arguments on operatorStack");
455 }
456 }
457
458
459
460
461
462
463
464 public boolean hasHigherPriority(ByteBuffer a, ByteBuffer b) {
465 if ((operatorPrecedenceHashMap.get(a) - operatorPrecedenceHashMap.get(b)) < 0) {
466 return true;
467 }
468 return false;
469 }
470
471
472
473
474
475
476
477
478
479 public static byte [] createUnescapdArgument (byte [] filterStringAsByteArray,
480 int argumentStartIndex, int argumentEndIndex) {
481 int unescapedArgumentLength = 2;
482 for (int i = argumentStartIndex + 1; i <= argumentEndIndex - 1; i++) {
483 unescapedArgumentLength ++;
484 if (filterStringAsByteArray[i] == ParseConstants.SINGLE_QUOTE &&
485 i != (argumentEndIndex - 1) &&
486 filterStringAsByteArray[i+1] == ParseConstants.SINGLE_QUOTE) {
487 i++;
488 continue;
489 }
490 }
491
492 byte [] unescapedArgument = new byte [unescapedArgumentLength];
493 int count = 1;
494 unescapedArgument[0] = '\'';
495 for (int i = argumentStartIndex + 1; i <= argumentEndIndex - 1; i++) {
496 if (filterStringAsByteArray [i] == ParseConstants.SINGLE_QUOTE &&
497 i != (argumentEndIndex - 1) &&
498 filterStringAsByteArray [i+1] == ParseConstants.SINGLE_QUOTE) {
499 unescapedArgument[count++] = filterStringAsByteArray [i+1];
500 i++;
501 }
502 else {
503 unescapedArgument[count++] = filterStringAsByteArray [i];
504 }
505 }
506 unescapedArgument[unescapedArgumentLength - 1] = '\'';
507 return unescapedArgument;
508 }
509
510
511
512
513
514
515
516
517 public static boolean checkForOr (byte [] filterStringAsByteArray, int indexOfOr)
518 throws CharacterCodingException, ArrayIndexOutOfBoundsException {
519
520 try {
521 if (filterStringAsByteArray[indexOfOr] == ParseConstants.O &&
522 filterStringAsByteArray[indexOfOr+1] == ParseConstants.R &&
523 (filterStringAsByteArray[indexOfOr-1] == ParseConstants.WHITESPACE ||
524 filterStringAsByteArray[indexOfOr-1] == ParseConstants.RPAREN) &&
525 (filterStringAsByteArray[indexOfOr+2] == ParseConstants.WHITESPACE ||
526 filterStringAsByteArray[indexOfOr+2] == ParseConstants.LPAREN)) {
527 return true;
528 } else {
529 return false;
530 }
531 } catch (ArrayIndexOutOfBoundsException e) {
532 return false;
533 }
534 }
535
536
537
538
539
540
541
542
543 public static boolean checkForAnd (byte [] filterStringAsByteArray, int indexOfAnd)
544 throws CharacterCodingException {
545
546 try {
547 if (filterStringAsByteArray[indexOfAnd] == ParseConstants.A &&
548 filterStringAsByteArray[indexOfAnd+1] == ParseConstants.N &&
549 filterStringAsByteArray[indexOfAnd+2] == ParseConstants.D &&
550 (filterStringAsByteArray[indexOfAnd-1] == ParseConstants.WHITESPACE ||
551 filterStringAsByteArray[indexOfAnd-1] == ParseConstants.RPAREN) &&
552 (filterStringAsByteArray[indexOfAnd+3] == ParseConstants.WHITESPACE ||
553 filterStringAsByteArray[indexOfAnd+3] == ParseConstants.LPAREN)) {
554 return true;
555 } else {
556 return false;
557 }
558 } catch (ArrayIndexOutOfBoundsException e) {
559 return false;
560 }
561 }
562
563
564
565
566
567
568
569
570 public static boolean checkForSkip (byte [] filterStringAsByteArray, int indexOfSkip)
571 throws CharacterCodingException {
572
573 try {
574 if (filterStringAsByteArray[indexOfSkip] == ParseConstants.S &&
575 filterStringAsByteArray[indexOfSkip+1] == ParseConstants.K &&
576 filterStringAsByteArray[indexOfSkip+2] == ParseConstants.I &&
577 filterStringAsByteArray[indexOfSkip+3] == ParseConstants.P &&
578 (indexOfSkip == 0 ||
579 filterStringAsByteArray[indexOfSkip-1] == ParseConstants.WHITESPACE ||
580 filterStringAsByteArray[indexOfSkip-1] == ParseConstants.RPAREN ||
581 filterStringAsByteArray[indexOfSkip-1] == ParseConstants.LPAREN) &&
582 (filterStringAsByteArray[indexOfSkip+4] == ParseConstants.WHITESPACE ||
583 filterStringAsByteArray[indexOfSkip+4] == ParseConstants.LPAREN)) {
584 return true;
585 } else {
586 return false;
587 }
588 } catch (ArrayIndexOutOfBoundsException e) {
589 return false;
590 }
591 }
592
593
594
595
596
597
598
599
600 public static boolean checkForWhile (byte [] filterStringAsByteArray, int indexOfWhile)
601 throws CharacterCodingException {
602
603 try {
604 if (filterStringAsByteArray[indexOfWhile] == ParseConstants.W &&
605 filterStringAsByteArray[indexOfWhile+1] == ParseConstants.H &&
606 filterStringAsByteArray[indexOfWhile+2] == ParseConstants.I &&
607 filterStringAsByteArray[indexOfWhile+3] == ParseConstants.L &&
608 filterStringAsByteArray[indexOfWhile+4] == ParseConstants.E &&
609 (indexOfWhile == 0 || filterStringAsByteArray[indexOfWhile-1] == ParseConstants.WHITESPACE
610 || filterStringAsByteArray[indexOfWhile-1] == ParseConstants.RPAREN ||
611 filterStringAsByteArray[indexOfWhile-1] == ParseConstants.LPAREN) &&
612 (filterStringAsByteArray[indexOfWhile+5] == ParseConstants.WHITESPACE ||
613 filterStringAsByteArray[indexOfWhile+5] == ParseConstants.LPAREN)) {
614 return true;
615 } else {
616 return false;
617 }
618 } catch (ArrayIndexOutOfBoundsException e) {
619 return false;
620 }
621 }
622
623
624
625
626
627
628
629
630 public static boolean isQuoteUnescaped (byte [] array, int quoteIndex) {
631 if (array == null) {
632 throw new IllegalArgumentException("isQuoteUnescaped called with a null array");
633 }
634
635 if (quoteIndex == array.length - 1 || array[quoteIndex+1] != ParseConstants.SINGLE_QUOTE) {
636 return true;
637 }
638 else {
639 return false;
640 }
641 }
642
643
644
645
646
647
648
649
650
651 public static byte [] removeQuotesFromByteArray (byte [] quotedByteArray) {
652 if (quotedByteArray == null ||
653 quotedByteArray.length < 2 ||
654 quotedByteArray[0] != ParseConstants.SINGLE_QUOTE ||
655 quotedByteArray[quotedByteArray.length - 1] != ParseConstants.SINGLE_QUOTE) {
656 throw new IllegalArgumentException("removeQuotesFromByteArray needs a quoted byte array");
657 } else {
658 byte [] targetString = new byte [quotedByteArray.length - 2];
659 Bytes.putBytes(targetString, 0, quotedByteArray, 1, quotedByteArray.length - 2);
660 return targetString;
661 }
662 }
663
664
665
666
667
668
669
670
671
672
673 public static int convertByteArrayToInt (byte [] numberAsByteArray) {
674
675 long tempResult = ParseFilter.convertByteArrayToLong(numberAsByteArray);
676
677 if (tempResult > Integer.MAX_VALUE) {
678 throw new IllegalArgumentException("Integer Argument too large");
679 } else if (tempResult < Integer.MIN_VALUE) {
680 throw new IllegalArgumentException("Integer Argument too small");
681 }
682
683 int result = (int) tempResult;
684 return result;
685 }
686
687
688
689
690
691
692
693
694
695
696 public static long convertByteArrayToLong (byte [] numberAsByteArray) {
697 if (numberAsByteArray == null) {
698 throw new IllegalArgumentException("convertByteArrayToLong called with a null array");
699 }
700
701 int i = 0;
702 long result = 0;
703 boolean isNegative = false;
704
705 if (numberAsByteArray[i] == ParseConstants.MINUS_SIGN) {
706 i++;
707 isNegative = true;
708 }
709
710 while (i != numberAsByteArray.length) {
711 if (numberAsByteArray[i] < ParseConstants.ZERO ||
712 numberAsByteArray[i] > ParseConstants.NINE) {
713 throw new IllegalArgumentException("Byte Array should only contain digits");
714 }
715 result = result*10 + (numberAsByteArray[i] - ParseConstants.ZERO);
716 if (result < 0) {
717 throw new IllegalArgumentException("Long Argument too large");
718 }
719 i++;
720 }
721
722 if (isNegative) {
723 return -result;
724 } else {
725 return result;
726 }
727 }
728
729
730
731
732
733
734
735
736
737
738
739 public static boolean convertByteArrayToBoolean (byte [] booleanAsByteArray) {
740 if (booleanAsByteArray == null) {
741 throw new IllegalArgumentException("convertByteArrayToBoolean called with a null array");
742 }
743
744 if (booleanAsByteArray.length == 4 &&
745 (booleanAsByteArray[0] == 't' || booleanAsByteArray[0] == 'T') &&
746 (booleanAsByteArray[1] == 'r' || booleanAsByteArray[1] == 'R') &&
747 (booleanAsByteArray[2] == 'u' || booleanAsByteArray[2] == 'U') &&
748 (booleanAsByteArray[3] == 'e' || booleanAsByteArray[3] == 'E')) {
749 return true;
750 }
751 else if (booleanAsByteArray.length == 5 &&
752 (booleanAsByteArray[0] == 'f' || booleanAsByteArray[0] == 'F') &&
753 (booleanAsByteArray[1] == 'a' || booleanAsByteArray[1] == 'A') &&
754 (booleanAsByteArray[2] == 'l' || booleanAsByteArray[2] == 'L') &&
755 (booleanAsByteArray[3] == 's' || booleanAsByteArray[3] == 'S') &&
756 (booleanAsByteArray[4] == 'e' || booleanAsByteArray[4] == 'E')) {
757 return false;
758 }
759 else {
760 throw new IllegalArgumentException("Incorrect Boolean Expression");
761 }
762 }
763
764
765
766
767
768
769
770 public static CompareFilter.CompareOp createCompareOp (byte [] compareOpAsByteArray) {
771 ByteBuffer compareOp = ByteBuffer.wrap(compareOpAsByteArray);
772 if (compareOp.equals(ParseConstants.LESS_THAN_BUFFER))
773 return CompareOp.LESS;
774 else if (compareOp.equals(ParseConstants.LESS_THAN_OR_EQUAL_TO_BUFFER))
775 return CompareOp.LESS_OR_EQUAL;
776 else if (compareOp.equals(ParseConstants.GREATER_THAN_BUFFER))
777 return CompareOp.GREATER;
778 else if (compareOp.equals(ParseConstants.GREATER_THAN_OR_EQUAL_TO_BUFFER))
779 return CompareOp.GREATER_OR_EQUAL;
780 else if (compareOp.equals(ParseConstants.NOT_EQUAL_TO_BUFFER))
781 return CompareOp.NOT_EQUAL;
782 else if (compareOp.equals(ParseConstants.EQUAL_TO_BUFFER))
783 return CompareOp.EQUAL;
784 else
785 throw new IllegalArgumentException("Invalid compare operator");
786 }
787
788
789
790
791
792
793
794 public static ByteArrayComparable createComparator (byte [] comparator) {
795 if (comparator == null)
796 throw new IllegalArgumentException("Incorrect Comparator");
797 byte [][] parsedComparator = ParseFilter.parseComparator(comparator);
798 byte [] comparatorType = parsedComparator[0];
799 byte [] comparatorValue = parsedComparator[1];
800
801
802 if (Bytes.equals(comparatorType, ParseConstants.binaryType))
803 return new BinaryComparator(comparatorValue);
804 else if (Bytes.equals(comparatorType, ParseConstants.binaryPrefixType))
805 return new BinaryPrefixComparator(comparatorValue);
806 else if (Bytes.equals(comparatorType, ParseConstants.regexStringType))
807 return new RegexStringComparator(new String(comparatorValue));
808 else if (Bytes.equals(comparatorType, ParseConstants.substringType))
809 return new SubstringComparator(new String(comparatorValue));
810 else
811 throw new IllegalArgumentException("Incorrect comparatorType");
812 }
813
814
815
816
817
818
819
820 public static byte [][] parseComparator (byte [] comparator) {
821 final int index = KeyValue.getDelimiter(comparator, 0, comparator.length, ParseConstants.COLON);
822 if (index == -1) {
823 throw new IllegalArgumentException("Incorrect comparator");
824 }
825
826 byte [][] result = new byte [2][0];
827 result[0] = new byte [index];
828 System.arraycopy(comparator, 0, result[0], 0, index);
829
830 final int len = comparator.length - (index + 1);
831 result[1] = new byte[len];
832 System.arraycopy(comparator, index + 1, result[1], 0, len);
833
834 return result;
835 }
836
837
838
839
840 public Set<String> getSupportedFilters () {
841 return filterHashMap.keySet();
842 }
843
844
845
846
847
848 public static Map<String, String> getAllFilters() {
849 return Collections.unmodifiableMap(filterHashMap);
850 }
851
852
853
854
855
856
857
858
859 public static void registerFilter(String name, String filterClass) {
860 if(LOG.isInfoEnabled())
861 LOG.info("Registering new filter " + name);
862
863 filterHashMap.put(name, filterClass);
864 }
865 }