1 21 package com.db4o; 22 23 import com.db4o.config.*; 24 import com.db4o.ext.*; 25 import com.db4o.foundation.*; 26 import com.db4o.inside.*; 27 import com.db4o.inside.classindex.*; 28 import com.db4o.inside.diagnostic.*; 29 import com.db4o.inside.marshall.*; 30 import com.db4o.inside.slots.*; 31 import com.db4o.query.*; 32 import com.db4o.reflect.*; 33 import com.db4o.reflect.generic.*; 34 35 38 public class YapClass extends YapMeta implements TypeHandler4, StoredClass { 39 40 public YapClass i_ancestor; 41 42 Config4Class i_config; 43 public int _metaClassID; 44 45 public YapField[] i_fields; 46 47 private final ClassIndexStrategy _index; 48 49 protected String i_name; 50 51 protected final YapStream i_stream; 52 53 byte[] i_nameBytes; 54 private YapReader i_reader; 55 56 private Db4oTypeImpl i_db4oType; 57 58 private ReflectClass _reflector; 59 private boolean _isEnum; 60 public boolean i_dontCallConstructors; 61 62 private EventDispatcher _eventDispatcher; 63 64 private boolean _internal; 65 66 private boolean _unversioned; 67 68 private int i_lastID; 71 72 73 boolean isInternal() { 74 return _internal; 75 } 76 77 private ClassIndexStrategy createIndexStrategy() { 78 return new BTreeClassIndexStrategy(this); 79 } 80 81 YapClass(YapStream stream, ReflectClass reflector){ 82 i_stream = stream; 83 _reflector = reflector; 84 _index = createIndexStrategy(); 85 } 86 87 void activateFields(Transaction a_trans, Object a_object, int a_depth) { 88 if(objectCanActivate(a_trans.stream(), a_object)){ 89 activateFields1(a_trans, a_object, a_depth); 90 } 91 } 92 93 void activateFields1(Transaction a_trans, Object a_object, int a_depth) { 94 for (int i = 0; i < i_fields.length; i++) { 95 i_fields[i].cascadeActivation(a_trans, a_object, a_depth, true); 96 } 97 if (i_ancestor != null) { 98 i_ancestor.activateFields1(a_trans, a_object, a_depth); 99 } 100 } 101 102 public final void addFieldIndices(YapWriter a_writer, Slot oldSlot) { 103 if(hasIndex() || hasVirtualAttributes()){ 104 ObjectHeader oh = new ObjectHeader(i_stream, this, a_writer); 105 oh._marshallerFamily._object.addFieldIndices(this, oh._headerAttributes, a_writer, oldSlot); 106 } 107 } 108 109 void addMembers(YapStream a_stream) { 110 bitTrue(YapConst.CHECKED_CHANGES); 111 if (addTranslatorFields(a_stream)) { 112 return; 113 } 114 115 if (a_stream.detectSchemaChanges()) { 116 boolean dirty = isDirty(); 117 118 Collection4 members = new Collection4(); 119 120 if (null != i_fields) { 121 members.addAll(i_fields); 122 if(i_fields.length==1&&i_fields[0] instanceof YapFieldTranslator) { 123 setStateOK(); 124 return; 125 } 126 } 127 if(generateVersionNumbers()) { 128 if(! hasVersionField()) { 129 members.add(a_stream.i_handlers.i_indexes.i_fieldVersion); 130 dirty = true; 131 } 132 } 133 if(generateUUIDs()) { 134 if(! hasUUIDField()) { 135 members.add(a_stream.i_handlers.i_indexes.i_fieldUUID); 136 dirty = true; 137 } 138 } 139 dirty = collectReflectFields(a_stream, members) | dirty; 140 if (dirty) { 141 i_stream.setDirtyInSystemTransaction(this); 142 i_fields = new YapField[members.size()]; 143 members.toArray(i_fields); 144 for (int i = 0; i < i_fields.length; i++) { 145 i_fields[i].setArrayPosition(i); 146 } 147 } else { 148 if (members.size() == 0) { 149 i_fields = new YapField[0]; 150 } 151 } 152 153 DiagnosticProcessor dp = i_stream.i_handlers._diagnosticProcessor; 154 if(dp.enabled()){ 155 dp.checkClassHasFields(this); 156 } 157 158 } else { 159 if (i_fields == null) { 160 i_fields = new YapField[0]; 161 } 162 } 163 setStateOK(); 164 } 165 166 private boolean collectReflectFields(YapStream stream, Collection4 collectedFields) { 167 boolean dirty=false; 168 ReflectField[] fields = classReflector().getDeclaredFields(); 169 for (int i = 0; i < fields.length; i++) { 170 if (storeField(fields[i])) { 171 TypeHandler4 wrapper = stream.i_handlers.handlerForClass(stream, fields[i].getFieldType()); 172 if (wrapper == null) { 173 continue; 174 } 175 YapField field = new YapField(this, fields[i], wrapper); 176 177 boolean found = false; 178 Iterator4 m = collectedFields.iterator(); 179 while (m.moveNext()) { 180 if (((YapField)m.current()).equals(field)) { 181 found = true; 182 break; 183 } 184 } 185 if (found) { 186 continue; 187 } 188 189 dirty = true; 191 194 collectedFields.add(field); 195 } 196 } 197 return dirty; 198 } 199 200 private boolean addTranslatorFields(YapStream a_stream) { 201 202 ObjectTranslator ot = getTranslator(); 203 if (ot == null) { 204 return false; 205 } 206 207 if (isNewTranslator(ot)) { 208 i_stream.setDirtyInSystemTransaction(this); 209 } 210 211 int fieldCount = 1; 212 213 boolean versions = generateVersionNumbers() && ! ancestorHasVersionField(); 214 boolean uuids = generateUUIDs() && ! ancestorHasUUIDField(); 215 216 if(versions){ 217 fieldCount = 2; 218 } 219 220 if(uuids){ 221 fieldCount = 3; 222 } 223 224 i_fields = new YapField[fieldCount]; 225 226 i_fields[0] = new YapFieldTranslator(this, ot); 227 228 230 233 236 240 if(versions || uuids) { 241 242 245 i_fields[1] = a_stream.i_handlers.i_indexes.i_fieldVersion; 246 } 247 248 if(uuids){ 249 i_fields[2] = a_stream.i_handlers.i_indexes.i_fieldUUID; 250 } 251 252 setStateOK(); 253 return true; 254 } 255 256 private ObjectTranslator getTranslator() { 257 return i_config == null 258 ? null 259 : i_config.getTranslator(); 260 } 261 262 private boolean isNewTranslator(ObjectTranslator ot) { 263 return !hasFields() 264 || !ot.getClass().getName().equals(i_fields[0].getName()); 265 } 266 267 private boolean hasFields() { 268 return i_fields != null 269 && i_fields.length > 0; 270 } 271 272 void addToIndex(YapFile a_stream, Transaction a_trans, int a_id) { 273 if (a_stream.maintainsIndices()) { 274 addToIndex1(a_stream, a_trans, a_id); 275 } 276 } 277 278 void addToIndex1(YapFile a_stream, Transaction a_trans, int a_id) { 279 if (i_ancestor != null) { 280 i_ancestor.addToIndex1(a_stream, a_trans, a_id); 281 } 282 if (hasIndex()) { 283 _index.add(a_trans, a_id); 284 } 285 } 286 287 boolean allowsQueries() { 288 return hasIndex(); 289 } 290 291 public boolean canHold(ReflectClass claxx) { 292 if (claxx == null) { 293 return true; 294 } 295 if (_reflector != null) { 296 if(classReflector().isCollection()){ 297 return true; 298 } 299 return classReflector().isAssignableFrom(claxx); 300 } 301 return false; 302 } 303 304 public void cascadeActivation( 305 Transaction a_trans, 306 Object a_object, 307 int a_depth, 308 boolean a_activate) { 309 Config4Class config = configOrAncestorConfig(); 310 if (config != null) { 311 if (a_activate) { 312 a_depth = config.adjustActivationDepth(a_depth); 313 } 314 } 315 if (a_depth > 0) { 316 YapStream stream = a_trans.stream(); 317 if (a_activate) { 318 if(isValueType()){ 319 activateFields(a_trans, a_object, a_depth - 1); 320 }else{ 321 stream.stillToActivate(a_object, a_depth - 1); 322 } 323 } else { 324 stream.stillToDeactivate(a_object, a_depth - 1, false); 325 } 326 } 327 } 328 329 void checkChanges() { 330 if (stateOK()) { 331 if (!bitIsTrue(YapConst.CHECKED_CHANGES)) { 332 bitTrue(YapConst.CHECKED_CHANGES); 333 if (i_ancestor != null) { 334 i_ancestor.checkChanges(); 335 } 338 if (_reflector != null) { 339 addMembers(i_stream); 340 if (!i_stream.isClient()) { 341 write(i_stream.getSystemTransaction()); 342 } 343 } 344 } 345 } 346 } 347 348 public void checkDb4oType() { 349 ReflectClass claxx = classReflector(); 350 if (claxx == null){ 351 return; 352 } 353 if (i_stream.i_handlers.ICLASS_INTERNAL.isAssignableFrom(claxx)) { 354 _internal = true; 355 } 356 if (i_stream.i_handlers.ICLASS_UNVERSIONED.isAssignableFrom(claxx)) { 357 _unversioned = true; 358 } 359 if (i_stream.i_handlers.ICLASS_DB4OTYPEIMPL.isAssignableFrom(claxx)) { 360 try { 361 i_db4oType = (Db4oTypeImpl)claxx.newInstance(); 362 } catch (Exception e) { 363 } 364 } 365 } 366 367 public void checkUpdateDepth(YapWriter a_bytes) { 368 int depth = a_bytes.getUpdateDepth(); 369 Config4Class config = configOrAncestorConfig(); 370 if (depth == YapConst.UNSPECIFIED) { 371 depth = checkUpdateDepthUnspecified(a_bytes.getStream()); 372 if (classReflector().isCollection()) { 373 depth = adjustDepth(depth); 374 } 375 } 376 if ((config != null && (config.cascadeOnDelete() == YapConst.YES || config.cascadeOnUpdate() == YapConst.YES))) { 377 depth = adjustDepth(depth); 378 } 379 a_bytes.setUpdateDepth(depth - 1); 380 } 381 382 private int adjustDepth(int depth) { 383 int depthBorder = reflector().collectionUpdateDepth(classReflector()); 384 if (depth>Integer.MIN_VALUE && depth < depthBorder) { 385 depth = depthBorder; 386 } 387 return depth; 388 } 389 390 int checkUpdateDepthUnspecified(YapStream a_stream) { 391 int depth = a_stream.configImpl().updateDepth() + 1; 392 if (i_config != null && i_config.updateDepth() != 0) { 393 depth = i_config.updateDepth() + 1; 394 } 395 if (i_ancestor != null) { 396 int ancestordepth = i_ancestor.checkUpdateDepthUnspecified(a_stream); 397 if (ancestordepth > depth) { 398 return ancestordepth; 399 } 400 } 401 return depth; 402 } 403 404 public Object coerce(ReflectClass claxx, Object obj) { 405 return canHold(claxx) ? obj : No4.INSTANCE; 406 } 407 408 void collectConstraints( 409 Transaction a_trans, 410 QConObject a_parent, 411 Object a_object, 412 Visitor4 a_visitor) { 413 if (i_fields != null) { 414 for (int i = 0; i < i_fields.length; i++) { 415 i_fields[i].collectConstraints(a_trans, a_parent, a_object, a_visitor); 416 } 417 } 418 if (i_ancestor != null) { 419 i_ancestor.collectConstraints(a_trans, a_parent, a_object, a_visitor); 420 } 421 } 422 423 final TreeInt collectFieldIDs(MarshallerFamily mf, ObjectHeaderAttributes attributes, TreeInt tree, YapWriter a_bytes, String name) { 424 return mf._object.collectFieldIDs(tree, this, attributes, a_bytes, name); 425 } 426 427 final boolean configInstantiates(){ 428 return i_config != null && i_config.instantiates(); 429 } 430 431 public Config4Class configOrAncestorConfig() { 432 if (i_config != null) { 433 return i_config; 434 } 435 if (i_ancestor != null) { 436 return i_ancestor.configOrAncestorConfig(); 437 } 438 return null; 439 } 440 441 public void copyValue(Object a_from, Object a_to) { 442 } 444 445 private boolean createConstructor(YapStream a_stream, String a_name) { 446 447 ReflectClass claxx; 448 try { 449 claxx = a_stream.reflector().forName(a_name); 450 } catch (Throwable t) { 451 claxx = null; 452 } 453 454 return createConstructor(a_stream,claxx , a_name, true); 455 } 456 457 public boolean createConstructor(YapStream a_stream, ReflectClass a_class, String a_name, boolean errMessages) { 458 459 _reflector = a_class; 460 461 _eventDispatcher = EventDispatcher.forClass(a_stream, a_class); 462 463 if(! Deploy.csharp){ 464 if(a_class != null){ 465 _isEnum = Platform4.jdk().isEnum(reflector(), a_class); 466 } 467 } 468 469 if(configInstantiates()){ 470 return true; 471 } 472 473 if(a_class != null){ 474 if(a_stream.i_handlers.ICLASS_TRANSIENTCLASS.isAssignableFrom(a_class) 475 || Platform4.isTransient(a_class)) { 476 a_class = null; 477 } 478 } 479 if (a_class == null) { 480 if(a_name == null || !Platform4.isDb4oClass(a_name)){ 481 if(errMessages){ 482 a_stream.logMsg(23, a_name); 483 } 484 } 485 setStateDead(); 486 return false; 487 } 488 489 if(a_stream.i_handlers.createConstructor(a_class, ! callConstructor())){ 490 return true; 491 } 492 493 setStateDead(); 494 if(errMessages){ 495 a_stream.logMsg(7, a_name); 496 } 497 498 if (a_stream.configImpl().exceptionsOnNotStorable()) { 499 throw new ObjectNotStorableException(a_class); 500 } 501 502 return false; 503 504 } 505 506 public void deactivate(Transaction a_trans, Object a_object, int a_depth) { 507 if(objectCanDeactivate(a_trans.stream(), a_object)){ 508 deactivate1(a_trans, a_object, a_depth); 509 objectOnDeactivate(a_trans.stream(), a_object); 510 } 511 } 512 513 private void objectOnDeactivate(YapStream stream, Object obj) { 514 stream.callbacks().objectOnDeactivate(obj); 515 dispatchEvent(stream, obj, EventDispatcher.DEACTIVATE); 516 } 517 518 private boolean objectCanDeactivate(YapStream stream, Object obj) { 519 return stream.callbacks().objectCanDeactivate(obj) 520 && dispatchEvent(stream, obj, EventDispatcher.CAN_DEACTIVATE); 521 } 522 523 void deactivate1(Transaction a_trans, Object a_object, int a_depth) { 524 525 for (int i = 0; i < i_fields.length; i++) { 526 i_fields[i].deactivate(a_trans, a_object, a_depth); 527 } 528 if (i_ancestor != null) { 529 i_ancestor.deactivate1(a_trans, a_object, a_depth); 530 } 531 } 532 533 final void delete(YapWriter a_bytes, Object a_object) { 534 ObjectHeader oh = new ObjectHeader(i_stream, this, a_bytes); 535 delete1(oh._marshallerFamily, oh._headerAttributes, a_bytes, a_object); 536 } 537 538 private final void delete1(MarshallerFamily mf, ObjectHeaderAttributes attributes, YapWriter a_bytes, Object a_object) { 539 removeFromIndex(a_bytes.getTransaction(), a_bytes.getID()); 540 deleteMembers(mf, attributes, a_bytes, a_bytes.getTransaction().stream().i_handlers.arrayType(a_object), false); 541 } 542 543 public void deleteEmbedded(MarshallerFamily mf, YapWriter a_bytes) { 544 if (a_bytes.cascadeDeletes() > 0) { 545 int id = a_bytes.readInt(); 546 if (id > 0) { 547 deleteEmbedded1(mf, a_bytes, id); 548 } 549 } else { 550 a_bytes.incrementOffset(linkLength()); 551 } 552 } 553 554 public void deleteEmbedded1(MarshallerFamily mf, YapWriter a_bytes, int a_id) { 555 if (a_bytes.cascadeDeletes() > 0) { 556 557 YapStream stream = a_bytes.getStream(); 558 559 Object obj = stream.getByID2(a_bytes.getTransaction(), a_id); 561 562 int cascade = a_bytes.cascadeDeletes() - 1; 563 if (obj != null) { 564 if (isCollection(obj)) { 565 cascade += reflector().collectionUpdateDepth(reflector().forObject(obj)) - 1; 566 } 567 } 568 569 YapObject yo = stream.getYapObject(a_id); 570 if (yo != null) { 571 a_bytes.getStream().delete2(a_bytes.getTransaction(), yo, obj,cascade, false); 572 } 573 } 574 } 575 576 void deleteMembers(MarshallerFamily mf, ObjectHeaderAttributes attributes, YapWriter a_bytes, int a_type, boolean isUpdate) { 577 try{ 578 Config4Class config = configOrAncestorConfig(); 579 if (config != null && (config.cascadeOnDelete() == YapConst.YES)) { 580 int preserveCascade = a_bytes.cascadeDeletes(); 581 if (classReflector().isCollection()) { 582 int newCascade = 583 preserveCascade + reflector().collectionUpdateDepth(classReflector()) - 3; 584 if (newCascade < 1) { 585 newCascade = 1; 586 } 587 a_bytes.setCascadeDeletes(newCascade); 588 } else { 589 a_bytes.setCascadeDeletes(1); 590 } 591 mf._object.deleteMembers(this, attributes, a_bytes, a_type, isUpdate); 592 a_bytes.setCascadeDeletes(preserveCascade); 593 } else { 594 mf._object.deleteMembers(this, attributes, a_bytes, a_type, isUpdate); 595 } 596 }catch(Exception e){ 597 598 603 if(Debug.atHome){ 604 e.printStackTrace(); 605 } 606 } 607 } 608 609 public final boolean dispatchEvent(YapStream stream, Object obj, int message) { 610 if(_eventDispatcher == null || ! stream.dispatchsEvents()){ 611 return true; 612 } 613 return _eventDispatcher.dispatch(stream, obj, message); 614 } 615 616 public final boolean equals(TypeHandler4 a_dataType) { 617 return (this == a_dataType); 618 } 619 620 public final int fieldCount(){ 621 int count = i_fields.length; 622 623 if(i_ancestor != null){ 624 count += i_ancestor.fieldCount(); 625 } 626 627 return count; 628 } 629 630 private static class YapFieldIterator implements Iterator4 { 631 private final YapClass _initialClazz; 632 private YapClass _curClazz; 633 private int _curIdx; 634 635 public YapFieldIterator(YapClass clazz) { 636 _initialClazz=clazz; 637 reset(); 638 } 639 640 public Object current() { 641 return _curClazz.i_fields[_curIdx]; 642 } 643 644 public boolean moveNext() { 645 if(_curClazz==null) { 646 _curClazz=_initialClazz; 647 _curIdx=0; 648 } 649 else { 650 _curIdx++; 651 } 652 while(_curClazz!=null&&!indexInRange()) { 653 _curClazz=_curClazz.i_ancestor; 654 _curIdx=0; 655 } 656 return _curClazz!=null&&indexInRange(); 657 } 658 659 public void reset() { 660 _curClazz=null; 661 _curIdx=-1; 662 } 663 664 private boolean indexInRange() { 665 return _curIdx<_curClazz.i_fields.length; 666 } 667 } 668 669 public Iterator4 fields() { 670 return new YapFieldIterator(this); 671 } 672 673 final MarshallerFamily findOffset(YapReader a_bytes, YapField a_field) { 680 if (a_bytes == null) { 681 return null; 682 } 683 a_bytes._offset = 0; 684 ObjectHeader oh = new ObjectHeader(i_stream, this, a_bytes); 685 boolean res = oh.objectMarshaller().findOffset(this, oh._headerAttributes, a_bytes, a_field); 686 if(! res){ 687 return null; 688 } 689 return oh._marshallerFamily; 690 } 691 692 void forEachYapField(Visitor4 visitor) { 693 if (i_fields != null) { 694 for (int i = 0; i < i_fields.length; i++) { 695 visitor.visit(i_fields[i]); 696 } 697 } 698 if (i_ancestor != null) { 699 i_ancestor.forEachYapField(visitor); 700 } 701 } 702 703 public static YapClass forObject(Transaction trans, Object obj, boolean allowCreation){ 704 ReflectClass reflectClass = trans.reflector().forObject(obj); 705 if (reflectClass != null && reflectClass.getSuperclass() == null && obj != null) { 706 throw new ObjectNotStorableException(obj.toString()); 707 } 708 if(allowCreation){ 709 return trans.stream().produceYapClass(reflectClass); 710 } 711 return trans.stream().getYapClass(reflectClass); 712 } 713 714 public boolean generateUUIDs() { 715 if(! generateVirtual()){ 716 return false; 717 } 718 int configValue = (i_config == null) ? 0 : i_config.generateUUIDs(); 719 720 return generate1(i_stream.config().generateUUIDs(), configValue); 721 } 722 723 private boolean generateVersionNumbers() { 724 if(! generateVirtual()){ 725 return false; 726 } 727 int configValue = (i_config == null) ? 0 : i_config.generateVersionNumbers(); 728 return generate1(i_stream.config().generateVersionNumbers(), configValue); 729 } 730 731 private boolean generateVirtual(){ 732 if(_unversioned){ 733 return false; 734 } 735 if(_internal){ 736 return false; 737 } 738 return true; 739 } 740 741 private boolean generate1(int bootRecordValue, int configValue) { 742 if(bootRecordValue < 0) { 743 return false; 744 } 745 if(configValue < 0) { 746 return false; 747 } 748 if(bootRecordValue > 1) { 749 return true; 750 } 751 return configValue > 0; 752 } 753 754 755 YapClass getAncestor() { 756 return i_ancestor; 757 } 758 759 Object getComparableObject(Object forObject) { 760 if (i_config != null) { 761 if (i_config.queryAttributeProvider() != null) { 762 return i_config.queryAttributeProvider().attribute(forObject); 763 } 764 } 765 return forObject; 766 } 767 768 YapClass getHigherHierarchy(YapClass a_yapClass) { 769 YapClass yc = getHigherHierarchy1(a_yapClass); 770 if (yc != null) { 771 return yc; 772 } 773 return a_yapClass.getHigherHierarchy1(this); 774 } 775 776 private YapClass getHigherHierarchy1(YapClass a_yapClass) { 777 if (a_yapClass == this) { 778 return this; 779 } 780 if (i_ancestor != null) { 781 return i_ancestor.getHigherHierarchy1(a_yapClass); 782 } 783 return null; 784 } 785 786 YapClass getHigherOrCommonHierarchy(YapClass a_yapClass) { 787 YapClass yc = getHigherHierarchy1(a_yapClass); 788 if (yc != null) { 789 return yc; 790 } 791 if (i_ancestor != null) { 792 yc = i_ancestor.getHigherOrCommonHierarchy(a_yapClass); 793 if (yc != null) { 794 return yc; 795 } 796 } 797 return a_yapClass.getHigherHierarchy1(this); 798 } 799 800 public byte getIdentifier() { 801 return YapConst.YAPCLASS; 802 } 803 804 public long[] getIDs() { 805 synchronized(i_stream.i_lock){ 806 if (! stateOK()) { 807 return new long[0]; 808 } 809 return getIDs(i_stream.getTransaction()); 810 } 811 } 812 813 public long[] getIDs(Transaction trans) { 814 if (! stateOK()) { 815 return new long[0]; 816 } 817 if (! hasIndex()) { 818 return new long[0]; 819 } 820 return trans.stream().getIDsForClass(trans, this); 821 } 822 823 public boolean hasIndex() { 824 return i_db4oType == null || i_db4oType.hasClassIndex(); 825 } 826 827 private boolean ancestorHasUUIDField(){ 828 if(i_ancestor == null) { 829 return false; 830 } 831 return i_ancestor.hasUUIDField(); 832 } 833 834 private boolean hasUUIDField() { 835 if(ancestorHasUUIDField()){ 836 return true; 837 } 838 if(i_fields != null) { 839 for (int i = 0; i < i_fields.length; i++) { 840 if(i_fields[i] instanceof YapFieldUUID) { 841 return true; 842 } 843 } 844 } 845 return false; 846 } 847 848 private boolean ancestorHasVersionField(){ 849 if(i_ancestor == null){ 850 return false; 851 } 852 return i_ancestor.hasVersionField(); 853 } 854 855 private boolean hasVersionField() { 856 if(ancestorHasVersionField()){ 857 return true; 858 } 859 if(i_fields != null) { 860 for (int i = 0; i < i_fields.length; i++) { 861 if(i_fields[i] instanceof YapFieldVersion) { 862 return true; 863 } 864 } 865 } 866 return false; 867 } 868 869 public ClassIndexStrategy index() { 870 return _index; 871 } 872 873 int indexEntryCount(Transaction ta){ 874 if(!stateOK()){ 875 return 0; 876 } 877 return _index.entryCount(ta); 878 } 879 880 public Object indexEntryToObject(Transaction trans, Object indexEntry){ 881 if(indexEntry == null){ 882 return null; 883 } 884 int id = ((Integer )indexEntry).intValue(); 885 return getStream().getByID2(trans, id); 886 } 887 888 public ReflectClass classReflector(){ 889 return _reflector; 890 } 891 892 public String getName() { 893 if(i_name == null){ 894 if(_reflector != null){ 895 i_name = _reflector.getName(); 896 } 897 } 898 return i_name; 899 } 900 901 public StoredClass getParentStoredClass(){ 902 return getAncestor(); 903 } 904 905 public StoredField[] getStoredFields(){ 906 synchronized(i_stream.i_lock){ 907 if(i_fields == null){ 908 return null; 909 } 910 StoredField[] fields = new StoredField[i_fields.length]; 911 System.arraycopy(i_fields, 0, fields, 0, i_fields.length); 912 return fields; 913 } 914 } 915 916 YapStream getStream() { 917 return i_stream; 918 } 919 920 public int getTypeID() { 921 return YapConst.TYPE_CLASS; 922 } 923 924 public YapClass getYapClass(YapStream a_stream) { 925 return this; 926 } 927 928 public YapField getYapField(final String name) { 929 final YapField[] yf = new YapField[1]; 930 forEachYapField(new Visitor4() { 931 public void visit(Object obj) { 932 if (name.equals(((YapField)obj).getName())) { 933 yf[0] = (YapField)obj; 934 } 935 } 936 }); 937 return yf[0]; 938 939 } 940 941 public boolean hasFixedLength(){ 942 return true; 943 } 944 945 public boolean hasField(YapStream a_stream, String a_field) { 946 if(classReflector().isCollection()){ 947 return true; 948 } 949 return getYapField(a_field) != null; 950 } 951 952 boolean hasVirtualAttributes(){ 953 if(_internal){ 954 return false; 955 } 956 return hasVersionField() || hasUUIDField(); 957 } 958 959 public boolean holdsAnyClass() { 960 return classReflector().isCollection(); 961 } 962 963 void incrementFieldsOffset1(YapReader a_bytes) { 964 int length = Debug.atHome ? readFieldCountSodaAtHome(a_bytes) : readFieldCount(a_bytes); 965 for (int i = 0; i < length; i++) { 966 i_fields[i].incrementOffset(a_bytes); 967 } 968 } 969 970 public Object comparableObject(Transaction a_trans, Object a_object) { 971 return a_object; 972 } 973 974 final boolean init( YapStream a_stream, YapClass a_ancestor,ReflectClass claxx) { 975 976 if(DTrace.enabled){ 977 DTrace.YAPCLASS_INIT.log(getID()); 978 } 979 980 i_ancestor = a_ancestor; 981 982 Config4Impl config = a_stream.configImpl(); 983 String className = claxx.getName(); 984 setConfig(config.configClass(className)); 985 986 if(! createConstructor(a_stream, claxx, className, false)){ 987 return false; 988 } 989 990 checkDb4oType(); 991 if (allowsQueries()) { 992 _index.initialize(a_stream); 993 } 994 i_name = className; 995 i_ancestor = a_ancestor; 996 bitTrue(YapConst.CHECKED_CHANGES); 997 998 return true; 999 } 1000 1001 final void initConfigOnUp(Transaction systemTrans) { 1002 Config4Class extendedConfig=Platform4.extendConfiguration(_reflector, i_stream.configure(), i_config); 1003 if(extendedConfig!=null) { 1004 i_config=extendedConfig; 1005 } 1006 if (i_config == null) { 1007 return; 1008 } 1009 if (! stateOK()) { 1010 return; 1011 } 1012 1013 if (i_fields == null) { 1014 return; 1015 } 1016 1017 for (int i = 0; i < i_fields.length; i++) { 1018 YapField curField = i_fields[i]; 1019 String fieldName = curField.getName(); 1020 if(!curField.hasConfig()&&extendedConfig!=null&&extendedConfig.configField(fieldName)!=null) { 1021 curField.initIndex(this,fieldName); 1022 } 1023 curField.initConfigOnUp(systemTrans); 1024 } 1025 } 1026 1027 void initOnUp(Transaction systemTrans) { 1028 if (! stateOK()) { 1029 return; 1030 } 1031 initConfigOnUp(systemTrans); 1032 storeStaticFieldValues(systemTrans, false); 1033 } 1034 1035 Object instantiate(YapObject a_yapObject, Object a_object, MarshallerFamily mf, ObjectHeaderAttributes attributes, YapWriter a_bytes, boolean a_addToIDTree) { 1036 1037 1040 YapStream stream = a_bytes.getStream(); 1041 Transaction trans = a_bytes.getTransaction(); 1042 boolean create = (a_object == null); 1043 1044 if (i_config != null) { 1045 a_bytes.setInstantiationDepth( 1046 i_config.adjustActivationDepth(a_bytes.getInstantiationDepth())); 1047 } 1048 1049 boolean doFields = 1050 (a_bytes.getInstantiationDepth() > 0) 1051 || (i_config != null && (i_config.cascadeOnActivate() == YapConst.YES)); 1052 1053 if (create) { 1054 if (configInstantiates()) { 1055 int bytesOffset = a_bytes._offset; 1056 a_bytes.incrementOffset(YapConst.INT_LENGTH); 1057 try { 1059 a_object = i_config.instantiate(stream, i_fields[0].read(mf, a_bytes)); 1060 } catch (Exception e) { 1061 Messages.logErr(stream.configImpl(), 6, classReflector().getName(), e); 1062 return null; 1063 } 1064 a_bytes._offset = bytesOffset; 1065 } else { 1066 if (_reflector == null) { 1067 return null; 1068 } 1069 1070 stream.instantiating(true); 1071 try { 1072 a_object = _reflector.newInstance(); 1073 } catch (NoSuchMethodError e) { 1074 stream.logMsg(7, classReflector().getName()); 1075 stream.instantiating(false); 1076 return null; 1077 } catch (Exception e) { 1078 stream.instantiating(false); 1080 return null; 1081 } 1082 stream.instantiating(false); 1083 1084 } 1085 if (a_object instanceof TransactionAware) { 1086 ((TransactionAware)a_object).setTrans(a_bytes.getTransaction()); 1087 } 1088 if (a_object instanceof Db4oTypeImpl) { 1089 ((Db4oTypeImpl)a_object).setYapObject(a_yapObject); 1090 } 1091 a_yapObject.setObjectWeak(stream, a_object); 1092 stream.hcTreeAdd(a_yapObject); 1093 } else { 1094 if(! stream.i_refreshInsteadOfActivate){ 1095 if (a_yapObject.isActive()) { 1096 doFields = false; 1097 } 1098 } 1099 } 1100 1101 if(a_addToIDTree){ 1102 a_yapObject.addToIDTree(stream); 1103 } 1104 1105 if (doFields) { 1106 if(objectCanActivate(stream, a_object)){ 1107 a_yapObject.setStateClean(); 1108 instantiateFields(a_yapObject, a_object, mf, attributes, a_bytes); 1109 objectOnActivate(stream, a_object); 1110 }else{ 1111 if (create) { 1112 a_yapObject.setStateDeactivated(); 1113 } 1114 } 1115 } else { 1116 if (create) { 1117 a_yapObject.setStateDeactivated(); 1118 } else { 1119 if (a_bytes.getInstantiationDepth() > 1) { 1120 activateFields(trans, a_object, a_bytes.getInstantiationDepth() - 1); 1121 } 1122 } 1123 } 1124 return a_object; 1125 } 1126 1127 private void objectOnActivate(YapStream stream, Object obj) { 1128 stream.callbacks().objectOnActivate(obj); 1129 dispatchEvent(stream, obj, EventDispatcher.ACTIVATE); 1130 } 1131 1132 private boolean objectCanActivate(YapStream stream, Object obj) { 1133 return stream.callbacks().objectCanActivate(obj) 1134 && dispatchEvent(stream, obj, EventDispatcher.CAN_ACTIVATE); 1135 } 1136 1137 Object instantiateTransient(YapObject a_yapObject, Object a_object, MarshallerFamily mf, ObjectHeaderAttributes attributes, YapWriter a_bytes) { 1138 1139 1142 YapStream stream = a_bytes.getStream(); 1143 1144 if (configInstantiates()) { 1145 int bytesOffset = a_bytes._offset; 1146 a_bytes.incrementOffset(YapConst.INT_LENGTH); 1147 try { 1149 a_object = i_config.instantiate(stream, i_fields[0].read(mf, a_bytes)); 1150 } catch (Exception e) { 1151 Messages.logErr(stream.configImpl(), 6, classReflector().getName(), e); 1152 return null; 1153 } 1154 a_bytes._offset = bytesOffset; 1155 } else { 1156 if (_reflector == null) { 1157 return null; 1158 } 1159 stream.instantiating(true); 1160 try { 1161 a_object = _reflector.newInstance(); 1162 } catch (NoSuchMethodError e) { 1163 stream.logMsg(7, classReflector().getName()); 1164 stream.instantiating(false); 1165 return null; 1166 } catch (Exception e) { 1167 stream.instantiating(false); 1169 return null; 1170 } 1171 stream.instantiating(false); 1172 } 1173 stream.peeked(a_yapObject.getID(), a_object); 1174 instantiateFields(a_yapObject, a_object, mf, attributes, a_bytes); 1175 return a_object; 1176 } 1177 1178 void instantiateFields(YapObject a_yapObject, Object a_onObject, MarshallerFamily mf,ObjectHeaderAttributes attributes, YapWriter a_bytes) { 1179 mf._object.instantiateFields(this, attributes, a_yapObject, a_onObject, a_bytes); 1180 } 1181 1182 public boolean indexNullHandling() { 1183 return true; 1184 } 1185 1186 public boolean isArray() { 1187 return classReflector().isCollection(); 1188 } 1189 1190 boolean isCollection(Object obj) { 1191 return reflector().forObject(obj).isCollection(); 1192 } 1193 1194 public boolean isDirty() { 1195 if (!stateOK()) { 1196 return false; 1197 } 1198 return super.isDirty(); 1199 } 1200 1201 boolean isEnum(){ 1202 return _isEnum; 1203 } 1204 1205 public boolean isPrimitive(){ 1206 return false; 1207 } 1208 1209 public int isSecondClass(){ 1210 return YapConst.NO; 1211 } 1212 1213 1217 boolean isStrongTyped() { 1218 return true; 1219 } 1220 1221 boolean isValueType(){ 1222 return Platform4.isValueType(classReflector()); 1223 } 1224 1225 public void calculateLengths(Transaction trans, ObjectHeaderAttributes header, boolean topLevel, Object obj, boolean withIndirection) { 1226 if(topLevel){ 1227 header.addBaseLength(linkLength()); 1228 }else{ 1229 header.addPayLoadLength(linkLength()); 1230 } 1231 } 1232 1233 public String nameToWrite() { 1234 if(i_config != null && i_config.writeAs() != null){ 1235 return i_config.writeAs(); 1236 } 1237 if(i_name == null){ 1238 return ""; 1239 } 1240 return i_stream.configImpl().resolveAliasRuntimeName(i_name); 1241 } 1242 1243 final boolean callConstructor() { 1244 i_dontCallConstructors = ! callConstructor1(); 1245 return ! i_dontCallConstructors; 1246 } 1247 1248 private final boolean callConstructor1() { 1249 int res = callConstructorSpecialized(); 1250 if(res != YapConst.DEFAULT){ 1251 return res == YapConst.YES; 1252 } 1253 return (i_stream.configImpl().callConstructors() == YapConst.YES); 1254 } 1255 1256 private final int callConstructorSpecialized(){ 1257 if(i_config!= null){ 1258 int res = i_config.callConstructor(); 1259 if(res != YapConst.DEFAULT){ 1260 return res; 1261 } 1262 } 1263 if(_isEnum){ 1264 return YapConst.NO; 1265 } 1266 if(i_ancestor != null){ 1267 return i_ancestor.callConstructorSpecialized(); 1268 } 1269 return YapConst.DEFAULT; 1270 } 1271 1272 public int ownLength() { 1273 return MarshallerFamily.current()._class.marshalledLength(i_stream, this); 1274 } 1275 1276 public ReflectClass primitiveClassReflector(){ 1277 return null; 1278 } 1279 1280 void purge() { 1281 _index.purge(); 1282 1283 } 1286 1287 public Object read(MarshallerFamily mf, YapWriter a_bytes, boolean redirect) throws CorruptionException{ 1288 try { 1289 int id = a_bytes.readInt(); 1290 int depth = a_bytes.getInstantiationDepth() - 1; 1291 1292 Transaction trans = a_bytes.getTransaction(); 1293 YapStream stream = trans.stream(); 1294 1295 if (a_bytes.getUpdateDepth() == YapConst.TRANSIENT) { 1296 return stream.peekPersisted1(trans, id, depth); 1297 } 1298 1299 if (isValueType()) { 1300 1301 1305 if(depth < 1){ 1307 depth = 1; 1308 } 1309 1310 1314 1315 YapObject yo = stream.getYapObject(id); 1316 if (yo != null) { 1317 Object obj = yo.getObject(); 1318 if(obj == null){ 1319 stream.removeReference(yo); 1320 }else{ 1321 yo.activate(trans, obj, depth, false); 1322 return yo.getObject(); 1323 } 1324 } 1325 1326 return new YapObject(id).read( 1327 trans, 1328 null, 1329 null, 1330 depth, 1331 YapConst.ADD_TO_ID_TREE, false); 1332 } 1333 1334 Object ret = stream.getByID2(trans, id); 1335 1336 if (ret instanceof Db4oTypeImpl) { 1337 depth = ((Db4oTypeImpl)ret).adjustReadDepth(depth); 1338 } 1339 1340 stream.stillToActivate(ret, depth); 1343 1344 return ret; 1345 1346 } catch (Exception e) { 1347 } 1348 return null; 1349 } 1350 1351 public Object readQuery(Transaction a_trans, MarshallerFamily mf, boolean withRedirection, YapReader a_reader, boolean a_toArray) throws CorruptionException{ 1352 try { 1353 return a_trans.stream().getByID2(a_trans, a_reader.readInt()); 1354 } catch (Exception e) { 1355 if (Debug.atHome) { 1356 e.printStackTrace(); 1357 } 1358 } 1359 return null; 1360 } 1361 1362 public TypeHandler4 readArrayHandler(Transaction a_trans, MarshallerFamily mf, YapReader[] a_bytes) { 1363 if (isArray()) { 1364 return this; 1365 } 1366 return null; 1367 } 1368 1369 public TypeHandler4 readArrayHandler1(YapReader[] a_bytes) { 1370 if(DTrace.enabled){ 1371 if(a_bytes[0] instanceof YapWriter){ 1372 DTrace.READ_ARRAY_WRAPPER.log(((YapWriter)a_bytes[0]).getID()); 1373 } 1374 } 1375 if (isArray()) { 1376 if (Platform4.isCollectionTranslator(this.i_config)) { 1377 a_bytes[0].incrementOffset(YapConst.INT_LENGTH); 1378 return new YapArray(i_stream, null, false); 1379 } 1380 incrementFieldsOffset1(a_bytes[0]); 1381 if (i_ancestor != null) { 1382 return i_ancestor.readArrayHandler1(a_bytes); 1383 } 1384 } 1385 return null; 1386 } 1387 1388 public QCandidate readSubCandidate(MarshallerFamily mf, YapReader reader, QCandidates candidates, boolean withIndirection) { 1389 int id = reader.readInt(); 1390 if(id == 0){ 1391 return null; 1392 } 1393 return new QCandidate(candidates, null, id, true); 1394 } 1395 1396 public void readCandidates(MarshallerFamily mf, final YapReader a_bytes, final QCandidates a_candidates) { 1397 int id = 0; 1398 1399 int offset = a_bytes._offset; 1400 try { 1401 id = a_bytes.readInt(); 1402 } catch (Exception e) { 1403 } 1404 a_bytes._offset = offset; 1405 1406 if (id != 0) { 1407 final Transaction trans = a_candidates.i_trans; 1408 Object obj = trans.stream().getByID1(trans, id); 1409 if (obj != null) { 1410 1411 a_candidates.i_trans.stream().activate1(trans, obj, 2); 1412 Platform4.forEachCollectionElement(obj, new Visitor4() { 1413 public void visit(Object elem) { 1414 a_candidates.addByIdentity(new QCandidate(a_candidates, elem, (int)trans.stream().getID(elem), true)); 1415 } 1416 }); 1417 } 1418 1419 } 1420 } 1421 1422 public final int readFieldCount(YapReader a_bytes) { 1423 int count = a_bytes.readInt(); 1424 if (count > i_fields.length) { 1425 if (Debug.atHome) { 1426 System.out.println( 1427 "YapClass.readFieldCount " 1428 + getName() 1429 + " count to high:" 1430 + count 1431 + " i_fields:" 1432 + i_fields.length); 1433 new Exception ().printStackTrace(); 1434 } 1435 return i_fields.length; 1436 } 1437 return count; 1438 } 1439 1440 public int readFieldCountSodaAtHome(YapReader a_bytes) { 1441 if (Debug.atHome) { 1442 int count = a_bytes.readInt(); 1443 if (count > i_fields.length) { 1444 return i_fields.length; 1445 } 1446 return count; 1447 } 1448 return 0; 1449 } 1450 1451 public Object readIndexEntry(YapReader a_reader) { 1452 return new Integer (a_reader.readInt()); 1453 } 1454 1455 public Object readIndexEntry(MarshallerFamily mf, YapWriter a_writer) throws CorruptionException{ 1456 return readIndexEntry(a_writer); 1457 } 1458 1459 byte[] readName(Transaction a_trans) { 1460 i_reader = a_trans.stream().readReaderByID(a_trans, getID()); 1461 if (i_reader != null) { 1462 return readName1(a_trans, i_reader); 1463 } 1464 return null; 1465 } 1466 1467 public final byte[] readName1(Transaction trans, YapReader reader) { 1468 i_reader = reader; 1469 1470 try { 1471 ClassMarshaller marshaller = MarshallerFamily.current()._class; 1472 i_nameBytes = marshaller.readName(trans, reader); 1473 _metaClassID = marshaller.readMetaClassID(reader); 1474 1475 setStateUnread(); 1476 1477 bitFalse(YapConst.CHECKED_CHANGES); 1478 bitFalse(YapConst.STATIC_FIELDS_STORED); 1479 1480 return i_nameBytes; 1481 1482 } catch (Throwable t) { 1483 setStateDead(); 1484 if (Debug.atHome) { 1485 t.printStackTrace(); 1486 } 1487 } 1488 return null; 1489 } 1490 1491 void readVirtualAttributes(Transaction a_trans, YapObject a_yapObject) { 1492 int id = a_yapObject.getID(); 1493 YapStream stream = a_trans.stream(); 1494 YapReader reader = stream.readReaderByID(a_trans, id); 1495 ObjectHeader oh = new ObjectHeader(stream, this, reader); 1496 oh.objectMarshaller().readVirtualAttributes(a_trans, this, a_yapObject, oh._headerAttributes, reader); 1497 } 1498 1499 GenericReflector reflector() { 1500 return i_stream.reflector(); 1501 } 1502 1503 public void rename(String newName){ 1504 if (!i_stream.isClient()) { 1505 int tempState = i_state; 1506 setStateOK(); 1507 i_name = newName; 1508 setStateDirty(); 1509 write(i_stream.getSystemTransaction()); 1510 i_state = tempState; 1511 }else{ 1512 Exceptions4.throwRuntimeException(58); 1513 } 1514 } 1515 1516 void createConfigAndConstructor( 1517 Hashtable4 a_byteHashTable, 1518 YapStream a_stream, 1519 ReflectClass a_class) { 1520 if (a_class == null) { 1521 if (i_nameBytes != null) { 1522 String name = a_stream.stringIO().read(i_nameBytes); 1523 i_name = a_stream.configImpl().resolveAliasStoredName(name); 1524 } 1525 } else { 1526 i_name = a_class.getName(); 1527 } 1528 setConfig(i_stream.configImpl().configClass(i_name)); 1529 if (a_class == null) { 1530 createConstructor(a_stream, i_name); 1531 } else { 1532 createConstructor(a_stream, a_class, i_name, true); 1533 } 1534 if (i_nameBytes != null) { 1535 a_byteHashTable.remove(i_nameBytes); 1536 i_nameBytes = null; 1537 } 1538 } 1539 1540 boolean readThis() { 1541 if (stateUnread()) { 1542 setStateOK(); 1543 setStateClean(); 1544 forceRead(); 1545 return true; 1546 } 1547 return false; 1548 } 1549 1550 final void forceRead(){ 1551 if(i_reader == null || bitIsTrue(YapConst.READING)){ 1552 return; 1553 } 1554 1555 bitTrue(YapConst.READING); 1556 1557 MarshallerFamily.forConverterVersion(i_stream.converterVersion())._class.read(i_stream, this, i_reader); 1558 1559 i_nameBytes = null; 1560 i_reader = null; 1561 bitFalse(YapConst.READING); 1562 } 1563 1564 public boolean readArray(Object array, YapReader reader) { 1565 return false; 1566 } 1567 1568 public void readThis(Transaction a_trans, YapReader a_reader) { 1569 throw Exceptions4.virtualException(); 1570 } 1571 1572 void refresh() { 1573 if (!stateUnread()) { 1574 createConstructor(i_stream, i_name); 1575 bitFalse(YapConst.CHECKED_CHANGES); 1576 checkChanges(); 1577 if (i_fields != null) { 1578 for (int i = 0; i < i_fields.length; i++) { 1579 i_fields[i].refresh(); 1580 } 1581 } 1582 } 1583 } 1584 1585 void removeFromIndex(Transaction ta, int id) { 1586 if (hasIndex()) { 1587 _index.remove(ta, id); 1588 } 1589 if (i_ancestor != null) { 1590 i_ancestor.removeFromIndex(ta, id); 1591 } 1592 } 1593 1594 boolean renameField(String a_from, String a_to) { 1595 boolean renamed = false; 1596 for (int i = 0; i < i_fields.length; i++) { 1597 if (i_fields[i].getName().equals(a_to)) { 1598 i_stream.logMsg(9, "class:" + getName() + " field:" + a_to); 1599 return false; 1600 } 1601 } 1602 for (int i = 0; i < i_fields.length; i++) { 1603 if (i_fields[i].getName().equals(a_from)) { 1604 i_fields[i].setName(a_to); 1605 renamed = true; 1606 } 1607 } 1608 return renamed; 1609 } 1610 1611 void setConfig(Config4Class config){ 1612 if(i_config == null){ 1616 i_config = config; 1617 } 1618 } 1619 1620 void setName(String a_name) { 1621 i_name = a_name; 1622 } 1623 1624 private final void setStateDead() { 1625 bitTrue(YapConst.DEAD); 1626 bitFalse(YapConst.CONTINUE); 1627 } 1628 1629 private final void setStateUnread() { 1630 bitFalse(YapConst.DEAD); 1631 bitTrue(YapConst.CONTINUE); 1632 } 1633 1634 private final void setStateOK() { 1635 bitFalse(YapConst.DEAD); 1636 bitFalse(YapConst.CONTINUE); 1637 } 1638 1639 boolean stateDead(){ 1640 return bitIsTrue(YapConst.DEAD); 1641 } 1642 1643 private final boolean stateOK() { 1644 return bitIsFalse(YapConst.CONTINUE) 1645 && bitIsFalse(YapConst.DEAD) 1646 && bitIsFalse(YapConst.READING); 1647 } 1648 1649 final boolean stateOKAndAncestors(){ 1650 if(! stateOK() || i_fields == null){ 1651 return false; 1652 } 1653 if(i_ancestor != null){ 1654 return i_ancestor.stateOKAndAncestors(); 1655 } 1656 return true; 1657 } 1658 1659 boolean stateUnread() { 1660 return bitIsTrue(YapConst.CONTINUE) 1661 && bitIsFalse(YapConst.DEAD) 1662 && bitIsFalse(YapConst.READING); 1663 } 1664 1665 boolean storeField(ReflectField a_field) { 1666 if (a_field.isStatic()) { 1667 return false; 1668 } 1669 if (a_field.isTransient()) { 1670 Config4Class config = configOrAncestorConfig(); 1671 if (config == null) { 1672 return false; 1673 } 1674 if (!config.storeTransientFields()) { 1675 return false; 1676 } 1677 } 1678 return Platform4.canSetAccessible() || a_field.isPublic(); 1679 } 1680 1681 public StoredField storedField(String a_name, Object a_type) { 1682 synchronized(i_stream.i_lock){ 1683 1684 YapClass yc = i_stream.getYapClass(i_stream.configImpl().reflectorFor(a_type)); 1685 1686 if(i_fields != null){ 1687 for (int i = 0; i < i_fields.length; i++) { 1688 if(i_fields[i].getName().equals(a_name)){ 1689 if(yc == null || yc == i_fields[i].getFieldYapClass(i_stream)){ 1690 return (i_fields[i]); 1691 } 1692 } 1693 } 1694 } 1695 1696 1698 return null; 1699 } 1700 } 1701 1702 void storeStaticFieldValues(Transaction trans, boolean force) { 1703 if (!bitIsTrue(YapConst.STATIC_FIELDS_STORED) || force) { 1704 bitTrue(YapConst.STATIC_FIELDS_STORED); 1705 boolean store = 1706 (i_config != null && i_config.staticFieldValuesArePersisted()) 1707 || Platform4.storeStaticFieldValues(trans.reflector(), classReflector()); 1708 1709 if (store) { 1710 YapStream stream = trans.stream(); 1711 stream.showInternalClasses(true); 1712 Query q = stream.query(trans); 1713 q.constrain(YapConst.CLASS_STATICCLASS); 1714 q.descend("name").constrain(i_name); 1715 StaticClass sc = new StaticClass(); 1716 sc.name = i_name; 1717 ObjectSet os = q.execute(); 1718 StaticField[] oldFields = null; 1719 if (os.size() > 0) { 1720 sc = (StaticClass)os.next(); 1721 stream.activate1(trans, sc, 4); 1722 oldFields = sc.fields; 1723 } 1724 ReflectField[] fields = classReflector().getDeclaredFields(); 1725 1726 Collection4 newFields = new Collection4(); 1727 1728 for (int i = 0; i < fields.length; i++) { 1729 if (fields[i].isStatic()) { 1730 fields[i].setAccessible(); 1731 String fieldName = fields[i].getName(); 1732 Object value = fields[i].get(null); 1733 boolean handled = false; 1734 if (oldFields != null) { 1735 for (int j = 0; j < oldFields.length; j++) { 1736 if (fieldName.equals(oldFields[j].name)) { 1737 if (oldFields[j].value != null 1738 && value != null 1739 && oldFields[j].value.getClass() == value.getClass()) { 1740 long id = stream.getID1(oldFields[j].value); 1741 if (id > 0) { 1742 if (oldFields[j].value != value) { 1743 1744 stream.bind1(trans, value, id); 1748 1749 1752 stream.refresh(value, Integer.MAX_VALUE); 1753 1754 oldFields[j].value = value; 1755 } 1756 handled = true; 1757 } 1758 } 1759 if (!handled) { 1760 if(value == null){ 1761 try{ 1762 fields[i].set(null, oldFields[j].value); 1763 }catch(Exception ex){ 1764 } 1766 1767 }else{ 1768 oldFields[j].value = value; 1769 if (!stream.isClient()) { 1770 stream.setInternal(trans, oldFields[j], true); 1771 } 1772 } 1773 } 1774 newFields.add(oldFields[j]); 1775 handled = true; 1776 break; 1777 } 1778 } 1779 } 1780 if (!handled) { 1781 newFields.add(new StaticField(fieldName, value)); 1782 } 1783 } 1784 } 1785 if (newFields.size() > 0) { 1786 sc.fields = new StaticField[newFields.size()]; 1787 newFields.toArray(sc.fields); 1788 if (!stream.isClient()) { 1789 stream.setInternal(trans, sc, true); 1790 } 1791 } 1792 stream.showInternalClasses(false); 1793 } 1794 } 1795 } 1796 1797 public boolean supportsIndex() { 1798 return true; 1799 } 1800 1801 public String toString() { 1802 if(i_name == null && i_nameBytes != null){ 1803 YapStringIO stringIO = 1804 i_stream == null ? 1805 YapConst.stringIO 1806 : i_stream.stringIO(); 1807 return stringIO.read(i_nameBytes); 1808 } 1809 return i_name; 1810 } 1811 1812 public boolean writeArray(Object array, YapReader reader) { 1813 return false; 1814 } 1815 1816 public boolean writeObjectBegin() { 1817 if (!stateOK()) { 1818 return false; 1819 } 1820 return super.writeObjectBegin(); 1821 } 1822 1823 public void writeIndexEntry(YapReader a_writer, Object a_object) { 1824 1825 if(a_object == null){ 1826 a_writer.writeInt(0); 1827 return; 1828 } 1829 1830 a_writer.writeInt(((Integer )a_object).intValue()); 1831 } 1832 1833 public Object writeNew(MarshallerFamily mf, Object a_object, boolean topLevel, YapWriter a_bytes, boolean withIndirection, boolean restoreLinkOffset) { 1834 if (a_object == null) { 1835 a_bytes.writeInt(0); 1836 return new Integer (0); 1837 } 1838 1839 int id = a_bytes.getStream().setInternal( 1840 a_bytes.getTransaction(), 1841 a_object, 1842 a_bytes.getUpdateDepth(), true); 1843 1844 a_bytes.writeInt(id); 1845 return new Integer (id); 1846 } 1847 1848 public final void writeThis(Transaction trans, YapReader writer) { 1849 MarshallerFamily.current()._class.write(trans, this, writer); 1850 } 1851 1852 1854 private ReflectClass i_compareTo; 1855 1856 public void prepareComparison(Transaction a_trans, Object obj) { 1857 prepareComparison(obj); 1858 } 1859 1860 public YapComparable prepareComparison(Object obj) { 1861 if (obj != null) { 1862 if(obj instanceof Integer ){ 1863 i_lastID = ((Integer )obj).intValue(); 1864 }else{ 1865 i_lastID = (int)i_stream.getID(obj); 1866 } 1867 i_compareTo = reflector().forObject(obj); 1868 } else { 1869 i_lastID = 0; 1870 i_compareTo = null; 1871 } 1872 return this; 1873 } 1874 1875 public Object current(){ 1876 if(i_compareTo == null){ 1877 return null; 1878 } 1879 return new Integer (i_lastID); 1880 } 1881 1882 public int compareTo(Object a_obj) { 1883 if(a_obj instanceof Integer ){ 1884 return ((Integer )a_obj).intValue() - i_lastID; 1885 } 1886 if( (a_obj == null) && (i_compareTo == null)){ 1887 return 0; 1888 } 1889 return -1; 1890 } 1891 1892 public boolean isEqual(Object obj) { 1893 if (obj == null) { 1894 return i_compareTo == null; 1895 } 1896 return i_compareTo.isAssignableFrom(reflector().forObject(obj)); 1897 } 1898 1899 public boolean isGreater(Object obj) { 1900 return false; 1901 } 1902 1903 public boolean isSmaller(Object obj) { 1904 return false; 1905 } 1906 1907 public String toString(MarshallerFamily mf, YapWriter writer, YapObject yapObject, int depth, int maxDepth) { 1908 int length = readFieldCount(writer); 1909 String str = ""; 1910 for (int i = 0; i < length; i++) { 1911 str += i_fields[i].toString(mf, writer); 1912 } 1913 if (i_ancestor != null) { 1914 str+= i_ancestor.toString(mf, writer, yapObject, depth, maxDepth); 1915 } 1916 return str; 1917 1918 } 1919 1920 public static void defragObject(ReaderPair readers) { 1921 ObjectHeader header=ObjectHeader.defrag(readers); 1922 header._marshallerFamily._object.defragFields(header.yapClass(),header,readers); 1923 if (Deploy.debug) { 1924 readers.readEnd(); 1925 } 1926 } 1927 1928 public void defrag(MarshallerFamily mf, ReaderPair readers, boolean redirect) { 1929 if(hasIndex()) { 1930 readers.copyID(); 1931 } 1932 else { 1933 readers.copyUnindexedID(); 1934 } 1935 int restLength = (linkLength()-YapConst.INT_LENGTH); 1936 readers.incrementOffset(restLength); 1937 } 1938 1939 public void defragClass(ReaderPair readers, int classIndexID) throws CorruptionException { 1940 MarshallerFamily mf = MarshallerFamily.current(); 1941 mf._class.defrag(this,i_stream.stringIO(), readers, classIndexID); 1942 } 1943 1944 public static YapClass readClass(YapStream stream, YapReader reader) { 1945 ObjectHeader oh = new ObjectHeader(stream, reader); 1946 return oh.yapClass(); 1947 } 1948 1949 public boolean isAssignableFrom(YapClass other) { 1950 return classReflector().isAssignableFrom(other.classReflector()); 1951 } 1952 1953 public final void defragIndexEntry(ReaderPair readers) { 1954 readers.copyID(); 1955 } 1956} 1957 | Popular Tags |