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