1 21 package com.db4o; 22 23 import com.db4o.foundation.*; 24 import com.db4o.inside.*; 25 import com.db4o.query.*; 26 import com.db4o.reflect.*; 27 import com.db4o.types.*; 28 29 34 public abstract class QCon implements Constraint, Visitor4, Unversioned { 35 36 static final IDGenerator idGenerator = new IDGenerator(); 38 39 transient QCandidates i_candidates; 41 42 public Collection4 i_childrenCandidates; 46 47 public List4 _children; 49 50 public QE i_evaluator = QE.DEFAULT; 52 53 public int i_id; 56 57 public Collection4 i_joins; 59 60 public int i_orderID = 0; 64 65 public QCon i_parent; 67 68 public boolean i_removed = false; 70 71 transient Transaction i_trans; 73 74 public QCon() { 75 } 77 78 QCon(Transaction a_trans) { 79 i_id = idGenerator.next(); 80 i_trans = a_trans; 81 } 82 83 QCon addConstraint(QCon a_child) { 84 _children = new List4(_children, a_child); 85 return a_child; 86 } 87 88 public Transaction transaction() { 89 return i_trans; 90 } 91 92 void addJoin(QConJoin a_join) { 93 if (i_joins == null) { 94 i_joins = new Collection4(); 95 } 96 i_joins.add(a_join); 97 } 98 99 QCon addSharedConstraint(QField a_field, Object a_object) { 100 QConObject newConstraint = new QConObject(i_trans, this, a_field, a_object); 101 addConstraint(newConstraint); 102 return newConstraint; 103 } 104 105 public Constraint and(Constraint andWith) { 106 synchronized (streamLock()) { 107 return join(andWith, true); 108 } 109 } 110 111 void applyOrdering() { 112 if (i_orderID != 0) { 113 QCon root = getRoot(); 114 root.i_candidates.applyOrdering(i_candidates.i_ordered, i_orderID); 115 } 116 } 117 118 boolean attach(final QQuery query, final String a_field) { 119 120 final QCon qcon = this; 121 122 YapClass yc = getYapClass(); 123 final boolean[] foundField = { false }; 124 forEachChildField(a_field, new Visitor4() { 125 public void visit(Object obj) { 126 foundField[0] = true; 127 query.addConstraint((QCon) obj); 128 } 129 }); 130 131 if (foundField[0]) { 132 return true; 133 } 134 135 QField qf = null; 136 137 if (yc == null || yc.holdsAnyClass()) { 138 139 final int[] count = { 0 }; 140 final YapField[] yfs = { null }; 141 142 i_trans.stream().classCollection().attachQueryNode(a_field, new Visitor4() { 143 public void visit(Object obj) { 144 yfs[0] = (YapField) ((Object []) obj)[1]; 145 count[0]++; 146 } 147 }); 148 149 if (count[0] == 0) { 150 return false; 151 } 152 153 if (count[0] == 1) { 154 qf = yfs[0].qField(i_trans); 155 } else { 156 qf = new QField(i_trans, a_field, null, 0, 0); 157 } 158 159 } else { 160 if(yc.configInstantiates()) { 161 i_trans.stream().i_handlers._diagnosticProcessor.descendIntoTranslator(yc, a_field); 162 } 163 YapField yf = yc.getYapField(a_field); 164 if (yf != null) { 165 qf = yf.qField(i_trans); 166 } 167 if (qf == null) { 168 qf = new QField(i_trans, a_field, null, 0, 0); 169 } 170 } 171 172 QConPath qcp = new QConPath(i_trans, qcon, qf); 173 query.addConstraint(qcp); 174 qcon.addConstraint(qcp); 175 return true; 176 } 177 178 public boolean canBeIndexLeaf(){ 179 return false; 180 } 181 182 public boolean canLoadByIndex(){ 183 return false; 185 } 186 187 void checkLastJoinRemoved() { 188 if (i_joins.size() == 0) { 189 i_joins = null; 190 } 191 } 192 193 void collect(QCandidates a_candidates) { 194 } 196 197 public Constraint contains() { 198 throw notSupported(); 199 } 200 201 void createCandidates(Collection4 a_candidateCollection) { 202 Iterator4 j = a_candidateCollection.iterator(); 203 while (j.moveNext()) { 204 QCandidates candidates = (QCandidates) j.current(); 205 if (candidates.tryAddConstraint(this)) { 206 i_candidates = candidates; 207 return; 208 } 209 } 210 i_candidates = new QCandidates(i_trans, getYapClass(), getField()); 211 i_candidates.addConstraint(this); 212 a_candidateCollection.add(i_candidates); 213 } 214 215 void doNotInclude(QCandidate a_root) { 216 if(DTrace.enabled){ 217 DTrace.DONOTINCLUDE.log(i_id); 218 } 219 if (Debug.queries) { 220 System.out.println("QCon.doNotInclude " + i_id 221 ); 222 } 223 if (i_parent != null) { 224 i_parent.visit1(a_root, this, false); 225 } else { 226 a_root.doNotInclude(); 227 } 228 } 229 230 public Constraint equal() { 231 throw notSupported(); 232 } 233 234 boolean evaluate(QCandidate a_candidate) { 235 throw Exceptions4.virtualException(); 236 } 237 238 void evaluateChildren() { 239 Iterator4 i = i_childrenCandidates.iterator(); 240 while (i.moveNext()) { 241 ((QCandidates) i.current()).evaluate(); 242 } 243 } 244 245 void evaluateCollectChildren() { 246 if(DTrace.enabled){ 247 DTrace.COLLECT_CHILDREN.log(i_id); 248 } 249 Iterator4 i = i_childrenCandidates.iterator(); 250 while (i.moveNext()) { 251 ((QCandidates) i.current()).collect(i_candidates); 252 } 253 } 254 255 void evaluateCreateChildrenCandidates() { 256 i_childrenCandidates = new Collection4(); 257 Iterator4 i = iterateChildren(); 258 while(i.moveNext()){ 259 ((QCon)i.current()).createCandidates(i_childrenCandidates); 260 } 261 } 262 263 void evaluateEvaluations() { 264 Iterator4 i = iterateChildren(); 265 while(i.moveNext()){ 266 ((QCon)i.current()).evaluateEvaluationsExec(i_candidates, true); 267 } 268 } 269 270 void evaluateEvaluationsExec(QCandidates a_candidates, boolean rereadObject) { 271 } 273 274 void evaluateSelf() { 275 i_candidates.filter(this); 276 } 277 278 void evaluateSimpleChildren() { 279 280 283 if(_children == null) { 284 return; 285 } 286 287 Iterator4 i = iterateChildren(); 288 while(i.moveNext()){ 289 QCon qcon = (QCon)i.current(); 290 i_candidates.setCurrentConstraint(qcon); 291 qcon.setCandidates(i_candidates); 292 qcon.evaluateSimpleExec(i_candidates); 293 qcon.applyOrdering(); 294 } 295 i_candidates.setCurrentConstraint(null); 296 } 297 298 void evaluateSimpleExec(QCandidates a_candidates) { 299 } 301 302 void exchangeConstraint(QCon a_exchange, QCon a_with) { 303 List4 previous = null; 304 List4 current = _children; 305 while (current != null) { 306 if (current._element == a_exchange) { 307 if (previous == null) { 308 _children = current._next; 309 } else { 310 previous._next = current._next; 311 } 312 } 313 previous = current; 314 current = current._next; 315 } 316 317 _children = new List4(_children, a_with); 318 } 319 320 void forEachChildField(final String name, final Visitor4 visitor) { 321 Iterator4 i = iterateChildren(); 322 while(i.moveNext()){ 323 Object obj = i.current(); 324 if (obj instanceof QConObject) { 325 if (((QConObject) obj).i_field.i_name.equals(name)) { 326 visitor.visit(obj); 327 } 328 } 329 } 330 } 331 332 public QField getField() { 333 return null; 334 } 335 336 public Object getObject() { 337 throw notSupported(); 338 } 339 340 QCon getRoot() { 341 if (i_parent != null) { 342 return i_parent.getRoot(); 343 } 344 return this; 345 } 346 347 QCon produceTopLevelJoin() { 348 if(! hasJoins()){ 349 return this; 350 } 351 Iterator4 i = iterateJoins(); 352 if (i_joins.size() == 1) { 353 i.moveNext(); 354 return ((QCon) i.current()).produceTopLevelJoin(); 355 } 356 Collection4 col = new Collection4(); 357 while (i.moveNext()) { 358 col.ensure(((QCon) i.current()).produceTopLevelJoin()); 359 } 360 i = col.iterator(); 361 i.moveNext(); 362 QCon qcon = (QCon) i.current(); 363 if (col.size() == 1) { 364 return qcon; 365 } 366 while (i.moveNext()) { 367 qcon = (QCon) qcon.and((Constraint) i.current()); 368 } 369 return qcon; 370 } 371 372 YapClass getYapClass() { 373 return null; 374 } 375 376 public Constraint greater() { 377 throw notSupported(); 378 } 379 380 public boolean hasChildren(){ 381 return _children != null; 382 } 383 384 public boolean hasParent() { 385 return i_parent != null; 386 } 387 388 public QCon parent() { 389 return i_parent; 390 } 391 392 public boolean hasOrJoins(){ 393 Collection4 lookedAt = new Collection4(); 394 return hasOrJoins(lookedAt); 395 } 396 397 boolean hasOrJoins(Collection4 lookedAt){ 398 if(lookedAt.containsByIdentity(this)){ 399 return false; 400 } 401 lookedAt.add(this); 402 if(i_joins == null){ 403 return false; 404 } 405 Iterator4 i = iterateJoins(); 406 while(i.moveNext()){ 407 QConJoin join = (QConJoin)i.current(); 408 if(join.isOr()){ 409 return true; 410 } 411 if(join.hasOrJoins(lookedAt)){ 412 return true; 413 } 414 } 415 return false; 416 } 417 418 public boolean hasOrJoinWith(QConObject y) { 419 Iterator4 i = iterateJoins(); 420 while(i.moveNext()){ 421 QConJoin join = (QConJoin)i.current(); 422 if(join.isOr()){ 423 if (y == join.getOtherConstraint(this)) { 424 return true; 425 } 426 } 427 } 428 return false; 429 } 430 431 public boolean hasJoins(){ 432 if(i_joins == null){ 433 return false; 434 } 435 return i_joins.size() > 0; 436 } 437 438 boolean hasObjectInParentPath(Object obj) { 439 if (i_parent != null) { 440 return i_parent.hasObjectInParentPath(obj); 441 } 442 return false; 443 } 444 445 public Constraint identity() { 446 throw notSupported(); 447 } 448 449 public int identityID() { 450 return 0; 451 } 452 453 boolean isNot() { 454 return i_evaluator instanceof QENot; 455 } 456 457 boolean isNullConstraint() { 458 return false; 459 } 460 461 Iterator4 iterateJoins(){ 462 if(i_joins == null){ 463 return Iterator4Impl.EMPTY; 464 } 465 return i_joins.iterator(); 466 } 467 468 public Iterator4 iterateChildren(){ 469 if(_children == null){ 470 return Iterator4Impl.EMPTY; 471 } 472 return new Iterator4Impl(_children); 473 } 474 475 Constraint join(Constraint a_with, boolean a_and) { 476 if (!(a_with instanceof QCon) 477 ) { 478 479 483 return null; 484 } 485 if (a_with == this) { 486 return this; 487 } 488 return join1((QCon) a_with, a_and); 489 } 490 491 Constraint join1(QCon a_with, boolean a_and) { 492 493 if (a_with instanceof QConstraints) { 494 int j = 0; 495 Collection4 joinHooks = new Collection4(); 496 Constraint[] constraints = ((QConstraints) a_with).toArray(); 497 for (j = 0; j < constraints.length; j++) { 498 joinHooks.ensure(((QCon) constraints[j]).joinHook()); 499 } 500 Constraint[] joins = new Constraint[joinHooks.size()]; 501 j = 0; 502 Iterator4 i = joinHooks.iterator(); 503 while (i.moveNext()) { 504 joins[j++] = join((Constraint) i.current(), a_and); 505 } 506 return new QConstraints(i_trans, joins); 507 } 508 509 QCon myHook = joinHook(); 510 QCon otherHook = a_with.joinHook(); 511 if (myHook == otherHook) { 512 return myHook; 516 } 517 518 QConJoin cj = new QConJoin(i_trans, myHook, otherHook, a_and); 519 myHook.addJoin(cj); 520 otherHook.addJoin(cj); 521 return cj; 522 } 523 524 QCon joinHook() { 525 return produceTopLevelJoin(); 526 } 527 528 public Constraint like() { 529 throw notSupported(); 530 } 531 532 public Constraint startsWith(boolean caseSensitive) { 533 throw notSupported(); 534 } 535 536 public Constraint endsWith(boolean caseSensitive) { 537 throw notSupported(); 538 } 539 540 void log(String indent) { 541 if (Debug.queries) { 542 543 final String childIndent = " " + indent; 544 String name = getClass().getName(); 545 int pos = name.lastIndexOf(".") + 1; 546 name = name.substring(pos); 547 System.out.println(indent + name + " " + logObject() + " " + i_id); 548 if (hasJoins()) { 550 Iterator4 i = iterateJoins(); 551 while (i.moveNext()) { 552 QCon join = (QCon) i.current(); 553 join.log(childIndent); 555 } 556 } 557 561 if(_children != null){ 562 Iterator4 i = new Iterator4Impl(_children); 563 while(i.moveNext()){ 564 ((QCon)i.current()).log(childIndent); 565 } 566 } 567 } 568 } 569 570 String logObject() { 571 return ""; 572 } 573 574 void marshall() { 575 Iterator4 i = iterateChildren(); 576 while(i.moveNext()){ 577 ((QCon)i.current()).marshall(); 578 } 579 } 580 581 public Constraint not() { 582 synchronized (streamLock()) { 583 if (!(i_evaluator instanceof QENot)) { 584 i_evaluator = new QENot(i_evaluator); 585 } 586 return this; 587 } 588 } 589 590 private RuntimeException notSupported() { 591 return new RuntimeException ("Not supported."); 592 } 593 594 public boolean onSameFieldAs(QCon other){ 595 return false; 596 } 597 598 public Constraint or(Constraint orWith) { 599 synchronized (streamLock()) { 600 return join(orWith, false); 601 } 602 } 603 604 boolean remove() { 605 if (!i_removed) { 606 i_removed = true; 607 removeChildrenJoins(); 608 return true; 609 } 610 return false; 611 } 612 613 void removeChildrenJoins() { 614 if (! hasJoins()) { 615 return; 616 } 617 Iterator4 i = iterateJoins(); 618 while(i.moveNext()){ 619 QConJoin qcj = (QConJoin) i.current(); 620 if (qcj.removeForParent(this)) { 621 i_joins.remove(qcj); 622 } 623 } 624 checkLastJoinRemoved(); 625 } 626 627 void removeJoin(QConJoin a_join) { 628 i_joins.remove(a_join); 629 checkLastJoinRemoved(); 630 } 631 632 void removeNot() { 633 if (isNot()) { 634 i_evaluator = ((QENot) i_evaluator).i_evaluator; 635 } 636 } 637 638 public void setCandidates(QCandidates a_candidates) { 639 i_candidates = a_candidates; 640 } 641 642 void setOrdering(int a_ordering) { 643 i_orderID = a_ordering; 644 } 645 646 void setParent(QCon a_newParent) { 647 i_parent = a_newParent; 648 } 649 650 QCon shareParent(Object a_object, boolean[] removeExisting) { 651 return null; 653 } 654 655 QConClass shareParentForClass(ReflectClass a_class, boolean[] removeExisting) { 656 return null; 658 } 659 660 public Constraint smaller() { 661 throw notSupported(); 662 } 663 664 protected Object streamLock() { 665 return i_trans.stream().i_lock; 666 } 667 668 boolean supportsOrdering() { 669 return false; 670 } 671 672 void unmarshall(final Transaction a_trans) { 673 if (i_trans != null) { 674 return; 675 } 676 i_trans = a_trans; 677 unmarshallParent(a_trans); 678 unmarshallJoins(a_trans); 679 unmarshallChildren(a_trans); 680 } 681 682 private void unmarshallParent(final Transaction a_trans) { 683 if (i_parent != null) { 684 i_parent.unmarshall(a_trans); 685 } 686 } 687 688 private void unmarshallChildren(final Transaction a_trans) { 689 Iterator4 i = iterateChildren(); 690 while(i.moveNext()){ 691 ((QCon)i.current()).unmarshall(a_trans); 692 } 693 } 694 695 private void unmarshallJoins(final Transaction a_trans) { 696 if (hasJoins()) { 697 Iterator4 i = iterateJoins(); 698 while (i.moveNext()) { 699 ((QCon) i.current()).unmarshall(a_trans); 700 } 701 } 702 } 703 704 public void visit(Object obj) { 705 QCandidate qc = (QCandidate) obj; 706 visit1(qc.getRoot(), this, evaluate(qc)); 707 } 708 709 void visit(QCandidate a_root, boolean res) { 710 visit1(a_root, this, i_evaluator.not(res)); 711 } 712 713 void visit1(QCandidate a_root, QCon a_reason, boolean res) { 714 715 718 if (hasJoins()) { 719 Iterator4 i = iterateJoins(); 721 while (i.moveNext()) { 722 a_root.evaluate(new QPending((QConJoin) i.current(), this, res)); 723 } 724 } else { 725 if (!res) { 726 doNotInclude(a_root); 727 } 728 } 729 } 730 731 final void visitOnNull(final QCandidate a_root) { 732 733 737 if (Debug.queries) { 738 System.out.println("QCon.visitOnNull " + i_id); 739 } 740 741 Iterator4 i = iterateChildren(); 742 while(i.moveNext()){ 743 ((QCon)i.current()).visitOnNull(a_root); 744 } 745 746 if (visitSelfOnNull()) { 747 visit(a_root, isNullConstraint()); 748 } 749 750 } 751 752 boolean visitSelfOnNull() { 753 return true; 754 } 755 756 public QE evaluator() { 757 return i_evaluator; 758 } 759 760 public boolean requiresSort() { 761 if (i_orderID != 0) { 762 return true; 763 } 764 Iterator4 i = iterateChildren(); 765 while(i.moveNext()){ 766 if(((QCon)i.current()).requiresSort()){ 767 return true; 768 } 769 } 770 return false; 771 } 772 } 773 | Popular Tags |