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