1 21 package com.db4o; 22 23 import com.db4o.ext.*; 24 import com.db4o.foundation.*; 25 import com.db4o.inside.*; 26 import com.db4o.inside.marshall.*; 27 import com.db4o.reflect.*; 28 29 33 public class YapObject extends YapMeta implements ObjectInfo{ 34 35 private YapClass _class; 36 private Object _object; 37 private VirtualAttributes _virtualAttributes; 38 39 private YapObject id_preceding; 40 private YapObject id_subsequent; 41 private int id_size; 42 43 private YapObject hc_preceding; 44 private YapObject hc_subsequent; 45 private int hc_size; 46 private int hc_code; 48 private int _lastTopLevelCallId; 49 50 public YapObject(){ 51 } 52 53 public YapObject(int a_id) { 54 i_id = a_id; 55 } 56 57 YapObject(YapClass a_yapClass, int a_id) { 58 _class = a_yapClass; 59 i_id = a_id; 60 } 61 62 void activate(Transaction ta, Object a_object, int a_depth, boolean a_refresh) { 63 activate1(ta, a_object, a_depth, a_refresh); 64 ta.stream().activate3CheckStill(ta); 65 } 66 67 void activate1(Transaction ta, Object a_object, int a_depth, boolean a_refresh) { 68 if(a_object instanceof Db4oTypeImpl){ 69 a_depth = ((Db4oTypeImpl)a_object).adjustReadDepth(a_depth); 70 } 71 if (a_depth > 0) { 72 YapStream stream = ta.stream(); 73 if(a_refresh){ 74 logActivation(stream, "refresh"); 75 }else{ 76 if (isActive()) { 77 if (a_object != null) { 78 if (a_depth > 1) { 79 if (_class.i_config != null) { 80 a_depth = _class.i_config.adjustActivationDepth(a_depth); 81 } 82 _class.activateFields(ta, a_object, a_depth); 83 } 84 return; 85 } 86 } 87 logActivation(stream, "activate"); 88 } 89 read(ta, null, a_object, a_depth, YapConst.ADD_MEMBERS_TO_ID_TREE_ONLY, false); 90 } 91 } 92 93 private void logActivation(YapStream stream, String event) { 94 logEvent(stream, event, YapConst.ACTIVATION); 95 } 96 97 private void logEvent(YapStream stream, String event, final int level) { 98 if (stream.configImpl().messageLevel() > level) { 99 stream.message("" + getID() + " " + event + " " + _class.getName()); 100 } 101 } 102 103 final void addToIDTree(YapStream a_stream) { 104 if (!(_class instanceof YapClassPrimitive)) { 105 a_stream.idTreeAdd(this); 106 } 107 } 108 109 110 boolean continueSet(Transaction a_trans, int a_updateDepth) { 111 if (bitIsTrue(YapConst.CONTINUE)) { 112 if(! _class.stateOKAndAncestors()){ 113 return false; 114 } 115 116 if(DTrace.enabled){ 117 DTrace.CONTINUESET.log(getID()); 118 } 119 120 bitFalse(YapConst.CONTINUE); 121 122 YapWriter writer = MarshallerFamily.current()._object.marshallNew(a_trans, this, a_updateDepth); 123 124 YapStream stream = a_trans.stream(); 125 stream.writeNew(_class, writer); 126 127 Object obj = _object; 128 objectOnNew(stream, obj); 129 130 if(! _class.isPrimitive()){ 131 _object = stream.i_references.createYapRef(this, obj); 132 } 133 134 setStateClean(); 135 endProcessing(); 136 } 137 return true; 138 } 139 140 private void objectOnNew(YapStream stream, Object obj) { 141 stream.callbacks().objectOnNew(obj); 142 _class.dispatchEvent(stream, obj, EventDispatcher.NEW); 143 } 144 145 void deactivate(Transaction a_trans, int a_depth) { 146 if (a_depth > 0) { 147 Object obj = getObject(); 148 if (obj != null) { 149 if(obj instanceof Db4oTypeImpl){ 150 ((Db4oTypeImpl)obj).preDeactivate(); 151 } 152 YapStream stream = a_trans.stream(); 153 logActivation(stream, "deactivate"); 154 setStateDeactivated(); 155 _class.deactivate(a_trans, obj, a_depth); 156 } 157 } 158 } 159 160 public byte getIdentifier() { 161 return YapConst.YAPOBJECT; 162 } 163 164 public Object getObject() { 165 if (Platform4.hasWeakReferences()) { 166 return Platform4.getYapRefObject(_object); 167 } 168 return _object; 169 } 170 171 public Object getObjectReference(){ 172 return _object; 173 } 174 175 public YapStream getStream(){ 176 if(_class == null){ 177 return null; 178 } 179 return _class.getStream(); 180 } 181 182 public Transaction getTrans(){ 186 YapStream stream = getStream(); 187 if(stream != null){ 188 return stream.getTransaction(); 189 } 190 return null; 191 } 192 193 public Db4oUUID getUUID(){ 194 VirtualAttributes va = virtualAttributes(getTrans()); 195 if(va != null && va.i_database != null){ 196 return new Db4oUUID(va.i_uuid, va.i_database.i_signature); 197 } 198 return null; 199 } 200 201 public long getVersion(){ 202 VirtualAttributes va = virtualAttributes(getTrans()); 203 if(va == null) { 204 return 0; 205 } 206 return va.i_version; 207 } 208 209 210 public YapClass getYapClass() { 211 return _class; 212 } 213 214 public int ownLength() { 215 throw Exceptions4.shouldNeverBeCalled(); 216 } 217 218 public VirtualAttributes produceVirtualAttributes() { 219 if(_virtualAttributes == null){ 220 _virtualAttributes = new VirtualAttributes(); 221 } 222 return _virtualAttributes; 223 } 224 225 final Object read( 226 Transaction ta, 227 YapWriter a_reader, 228 Object a_object, 229 int a_instantiationDepth, 230 int addToIDTree, 231 boolean checkIDTree) { 232 233 236 if (beginProcessing()) { 237 238 YapStream stream = ta.stream(); 239 240 if (a_reader == null) { 241 a_reader = stream.readWriterByID(ta, getID()); 242 } 243 if (a_reader != null) { 244 245 ObjectHeader header = new ObjectHeader(stream, a_reader); 246 247 _class = header.yapClass(); 248 249 if (_class == null) { 250 return null; 251 } 252 253 if(checkIDTree){ 254 256 Object objectInCacheFromClassCreation = stream.objectForIDFromCache(getID()); 257 if(objectInCacheFromClassCreation != null){ 258 return objectInCacheFromClassCreation; 259 } 260 } 261 262 a_reader.setInstantiationDepth(a_instantiationDepth); 263 a_reader.setUpdateDepth(addToIDTree); 264 265 if(addToIDTree == YapConst.TRANSIENT){ 266 a_object = _class.instantiateTransient(this, a_object, header._marshallerFamily, header._headerAttributes, a_reader); 267 }else{ 268 a_object = _class.instantiate(this, a_object, header._marshallerFamily, header._headerAttributes, a_reader, addToIDTree == YapConst.ADD_TO_ID_TREE); 269 } 270 271 } 272 endProcessing(); 273 } 274 return a_object; 275 } 276 277 public final Object readPrefetch(YapStream a_stream, YapWriter a_reader) { 278 279 Object readObject = null; 280 if (beginProcessing()) { 281 282 ObjectHeader header = new ObjectHeader(a_stream, a_reader); 283 284 _class = header.yapClass(); 285 286 if (_class == null) { 287 return null; 288 } 289 290 a_reader.setInstantiationDepth(_class.configOrAncestorConfig() == null ? 1 : 0); 300 301 readObject = _class.instantiate(this, getObject(), header._marshallerFamily, header._headerAttributes, a_reader, true); 302 303 endProcessing(); 304 } 305 return readObject; 306 } 307 308 public final void readThis(Transaction a_trans, YapReader a_bytes) { 309 if (Deploy.debug) { 310 System.out.println( 311 "YapObject.readThis should never be called. All handling takes place in read"); 312 } 313 } 314 315 void setObjectWeak(YapStream a_stream, Object a_object) { 316 if (a_stream.i_references._weak) { 317 if(_object != null){ 318 Platform4.killYapRef(_object); 319 } 320 _object = Platform4.createYapRef(a_stream.i_references._queue, this, a_object); 321 } else { 322 _object = a_object; 323 } 324 } 325 326 public void setObject(Object a_object) { 327 _object = a_object; 328 } 329 330 final void store(Transaction trans, YapClass yapClass, Object obj){ 331 _object = obj; 332 _class = yapClass; 333 334 writeObjectBegin(); 335 336 setID(trans.stream().newUserObject()); 337 338 beginProcessing(); 340 341 bitTrue(YapConst.CONTINUE); 342 } 343 344 public void flagForDelete(int callId){ 345 _lastTopLevelCallId = - callId; 346 } 347 348 public boolean isFlaggedForDelete(){ 349 return _lastTopLevelCallId < 0; 350 } 351 352 public void flagAsHandled(int callId){ 353 _lastTopLevelCallId = callId; 354 } 355 356 public final boolean isFlaggedAsHandled(int callID){ 357 return _lastTopLevelCallId == callID; 358 } 359 360 public VirtualAttributes virtualAttributes(){ 361 return _virtualAttributes; 362 } 363 364 public VirtualAttributes virtualAttributes(Transaction a_trans){ 365 if(a_trans == null){ 366 return _virtualAttributes; 367 } 368 if(_virtualAttributes == null){ 369 if(_class.hasVirtualAttributes()){ 370 _virtualAttributes = new VirtualAttributes(); 371 _class.readVirtualAttributes(a_trans, this); 372 } 373 }else{ 374 if(! _virtualAttributes.suppliesUUID()){ 375 if(_class.hasVirtualAttributes()){ 376 _class.readVirtualAttributes(a_trans, this); 377 } 378 } 379 } 380 return _virtualAttributes; 381 } 382 383 public void setVirtualAttributes(VirtualAttributes at){ 384 _virtualAttributes = at; 385 } 386 387 public void writeThis(Transaction trans, YapReader a_writer) { 388 if (Deploy.debug) { 389 System.out.println("YapObject.writeThis should never be called."); 390 } 391 } 392 393 void writeUpdate(Transaction a_trans, int a_updatedepth) { 394 395 continueSet(a_trans, a_updatedepth); 396 399 if (beginProcessing()) { 401 402 Object obj = getObject(); 403 404 if(objectCanUpdate(a_trans.stream(), obj)){ 405 406 if ((!isActive()) || obj == null) { 407 endProcessing(); 408 return; 409 } 410 if (Deploy.debug) { 411 if (!(getID() > 0)) { 412 System.out.println( 413 "Object passed to set() with valid YapObject. YapObject had no ID."); 414 throw new RuntimeException (); 415 } 416 if (_class == null) { 417 System.out.println( 418 "Object passed to set() with valid YapObject. YapObject has no valid yapClass."); 419 throw new RuntimeException (); 420 } 421 } 422 423 logEvent(a_trans.stream(), "update", YapConst.STATE); 424 425 setStateClean(); 426 427 a_trans.writeUpdateDeleteMembers(getID(), _class, a_trans.stream().i_handlers.arrayType(obj), 0); 428 429 MarshallerFamily.current()._object.marshallUpdate(a_trans, a_updatedepth, this, obj); 430 431 } else{ 432 endProcessing(); 433 } 434 } 435 } 436 437 private boolean objectCanUpdate(YapStream stream, Object obj) { 438 return stream.callbacks().objectCanUpdate(obj) 439 && _class.dispatchEvent(stream, obj, EventDispatcher.CAN_UPDATE); 440 } 441 442 443 444 public YapObject hc_add(YapObject a_add) { 445 Object obj = a_add.getObject(); 446 if (obj != null) { 447 a_add.hc_init(obj); 448 return hc_add1(a_add); 449 } 450 return this; 451 } 452 453 public void hc_init(Object obj){ 454 hc_preceding = null; 455 hc_subsequent = null; 456 hc_size = 1; 457 hc_code = hc_getCode(obj); 458 } 459 460 private YapObject hc_add1(YapObject a_new) { 461 int cmp = hc_compare(a_new); 462 if (cmp < 0) { 463 if (hc_preceding == null) { 464 hc_preceding = a_new; 465 hc_size++; 466 } else { 467 hc_preceding = hc_preceding.hc_add1(a_new); 468 if (hc_subsequent == null) { 469 return hc_rotateRight(); 470 } 471 return hc_balance(); 472 } 473 } else { 474 if (hc_subsequent == null) { 475 hc_subsequent = a_new; 476 hc_size++; 477 } else { 478 hc_subsequent = hc_subsequent.hc_add1(a_new); 479 if (hc_preceding == null) { 480 return hc_rotateLeft(); 481 } 482 return hc_balance(); 483 } 484 } 485 return this; 486 } 487 488 private YapObject hc_balance() { 489 int cmp = hc_subsequent.hc_size - hc_preceding.hc_size; 490 if (cmp < -2) { 491 return hc_rotateRight(); 492 } else if (cmp > 2) { 493 return hc_rotateLeft(); 494 } else { 495 hc_size = hc_preceding.hc_size + hc_subsequent.hc_size + 1; 496 return this; 497 } 498 } 499 500 private void hc_calculateSize() { 501 if (hc_preceding == null) { 502 if (hc_subsequent == null) { 503 hc_size = 1; 504 } else { 505 hc_size = hc_subsequent.hc_size + 1; 506 } 507 } else { 508 if (hc_subsequent == null) { 509 hc_size = hc_preceding.hc_size + 1; 510 } else { 511 hc_size = hc_preceding.hc_size + hc_subsequent.hc_size + 1; 512 } 513 } 514 } 515 516 private int hc_compare(YapObject a_to) { 517 int cmp = a_to.hc_code - hc_code; 518 if(cmp == 0){ 519 cmp = a_to.i_id - i_id; 520 } 521 return cmp; 522 } 523 524 public YapObject hc_find(Object obj) { 525 return hc_find(hc_getCode(obj), obj); 526 } 527 528 private YapObject hc_find(int a_id, Object obj) { 529 int cmp = a_id - hc_code; 530 if (cmp < 0) { 531 if (hc_preceding != null) { 532 return hc_preceding.hc_find(a_id, obj); 533 } 534 } else if (cmp > 0) { 535 if (hc_subsequent != null) { 536 return hc_subsequent.hc_find(a_id, obj); 537 } 538 } else { 539 if (obj == getObject()) { 540 return this; 541 } 542 if (hc_preceding != null) { 543 YapObject inPreceding = hc_preceding.hc_find(a_id, obj); 544 if (inPreceding != null) { 545 return inPreceding; 546 } 547 } 548 if (hc_subsequent != null) { 549 return hc_subsequent.hc_find(a_id, obj); 550 } 551 } 552 return null; 553 } 554 555 private int hc_getCode(Object obj) { 556 int hcode = System.identityHashCode(obj); 557 if (hcode < 0) { 558 hcode = ~hcode; 559 } 560 return hcode; 561 } 562 563 private YapObject hc_rotateLeft() { 564 YapObject tree = hc_subsequent; 565 hc_subsequent = tree.hc_preceding; 566 hc_calculateSize(); 567 tree.hc_preceding = this; 568 if(tree.hc_subsequent == null){ 569 tree.hc_size = 1 + hc_size; 570 }else{ 571 tree.hc_size = 1 + hc_size + tree.hc_subsequent.hc_size; 572 } 573 return tree; 574 } 575 576 private YapObject hc_rotateRight() { 577 YapObject tree = hc_preceding; 578 hc_preceding = tree.hc_subsequent; 579 hc_calculateSize(); 580 tree.hc_subsequent = this; 581 if(tree.hc_preceding == null){ 582 tree.hc_size = 1 + hc_size; 583 }else{ 584 tree.hc_size = 1 + hc_size + tree.hc_preceding.hc_size; 585 } 586 return tree; 587 } 588 589 private YapObject hc_rotateSmallestUp() { 590 if (hc_preceding != null) { 591 hc_preceding = hc_preceding.hc_rotateSmallestUp(); 592 return hc_rotateRight(); 593 } 594 return this; 595 } 596 597 YapObject hc_remove(YapObject a_find) { 598 if (this == a_find) { 599 return hc_remove(); 600 } 601 int cmp = hc_compare(a_find); 602 if (cmp <= 0) { 603 if (hc_preceding != null) { 604 hc_preceding = hc_preceding.hc_remove(a_find); 605 } 606 } 607 if (cmp >= 0) { 608 if (hc_subsequent != null) { 609 hc_subsequent = hc_subsequent.hc_remove(a_find); 610 } 611 } 612 hc_calculateSize(); 613 return this; 614 } 615 616 public void hc_traverse(Visitor4 visitor){ 617 if(hc_preceding != null){ 618 hc_preceding.hc_traverse(visitor); 619 } 620 visitor.visit(this); 621 if(hc_subsequent != null){ 622 hc_subsequent.hc_traverse(visitor); 623 } 624 } 625 626 private YapObject hc_remove() { 627 if (hc_subsequent != null && hc_preceding != null) { 628 hc_subsequent = hc_subsequent.hc_rotateSmallestUp(); 629 hc_subsequent.hc_preceding = hc_preceding; 630 hc_subsequent.hc_calculateSize(); 631 return hc_subsequent; 632 } 633 if (hc_subsequent != null) { 634 return hc_subsequent; 635 } 636 return hc_preceding; 637 } 638 639 640 641 YapObject id_add(YapObject a_add) { 642 a_add.id_preceding = null; 643 a_add.id_subsequent = null; 644 a_add.id_size = 1; 645 return id_add1(a_add); 646 } 647 648 private YapObject id_add1(YapObject a_new) { 649 int cmp = a_new.i_id - i_id; 650 if (cmp < 0) { 651 if (id_preceding == null) { 652 id_preceding = a_new; 653 id_size++; 654 } else { 655 id_preceding = id_preceding.id_add1(a_new); 656 if (id_subsequent == null) { 657 return id_rotateRight(); 658 } 659 return id_balance(); 660 } 661 } else if(cmp > 0) { 662 if (id_subsequent == null) { 663 id_subsequent = a_new; 664 id_size++; 665 } else { 666 id_subsequent = id_subsequent.id_add1(a_new); 667 if (id_preceding == null) { 668 return id_rotateLeft(); 669 } 670 return id_balance(); 671 } 672 } 673 return this; 674 } 675 676 private YapObject id_balance() { 677 int cmp = id_subsequent.id_size - id_preceding.id_size; 678 if (cmp < -2) { 679 return id_rotateRight(); 680 } else if (cmp > 2) { 681 return id_rotateLeft(); 682 } else { 683 id_size = id_preceding.id_size + id_subsequent.id_size + 1; 684 return this; 685 } 686 } 687 688 private void id_calculateSize() { 689 if (id_preceding == null) { 690 if (id_subsequent == null) { 691 id_size = 1; 692 } else { 693 id_size = id_subsequent.id_size + 1; 694 } 695 } else { 696 if (id_subsequent == null) { 697 id_size = id_preceding.id_size + 1; 698 } else { 699 id_size = id_preceding.id_size + id_subsequent.id_size + 1; 700 } 701 } 702 } 703 704 YapObject id_find(int a_id) { 705 int cmp = a_id - i_id; 706 if (cmp > 0) { 707 if (id_subsequent != null) { 708 return id_subsequent.id_find(a_id); 709 } 710 } else if (cmp < 0) { 711 if (id_preceding != null) { 712 return id_preceding.id_find(a_id); 713 } 714 } else { 715 return this; 716 } 717 return null; 718 } 719 720 private YapObject id_rotateLeft() { 721 YapObject tree = id_subsequent; 722 id_subsequent = tree.id_preceding; 723 id_calculateSize(); 724 tree.id_preceding = this; 725 if(tree.id_subsequent == null){ 726 tree.id_size = id_size + 1; 727 }else{ 728 tree.id_size = id_size + 1 + tree.id_subsequent.id_size; 729 } 730 return tree; 731 } 732 733 private YapObject id_rotateRight() { 734 YapObject tree = id_preceding; 735 id_preceding = tree.id_subsequent; 736 id_calculateSize(); 737 tree.id_subsequent = this; 738 if(tree.id_preceding == null){ 739 tree.id_size = id_size + 1; 740 }else{ 741 tree.id_size = id_size + 1 + tree.id_preceding.id_size; 742 } 743 return tree; 744 } 745 746 private YapObject id_rotateSmallestUp() { 747 if (id_preceding != null) { 748 id_preceding = id_preceding.id_rotateSmallestUp(); 749 return id_rotateRight(); 750 } 751 return this; 752 } 753 754 YapObject id_remove(int a_id) { 755 int cmp = a_id - i_id; 756 if (cmp < 0) { 757 if (id_preceding != null) { 758 id_preceding = id_preceding.id_remove(a_id); 759 } 760 } else if (cmp > 0) { 761 if (id_subsequent != null) { 762 id_subsequent = id_subsequent.id_remove(a_id); 763 } 764 } else { 765 return id_remove(); 766 } 767 id_calculateSize(); 768 return this; 769 } 770 771 private YapObject id_remove() { 772 if (id_subsequent != null && id_preceding != null) { 773 id_subsequent = id_subsequent.id_rotateSmallestUp(); 774 id_subsequent.id_preceding = id_preceding; 775 id_subsequent.id_calculateSize(); 776 return id_subsequent; 777 } 778 if (id_subsequent != null) { 779 return id_subsequent; 780 } 781 return id_preceding; 782 } 783 784 public String toString(){ 785 if(! Debug4.prettyToStrings){ 786 return super.toString(); 787 } 788 try{ 789 int id = getID(); 790 String str = "YapObject\nID=" + id; 791 if(_class != null){ 792 YapStream stream = _class.getStream(); 793 if(stream != null && id > 0){ 794 YapWriter writer = stream.readWriterByID(stream.getTransaction(), id); 795 if(writer != null){ 796 str += "\nAddress=" + writer.getAddress(); 797 } 798 ObjectHeader oh = new ObjectHeader(stream, writer); 799 YapClass yc = oh.yapClass(); 800 if(yc != _class){ 801 str += "\nYapClass corruption"; 802 }else{ 803 str += yc.toString(oh._marshallerFamily, writer, this, 0, 5); 804 } 805 } 806 } 807 Object obj = getObject(); 808 if(obj == null){ 809 str += "\nfor [null]"; 810 }else{ 811 String objToString =""; 812 try{ 813 objToString = obj.toString(); 814 }catch(Exception e){ 815 } 816 ReflectClass claxx = getYapClass().reflector().forObject(obj); 817 str += "\n" + claxx.getName() + "\n" + objToString; 818 } 819 return str; 820 }catch(Exception e){ 821 } 823 return "Exception in YapObject analyzer"; 824 } 825 826 827 828 829 } 830 | Popular Tags |