1 10 package org.mmbase.storage.search.legacy; 11 12 import java.util.*; 13 import org.mmbase.bridge.Field; 14 import org.mmbase.core.CoreField; 15 import org.mmbase.module.core.*; 16 import org.mmbase.storage.StorageManagerFactory; 17 import org.mmbase.storage.search.*; 18 import org.mmbase.storage.search.implementation.*; 19 import org.mmbase.util.logging.*; 20 import org.mmbase.bridge.NodeQuery; 21 22 118 public class ConstraintParser { 119 120 private final static Logger log = Logging.getLoggerInstance(ConstraintParser.class); 121 122 123 private final static Logger fallbackLog = Logging.getLoggerInstance(ConstraintParser.class.getName() + ".fallback"); 124 125 126 134 private static String convertClausePartToDBS(String constraints) { 135 StorageManagerFactory factory = MMBase.getMMBase().getStorageManagerFactory(); 136 StringBuffer result = new StringBuffer (); 137 int posa = constraints.indexOf('['); 138 while (posa > -1) { 139 int posb = constraints.indexOf(']', posa); 140 if (posb == -1) { 141 posa = -1; 142 } else { 143 String fieldName = constraints.substring(posa + 1, posb); 144 int posc = fieldName.indexOf('.'); 145 if (posc == -1) { 146 fieldName = factory != null ? factory.getStorageIdentifier(fieldName).toString() : fieldName; 147 } else { 148 fieldName = fieldName.substring(0, posc + 1) + (factory != null ? factory.getStorageIdentifier(fieldName.substring(posc + 1)) : fieldName.substring(posc + 1)); 149 } 150 result.append(constraints.substring(0, posa)).append(fieldName); 151 constraints = constraints.substring(posb + 1); 152 posa = constraints.indexOf('['); 153 } 154 } 155 result.append(constraints); 156 return result.toString(); 157 } 158 159 167 public static String convertClauseToDBS(String constraints) { 168 if (constraints.startsWith("MMNODE")) { 169 return constraints; 172 } else if (constraints.startsWith("ALTA")) { 173 return constraints.substring(5); 176 } 177 178 180 StringBuffer result = new StringBuffer (); 181 183 int quoteOpen = constraints.indexOf('\''); 184 while (quoteOpen > -1) { 185 int quoteClose = constraints.indexOf('\'', quoteOpen + 1); 187 if (quoteClose == -1) { 188 log.warn("unbalanced quote in " + constraints); 190 break; 191 } 192 193 String part = constraints.substring(0, quoteOpen); 195 196 result.append(convertClausePartToDBS(part)); 198 result.append(constraints.substring(quoteOpen, quoteClose + 1)); 199 200 constraints = constraints.substring(quoteClose + 1); 201 quoteOpen = constraints.indexOf('\''); 202 203 } 204 result.append(convertClausePartToDBS(constraints)); 205 return result.toString(); 206 } 207 208 215 static public boolean validConstraints(String constraints) { 216 String remaining = constraints; 218 while (remaining.indexOf("''") != -1) { 219 int start = remaining.indexOf("''"); 220 int stop = start + 2; 221 if (stop < remaining.length()) { 222 String begin = remaining.substring(0, start); 223 String end = remaining.substring(stop); 224 remaining = begin + end; 225 } else { 226 remaining = remaining.substring(0, start); 227 } 228 } 229 while (remaining.length() > 0) { 234 if (remaining.indexOf('\'') != -1) { 235 int start = remaining.indexOf('\''); 237 238 if (start == remaining.length()) { 240 log.warn("reached end, but we are still escaping(you should sql-escape the search query inside the jsp-page?)\noriginal:" + constraints); 241 return false; 242 } 243 244 String notEscaped = remaining.substring(0, start); 245 if (notEscaped.indexOf(';') != -1) { 246 log.warn("found a ';' outside the constraints(you should sql-escape the search query inside the jsp-page?)\noriginal:" + constraints + "\nnot excaped:" + notEscaped); 247 return false; 248 } 249 250 int stop = remaining.substring(start + 1).indexOf('\''); 251 if (stop < 0) { 252 log.warn("reached end, but we are still escaping(you should sql-escape the search query inside the jsp-page?)\noriginal:" + constraints + "\nlast escaping:" + remaining.substring(start + 1)); 253 return false; 254 } 255 stop = start + stop + 1; 257 258 if (stop == remaining.length()) { 260 return true; 261 } 262 263 remaining = remaining.substring(stop + 1); 265 } else { 266 if (remaining.indexOf(';') != -1) { 267 log.warn("found a ';' inside our constrain:" + constraints); 268 return false; 269 } 270 return true; 271 } 272 } 273 return true; 274 } 275 276 277 278 private SearchQuery query = null; 279 private List steps = null; 280 281 297 static Object parseValue(Iterator iTokens, StepField field) throws NumberFormatException { 299 Object result = null; 300 String token = (String ) iTokens.next(); 301 if (token.equals("'")) { 302 result = (String ) iTokens.next(); 304 token = (String ) iTokens.next(); 305 if (!token.equals("'")) { 306 throw new IllegalArgumentException ("Unexpected token (expected \"'\"): \"" + token + "\""); 307 } 308 309 int fieldType = field.getType(); 310 if (fieldType == Field.TYPE_BINARY || fieldType == Field.TYPE_DOUBLE || 311 fieldType == Field.TYPE_FLOAT || fieldType == Field.TYPE_INTEGER || 312 fieldType == Field.TYPE_LONG || fieldType == Field.TYPE_NODE) { 313 result = new Double ((String ) result); 315 } 316 } else { 317 result = new Double (token); 318 } 319 return result; 320 } 321 322 331 static List tokenize(String sqlConstraint) { 333 List tokens = new ArrayList(); 335 StringTokenizer st = new StringTokenizer(sqlConstraint, " ()'\"=<>!,", true); 336 tokenize: 337 while (st.hasMoreTokens()) { 338 String token = st.nextToken(" ()'\"=<>!,"); 339 340 if (token.equals("'") || token.equals("\"")) { 342 tokens.add("'"); 343 StringBuffer sb = new StringBuffer (); 344 while (true) { 345 String token2 = st.nextToken(token); 346 if (token2.equals(token)) { 347 if (!st.hasMoreTokens()) { 348 tokens.add(sb.toString()); 350 tokens.add("'"); 351 break tokenize; 352 } else { 353 String token3 = st.nextToken(" ()'\"=<>!,"); 354 if (token3.equals(token)) { 355 sb.append(token); 357 } else { 358 tokens.add(sb.toString()); 360 tokens.add("'"); 361 token = token3; 362 break; 363 } 364 } 365 } else { 366 sb.append(token2); 368 } 369 } 370 } 371 372 if (!token.equals(" ")) { 374 tokens.add(token); 375 } 376 } 377 return tokens; 378 } 379 380 396 397 public static StepField getField(String token, List steps) { 398 return getField(token, steps, null); 399 } 400 418 419 static StepField getField(String token, List steps, SearchQuery query) { 420 BasicStep step = null; 421 int bracketOffset = (token.startsWith("[") && token.endsWith("]")) ? 1 : 0; 422 int idx = token.indexOf('.'); 423 if (idx == -1) { 424 if (steps.size() > 1) { 425 if (query != null && query instanceof NodeQuery) { 426 step = (BasicStep) ((NodeQuery) query).getNodeStep(); 427 if (step == null) { 428 throw new IllegalArgumentException ( "NodeQuery has no step; Fieldname not prefixed with table alias: \"" + token + "\""); 429 } 430 } else { 431 throw new IllegalArgumentException ( "Fieldname not prefixed with table alias: \"" + token + "\""); 432 } 433 } else { 434 step = (BasicStep) steps.get(0); 435 } 436 } else { 437 step = getStep(token.substring(bracketOffset, idx), steps); 438 } 439 MMObjectBuilder builder = step.getBuilder(); 440 String fieldName; 441 if (idx == -1) { 442 fieldName = token.substring(bracketOffset, token.length() - bracketOffset); 443 } else { 444 fieldName = token.substring(idx + 1, token.length() - bracketOffset); 445 } 446 447 CoreField coreField = builder.getField(fieldName); 448 if (coreField == null) { 451 String escapedFieldName = MMBase.getMMBase().getStorageManagerFactory().getStorageIdentifier(fieldName).toString(); 452 if (! escapedFieldName.equals(fieldName)) { 453 coreField = builder.getField(fieldName); 454 if (coreField == null) { 455 throw new IllegalArgumentException ("Unknown field (of builder " + builder.getTableName() + "): \"" + escapedFieldName + "\""); 456 } 457 } 458 } 459 if (coreField == null) { 460 throw new IllegalArgumentException ("Unknown field (of builder " + builder.getTableName() + "): \"" + fieldName + "\""); 461 } 462 BasicStepField field = new BasicStepField(step, coreField); 463 return field; 464 } 465 466 473 private static BasicStep getStep(String alias, List steps) { 474 Iterator iSteps = steps.iterator(); 475 while (iSteps.hasNext()) { 476 BasicStep step = (BasicStep) iSteps.next(); 477 String alias2 = step.getAlias(); 478 if (alias2 == null) { 479 alias2 = step.getTableName(); 480 } 481 if (alias2.equals(alias)) { 482 return step; 483 } 484 } 485 486 throw new IllegalArgumentException ("Unknown table alias: \"" + alias + "\""); 488 } 489 490 493 public ConstraintParser(SearchQuery query) { 494 this.query = query; 495 this.steps = query.getSteps(); 496 } 497 498 508 public Constraint toConstraint(String sqlConstraint) { 509 Constraint result = null; 510 try { 511 ListIterator iTokens = tokenize(sqlConstraint).listIterator(); 512 result = parseCondition(iTokens); 513 514 } catch (Exception e) { 516 if (fallbackLog.isServiceEnabled()) { 518 fallbackLog.service( 519 "Failed to parse Constraint from search condition string: " 520 + "\n sqlConstraint = " + sqlConstraint 521 + "\n exception: " + e.getMessage() 522 + "\nFalling back to BasicLegacyConstraint...", e); 523 } 524 String escapedSqlConstraint = convertClauseToDBS(sqlConstraint); 525 if (! validConstraints(escapedSqlConstraint)) { 526 throw new IllegalArgumentException ("Invalid constraints: " + sqlConstraint); 527 } 528 result = new BasicLegacyConstraint(escapedSqlConstraint); 529 } 530 531 if (log.isDebugEnabled()) { 532 log.debug("Parsed constraint \"" + sqlConstraint + "\" to :\n" + result); 533 } 534 return result; 535 } 536 537 538 548 StepField getField(String token) { 550 return getField(token, steps, query); 551 } 552 553 564 BasicConstraint parseCondition(ListIterator iTokens) { 566 BasicCompositeConstraint composite = null; 567 BasicConstraint constraint= null; 568 while (iTokens.hasNext()) { 569 boolean inverse = false; 570 String token = (String ) iTokens.next(); 571 if (token.equalsIgnoreCase("NOT")) { 572 inverse = true; 574 token = (String ) iTokens.next(); 575 } 576 577 if (token.equals("(")) { 578 constraint = parseCondition(iTokens); 581 } else { 582 iTokens.previous(); 584 constraint = parseSimpleCondition(iTokens); 585 } 586 if (inverse) { 587 constraint.setInverse(!constraint.isInverse()); 588 } 589 if (composite != null) { 590 composite.addChild(constraint); 591 } 592 593 if (iTokens.hasNext()) { 594 token = (String ) iTokens.next(); 595 if (token.equals(")")) { 596 break; 599 } 600 int logicalOperator = 0; 601 if (token.equalsIgnoreCase("OR")) { 602 logicalOperator = CompositeConstraint.LOGICAL_OR; 603 } else if (token.equalsIgnoreCase("AND")) { 604 logicalOperator = CompositeConstraint.LOGICAL_AND; 605 } else { 606 throw new IllegalArgumentException ( 607 "Unexpected token (expected \"AND\" or \"OR\"): \"" 608 + token + "\""); 609 } 610 if (composite == null) { 611 composite = new BasicCompositeConstraint(logicalOperator). 612 addChild(constraint); 613 } 614 615 if (composite.getLogicalOperator() != logicalOperator) { 616 composite = new BasicCompositeConstraint(logicalOperator). 617 addChild(composite); 618 } 619 620 if (!iTokens.hasNext()) { 621 throw new IllegalArgumentException ("Unexpected end of tokens after \"" + token + "\""); 622 } 623 } 624 } 625 if (composite != null) { 626 return composite; 627 } else { 628 return constraint; 629 } 630 } 631 632 643 BasicConstraint parseSimpleCondition(ListIterator iTokens) { 645 BasicConstraint result = null; 646 647 String token = (String ) iTokens.next(); 648 if (token.equalsIgnoreCase("StringSearch")) { 649 return parseStringSearchCondition(iTokens); 651 } 652 653 String function = token.toUpperCase(); 654 if (function.equals("LOWER") || function.equals("UPPER")) { 655 if (iTokens.next().equals("(")) { 656 token = (String ) iTokens.next(); 658 } else { 659 iTokens.previous(); 661 function = null; 662 } 663 } else { 664 function = null; 665 } 666 667 StepField field = getField(token); 668 669 token = (String ) iTokens.next(); 670 if (function != null) { 671 if (!token.equals(")")) { 672 throw new IllegalArgumentException ( 673 "Unexpected token (expected \")\"): \"" 674 + token + "\""); 675 } 676 token = (String ) iTokens.next(); 677 } 678 679 boolean inverse = false; 680 if (token.equalsIgnoreCase("NOT")) { 681 inverse = true; 683 token = (String ) iTokens.next(); 684 if (!token.equalsIgnoreCase("LIKE") 685 && !token.equalsIgnoreCase("IN") 686 && !token.equalsIgnoreCase("BETWEEN")) { 687 throw new IllegalArgumentException ( 688 "Unexpected token (expected " 689 + "\"LIKE\" OR \"IN\" OR \"BETWEEN\"): \"" 690 + token + "\""); 691 } 692 } 693 694 if (token.equalsIgnoreCase("LIKE")) { 695 String value = (String ) parseValue(iTokens, field); 697 boolean caseSensitive = true; 698 if (function != null) { 699 if ((function.equals("LOWER") 700 && value.equals(value.toLowerCase())) 701 || (function.equals("UPPER") 702 && value.equals(value.toUpperCase()))) { 703 caseSensitive = false; 704 } 705 } 706 result = new BasicFieldValueConstraint(field, value) 707 .setOperator(FieldCompareConstraint.LIKE) 708 .setCaseSensitive(caseSensitive); 709 710 } else if (token.equalsIgnoreCase("IS")) { 711 token = (String ) iTokens.next(); 713 if (token.equalsIgnoreCase("NOT")) { 714 inverse = !inverse; 715 token = (String ) iTokens.next(); 716 } 717 if (token.equalsIgnoreCase("NULL")) { 718 result = new BasicFieldNullConstraint(field); 719 } else { 720 throw new IllegalArgumentException ( 721 "Unexpected token (expected \"NULL\"): \"" 722 + token + "\""); 723 } 724 } else if (token.equalsIgnoreCase("IN")) { 725 String separator = (String ) iTokens.next(); 727 if (!separator.equals("(")) { 728 throw new IllegalArgumentException ( 729 "Unexpected token (expected \"(\"): \"" 730 + separator + "\""); 731 } 732 BasicFieldValueInConstraint fieldValueInConstraint 733 = new BasicFieldValueInConstraint(field); 734 if (!iTokens.next().equals(")")) { 735 736 iTokens.previous(); 737 do { 738 Object value = parseValue(iTokens, field); 739 separator = (String ) iTokens.next(); 740 if (separator.equals(",") || separator.equals(")")) { 741 fieldValueInConstraint.addValue(value); 742 } else { 743 throw new IllegalArgumentException ( 744 "Unexpected token (expected \",\" or \")\"): \"" 745 + separator + "\""); 746 } 747 } while (separator.equals(",")); 748 } 749 result = fieldValueInConstraint; 750 751 } else if (token.equalsIgnoreCase("BETWEEN")) { 752 Object value1 = parseValue(iTokens, field); 754 String separator = (String ) iTokens.next(); 755 if (!separator.equals("AND")) { 756 throw new IllegalArgumentException ( 757 "Unexpected token (expected \"AND\"): \"" 758 + separator + "\""); 759 } 760 Object value2 = parseValue(iTokens, field); 761 boolean caseSensitive = true; 762 if (function != null 763 && value1 instanceof String && value2 instanceof String ) { 764 String strValue1 = (String ) value1; 765 String strValue2 = (String ) value2; 766 if ((function.equals("LOWER") 767 && strValue1.equals(strValue1.toLowerCase()) 768 && strValue2.equals(strValue2.toLowerCase())) 769 || (function.equals("UPPER") 770 && strValue1.equals(strValue1.toUpperCase()) 771 && strValue2.equals(strValue2.toUpperCase()))) { 772 caseSensitive = false; 773 } 774 } 775 776 BasicFieldValueBetweenConstraint fieldValueBetweenConstraint 777 = (BasicFieldValueBetweenConstraint) 778 new BasicFieldValueBetweenConstraint(field, value1, value2) 779 .setCaseSensitive(caseSensitive); 780 result = fieldValueBetweenConstraint; 781 782 } else if (token.equals("=")) { 783 token = (String ) iTokens.next(); 784 if (token.equals("=")) { 785 try { 786 Object value = parseValue(iTokens, field); 788 result = new BasicFieldValueConstraint(field, value) 789 .setOperator(FieldCompareConstraint.EQUAL); 790 } catch (NumberFormatException e) { 791 iTokens.previous(); 793 token = (String ) iTokens.next(); 794 StepField field2 = getField(token); 795 result = new BasicCompareFieldsConstraint(field, field2) 796 .setOperator(FieldCompareConstraint.EQUAL); 797 } 798 } else { 799 iTokens.previous(); 800 try { 801 Object value = parseValue(iTokens, field); 803 boolean caseSensitive = true; 804 if (function != null && value instanceof String ) { 805 String strValue = (String ) value; 806 if ((function.equals("LOWER") 807 && strValue.equals(strValue.toLowerCase())) 808 || (function.equals("UPPER") 809 && strValue.equals(strValue.toUpperCase()))) { 810 caseSensitive = false; 811 } 812 } 813 result = new BasicFieldValueConstraint(field, value) 814 .setOperator(FieldCompareConstraint.EQUAL) 815 .setCaseSensitive(caseSensitive); 816 } catch (NumberFormatException e) { 817 iTokens.previous(); 819 token = (String ) iTokens.next(); 820 StepField field2 = getField(token); 821 result = new BasicCompareFieldsConstraint(field, field2) 822 .setOperator(FieldCompareConstraint.EQUAL); 823 } 824 } 825 } else if (token.equals("<")) { 826 token = (String ) iTokens.next(); 827 if (token.equals("=")) { 828 try { 829 Object value = parseValue(iTokens, field); 831 result = new BasicFieldValueConstraint(field, value) 832 .setOperator(FieldCompareConstraint.LESS_EQUAL); 833 } catch (NumberFormatException e) { 834 iTokens.previous(); 836 token = (String ) iTokens.next(); 837 StepField field2 = getField(token); 838 result = new BasicCompareFieldsConstraint(field, field2) 839 .setOperator(FieldCompareConstraint.LESS_EQUAL); 840 } 841 } else if (token.equals(">")) { 842 try { 843 Object value = parseValue(iTokens, field); 845 result = new BasicFieldValueConstraint(field, value) 846 .setOperator(FieldCompareConstraint.NOT_EQUAL); 847 } catch (NumberFormatException e) { 848 iTokens.previous(); 850 token = (String ) iTokens.next(); 851 StepField field2 = getField(token); 852 result = new BasicCompareFieldsConstraint(field, field2) 853 .setOperator(FieldCompareConstraint.NOT_EQUAL); 854 } 855 } else { 856 try { 857 iTokens.previous(); 859 Object value = parseValue(iTokens, field); 860 result = new BasicFieldValueConstraint(field, value) 861 .setOperator(FieldCompareConstraint.LESS); 862 } catch (NumberFormatException e) { 863 iTokens.previous(); 865 token = (String ) iTokens.next(); 866 StepField field2 = getField(token); 867 result = new BasicCompareFieldsConstraint(field, field2) 868 .setOperator(FieldCompareConstraint.LESS); 869 } 870 } 871 } else if (token.equals(">")) { 872 token = (String ) iTokens.next(); 873 if (token.equals("=")) { 874 try { 875 Object value = parseValue(iTokens, field); 877 result = new BasicFieldValueConstraint(field, value) 878 .setOperator(FieldCompareConstraint.GREATER_EQUAL); 879 } catch (NumberFormatException e) { 880 iTokens.previous(); 882 token = (String ) iTokens.next(); 883 StepField field2 = getField(token); 884 result = new BasicCompareFieldsConstraint(field, field2) 885 .setOperator(FieldCompareConstraint.GREATER_EQUAL); 886 } 887 } else { 888 try { 889 iTokens.previous(); 891 Object value = parseValue(iTokens, field); 892 result = new BasicFieldValueConstraint(field, value) 893 .setOperator(FieldCompareConstraint.GREATER); 894 } catch (NumberFormatException e) { 895 iTokens.previous(); 897 token = (String ) iTokens.next(); 898 StepField field2 = getField(token); 899 result = new BasicCompareFieldsConstraint(field, field2) 900 .setOperator(FieldCompareConstraint.GREATER); 901 } 902 } 903 } else if (token.equals("!")) { 904 token = (String ) iTokens.next(); 905 if (token.equals("=")) { 906 try { 907 Object value = parseValue(iTokens, field); 909 result = new BasicFieldValueConstraint(field, value) 910 .setOperator(FieldCompareConstraint.NOT_EQUAL); 911 } catch (NumberFormatException e) { 912 iTokens.previous(); 914 token = (String ) iTokens.next(); 915 StepField field2 = getField(token); 916 result = new BasicCompareFieldsConstraint(field, field2) 917 .setOperator(FieldCompareConstraint.NOT_EQUAL); 918 } 919 } else { 920 throw new IllegalArgumentException ("Unexpected token (expected \"=\"): \"" + token + "\""); 921 } 922 } else { 923 throw new IllegalArgumentException ("Unexpected token: \"" + token + "\""); 924 } 925 926 if (inverse) { 927 result.setInverse(!result.isInverse()); 928 } 929 930 return result; 931 } 932 933 944 private BasicStringSearchConstraint parseStringSearchCondition( 945 ListIterator iTokens) { 946 947 String token = (String ) iTokens.next(); 948 if (!token.equals("(")) { 949 throw new IllegalArgumentException ("Unexpected token (expected \"(\"): \"" + token + "\""); 950 } 951 952 token = (String ) iTokens.next(); 954 StepField field = getField(token); 955 956 token = (String ) iTokens.next(); 957 if (!token.equals(",")) { 958 throw new IllegalArgumentException ("Unexpected token (expected \",\"): \"" + token + "\""); 959 } 960 961 int searchType; 963 token = (String ) iTokens.next(); 964 if (token.equalsIgnoreCase("PHRASE")) { 965 searchType = StringSearchConstraint.SEARCH_TYPE_PHRASE_ORIENTED; 966 } else if (token.equalsIgnoreCase("PROXIMITY")) { 967 searchType = StringSearchConstraint.SEARCH_TYPE_PROXIMITY_ORIENTED; 968 } else if (token.equalsIgnoreCase("WORD")) { 969 searchType = StringSearchConstraint.SEARCH_TYPE_WORD_ORIENTED; 970 } else { 971 throw new IllegalArgumentException ("Invalid searchtype (expected \"PHRASE\", \"PROXIMITY\" or \"WORD\": \"" + token + "\""); 972 } 973 974 token = (String ) iTokens.next(); 975 if (!token.equals(",")) { 976 throw new IllegalArgumentException ( 977 "Unexpected token (expected \",\"): \"" 978 + token + "\""); 979 } 980 981 int matchType; 983 token = (String ) iTokens.next(); 984 if (token.equalsIgnoreCase("FUZZY")) { 985 matchType = StringSearchConstraint.MATCH_TYPE_FUZZY; 986 } else if (token.equalsIgnoreCase("LITERAL")) { 987 matchType = StringSearchConstraint.MATCH_TYPE_LITERAL; 988 } else if (token.equalsIgnoreCase("SYNONYM")) { 989 matchType = StringSearchConstraint.MATCH_TYPE_SYNONYM; 990 } else { 991 throw new IllegalArgumentException ("Invalid matchtype (expected \"FUZZY\", \"LITERAL\" or \"SYNONYM\": \"" + token + "\""); 992 } 993 994 token = (String ) iTokens.next(); 995 if (!token.equals(",")) { 996 throw new IllegalArgumentException ("Unexpected token (expected \",\"): \"" + token + "\""); 997 } 998 999 String searchTerms; 1001 token = (String ) iTokens.next(); 1002 if (!token.equals("'")) { 1003 throw new IllegalArgumentException ("Unexpected token (expected \"'\" or \"\"\"): \"" + token + "\""); 1004 } 1005 searchTerms = (String ) iTokens.next(); 1006 token = (String ) iTokens.next(); 1007 if (!token.equals("'")) { 1008 throw new IllegalArgumentException ("Unexpected token (expected \"'\" or \"\"\"): \"" + token + "\""); 1009 } 1010 1011 token = (String ) iTokens.next(); 1012 if (!token.equals(",")) { 1013 throw new IllegalArgumentException ("Unexpected token (expected \",\"): \"" + token + "\""); 1014 } 1015 1016 boolean caseSensitive; 1018 token = (String ) iTokens.next(); 1019 if (token.equalsIgnoreCase("true")) { 1020 caseSensitive = true; 1021 } else if (token.equalsIgnoreCase("false")) { 1022 caseSensitive = false; 1023 } else { 1024 throw new IllegalArgumentException ("Invalid caseSensitive value (expected \"true\" " + "or \"false\": \"" + token + "\""); 1025 } 1026 1027 token = (String ) iTokens.next(); 1028 if (!token.equals(")")) { 1029 throw new IllegalArgumentException ("Unexpected token (expected \")\"): \"" + token + "\""); 1030 } 1031 1032 BasicStringSearchConstraint result = (BasicStringSearchConstraint) 1033 new BasicStringSearchConstraint( 1034 field, searchType, matchType, searchTerms) 1035 .setCaseSensitive(caseSensitive); 1036 1037 while (iTokens.hasNext()) { 1039 token = (String ) iTokens.next(); 1040 if (!token.equalsIgnoreCase(".set")) { 1041 iTokens.previous(); 1042 break; 1043 } 1044 1045 token = (String ) iTokens.next(); 1046 if (!token.equals("(")) { 1047 throw new IllegalArgumentException ("Unexpected token (expected \"(\"): \"" + token + "\""); 1048 } 1049 1050 String parameterName = (String ) iTokens.next(); 1051 1052 token = (String ) iTokens.next(); 1053 if (!token.equals(",")) { 1054 throw new IllegalArgumentException ("Unexpected token (expected \",\"): \"" + token + "\""); 1055 } 1056 1057 String parameterValue = (String ) iTokens.next(); 1058 1059 token = (String ) iTokens.next(); 1060 if (!token.equals(")")) { 1061 throw new IllegalArgumentException ("Unexpected token (expected \")\"): \"" + token + "\""); 1062 } 1063 1064 if (parameterName.equalsIgnoreCase("FUZZINESS")) { 1065 result.setParameter(StringSearchConstraint.PARAM_FUZZINESS, 1066 new Float (parameterValue)); 1067 } else if (parameterName.equalsIgnoreCase("PROXIMITY_LIMIT")) { 1068 result.setParameter( 1069 StringSearchConstraint.PARAM_PROXIMITY_LIMIT, 1070 new Integer (parameterValue)); 1071 } else { 1072 throw new IllegalArgumentException ("Invalid parameter name (expected \"FUZZINESS\" or \"PROXIMITY\": \"" + parameterName + "\""); 1073 } 1074 } 1075 1076 return result; 1077 } 1078} 1079 | Popular Tags |