1 package org.mmbase.storage.search.legacy; 2 3 import junit.framework.*; 4 import java.util.*; 5 import org.mmbase.module.core.*; 6 import org.mmbase.module.corebuilders.*; 7 import org.mmbase.storage.search.*; 8 import org.mmbase.storage.search.implementation.*; 9 10 16 public class ConstraintParserTest extends TestCase { 17 18 19 private ConstraintParser instance = null; 20 21 22 private BasicSearchQuery query = null; 23 24 private MMBase mmbase = null; 25 private MMObjectBuilder images = null; 26 private InsRel insrel = null; 27 private MMObjectBuilder news = null; 28 29 public ConstraintParserTest(java.lang.String testName) { 30 super(testName); 31 } 32 33 public static void main(java.lang.String [] args) { 34 junit.textui.TestRunner.run(suite()); 35 System.exit(0); 36 } 37 38 41 public void setUp() throws Exception { 42 MMBaseContext.init(); 43 mmbase = MMBase.getMMBase(); 44 images = mmbase.getBuilder("images"); 45 insrel = mmbase.getInsRel(); 46 news = mmbase.getBuilder("news"); 47 48 query = new BasicSearchQuery(); 49 instance = new ConstraintParser(query); 50 } 51 52 55 public void tearDown() throws Exception {} 56 57 58 public void testParseValue() { 59 query.addStep(news); 60 StepField numericalField = instance.getField("number"); 61 StepField stringField = instance.getField("title"); 62 Iterator iTokens = Arrays.asList(new String [] { 63 "12345.6", 64 "NotANumber", 65 "'", "12345.6", "'", 66 "'", "NotANumber", "'", 67 "'", "value1", "'", 68 "-10", 69 "'", "value2", "'", 70 "'", "value3", "123"}).iterator(); 71 Object value = ConstraintParser.parseValue(iTokens, numericalField); 72 assertTrue(value.toString(), value.equals(new Double ("12345.6"))); 73 try { 74 value = ConstraintParser.parseValue(iTokens, numericalField); 76 fail("Invalid value for numerical field, must throw NumberFormatException."); 77 } catch (NumberFormatException e) {} 78 value = ConstraintParser.parseValue(iTokens, numericalField); 79 assertTrue(value.toString(), value.equals(new Double ("12345.6"))); 80 try { 81 value = ConstraintParser.parseValue(iTokens, numericalField); 83 fail("Invalid value for numerical field, must throw NumberFormatException."); 84 } catch (NumberFormatException e) {} 85 value = ConstraintParser.parseValue(iTokens, stringField); 86 assertTrue(value.toString(), value.equals("value1")); 87 value = ConstraintParser.parseValue(iTokens, numericalField); 88 assertTrue(value.toString(), value.equals(new Double ("-10"))); 89 value = ConstraintParser.parseValue(iTokens, stringField); 90 assertTrue(value.toString(), value.equals("value2")); 91 try { 92 ConstraintParser.parseValue(iTokens, stringField); 94 fail("Missing end delimiter, must throw IllegalArgumentException."); 95 } catch (IllegalArgumentException e) {} 96 } 97 98 99 public void testTokenize() { 100 List tokens = ConstraintParser.tokenize("qwe '' and '123''456' or \"\"\"789\""); 101 assertTrue(tokens.toString(), tokens.equals( 102 Arrays.asList(new String [] { 103 "qwe", "'", "", "'", "and", "'", "123'456", "'", "or", "'", 104 "\"789", "'"}))); 105 106 tokens = ConstraintParser.tokenize("'''' and \"\"\"\" and '\"\"' and \"''\""); 107 assertTrue(tokens.toString(), tokens.equals( 108 Arrays.asList(new String [] { 109 "'", "'", "'", "and", "'", "\"", "'", "and", "'", "\"\"", "'", 110 "and", "'", "''", "'"}))); 111 } 112 113 114 115 public void testGetField() { 116 Step step1 = query.addStep(images).setAlias("step1"); 117 StepField field = instance.getField("number"); 118 assertTrue(field.toString(), field.getStep() == step1); 119 assertTrue(field.toString(), field.getFieldName().equals("number")); 120 assertTrue(field.toString(), field.getAlias() == null); 121 122 field = instance.getField("step1.number"); 123 assertTrue(field.toString(), field.getStep() == step1); 124 assertTrue(field.toString(), field.getFieldName().equals("number")); 125 assertTrue(field.toString(), field.getAlias() == null); 126 127 try { 128 instance.getField("step1.abcdef"); 130 fail("Field does not exist, should throw IllegalArgumentException."); 131 } catch (IllegalArgumentException e) {} 132 133 RelationStep step2 = query.addRelationStep(insrel, news); 134 Step step3 = step2.getNext(); 135 try { 136 instance.getField("number"); 138 fail("Field not prefixed, should throw IllegalArgumentException."); 139 } catch (IllegalArgumentException e) {} 140 141 field = instance.getField("step1.title"); 142 assertTrue(field.toString(), field.getStep() == step1); 143 assertTrue(field.toString(), field.getFieldName().equals("title")); 144 assertTrue(field.toString(), field.getAlias() == null); 145 146 field = instance.getField("news.title"); 147 assertTrue(field.toString(), field.getStep() == step3); 148 assertTrue(field.toString(), field.getFieldName().equals("title")); 149 assertTrue(field.toString(), field.getAlias() == null); 150 } 151 152 153 public void testGetField2() { 154 List steps = query.getSteps(); 155 Step step1 = query.addStep(images).setAlias("step1"); 156 StepField field = ConstraintParser.getField("number", steps); 157 assertTrue(field.toString(), field.getStep() == step1); 158 assertTrue(field.toString(), field.getFieldName().equals("number")); 159 assertTrue(field.toString(), field.getAlias() == null); 160 161 field = ConstraintParser.getField("step1.number", steps); 162 assertTrue(field.toString(), field.getStep() == step1); 163 assertTrue(field.toString(), field.getFieldName().equals("number")); 164 assertTrue(field.toString(), field.getAlias() == null); 165 166 try { 167 ConstraintParser.getField("step1.abcdef", steps); 169 fail("Field does not exist, should throw IllegalArgumentException."); 170 } catch (IllegalArgumentException e) {} 171 172 RelationStep step2 = query.addRelationStep(insrel, news); 173 Step step3 = step2.getNext(); 174 try { 175 ConstraintParser.getField("number", steps); 177 fail("Field not prefixed, should throw IllegalArgumentException."); 178 } catch (IllegalArgumentException e) {} 179 180 field = ConstraintParser.getField("step1.title", steps); 181 assertTrue(field.toString(), field.getStep() == step1); 182 assertTrue(field.toString(), field.getFieldName().equals("title")); 183 assertTrue(field.toString(), field.getAlias() == null); 184 185 field = ConstraintParser.getField("news.title", steps); 186 assertTrue(field.toString(), field.getStep() == step3); 187 assertTrue(field.toString(), field.getFieldName().equals("title")); 188 assertTrue(field.toString(), field.getAlias() == null); 189 } 190 191 192 public void testParseSimpleCondition() { 193 query.addStep(images).setAlias("step1"); 194 RelationStep step2 = query.addRelationStep(insrel, news); 195 step2.getNext(); 196 StepField field1 = instance.getField("step1.title"); 197 StepField field2 = instance.getField("step1.description"); 198 StepField field3 = instance.getField("step1.number"); 199 200 BasicFieldValueConstraint constraint1 202 = (BasicFieldValueConstraint) 203 new BasicFieldValueConstraint(field1, "%abc def%") 204 .setOperator(FieldCompareConstraint.LIKE); 205 Constraint constraint = instance.parseSimpleCondition( 206 ConstraintParser.tokenize("step1.title like '%abc def%'").listIterator()); 207 assertTrue(constraint.toString(), constraint.equals(constraint1)); 208 209 constraint1.setCaseSensitive(false); 211 constraint = instance.parseSimpleCondition( 212 ConstraintParser.tokenize("lower(step1.title) like '%abc def%'").listIterator()); 213 assertTrue(constraint.toString(), constraint.equals(constraint1)); 214 215 constraint1.setValue("%ABC DEF%").setCaseSensitive(true); 217 constraint = instance.parseSimpleCondition( 218 ConstraintParser.tokenize("lower(step1.title) like '%ABC DEF%'").listIterator()); 219 assertTrue(constraint.toString(), constraint.equals(constraint1)); 220 221 constraint1.setCaseSensitive(false); 223 constraint = instance.parseSimpleCondition( 224 ConstraintParser.tokenize("UPPER(step1.title) like '%ABC DEF%'").listIterator()); 225 assertTrue(constraint.toString(), constraint.equals(constraint1)); 226 227 constraint1.setValue("%abc def%").setCaseSensitive(true); 229 constraint = instance.parseSimpleCondition( 230 ConstraintParser.tokenize("UPPER(step1.title) like '%abc def%'").listIterator()); 231 assertTrue(constraint.toString(), constraint.equals(constraint1)); 232 233 try { 234 instance.parseSimpleCondition( 237 ConstraintParser.tokenize("step1.number like '%abc def%'") 238 .listIterator()); 239 fail("LIKE applied to numerical field, should throw " 240 + "IllegalArgumentException."); 241 } catch (IllegalArgumentException e) {} 242 243 constraint1.setInverse(true); 245 constraint = instance.parseSimpleCondition( 246 ConstraintParser.tokenize("step1.title not like '%abc def%'") 247 .listIterator()); 248 assertTrue(constraint.toString(), constraint.equals(constraint1)); 249 250 BasicFieldNullConstraint constraint2 252 = new BasicFieldNullConstraint(field1); 253 constraint = instance.parseSimpleCondition( 254 ConstraintParser.tokenize("step1.title is null").listIterator()); 255 assertTrue(constraint.toString(), constraint.equals(constraint2)); 256 257 constraint2.setInverse(true); 259 constraint = instance.parseSimpleCondition( 260 ConstraintParser.tokenize("step1.title is not null").listIterator()); 261 assertTrue(constraint.toString(), constraint.equals(constraint2)); 262 263 BasicFieldValueConstraint constraint3 265 = (BasicFieldValueConstraint) 266 new BasicFieldValueConstraint(field1, "abc def") 267 .setOperator(FieldCompareConstraint.EQUAL); 268 constraint = instance.parseSimpleCondition( 269 ConstraintParser.tokenize("step1.title = 'abc def'").listIterator()); 270 assertTrue(constraint.toString(), constraint.equals(constraint3)); 271 272 constraint = instance.parseSimpleCondition( 274 ConstraintParser.tokenize("step1.title == 'abc def'").listIterator()); 275 assertTrue(constraint.toString(), constraint.equals(constraint3)); 276 277 constraint3.setCaseSensitive(false); 279 constraint = instance.parseSimpleCondition( 280 ConstraintParser.tokenize("LOWER(step1.title) = 'abc def'").listIterator()); 281 assertTrue(constraint.toString(), constraint.equals(constraint3)); 282 283 constraint3.setValue("ABC DEF").setCaseSensitive(true); 285 constraint = instance.parseSimpleCondition( 286 ConstraintParser.tokenize("LOWER(step1.title) = 'ABC DEF'").listIterator()); 287 assertTrue(constraint.toString(), constraint.equals(constraint3)); 288 289 constraint3.setCaseSensitive(false); 291 constraint = instance.parseSimpleCondition( 292 ConstraintParser.tokenize("upper(step1.title) = 'ABC DEF'").listIterator()); 293 assertTrue(constraint.toString(), constraint.equals(constraint3)); 294 295 constraint3.setValue("abc def").setCaseSensitive(true); 297 constraint = instance.parseSimpleCondition( 298 ConstraintParser.tokenize("upper(step1.title) = 'abc def'").listIterator()); 299 assertTrue(constraint.toString(), constraint.equals(constraint3)); 300 301 BasicCompareFieldsConstraint constraint3a 303 = (BasicCompareFieldsConstraint) 304 new BasicCompareFieldsConstraint(field1, field2) 305 .setOperator(FieldCompareConstraint.EQUAL); 306 constraint = instance.parseSimpleCondition( 307 ConstraintParser.tokenize("step1.title = step1.description").listIterator()); 308 assertTrue(constraint.toString(), constraint.equals(constraint3a)); 309 310 constraint = instance.parseSimpleCondition( 312 ConstraintParser.tokenize("step1.title == step1.description").listIterator()); 313 assertTrue(constraint.toString(), constraint.equals(constraint3a)); 314 315 BasicFieldValueConstraint constraint4 317 = (BasicFieldValueConstraint) 318 new BasicFieldValueConstraint(field1, "abc def") 319 .setOperator(FieldCompareConstraint.NOT_EQUAL); 320 constraint = instance.parseSimpleCondition( 321 ConstraintParser.tokenize("step1.title != 'abc def'").listIterator()); 322 assertTrue(constraint.toString(), constraint.equals(constraint4)); 323 324 constraint = instance.parseSimpleCondition( 326 ConstraintParser.tokenize("step1.title <> 'abc def'").listIterator()); 327 assertTrue(constraint.toString(), constraint.equals(constraint4)); 328 329 BasicCompareFieldsConstraint constraint4a 331 = (BasicCompareFieldsConstraint) 332 new BasicCompareFieldsConstraint(field1, field2) 333 .setOperator(FieldCompareConstraint.NOT_EQUAL); 334 constraint = instance.parseSimpleCondition( 335 ConstraintParser.tokenize("step1.title != step1.description").listIterator()); 336 assertTrue(constraint.toString(), constraint.equals(constraint4a)); 337 338 constraint = instance.parseSimpleCondition( 340 ConstraintParser.tokenize("step1.title <> step1.description").listIterator()); 341 assertTrue(constraint.toString(), constraint.equals(constraint4a)); 342 343 BasicFieldValueConstraint constraint5 345 = (BasicFieldValueConstraint) 346 new BasicFieldValueConstraint(field1, "abc def") 347 .setOperator(FieldCompareConstraint.GREATER); 348 constraint = instance.parseSimpleCondition( 349 ConstraintParser.tokenize("step1.title>'abc def'").listIterator()); 350 assertTrue(constraint.toString(), constraint.equals(constraint5)); 351 352 BasicCompareFieldsConstraint constraint5a 354 = (BasicCompareFieldsConstraint) 355 new BasicCompareFieldsConstraint(field1, field2) 356 .setOperator(FieldCompareConstraint.GREATER); 357 constraint = instance.parseSimpleCondition( 358 ConstraintParser.tokenize("step1.title>step1.description").listIterator()); 359 assertTrue(constraint.toString(), constraint.equals(constraint5a)); 360 361 BasicFieldValueConstraint constraint6 363 = (BasicFieldValueConstraint) 364 new BasicFieldValueConstraint(field1, "abc def") 365 .setOperator(FieldCompareConstraint.GREATER_EQUAL); 366 constraint = instance.parseSimpleCondition( 367 ConstraintParser.tokenize("step1.title>='abc def'").listIterator()); 368 assertTrue(constraint.toString(), constraint.equals(constraint6)); 369 370 BasicCompareFieldsConstraint constraint6a 372 = (BasicCompareFieldsConstraint) 373 new BasicCompareFieldsConstraint(field1, field2) 374 .setOperator(FieldCompareConstraint.GREATER_EQUAL); 375 constraint = instance.parseSimpleCondition( 376 ConstraintParser.tokenize("step1.title>=step1.description").listIterator()); 377 assertTrue(constraint.toString(), constraint.equals(constraint6a)); 378 379 BasicFieldValueConstraint constraint7 381 = (BasicFieldValueConstraint) 382 new BasicFieldValueConstraint(field1, "abc def") 383 .setOperator(FieldCompareConstraint.LESS); 384 constraint = instance.parseSimpleCondition( 385 ConstraintParser.tokenize("step1.title<'abc def'").listIterator()); 386 assertTrue(constraint.toString(), constraint.equals(constraint7)); 387 388 BasicCompareFieldsConstraint constraint7a 390 = (BasicCompareFieldsConstraint) 391 new BasicCompareFieldsConstraint(field1, field2) 392 .setOperator(FieldCompareConstraint.LESS); 393 constraint = instance.parseSimpleCondition( 394 ConstraintParser.tokenize("step1.title<step1.description").listIterator()); 395 assertTrue(constraint.toString(), constraint.equals(constraint7a)); 396 397 BasicFieldValueConstraint constraint8 399 = (BasicFieldValueConstraint) 400 new BasicFieldValueConstraint(field1, "abc def") 401 .setOperator(FieldCompareConstraint.LESS_EQUAL); 402 constraint = instance.parseSimpleCondition( 403 ConstraintParser.tokenize("step1.title<='abc def'").listIterator()); 404 assertTrue(constraint.toString(), constraint.equals(constraint8)); 405 406 BasicCompareFieldsConstraint constraint8a 408 = (BasicCompareFieldsConstraint) 409 new BasicCompareFieldsConstraint(field1, field2) 410 .setOperator(FieldCompareConstraint.LESS_EQUAL); 411 constraint = instance.parseSimpleCondition( 412 ConstraintParser.tokenize("step1.title<=step1.description").listIterator()); 413 assertTrue(constraint.toString(), constraint.equals(constraint8a)); 414 415 BasicFieldValueConstraint constraint8b 418 = (BasicFieldValueConstraint) 419 new BasicFieldValueConstraint(field3, new Double ("123")) 420 .setOperator(FieldCompareConstraint.LESS_EQUAL); 421 constraint = instance.parseSimpleCondition( 422 ConstraintParser.tokenize("step1.number<='123'").listIterator()); 423 assertTrue(constraint.toString(), constraint.equals(constraint8b)); 424 425 try { 426 instance.parseSimpleCondition( 429 ConstraintParser.tokenize("step1.number<='abc def'").listIterator()); 430 fail("Comparing numerical field with string, should throw " 431 + "IllegalArgumentException."); 432 } catch (IllegalArgumentException e) {} 433 434 try { 435 instance.parseSimpleCondition( 438 ConstraintParser.tokenize("step1.title<=123").listIterator()); 439 fail("Comparing string field with number, should throw " 440 + "IllegalArgumentException"); 441 } catch (IllegalArgumentException e) {} 442 443 BasicFieldValueInConstraint constraint9 445 = new BasicFieldValueInConstraint(field1); 446 constraint = instance.parseSimpleCondition( 447 ConstraintParser.tokenize("step1.title IN ()").listIterator()); 448 assertTrue(constraint.toString(), constraint.equals(constraint9)); 449 450 constraint9.addValue("abc def"); 452 constraint = instance.parseSimpleCondition( 453 ConstraintParser.tokenize("step1.title IN ('abc def')").listIterator()); 454 assertTrue(constraint.toString(), constraint.equals(constraint9)); 455 456 constraint9.addValue("hijk lm"); 458 constraint = instance.parseSimpleCondition( 459 ConstraintParser.tokenize("step1.title IN ('abc def', \"hijk lm\")") 460 .listIterator()); 461 assertTrue(constraint.toString(), constraint.equals(constraint9)); 462 463 constraint9.setInverse(true); 465 constraint = instance.parseSimpleCondition( 466 ConstraintParser.tokenize("step1.title NOT IN ('abc def', \"hijk lm\")") 467 .listIterator()); 468 assertTrue(constraint.toString(), constraint.equals(constraint9)); 469 } 470 471 472 public void testParseCondition() { 473 query.addStep(images).setAlias("step1"); 474 RelationStep step2 = query.addRelationStep(insrel, news); 475 step2.getNext(); 476 StepField field1 = instance.getField("step1.title"); 477 StepField field2 = instance.getField("news.number"); 478 479 Constraint constraint = instance.parseCondition( 481 ConstraintParser.tokenize("").listIterator()); 482 assertTrue(constraint == null); 483 484 BasicFieldValueConstraint constraint1 = 486 new BasicFieldValueConstraint(field1, "abc def"); 487 constraint = instance.parseCondition( 488 ConstraintParser.tokenize("step1.title = 'abc def'").listIterator()); 489 assertTrue(constraint.toString(), constraint.equals(constraint1)); 490 491 constraint1.setInverse(true); 493 constraint = instance.parseCondition( 494 ConstraintParser.tokenize("NOT step1.title = 'abc def'").listIterator()); 495 assertTrue(constraint.toString(), constraint.equals(constraint1)); 496 497 constraint = instance.parseCondition( 499 ConstraintParser.tokenize("NOT (step1.title = 'abc def')").listIterator()); 500 assertTrue(constraint.toString(), constraint.equals(constraint1)); 501 502 constraint1.setInverse(false); 504 constraint = instance.parseCondition( 505 ConstraintParser.tokenize("(step1.title = 'abc def')").listIterator()); 506 assertTrue(constraint.toString(), constraint.equals(constraint1)); 507 508 BasicFieldCompareConstraint constraint2 510 = new BasicFieldValueConstraint(field2, new Integer (123)) 511 .setOperator(FieldCompareConstraint.GREATER); 512 BasicCompositeConstraint constraint3 513 = new BasicCompositeConstraint(CompositeConstraint.LOGICAL_AND) 514 .addChild(constraint1) 515 .addChild(constraint2); 516 constraint = instance.parseCondition( 517 ConstraintParser.tokenize( 518 "step1.title = 'abc def' AND news.number > 123") 519 .listIterator()); 520 assertTrue(constraint.toString(), constraint.equals(constraint3)); 521 522 constraint3 524 = new BasicCompositeConstraint(CompositeConstraint.LOGICAL_OR) 525 .addChild(constraint1) 526 .addChild(constraint2); 527 constraint = instance.parseCondition( 528 ConstraintParser.tokenize( 529 "step1.title = 'abc def' OR news.number > 123") 530 .listIterator()); 531 assertTrue(constraint.toString(), constraint.equals(constraint3)); 532 533 BasicFieldCompareConstraint constraint4 = 535 new BasicFieldValueConstraint(field2, new Integer (200)) 536 .setOperator(FieldCompareConstraint.LESS); 537 BasicCompositeConstraint constraint5 = 538 new BasicCompositeConstraint(CompositeConstraint.LOGICAL_AND) 539 .addChild(constraint3) 540 .addChild(constraint4); 541 constraint = instance.parseCondition( 542 ConstraintParser.tokenize( 543 "step1.title = 'abc def' OR news.number > 123" 544 + " AND news.number < 200") 545 .listIterator()); 546 assertTrue(constraint.toString(), constraint.equals(constraint5)); 547 } 548 549 550 public void testToConstraint() { 551 query.addStep(images).setAlias("step1"); 552 RelationStep step2 = query.addRelationStep(insrel, news); 553 step2.getNext(); 554 StepField field1 = instance.getField("step1.title"); 555 instance.getField("news.number"); 556 557 Constraint constraint = instance.toConstraint(""); 559 assertTrue(constraint == null); 560 561 BasicFieldValueConstraint constraint1 = 563 new BasicFieldValueConstraint(field1, "abc def"); 564 constraint = instance.toConstraint("step1.title = 'abc def'"); 565 assertTrue(constraint.toString(), constraint.equals(constraint1)); 566 567 String con = "NOT(step1.title='hoi')"; 569 constraint = instance.toConstraint(con); 570 assertTrue(constraint instanceof BasicFieldValueConstraint); 571 assertTrue(constraint.isInverse()); 572 } 573 574 public void testUnsupported() { 575 BasicLegacyConstraint constraint2 = 577 new BasicLegacyConstraint("abc DEF ghi"); 578 Constraint constraint = instance.toConstraint("abc DEF ghi"); 579 assertTrue(constraint.toString(), constraint.equals(constraint2)); 580 581 BasicLegacyConstraint constraint3 = 583 new BasicLegacyConstraint("WHERE step1.title = 'abc def'"); 584 constraint = instance.toConstraint("WHERE step1.title = 'abc def'"); 585 assertTrue(constraint.toString(), constraint.equals(constraint3)); 586 587 588 } 589 590 public static Test suite() { 591 TestSuite suite = new TestSuite(ConstraintParserTest.class); 592 593 return suite; 594 } 595 596 } 597 | Popular Tags |