1 8 9 package com.sleepycat.persist.impl; 10 11 import java.io.Serializable ; 12 import java.util.ArrayList ; 13 import java.util.Collections ; 14 import java.util.HashMap ; 15 import java.util.HashSet ; 16 import java.util.IdentityHashMap ; 17 import java.util.List ; 18 import java.util.Map ; 19 import java.util.Set ; 20 21 import com.sleepycat.persist.evolve.Converter; 22 import com.sleepycat.persist.evolve.Deleter; 23 import com.sleepycat.persist.evolve.EntityConverter; 24 import com.sleepycat.persist.evolve.Mutations; 25 import com.sleepycat.persist.evolve.Renamer; 26 import com.sleepycat.persist.model.ClassMetadata; 27 import com.sleepycat.persist.model.EntityMetadata; 28 import com.sleepycat.persist.model.FieldMetadata; 29 import com.sleepycat.persist.model.Relationship; 30 import com.sleepycat.persist.model.SecondaryKeyMetadata; 31 import com.sleepycat.persist.raw.RawField; 32 import com.sleepycat.persist.raw.RawObject; 33 34 40 public class ComplexFormat extends Format { 41 42 private static final long serialVersionUID = -2847843033590454917L; 43 44 private ClassMetadata clsMeta; 45 private EntityMetadata entityMeta; 46 private FieldInfo priKeyField; 47 private List <FieldInfo> secKeyFields; 48 private List <FieldInfo> nonKeyFields; 49 private FieldReader secKeyFieldReader; 50 private FieldReader nonKeyFieldReader; 51 private Map <String ,String > oldToNewKeyMap; 52 private Map <String ,String > newToOldFieldMap; 53 private boolean evolveNeeded; 54 private transient Accessor objAccessor; 55 private transient Accessor rawAccessor; 56 private transient Format entityFormat; 57 private transient Map <String ,FieldAddress> secKeyAddresses; 58 private transient volatile Map <String ,RawField> rawFields; 59 private transient volatile FieldInfo[] rawInputFields; 60 private transient volatile int[] rawInputLevels; 61 private transient volatile int rawInputDepth; 62 63 ComplexFormat(Class cls, 64 ClassMetadata clsMeta, 65 EntityMetadata entityMeta) { 66 super(cls); 67 this.clsMeta = clsMeta; 68 this.entityMeta = entityMeta; 69 secKeyFields = new ArrayList <FieldInfo>(); 70 nonKeyFields = FieldInfo.getInstanceFields(cls); 71 72 76 if (clsMeta.getPrimaryKey() != null) { 77 String fieldName = clsMeta.getPrimaryKey().getName(); 78 FieldInfo field = FieldInfo.getField(nonKeyFields, fieldName); 79 if (field == null) { 80 throw new IllegalArgumentException 81 ("Primary key field does not exist: " + 82 getClassName() + '.' + fieldName); 83 } 84 nonKeyFields.remove(field); 85 priKeyField = field; 86 } 87 88 92 if (clsMeta.getSecondaryKeys() != null) { 93 for (SecondaryKeyMetadata secKeyMeta : 94 clsMeta.getSecondaryKeys().values()) { 95 String fieldName = secKeyMeta.getName(); 96 FieldInfo field = FieldInfo.getField(nonKeyFields, fieldName); 97 if (field == null) { 98 throw new IllegalArgumentException 99 ("Secondary key field does not exist: " + 100 getClassName() + '.' + fieldName); 101 } 102 Class fieldCls = field.getFieldClass(); 103 Relationship rel = secKeyMeta.getRelationship(); 104 if (rel == Relationship.ONE_TO_MANY || 105 rel == Relationship.MANY_TO_MANY) { 106 if (!PersistKeyCreator.isManyType(fieldCls)) { 107 throw new IllegalArgumentException 108 ("ONE_TO_MANY and MANY_TO_MANY keys must" + 109 " have an array or Collection type: " + 110 getClassName() + '.' + fieldName); 111 } 112 } else { 113 if (PersistKeyCreator.isManyType(fieldCls)) { 114 throw new IllegalArgumentException 115 ("ONE_TO_ONE and MANY_TO_ONE keys must not" + 116 " have an array or Collection type: " + 117 getClassName() + '.' + fieldName); 118 } 119 } 120 nonKeyFields.remove(field); 121 secKeyFields.add(field); 122 } 123 } 124 125 126 Collections.sort(secKeyFields); 127 Collections.sort(nonKeyFields); 128 } 129 130 @Override 131 void migrateFromBeta(Map <String ,Format> formatMap) { 132 super.migrateFromBeta(formatMap); 133 if (priKeyField != null) { 134 priKeyField.migrateFromBeta(formatMap); 135 } 136 for (FieldInfo field : secKeyFields) { 137 field.migrateFromBeta(formatMap); 138 } 139 for (FieldInfo field : nonKeyFields) { 140 field.migrateFromBeta(formatMap); 141 } 142 } 143 144 148 private ComplexFormat getComplexSuper() { 149 return (ComplexFormat) getSuperFormat(); 150 } 151 152 156 private ComplexFormat getComplexLatest() { 157 return (ComplexFormat) getLatestVersion(); 158 } 159 160 String getPriKeyField() { 161 if (clsMeta.getPrimaryKey() != null) { 162 return clsMeta.getPrimaryKey().getName(); 163 } else { 164 return null; 165 } 166 } 167 168 @Override 169 boolean isEntity() { 170 return clsMeta.isEntityClass(); 171 } 172 173 @Override 174 boolean isModelClass() { 175 return true; 176 } 177 178 @Override 179 ClassMetadata getClassMetadata() { 180 return clsMeta; 181 } 182 183 @Override 184 EntityMetadata getEntityMetadata() { 185 return entityMeta; 186 } 187 188 @Override 189 Format getEntityFormat() { 190 if (isInitialized()) { 191 return entityFormat; 192 } else { 193 for (Format format = this; 194 format != null; 195 format = format.getSuperFormat()) { 196 if (format.isEntity()) { 197 return format; 198 } 199 } 200 return null; 201 } 202 } 203 204 @Override 205 void setEvolveNeeded(boolean needed) { 206 evolveNeeded = needed; 207 } 208 209 @Override 210 boolean getEvolveNeeded() { 211 return evolveNeeded; 212 } 213 214 @Override 215 public Map <String ,RawField> getFields() { 216 217 223 if (rawFields == null) { 224 Map <String ,RawField> map = new HashMap <String ,RawField>(); 225 if (priKeyField != null) { 226 map.put(priKeyField.getName(), priKeyField); 227 } 228 for (RawField field : secKeyFields) { 229 map.put(field.getName(), field); 230 } 231 for (RawField field : nonKeyFields) { 232 map.put(field.getName(), field); 233 } 234 rawFields = map; 235 } 236 return rawFields; 237 } 238 239 @Override 240 void collectRelatedFormats(Catalog catalog, 241 Map <String ,Format> newFormats) { 242 Class cls = getType(); 243 244 if (priKeyField != null) { 245 priKeyField.collectRelatedFormats(catalog, newFormats); 246 } 247 for (FieldInfo field : secKeyFields) { 248 field.collectRelatedFormats(catalog, newFormats); 249 } 250 for (FieldInfo field : nonKeyFields) { 251 field.collectRelatedFormats(catalog, newFormats); 252 } 253 254 if (entityMeta != null) { 255 for (SecondaryKeyMetadata secKeyMeta : 256 entityMeta.getSecondaryKeys().values()) { 257 String elemClsName = secKeyMeta.getElementClassName(); 258 if (elemClsName != null) { 259 Class elemCls = 260 SimpleCatalog.keyClassForName(elemClsName); 261 catalog.createFormat(elemCls, newFormats); 262 } 263 } 264 } 265 266 Class superCls = cls.getSuperclass(); 267 if (superCls != Object .class) { 268 Format superFormat = catalog.createFormat(superCls, newFormats); 269 if (!(superFormat instanceof ComplexFormat)) { 270 throw new IllegalArgumentException 271 ("The superclass of a complex type must not be a" + 272 " composite key class or a simple type class: " + 273 superCls.getName()); 274 } 275 } 276 277 String proxiedClsName = clsMeta.getProxiedClassName(); 278 if (proxiedClsName != null) { 279 catalog.createFormat(proxiedClsName, newFormats); 280 } 281 } 282 283 @Override 284 void initialize(Catalog catalog) { 285 Class type = getType(); 286 boolean useEnhanced = false; 287 if (type != null) { 288 useEnhanced = EnhancedAccessor.isEnhanced(type); 289 } 290 291 if (priKeyField != null) { 292 priKeyField.initialize(catalog); 293 } 294 for (FieldInfo field : secKeyFields) { 295 field.initialize(catalog); 296 } 297 for (FieldInfo field : nonKeyFields) { 298 field.initialize(catalog); 299 } 300 301 ComplexFormat superFormat = getComplexSuper(); 302 if (type != null && superFormat == null) { 303 Class superCls = type.getSuperclass(); 304 if (superCls != Object .class) { 305 superFormat = 306 (ComplexFormat) catalog.getFormat(superCls.getName()); 307 setSuperFormat(superFormat); 308 } 309 } 310 311 if (superFormat != null) { 312 superFormat.initializeIfNeeded(catalog); 313 Accessor superAccessor = superFormat.objAccessor; 314 if (type != null && superAccessor != null) { 315 if (useEnhanced) { 316 if (!(superAccessor instanceof EnhancedAccessor)) { 317 throw new IllegalStateException 318 ("The superclass of an enhanced class must also " + 319 "be enhanced: " + getClassName() + 320 " extends " + superFormat.getClassName()); 321 } 322 } else { 323 if (!(superAccessor instanceof ReflectionAccessor)) { 324 throw new IllegalStateException 325 ("The superclass of an unenhanced class must " + 326 "not be enhanced: " + getClassName() + 327 " extends " + superFormat.getClassName()); 328 } 329 } 330 } 331 } 332 333 for (Format format = this; 334 format != null; 335 format = format.getSuperFormat()) { 336 if (format.isEntity()) { 337 entityFormat = format; 338 break; 339 } 340 } 341 342 if (type != null) { 343 if (useEnhanced) { 344 objAccessor = new EnhancedAccessor(catalog, type, this); 345 } else { 346 Accessor superObjAccessor = 347 (superFormat != null) ? superFormat.objAccessor : null; 348 objAccessor = new ReflectionAccessor 349 (catalog, type, superObjAccessor, priKeyField, 350 secKeyFields, nonKeyFields); 351 } 352 } 353 Accessor superRawAccessor = 354 (superFormat != null) ? superFormat.rawAccessor : null; 355 rawAccessor = new RawAccessor 356 (this, superRawAccessor, priKeyField, secKeyFields, nonKeyFields); 357 358 359 EntityMetadata latestEntityMeta = null; 360 if (entityFormat != null) { 361 latestEntityMeta = 362 entityFormat.getLatestVersion().getEntityMetadata(); 363 } 364 if (latestEntityMeta != null) { 365 secKeyAddresses = new HashMap <String ,FieldAddress>(); 366 ComplexFormat thisLatest = getComplexLatest(); 367 if (thisLatest != this) { 368 thisLatest.initializeIfNeeded(catalog); 369 } 370 nextKeyLoop: 371 for (SecondaryKeyMetadata secKeyMeta : 372 latestEntityMeta.getSecondaryKeys().values()) { 373 String clsName = secKeyMeta.getDeclaringClassName(); 374 String fieldName = secKeyMeta.getName(); 375 int superLevel = 0; 376 for (ComplexFormat format = this; 377 format != null; 378 format = format.getComplexSuper()) { 379 if (clsName.equals 380 (format.getLatestVersion().getClassName())) { 381 String useFieldName = null; 382 if (format.newToOldFieldMap != null && 383 format.newToOldFieldMap.containsKey(fieldName)) { 384 useFieldName = 385 format.newToOldFieldMap.get(fieldName); 386 } else { 387 useFieldName = fieldName; 388 } 389 boolean isSecField; 390 int fieldNum; 391 FieldInfo info = FieldInfo.getField 392 (format.secKeyFields, useFieldName); 393 if (info != null) { 394 isSecField = true; 395 fieldNum = format.secKeyFields.indexOf(info); 396 } else { 397 isSecField = false; 398 info = FieldInfo.getField 399 (format.nonKeyFields, useFieldName); 400 if (info == null) { 401 402 assert thisLatest != this; 403 thisLatest.checkNewSecKeyInitializer 404 (secKeyMeta); 405 continue nextKeyLoop; 406 } 407 fieldNum = format.nonKeyFields.indexOf(info); 408 } 409 FieldAddress addr = new FieldAddress 410 (isSecField, fieldNum, superLevel, format, 411 info.getType()); 412 secKeyAddresses.put(secKeyMeta.getKeyName(), addr); 413 } 414 superLevel += 1; 415 } 416 } 417 } 418 } 419 420 424 private void checkNewSecKeyInitializer(SecondaryKeyMetadata secKeyMeta) { 425 if (objAccessor != null) { 426 FieldAddress addr = secKeyAddresses.get(secKeyMeta.getKeyName()); 427 Object obj = objAccessor.newInstance(); 428 Object val = objAccessor.getField 429 (obj, addr.fieldNum, addr.superLevel, addr.isSecField); 430 if (val != null) { 431 if (addr.keyFormat.isPrimitive()) { 432 throw new IllegalArgumentException 433 ("For a new secondary key field the field type must " + 434 "not be a primitive -- class: " + 435 secKeyMeta.getDeclaringClassName() + " field: " + 436 secKeyMeta.getName()); 437 } else { 438 throw new IllegalArgumentException 439 ("For a new secondary key field the default " + 440 "constructor must not initialize the field to a " + 441 "non-null value -- class: " + 442 secKeyMeta.getDeclaringClassName() + " field: " + 443 secKeyMeta.getName()); 444 } 445 } 446 } 447 } 448 449 private boolean nullOrEqual(Object o1, Object o2) { 450 if (o1 == null) { 451 return o2 == null; 452 } else { 453 return o1.equals(o2); 454 } 455 } 456 457 @Override 458 Object newArray(int len) { 459 return objAccessor.newArray(len); 460 } 461 462 @Override 463 public Object newInstance(EntityInput input, boolean rawAccess) { 464 Accessor accessor = rawAccess ? rawAccessor : objAccessor; 465 return accessor.newInstance(); 466 } 467 468 @Override 469 public Object readObject(Object o, EntityInput input, boolean rawAccess) { 470 Accessor accessor = rawAccess ? rawAccessor : objAccessor; 471 accessor.readSecKeyFields(o, input, 0, Accessor.MAX_FIELD_NUM, -1); 472 accessor.readNonKeyFields(o, input, 0, Accessor.MAX_FIELD_NUM, -1); 473 return o; 474 } 475 476 @Override 477 void writeObject(Object o, EntityOutput output, boolean rawAccess) { 478 Accessor accessor = rawAccess ? rawAccessor : objAccessor; 479 accessor.writeSecKeyFields(o, output); 480 accessor.writeNonKeyFields(o, output); 481 } 482 483 @Override 484 Object convertRawObject(Catalog catalog, 485 boolean rawAccess, 486 RawObject rawObject, 487 IdentityHashMap converted) { 488 494 FieldInfo[] fields = rawInputFields; 495 int[] levels = rawInputLevels; 496 int depth = rawInputDepth; 497 if (fields == null || levels == null || depth == 0) { 498 499 504 depth = 0; 505 int nFields = 0; 506 for (ComplexFormat format = this; 507 format != null; 508 format = format.getComplexSuper()) { 509 nFields += format.getNFields(); 510 depth += 1; 511 } 512 ComplexFormat[] hierarchy = new ComplexFormat[depth]; 513 int level = depth; 514 for (ComplexFormat format = this; 515 format != null; 516 format = format.getComplexSuper()) { 517 level -= 1; 518 hierarchy[level] = format; 519 } 520 assert level == 0; 521 522 523 levels = new int[nFields]; 524 fields = new FieldInfo[nFields]; 525 int index = 0; 526 527 532 if (getEntityFormat() != null) { 533 for (level = depth - 1; level >= 0; level -= 1) { 534 ComplexFormat format = hierarchy[level]; 535 if (format.priKeyField != null) { 536 levels[index] = level; 537 fields[index] = format.priKeyField; 538 index += 1; 539 break; 540 } 541 } 542 assert index == 1; 543 } 544 545 549 for (level = 0; level < depth; level += 1) { 550 ComplexFormat format = hierarchy[level]; 551 for (FieldInfo field : format.secKeyFields) { 552 levels[index] = level; 553 fields[index] = field; 554 index += 1; 555 } 556 } 557 558 562 for (level = 0; level < depth; level += 1) { 563 ComplexFormat format = hierarchy[level]; 564 for (FieldInfo field : format.nonKeyFields) { 565 levels[index] = level; 566 fields[index] = field; 567 index += 1; 568 } 569 } 570 571 572 assert index == fields.length; 573 rawInputFields = fields; 574 rawInputLevels = levels; 575 rawInputDepth = depth; 576 } 577 578 584 RawObject[] objectsByLevel = new RawObject[depth]; 585 int level = depth; 586 for (RawObject raw = rawObject; raw != null; raw = raw.getSuper()) { 587 if (level == 0) { 588 throw new IllegalArgumentException 589 ("RawObject has too many superclasses: " + 590 rawObject.getType().getClassName()); 591 } 592 level -= 1; 593 objectsByLevel[level] = raw; 594 } 595 if (level > 0) { 596 throw new IllegalArgumentException 597 ("RawObject has too few superclasses: " + 598 rawObject.getType().getClassName()); 599 } 600 assert level == 0; 601 RawObject[] objects = new RawObject[fields.length]; 602 for (int i = 0; i < objects.length; i += 1) { 603 objects[i] = objectsByLevel[levels[i]]; 604 } 605 606 607 EntityInput in = new RawComplexInput 608 (catalog, rawAccess, converted, fields, objects); 609 Object o = newInstance(in, rawAccess); 610 converted.put(rawObject, o); 611 if (getEntityFormat() != null) { 612 readPriKey(o, in, rawAccess); 613 } 614 return readObject(o, in, rawAccess); 615 } 616 617 @Override 618 boolean isPriKeyNullOrZero(Object o, boolean rawAccess) { 619 Accessor accessor = rawAccess ? rawAccessor : objAccessor; 620 return accessor.isPriKeyFieldNullOrZero(o); 621 } 622 623 @Override 624 void writePriKey(Object o, EntityOutput output, boolean rawAccess) { 625 Accessor accessor = rawAccess ? rawAccessor : objAccessor; 626 accessor.writePriKeyField(o, output); 627 } 628 629 @Override 630 public void readPriKey(Object o, EntityInput input, boolean rawAccess) { 631 Accessor accessor = rawAccess ? rawAccessor : objAccessor; 632 accessor.readPriKeyField(o, input); 633 } 634 635 @Override 636 boolean nullifySecKey(Catalog catalog, 637 Object entity, 638 String keyName, 639 Object keyElement) { 640 if (secKeyAddresses == null) { 641 throw new IllegalStateException (); 642 } 643 FieldAddress addr = secKeyAddresses.get(keyName); 644 if (addr != null) { 645 Object oldVal = rawAccessor.getField 646 (entity, addr.fieldNum, addr.superLevel, addr.isSecField); 647 if (oldVal != null) { 648 if (keyElement != null) { 649 RawObject container = (RawObject) oldVal; 650 Object [] a1 = container.getElements(); 651 boolean isArray = (a1 != null); 652 if (!isArray) { 653 a1 = CollectionProxy.getElements(container); 654 } 655 if (a1 != null) { 656 for (int i = 0; i < a1.length; i += 1) { 657 if (keyElement.equals(a1[i])) { 658 int len = a1.length - 1; 659 Object [] a2 = new Object [len]; 660 System.arraycopy(a1, 0, a2, 0, i); 661 System.arraycopy(a1, i + 1, a2, i, len - i); 662 if (isArray) { 663 rawAccessor.setField 664 (entity, addr.fieldNum, 665 addr.superLevel, addr.isSecField, 666 new RawObject 667 (container.getType(), a2)); 668 } else { 669 CollectionProxy.setElements(container, a2); 670 } 671 return true; 672 } 673 } 674 } 675 return false; 676 } else { 677 rawAccessor.setField 678 (entity, addr.fieldNum, addr.superLevel, 679 addr.isSecField, null); 680 return true; 681 } 682 } else { 683 return false; 684 } 685 } else { 686 return false; 687 } 688 } 689 690 @Override 691 void skipContents(RecordInput input) { 692 skipToSecKeyField(input, Accessor.MAX_FIELD_NUM); 693 skipToNonKeyField(input, Accessor.MAX_FIELD_NUM); 694 } 695 696 @Override 697 void copySecMultiKey(RecordInput input, Format keyFormat, Set results) { 698 CollectionProxy.copyElements(input, this, keyFormat, results); 699 } 700 701 @Override 702 Format skipToSecKey(RecordInput input, String keyName) { 703 if (secKeyAddresses == null) { 704 throw new IllegalStateException (); 705 } 706 FieldAddress addr = secKeyAddresses.get(keyName); 707 if (addr != null) { 708 if (addr.isSecField) { 709 addr.clsFormat.skipToSecKeyField(input, addr.fieldNum); 710 } else { 711 skipToSecKeyField(input, Accessor.MAX_FIELD_NUM); 712 addr.clsFormat.skipToNonKeyField(input, addr.fieldNum); 713 } 714 return addr.keyFormat; 715 } else { 716 return null; 717 } 718 } 719 720 private int getNFields() { 721 return ((priKeyField != null) ? 1 : 0) + 722 secKeyFields.size() + 723 nonKeyFields.size(); 724 } 725 726 private void skipToSecKeyField(RecordInput input, int toFieldNum) { 727 ComplexFormat superFormat = getComplexSuper(); 728 if (superFormat != null) { 729 superFormat.skipToSecKeyField(input, Accessor.MAX_FIELD_NUM); 730 } 731 int maxNum = Math.min(secKeyFields.size(), toFieldNum); 732 for (int i = 0; i < maxNum; i += 1) { 733 input.skipField(secKeyFields.get(i).getType()); 734 } 735 } 736 737 private void skipToNonKeyField(RecordInput input, int toFieldNum) { 738 ComplexFormat superFormat = getComplexSuper(); 739 if (superFormat != null) { 740 superFormat.skipToNonKeyField(input, Accessor.MAX_FIELD_NUM); 741 } 742 int maxNum = Math.min(nonKeyFields.size(), toFieldNum); 743 for (int i = 0; i < maxNum; i += 1) { 744 input.skipField(nonKeyFields.get(i).getType()); 745 } 746 } 747 748 private static class FieldAddress { 749 750 boolean isSecField; 751 int fieldNum; 752 int superLevel; 753 ComplexFormat clsFormat; 754 Format keyFormat; 755 756 FieldAddress(boolean isSecField, 757 int fieldNum, 758 int superLevel, 759 ComplexFormat clsFormat, 760 Format keyFormat) { 761 this.isSecField = isSecField; 762 this.fieldNum = fieldNum; 763 this.superLevel = superLevel; 764 this.clsFormat = clsFormat; 765 this.keyFormat = keyFormat; 766 } 767 } 768 769 @Override 770 boolean evolve(Format newFormatParam, Evolver evolver) { 771 772 773 if (!(newFormatParam instanceof ComplexFormat)) { 774 evolver.addMissingMutation 775 (this, newFormatParam, 776 "Converter is required when a complex type is changed " + 777 "to a simple type or enum type"); 778 return false; 779 } 780 ComplexFormat newFormat = (ComplexFormat) newFormatParam; 781 Mutations mutations = evolver.getMutations(); 782 boolean thisChanged = false; 783 boolean superChanged = false; 784 Map <String ,String > allKeyNameMap = new HashMap <String ,String >(); 785 786 792 for (ComplexFormat oldSuper = getComplexSuper(); 793 oldSuper != null; 794 oldSuper = oldSuper.getComplexSuper()) { 795 Converter converter = mutations.getConverter 796 (oldSuper.getClassName(), oldSuper.getVersion(), null); 797 if (converter != null) { 798 evolver.addMissingMutation 799 (this, newFormatParam, 800 "Converter is required for this subclass when a " + 801 "Converter appears on its superclass: " + converter); 802 return false; 803 } 804 if (!evolver.evolveFormat(oldSuper)) { 805 return false; 806 } 807 if (!oldSuper.isCurrentVersion()) { 808 if (oldSuper.isDeleted()) { 809 if (!oldSuper.evolveDeletedClass(evolver)) { 810 return false; 811 } 812 } 813 if (oldSuper.oldToNewKeyMap != null) { 814 allKeyNameMap.putAll(oldSuper.oldToNewKeyMap); 815 } 816 superChanged = true; 817 } 818 } 819 820 829 Class newFormatCls = newFormat.getExistingType(); 830 Class newSuper = newFormatCls; 831 List <Integer > newLevels = new ArrayList <Integer >(); 832 int newLevel = 0; 833 newLevels.add(newLevel); 834 835 839 if (getSuperFormat() == null) { 840 if (newFormatCls.getSuperclass() != Object .class) { 841 thisChanged = true; 842 superChanged = true; 843 } 844 } else { 845 if (!getSuperFormat().getLatestVersion().getClassName().equals 846 (newFormatCls.getSuperclass().getName())) { 847 thisChanged = true; 848 superChanged = true; 849 } 850 } 851 852 for (ComplexFormat oldSuper = getComplexSuper(); 853 oldSuper != null; 854 oldSuper = oldSuper.getComplexSuper()) { 855 856 857 String oldSuperName = oldSuper.getLatestVersion().getClassName(); 858 Class foundNewSuper = null; 859 int tryNewLevel = newLevel; 860 for (Class newSuper2 = newSuper.getSuperclass(); 861 newSuper2 != Object .class; 862 newSuper2 = newSuper2.getSuperclass()) { 863 tryNewLevel += 1; 864 if (oldSuperName.equals(newSuper2.getName())) { 865 foundNewSuper = newSuper2; 866 newLevel = tryNewLevel; 867 break; 868 } 869 } 870 871 if (foundNewSuper != null) { 872 873 878 for (Class newSuper2 = newSuper.getSuperclass(); 879 newSuper2 != foundNewSuper; 880 newSuper2 = newSuper2.getSuperclass()) { 881 882 885 superChanged = true; 886 887 891 for (ComplexFormat oldSuper2 = oldSuper.getComplexSuper(); 892 oldSuper2 != null; 893 oldSuper2 = oldSuper2.getComplexSuper()) { 894 String oldSuper2Name = 895 oldSuper2.getLatestVersion().getClassName(); 896 if (oldSuper2Name.equals(newSuper2.getName())) { 897 evolver.addMissingMutation 898 (this, newFormatParam, 899 "Class Converter is required when a " + 900 "superclass is moved in the class " + 901 "hierarchy: " + newSuper2.getName()); 902 return false; 903 } 904 } 905 } 906 newSuper = foundNewSuper; 907 newLevels.add(newLevel); 908 } else { 909 910 915 superChanged = true; 916 917 918 if (!oldSuper.isDeleted()) { 919 ComplexFormat oldSuperLatest = 920 oldSuper.getComplexLatest(); 921 if (oldSuperLatest.getNFields() != 0) { 922 evolver.addMissingMutation 923 (this, newFormatParam, 924 "When a superclass is removed from the class " + 925 "hierarchy, the superclass or all of its " + 926 "persistent fields must be deleted with a " + 927 "Deleter: " + 928 oldSuperLatest.getClassName()); 929 return false; 930 } 931 } 932 933 if (isEntity() && isCurrentVersion()) { 934 Map <String ,SecondaryKeyMetadata> secKeys = 935 oldSuper.clsMeta.getSecondaryKeys(); 936 for (FieldInfo field : oldSuper.secKeyFields) { 937 SecondaryKeyMetadata meta = 938 secKeys.get(field.getName()); 939 assert meta != null; 940 allKeyNameMap.put(meta.getKeyName(), null); 941 } 942 } 943 944 948 newLevels.add(EvolveReader.DO_NOT_READ_ACCESSOR); 949 } 950 } 951 952 953 int result = evolveAllFields(newFormat, evolver); 954 if (result == Evolver.EVOLVE_FAILURE) { 955 return false; 956 } 957 if (result == Evolver.EVOLVE_NEEDED) { 958 thisChanged = true; 959 } 960 if (oldToNewKeyMap != null) { 961 allKeyNameMap.putAll(oldToNewKeyMap); 962 } 963 964 965 if (thisChanged && 966 !evolver.checkUpdatedVersion 967 ("Changes to the fields or superclass were detected", this, 968 newFormat)) { 969 return false; 970 } 971 972 973 if (allKeyNameMap.size() > 0 && isEntity() && isCurrentVersion()) { 974 for (Map.Entry <String ,String > entry : allKeyNameMap.entrySet()) { 975 String oldKeyName = entry.getKey(); 976 String newKeyName = entry.getValue(); 977 if (newKeyName != null) { 978 evolver.renameSecondaryDatabase 979 (this, newFormat, oldKeyName, newKeyName); 980 } else { 981 evolver.deleteSecondaryDatabase(this, oldKeyName); 982 } 983 } 984 } 985 986 987 if (superChanged || thisChanged) { 988 Reader reader = new EvolveReader(newLevels); 989 evolver.useEvolvedFormat(this, reader, newFormat); 990 } else { 991 evolver.useOldFormat(this, newFormat); 992 } 993 return true; 994 } 995 996 @Override 997 boolean evolveMetadata(Format newFormatParam, 998 Converter converter, 999 Evolver evolver) { 1000 assert !isDeleted(); 1001 assert isEntity(); 1002 assert newFormatParam.isEntity(); 1003 ComplexFormat newFormat = (ComplexFormat) newFormatParam; 1004 1005 if (!checkKeyTypeChange 1006 (newFormat, entityMeta.getPrimaryKey(), 1007 newFormat.entityMeta.getPrimaryKey(), "primary key", 1008 evolver)) { 1009 return false; 1010 } 1011 1012 Set <String > deletedKeys; 1013 if (converter instanceof EntityConverter) { 1014 EntityConverter entityConverter = (EntityConverter) converter; 1015 deletedKeys = entityConverter.getDeletedKeys(); 1016 } else { 1017 deletedKeys = Collections.emptySet(); 1018 } 1019 1020 Map <String ,SecondaryKeyMetadata> oldSecondaryKeys = 1021 entityMeta.getSecondaryKeys(); 1022 Map <String ,SecondaryKeyMetadata> newSecondaryKeys = 1023 newFormat.entityMeta.getSecondaryKeys(); 1024 Set <String > insertedKeys = 1025 new HashSet <String >(newSecondaryKeys.keySet()); 1026 1027 for (SecondaryKeyMetadata oldMeta : oldSecondaryKeys.values()) { 1028 String keyName = oldMeta.getKeyName(); 1029 if (deletedKeys.contains(keyName)) { 1030 if (isCurrentVersion()) { 1031 evolver.deleteSecondaryDatabase(this, keyName); 1032 } 1033 } else { 1034 SecondaryKeyMetadata newMeta = newSecondaryKeys.get(keyName); 1035 if (newMeta == null) { 1036 evolver.addInvalidMutation 1037 (this, newFormat, converter, 1038 "Existing key not found in new entity metadata: " + 1039 keyName); 1040 return false; 1041 } 1042 insertedKeys.remove(keyName); 1043 String keyLabel = "secondary key: " + keyName; 1044 if (!checkKeyTypeChange 1045 (newFormat, oldMeta, newMeta, keyLabel, evolver)) { 1046 return false; 1047 } 1048 if (!checkSecKeyMetadata 1049 (newFormat, oldMeta, newMeta, evolver)) { 1050 return false; 1051 } 1052 } 1053 } 1054 1055 if (!insertedKeys.isEmpty()) { 1056 evolver.addEvolveError 1057 (this, newFormat, "Error", 1058 "New keys " + insertedKeys + 1059 " not allowed when using a Converter with an entity class"); 1060 } 1061 1062 return true; 1063 } 1064 1065 1068 private boolean checkSecKeyMetadata(Format newFormat, 1069 SecondaryKeyMetadata oldMeta, 1070 SecondaryKeyMetadata newMeta, 1071 Evolver evolver) { 1072 if (oldMeta.getRelationship() != newMeta.getRelationship()) { 1073 evolver.addEvolveError 1074 (this, newFormat, 1075 "Change detected in the relate attribute (Relationship) " + 1076 "of a secondary key", 1077 "Old key: " + oldMeta.getKeyName() + 1078 " relate: " + oldMeta.getRelationship() + 1079 " new key: " + newMeta.getKeyName() + 1080 " relate: " + newMeta.getRelationship()); 1081 return false; 1082 } 1083 return true; 1084 } 1085 1086 1090 private boolean checkKeyTypeChange(Format newFormat, 1091 FieldMetadata oldMeta, 1092 FieldMetadata newMeta, 1093 String keyLabel, 1094 Evolver evolver) { 1095 String oldClass = oldMeta.getClassName(); 1096 String newClass = newMeta.getClassName(); 1097 if (!oldClass.equals(newClass)) { 1098 SimpleCatalog catalog = SimpleCatalog.getInstance(); 1099 Format oldType = catalog.getFormat(oldClass); 1100 Format newType = catalog.getFormat(newClass); 1101 if (oldType == null || newType == null || 1102 ((oldType.getWrapperFormat() == null || 1103 oldType.getWrapperFormat().getId() != 1104 newType.getId()) && 1105 (newType.getWrapperFormat() == null || 1106 newType.getWrapperFormat().getId() != 1107 oldType.getId()))) { 1108 evolver.addEvolveError 1109 (this, newFormat, 1110 "Type change detected for " + keyLabel, 1111 "Old field type: " + oldClass + 1112 " is not compatible with the new type: " + 1113 newClass + 1114 " old field: " + oldMeta.getName() + 1115 " new field: " + newMeta.getName()); 1116 return false; 1117 } 1118 } 1119 return true; 1120 } 1121 1122 1126 private boolean evolveDeletedClass(Evolver evolver) { 1127 assert isDeleted(); 1128 if (secKeyFieldReader == null || nonKeyFieldReader == null) { 1129 if (priKeyField != null && 1130 getEntityFormat() != null && 1131 !getEntityFormat().isDeleted()) { 1132 evolver.addEvolveError 1133 (this, this, 1134 "Class containing primary key field was deleted ", 1135 "Primary key is needed in an entity class hierarchy: " + 1136 priKeyField.getName()); 1137 return false; 1138 } else { 1139 secKeyFieldReader = new SkipFieldReader(0, secKeyFields); 1140 nonKeyFieldReader = new SkipFieldReader(0, nonKeyFields); 1141 return true; 1142 } 1143 } else { 1144 return true; 1145 } 1146 } 1147 1148 1153 private int evolveAllFields(ComplexFormat newFormat, Evolver evolver) { 1154 1155 assert !isDeleted(); 1156 secKeyFieldReader = null; 1157 nonKeyFieldReader = null; 1158 oldToNewKeyMap = null; 1159 1160 1161 boolean evolveFailure = false; 1162 boolean evolveNeeded = false; 1163 if (priKeyField != null) { 1164 int result = evolver.evolveRequiredKeyField 1165 (this, newFormat, priKeyField, newFormat.priKeyField); 1166 if (result == Evolver.EVOLVE_FAILURE) { 1167 evolveFailure = true; 1168 } else if (result == Evolver.EVOLVE_NEEDED) { 1169 evolveNeeded = true; 1170 } 1171 } 1172 1173 1174 FieldReader reader = evolveFieldList 1175 (secKeyFields, newFormat.secKeyFields, true, 1176 newFormat.nonKeyFields, newFormat, evolver); 1177 if (reader == FieldReader.EVOLVE_FAILURE) { 1178 evolveFailure = true; 1179 } else if (reader != null) { 1180 evolveNeeded = true; 1181 } 1182 if (reader != FieldReader.EVOLVE_NEEDED) { 1183 secKeyFieldReader = reader; 1184 } 1185 1186 1187 reader = evolveFieldList 1188 (nonKeyFields, newFormat.nonKeyFields, false, 1189 newFormat.secKeyFields, newFormat, evolver); 1190 if (reader == FieldReader.EVOLVE_FAILURE) { 1191 evolveFailure = true; 1192 } else if (reader != null) { 1193 evolveNeeded = true; 1194 } 1195 if (reader != FieldReader.EVOLVE_NEEDED) { 1196 nonKeyFieldReader = reader; 1197 } 1198 1199 1200 if (evolveFailure) { 1201 return Evolver.EVOLVE_FAILURE; 1202 } else if (evolveNeeded) { 1203 return Evolver.EVOLVE_NEEDED; 1204 } else { 1205 return Evolver.EVOLVE_NONE; 1206 } 1207 } 1208 1209 1216 private FieldReader evolveFieldList(List <FieldInfo> oldFields, 1217 List <FieldInfo> newFields, 1218 boolean isOldSecKeyField, 1219 List <FieldInfo> otherNewFields, 1220 ComplexFormat newFormat, 1221 Evolver evolver) { 1222 Mutations mutations = evolver.getMutations(); 1223 boolean evolveFailure = false; 1224 boolean evolveNeeded = false; 1225 boolean readerNeeded = false; 1226 List <FieldReader> fieldReaders = new ArrayList <FieldReader>(); 1227 FieldReader currentReader = null; 1228 int prevNewFieldIndex = newFields.size(); 1229 int newFieldsMatched = 0; 1230 1231 1235 fieldLoop: 1236 for (int oldFieldIndex = 0; 1237 oldFieldIndex < oldFields.size(); 1238 oldFieldIndex += 1) { 1239 1240 FieldInfo oldField = oldFields.get(oldFieldIndex); 1241 String oldName = oldField.getName(); 1242 SecondaryKeyMetadata oldMeta = null; 1243 if (isOldSecKeyField) { 1244 oldMeta = clsMeta.getSecondaryKeys().get(oldName); 1245 assert oldMeta != null; 1246 } 1247 1248 1249 Renamer renamer = mutations.getRenamer 1250 (getClassName(), getVersion(), oldName); 1251 Deleter deleter = mutations.getDeleter 1252 (getClassName(), getVersion(), oldName); 1253 Converter converter = mutations.getConverter 1254 (getClassName(), getVersion(), oldName); 1255 if (deleter != null && (converter != null || renamer != null)) { 1256 evolver.addInvalidMutation 1257 (this, newFormat, deleter, 1258 "Field Deleter is not allowed along with a Renamer or " + 1259 "Converter for the same field: " + oldName); 1260 evolveFailure = true; 1261 continue fieldLoop; 1262 } 1263 1264 1270 String newName = (renamer != null) ? 1271 renamer.getNewName() : oldName; 1272 if (!oldName.equals(newName)) { 1273 if (newToOldFieldMap == null) { 1274 newToOldFieldMap = new HashMap <String ,String >(); 1275 } 1276 newToOldFieldMap.put(newName, oldName); 1277 } 1278 int newFieldIndex = FieldInfo.getFieldIndex(newFields, newName); 1279 FieldInfo newField = null; 1280 boolean isNewSecKeyField = isOldSecKeyField; 1281 if (newFieldIndex >= 0) { 1282 newField = newFields.get(newFieldIndex); 1283 } else { 1284 newFieldIndex = FieldInfo.getFieldIndex 1285 (otherNewFields, newName); 1286 if (newFieldIndex >= 0) { 1287 newField = otherNewFields.get(newFieldIndex); 1288 isNewSecKeyField = !isOldSecKeyField; 1289 } 1290 evolveNeeded = true; 1291 readerNeeded = true; 1292 } 1293 1294 1295 if (deleter != null) { 1296 if (newField != null) { 1297 evolver.addInvalidMutation 1298 (this, newFormat, deleter, 1299 "Field Deleter is not allowed when the persistent " + 1300 "field is still present: " + oldName); 1301 evolveFailure = true; 1302 } 1303 1304 if (currentReader instanceof SkipFieldReader && 1305 currentReader.acceptField 1306 (oldFieldIndex, newFieldIndex, isNewSecKeyField)) { 1307 currentReader.addField(oldField); 1308 } else { 1309 currentReader = new SkipFieldReader 1310 (oldFieldIndex, oldField); 1311 fieldReaders.add(currentReader); 1312 readerNeeded = true; 1313 evolveNeeded = true; 1314 } 1315 if (isOldSecKeyField) { 1316 if (oldToNewKeyMap == null) { 1317 oldToNewKeyMap = new HashMap <String ,String >(); 1318 } 1319 oldToNewKeyMap.put(oldMeta.getKeyName(), null); 1320 } 1321 continue fieldLoop; 1322 } else { 1323 if (newField == null) { 1324 evolver.addMissingMutation 1325 (this, newFormat, 1326 "Field is not present or not persistent: " + 1327 oldName); 1328 evolveFailure = true; 1329 continue fieldLoop; 1330 } 1331 } 1332 1333 1337 newFieldsMatched += 1; 1338 1339 1340 SecondaryKeyMetadata newMeta = null; 1341 if (isOldSecKeyField && isNewSecKeyField) { 1342 newMeta = newFormat.clsMeta.getSecondaryKeys().get(newName); 1343 assert newMeta != null; 1344 1345 1346 if (!checkSecKeyMetadata 1347 (newFormat, oldMeta, newMeta, evolver)) { 1348 evolveFailure = true; 1349 continue fieldLoop; 1350 } 1351 1352 1357 String oldKeyName = oldMeta.getKeyName(); 1358 String newKeyName = newMeta.getKeyName(); 1359 if (!oldKeyName.equals(newKeyName)) { 1360 if (oldToNewKeyMap == null) { 1361 oldToNewKeyMap = new HashMap <String ,String >(); 1362 } 1363 oldToNewKeyMap.put(oldName, newName); 1364 evolveNeeded = true; 1365 } 1366 } else if (isOldSecKeyField && !isNewSecKeyField) { 1367 if (oldToNewKeyMap == null) { 1368 oldToNewKeyMap = new HashMap <String ,String >(); 1369 } 1370 oldToNewKeyMap.put(oldMeta.getKeyName(), null); 1371 } 1372 1373 1374 if (converter != null) { 1375 if (isOldSecKeyField) { 1376 evolver.addInvalidMutation 1377 (this, newFormat, converter, 1378 "Field Converter is not allowed for secondary key " + 1379 "fields: " + oldName); 1380 evolveFailure = true; 1381 } else { 1382 currentReader = new ConvertFieldReader 1383 (converter, newFieldIndex, isNewSecKeyField); 1384 fieldReaders.add(currentReader); 1385 readerNeeded = true; 1386 evolveNeeded = true; 1387 } 1388 continue fieldLoop; 1389 } 1390 1391 1396 boolean allClassesConverted = true; 1397 Format oldFieldFormat = oldField.getType(); 1398 for (Format formatVersion = oldFieldFormat.getLatestVersion(); 1399 true; 1400 formatVersion = formatVersion.getPreviousVersion()) { 1401 assert formatVersion != null; 1402 if (!evolver.evolveFormat(formatVersion)) { 1403 evolveFailure = true; 1404 continue fieldLoop; 1405 } 1406 if (!formatVersion.isNew() && 1407 !evolver.isClassConverted(formatVersion)) { 1408 allClassesConverted = false; 1409 } 1410 Set <Format> subclassFormats = 1411 evolver.getSubclassFormats(formatVersion); 1412 if (subclassFormats != null) { 1413 for (Format format2 : subclassFormats) { 1414 if (!evolver.evolveFormat(format2)) { 1415 evolveFailure = true; 1416 continue fieldLoop; 1417 } 1418 if (!format2.isNew() && 1419 !evolver.isClassConverted(format2)) { 1420 allClassesConverted = false; 1421 } 1422 } 1423 } 1424 if (formatVersion == oldFieldFormat) { 1425 break; 1426 } 1427 } 1428 1429 1434 Format oldLatestFormat = oldFieldFormat.getLatestVersion(); 1435 Format newFieldFormat = newField.getType(); 1436 if (oldLatestFormat.getClassName().equals 1437 (newFieldFormat.getClassName()) && 1438 !oldLatestFormat.isDeleted()) { 1439 1440 } else if (allClassesConverted) { 1441 1442 evolveNeeded = true; 1443 } else if (WidenerInput.isWideningSupported 1444 (oldLatestFormat, newFieldFormat, isOldSecKeyField)) { 1445 1446 currentReader = new WidenFieldReader 1447 (oldLatestFormat, newFieldFormat, newFieldIndex, 1448 isNewSecKeyField); 1449 fieldReaders.add(currentReader); 1450 readerNeeded = true; 1451 evolveNeeded = true; 1452 continue fieldLoop; 1453 } else { 1454 boolean refWidened = false; 1455 if (!newFieldFormat.isPrimitive() && 1456 !oldLatestFormat.isPrimitive() && 1457 !oldLatestFormat.isDeleted() && 1458 !evolver.isClassConverted(oldLatestFormat)) { 1459 Class oldCls = oldLatestFormat.getExistingType(); 1460 Class newCls = newFieldFormat.getExistingType(); 1461 if (newCls.isAssignableFrom(oldCls)) { 1462 refWidened = true; 1463 } 1464 } 1465 if (refWidened) { 1466 1467 evolveNeeded = true; 1468 } else { 1469 1470 evolver.addMissingMutation 1471 (this, newFormat, 1472 "Old field type: " + oldLatestFormat.getClassName() + 1473 " is not compatible with the new type: " + 1474 newFieldFormat.getClassName() + 1475 " for field: " + oldName); 1476 evolveFailure = true; 1477 continue fieldLoop; 1478 } 1479 } 1480 1481 1486 if (currentReader instanceof PlainFieldReader && 1487 currentReader.acceptField 1488 (oldFieldIndex, newFieldIndex, isNewSecKeyField)) { 1489 currentReader.addField(oldField); 1490 } else { 1491 currentReader = new PlainFieldReader 1492 (oldFieldIndex, newFieldIndex, isNewSecKeyField); 1493 fieldReaders.add(currentReader); 1494 } 1495 } 1496 1497 1498 if (newFieldsMatched < newFields.size()) { 1499 evolveNeeded = true; 1500 if (oldFields.size() > 0) { 1501 readerNeeded = true; 1502 } 1503 } 1504 1505 if (evolveFailure) { 1506 return FieldReader.EVOLVE_FAILURE; 1507 } else if (readerNeeded) { 1508 assert fieldReaders.size() > 0 : getClassName(); 1509 if (fieldReaders.size() == 1) { 1510 return fieldReaders.get(0); 1511 } else { 1512 return new MultiFieldReader(fieldReaders); 1513 } 1514 } else if (evolveNeeded) { 1515 return FieldReader.EVOLVE_NEEDED; 1516 } else { 1517 return null; 1518 } 1519 } 1520 1521 1526 private static abstract class FieldReader implements Serializable { 1527 1528 static final FieldReader EVOLVE_NEEDED = 1529 new PlainFieldReader(0, 0, false); 1530 static final FieldReader EVOLVE_FAILURE = 1531 new PlainFieldReader(0, 0, false); 1532 1533 private static final long serialVersionUID = 866041475399255164L; 1534 1535 FieldReader() { 1536 } 1537 1538 void initialize(Catalog catalog, 1539 ComplexFormat oldParentFormat, 1540 ComplexFormat newParentFormat, 1541 boolean isOldSecKey) { 1542 } 1543 1544 boolean acceptField(int oldFieldIndex, 1545 int newFieldIndex, 1546 boolean isNewSecKeyField) { 1547 return false; 1548 } 1549 1550 void addField(FieldInfo oldField) { 1551 throw new UnsupportedOperationException (); 1552 } 1553 1554 abstract void readFields(Object o, 1555 EntityInput input, 1556 Accessor accessor, 1557 int superLevel); 1558 } 1559 1560 1564 private static class PlainFieldReader extends FieldReader { 1565 1566 private static final long serialVersionUID = 1795593463439931402L; 1567 1568 private int startField; 1569 private int endField; 1570 private boolean secKeyField; 1571 private transient int endOldField; 1572 1573 PlainFieldReader(int oldFieldIndex, 1574 int newFieldIndex, 1575 boolean isNewSecKeyField) { 1576 endOldField = oldFieldIndex; 1577 startField = newFieldIndex; 1578 endField = newFieldIndex; 1579 secKeyField = isNewSecKeyField; 1580 } 1581 1582 @Override 1583 boolean acceptField(int oldFieldIndex, 1584 int newFieldIndex, 1585 boolean isNewSecKeyField) { 1586 return oldFieldIndex == endOldField + 1 && 1587 newFieldIndex == endField + 1 && 1588 secKeyField == isNewSecKeyField; 1589 } 1590 1591 @Override 1592 void addField(FieldInfo oldField) { 1593 endField += 1; 1594 endOldField += 1; 1595 } 1596 1597 @Override 1598 final void readFields(Object o, 1599 EntityInput input, 1600 Accessor accessor, 1601 int superLevel) { 1602 if (secKeyField) { 1603 accessor.readSecKeyFields 1604 (o, input, startField, endField, superLevel); 1605 } else { 1606 accessor.readNonKeyFields 1607 (o, input, startField, endField, superLevel); 1608 } 1609 } 1610 } 1611 1612 1616 private static class SkipFieldReader extends FieldReader { 1617 1618 private static final long serialVersionUID = -3060281692155253098L; 1619 1620 private List <Format> fieldFormats; 1621 private transient int endField; 1622 1623 SkipFieldReader(int startField, List <FieldInfo> fields) { 1624 endField = startField + fields.size() - 1; 1625 fieldFormats = new ArrayList <Format>(fields.size()); 1626 for (FieldInfo field : fields) { 1627 fieldFormats.add(field.getType()); 1628 } 1629 } 1630 1631 SkipFieldReader(int startField, FieldInfo oldField) { 1632 endField = startField; 1633 fieldFormats = new ArrayList <Format>(); 1634 fieldFormats.add(oldField.getType()); 1635 } 1636 1637 @Override 1638 boolean acceptField(int oldFieldIndex, 1639 int newFieldIndex, 1640 boolean isNewSecKeyField) { 1641 return oldFieldIndex == endField + 1; 1642 } 1643 1644 @Override 1645 void addField(FieldInfo oldField) { 1646 endField += 1; 1647 fieldFormats.add(oldField.getType()); 1648 } 1649 1650 @Override 1651 final void readFields(Object o, 1652 EntityInput input, 1653 Accessor accessor, 1654 int superLevel) { 1655 for (Format format : fieldFormats) { 1656 input.skipField(format); 1657 } 1658 } 1659 } 1660 1661 1664 private static class ConvertFieldReader extends FieldReader { 1665 1666 private static final long serialVersionUID = 8736410481633998710L; 1667 1668 private Converter converter; 1669 private int fieldNum; 1670 private boolean secKeyField; 1671 private transient Format oldFormat; 1672 private transient Format newFormat; 1673 1674 ConvertFieldReader(Converter converter, 1675 int newFieldIndex, 1676 boolean isNewSecKeyField) { 1677 this.converter = converter; 1678 fieldNum = newFieldIndex; 1679 secKeyField = isNewSecKeyField; 1680 } 1681 1682 @Override 1683 void initialize(Catalog catalog, 1684 ComplexFormat oldParentFormat, 1685 ComplexFormat newParentFormat, 1686 boolean isOldSecKey) { 1687 if (isOldSecKey) { 1688 oldFormat = 1689 oldParentFormat.secKeyFields.get(fieldNum).getType(); 1690 } else { 1691 oldFormat = 1692 oldParentFormat.nonKeyFields.get(fieldNum).getType(); 1693 } 1694 if (secKeyField) { 1695 newFormat = 1696 newParentFormat.secKeyFields.get(fieldNum).getType(); 1697 } else { 1698 newFormat = 1699 newParentFormat.nonKeyFields.get(fieldNum).getType(); 1700 } 1701 } 1702 1703 @Override 1704 final void readFields(Object o, 1705 EntityInput input, 1706 Accessor accessor, 1707 int superLevel) { 1708 1709 1710 boolean currentRawMode = input.setRawAccess(true); 1711 Object value; 1712 try { 1713 if (oldFormat.isPrimitive()) { 1714 value = input.readKeyObject(oldFormat); 1715 } else { 1716 value = input.readObject(); 1717 } 1718 } finally { 1719 input.setRawAccess(currentRawMode); 1720 } 1721 1722 1723 Catalog catalog = input.getCatalog(); 1724 value = converter.getConversion().convert(value); 1725 1726 1727 EntityInput rawInput = new RawSingleInput 1728 (catalog, currentRawMode, null, value, newFormat); 1729 1730 if (secKeyField) { 1731 accessor.readSecKeyFields 1732 (o, rawInput, fieldNum, fieldNum, superLevel); 1733 } else { 1734 accessor.readNonKeyFields 1735 (o, rawInput, fieldNum, fieldNum, superLevel); 1736 } 1737 } 1738 } 1739 1740 1743 private static class WidenFieldReader extends FieldReader { 1744 1745 private static final long serialVersionUID = -2054520670170407282L; 1746 1747 private int fromFormatId; 1748 private int toFormatId; 1749 private int fieldNum; 1750 private boolean secKeyField; 1751 1752 WidenFieldReader(Format oldFormat, 1753 Format newFormat, 1754 int newFieldIndex, 1755 boolean isNewSecKeyField) { 1756 fromFormatId = oldFormat.getId(); 1757 toFormatId = newFormat.getId(); 1758 fieldNum = newFieldIndex; 1759 secKeyField = isNewSecKeyField; 1760 } 1761 1762 @Override 1763 final void readFields(Object o, 1764 EntityInput input, 1765 Accessor accessor, 1766 int superLevel) { 1767 1768 1769 EntityInput widenerInput = new WidenerInput 1770 (input, fromFormatId, toFormatId); 1771 1772 if (secKeyField) { 1773 accessor.readSecKeyFields 1774 (o, widenerInput, fieldNum, fieldNum, superLevel); 1775 } else { 1776 accessor.readNonKeyFields 1777 (o, widenerInput, fieldNum, fieldNum, superLevel); 1778 } 1779 } 1780 } 1781 1782 1787 private static class MultiFieldReader extends FieldReader { 1788 1789 private static final long serialVersionUID = -6035976787562441473L; 1790 1791 private List <FieldReader> subReaders; 1792 1793 MultiFieldReader(List <FieldReader> subReaders) { 1794 this.subReaders = subReaders; 1795 } 1796 1797 @Override 1798 void initialize(Catalog catalog, 1799 ComplexFormat oldParentFormat, 1800 ComplexFormat newParentFormat, 1801 boolean isOldSecKey) { 1802 for (FieldReader reader : subReaders) { 1803 reader.initialize 1804 (catalog, oldParentFormat, newParentFormat, isOldSecKey); 1805 } 1806 } 1807 1808 @Override 1809 final void readFields(Object o, 1810 EntityInput input, 1811 Accessor accessor, 1812 int superLevel) { 1813 for (FieldReader reader : subReaders) { 1814 reader.readFields(o, input, accessor, superLevel); 1815 } 1816 } 1817 } 1818 1819 1827 private static class EvolveReader implements Reader { 1828 1829 static final int DO_NOT_READ_ACCESSOR = Integer.MAX_VALUE; 1830 1831 private static final long serialVersionUID = -1016140948306913283L; 1832 1833 private transient ComplexFormat newFormat; 1834 1835 1839 private transient ComplexFormat[] oldHierarchy; 1840 1841 1846 private int[] newHierarchyLevels; 1847 1848 EvolveReader(List <Integer > newHierarchyLevelsList) { 1849 int oldDepth = newHierarchyLevelsList.size(); 1850 newHierarchyLevels = new int[oldDepth]; 1851 newHierarchyLevelsList.toArray(); 1852 for (int i = 0; i < oldDepth; i += 1) { 1853 newHierarchyLevels[i] = newHierarchyLevelsList.get(i); 1854 } 1855 } 1856 1857 public void initializeReader(Catalog catalog, Format oldFormatParam) { 1858 1859 ComplexFormat oldFormat = (ComplexFormat) oldFormatParam; 1860 newFormat = oldFormat.getComplexLatest(); 1861 newFormat.initializeIfNeeded(catalog); 1862 1863 1864 int newDepth = 0; 1865 for (Format format = newFormat; 1866 format != null; 1867 format = format.getSuperFormat()) { 1868 newDepth += 1; 1869 } 1870 ComplexFormat[] newHierarchy = new ComplexFormat[newDepth]; 1871 int level = 0; 1872 for (ComplexFormat format = newFormat; 1873 format != null; 1874 format = format.getComplexSuper()) { 1875 newHierarchy[level] = format; 1876 level += 1; 1877 } 1878 assert level == newDepth; 1879 1880 1881 int oldDepth = newHierarchyLevels.length; 1882 oldHierarchy = new ComplexFormat[oldDepth]; 1883 level = 0; 1884 for (ComplexFormat oldFormat2 = oldFormat; 1885 oldFormat2 != null; 1886 oldFormat2 = oldFormat2.getComplexSuper()) { 1887 oldHierarchy[level] = oldFormat2; 1888 int level2 = newHierarchyLevels[level]; 1889 ComplexFormat newFormat2 = (level2 != DO_NOT_READ_ACCESSOR) ? 1890 newHierarchy[level2] : null; 1891 level += 1; 1892 if (oldFormat2.secKeyFieldReader != null) { 1893 oldFormat2.secKeyFieldReader.initialize 1894 (catalog, oldFormat2, newFormat2, true); 1895 } 1896 if (oldFormat2.nonKeyFieldReader != null) { 1897 oldFormat2.nonKeyFieldReader.initialize 1898 (catalog, oldFormat2, newFormat2, false); 1899 } 1900 } 1901 assert level == oldDepth; 1902 } 1903 1904 public Object newInstance(EntityInput input, boolean rawAccess) { 1905 return newFormat.newInstance(input, rawAccess); 1906 } 1907 1908 public void readPriKey(Object o, 1909 EntityInput input, 1910 boolean rawAccess) { 1911 1912 newFormat.readPriKey(o, input, rawAccess); 1913 } 1914 1915 public Object readObject(Object o, 1916 EntityInput input, 1917 boolean rawAccess) { 1918 1919 1920 Accessor accessor = rawAccess ? newFormat.rawAccessor 1921 : newFormat.objAccessor; 1922 1923 1924 int maxMinusOne = oldHierarchy.length - 1; 1925 1926 1927 for (int i = maxMinusOne; i >= 0; i -= 1) { 1928 FieldReader reader = oldHierarchy[i].secKeyFieldReader; 1929 int newLevel = newHierarchyLevels[i]; 1930 if (reader != null) { 1931 reader.readFields(o, input, accessor, newLevel); 1932 } else if (newLevel != DO_NOT_READ_ACCESSOR) { 1933 accessor.readSecKeyFields 1934 (o, input, 0, Accessor.MAX_FIELD_NUM, newLevel); 1935 } 1936 } 1937 1938 1939 for (int i = maxMinusOne; i >= 0; i -= 1) { 1940 FieldReader reader = oldHierarchy[i].nonKeyFieldReader; 1941 int newLevel = newHierarchyLevels[i]; 1942 if (reader != null) { 1943 reader.readFields(o, input, accessor, newLevel); 1944 } else if (newLevel != DO_NOT_READ_ACCESSOR) { 1945 accessor.readNonKeyFields 1946 (o, input, 0, Accessor.MAX_FIELD_NUM, newLevel); 1947 } 1948 } 1949 return o; 1950 } 1951 } 1952} 1953 | Popular Tags |