1 2 12 package com.versant.core.metadata; 13 14 import com.versant.core.jdo.VersantPersistenceManagerImp; 15 import com.versant.core.jdo.VersantStateManager; 16 import com.versant.core.jdo.sco.*; 17 import com.versant.core.metadata.parser.JdoArray; 18 import com.versant.core.metadata.parser.JdoCollection; 19 import com.versant.core.metadata.parser.JdoField; 20 import com.versant.core.metadata.parser.JdoMap; 21 import com.versant.core.jdo.query.OrderNode; 22 import com.versant.core.jdo.externalizer.Externalizer; 23 import com.versant.core.util.classhelper.ClassHelper; 24 25 import javax.jdo.spi.PersistenceCapable; 26 import java.io.*; 27 import java.lang.reflect.Field ; 28 import java.lang.reflect.Modifier ; 29 import java.util.*; 30 31 import com.versant.core.common.*; 32 33 37 public class FieldMetaData implements Externalizable, Comparable , MDStatics, 38 VersantFieldMetaData 39 { 40 41 44 public ClassMetaData classMetaData; 45 49 public JdoField jdoField; 50 53 public String name; 54 public String origName; 55 58 public int fieldNo; 59 62 public int stateFieldNo; 63 66 public int managedFieldNo = -1; 67 71 public boolean fake; 72 78 public FieldMetaData[] fakeLinks; 79 85 public int persistenceModifier; 86 98 public int category; 99 103 public Externalizer externalizer; 104 108 public boolean collectionDiffType; 109 110 116 public boolean primaryField; 117 123 public boolean secondaryField; 124 127 public Class type; 128 134 public int typeCode; 135 136 139 public String stateGetMethodName; 140 144 public Class componentType; 145 150 public int componentTypeCode; 151 159 public ClassMetaData typeMetaData; 160 165 public int modifiers; 166 169 public boolean primaryKey; 170 175 private Object pkDefaultValue; 176 180 private transient Field objectidClassField; 181 188 public int nullValue; 189 192 public boolean defaultFetchGroup; 193 197 public boolean defaultFetchGroupDefault; 198 201 public boolean embedded; 202 203 206 public JdoCollection jdoCollection; 207 210 public JdoArray jdoArray; 211 214 public JdoMap jdoMap; 215 219 public Class elementType; 220 226 public int elementTypeCode; 227 230 public ClassMetaData elementTypeMetaData; 231 235 public boolean embeddedElement; 236 239 public Class keyType; 240 246 public int keyTypeCode; 247 250 public ClassMetaData keyTypeMetaData; 251 254 public boolean embeddedKey; 255 258 public boolean ordered; 259 263 public FetchGroup fetchGroup; 264 265 273 public boolean dependentValues; 274 281 public boolean dependentKeys; 282 283 288 public int autoSet; 289 290 293 public transient Object storeField; 294 300 public boolean includeAllDataInDiff; 301 305 public boolean isMaster; 306 311 public boolean isDetail; 312 315 public boolean isManyToMany; 316 319 public boolean isReadOnly; 320 324 public int inverseFieldNo = -1; 325 330 public boolean managed; 331 335 public FieldMetaData inverseFieldMetaData; 336 339 public boolean scoField; 340 345 public boolean nullIfNotFound; 346 350 public transient OrderNode[] ordering; 351 360 public int cascadeType = 0; 361 362 private transient Comparator comparator; 363 private transient boolean comparatorInitDone; 364 private RuntimeException error; 365 private long errorTime = Long.MAX_VALUE; 366 private Object scoFactory; 367 public VersantSCOFactory simpleSCOFactory; 368 public VersantSCOCollectionFactory collectionFactory; 369 public VersantSCOMapFactory mapFactory; 370 public static final String NO_FIELD_TEXT = "{auto}"; 371 public FieldMetaData origFmd; 374 public FieldMetaData[] embeddedFmds; 375 378 public FieldMetaData nullIndicatorFmd; 379 public FieldMetaData[] managedEmbeddedFields; 380 383 public boolean embeddedFakeField; 384 387 public boolean horizontalFakeField; 388 389 public FieldMetaData() { 390 } 391 392 public String toString() { 393 return "Field " + name; 394 } 395 396 399 public String getQName() { 400 return classMetaData.qname + "." + name; 401 } 402 403 406 public String getTypeQName() { 407 return type.getName() + " " + getQName(); 408 } 409 410 420 public ClassMetaData getRefOrValueClassMetaData() { 421 if (category == MDStatics.CATEGORY_EXTERNALIZED) return null; 422 if (typeMetaData != null) return typeMetaData; 423 return elementTypeMetaData; 424 } 425 426 429 public void findFetchGroups(ArrayList a) { 430 FetchGroup[] groups = classMetaData.fetchGroups; 431 int n = groups.length; 432 for (int i = 0; i < n; i++) { 433 FetchGroup g = groups[i]; 434 if (g.contains(this)) a.add(g); 435 } 436 } 437 438 public void dump() { 439 dump(Debug.OUT, ""); 440 } 441 442 public void dump(PrintStream out, String indent) { 443 out.println(indent + this); 444 String is = indent + " "; 445 out.println(is + "persistenceModifier = " + 446 MDStaticUtils.toPersistenceModifierString(persistenceModifier)); 447 out.println(is + "category = " + 448 MDStaticUtils.toCategoryString(category)); 449 out.println(is + "isPass1Field = " + primaryField); 450 out.println(is + "isPass2Field = " + secondaryField); 451 out.println(is + "fieldNo = " + fieldNo); 452 out.println(is + "stateFieldNo = " + stateFieldNo); 453 out.println(is + "fake = " + fake); 454 StringBuffer s = new StringBuffer (); 455 s.append(is + "fakeLinks = "); 456 if (fakeLinks == null) { 457 s.append("null"); 458 } else { 459 for (int i = 0; i < fakeLinks.length; i++) { 460 if (i > 0) s.append(", "); 461 s.append(fakeLinks[i].name); 462 } 463 s.append(']'); 464 } 465 out.println(s.toString()); 466 out.println(is + "type = " + type); 467 out.println(is + "typeCode = " + typeCode); 468 out.println(is + "componentType = " + componentType); 469 out.println(is + "componentTypeCode = " + componentTypeCode); 470 out.println(is + "typeMetaData = " + typeMetaData); 471 out.println(is + "modifiers = " + modifiers); 472 out.println(is + "primaryKey = " + primaryKey); 473 out.println(is + "nullValue = " + 474 MDStaticUtils.toNullValueString(nullValue)); 475 out.println(is + "defaultFetchGroup = " + defaultFetchGroup); 476 out.println( 477 is + "defaultFetchGroupDefault = " + defaultFetchGroupDefault); 478 out.println(is + "embedded = " + embedded); 479 out.println(is + "jdoCollection = " + jdoCollection); 480 out.println(is + "jdoArray = " + jdoArray); 481 out.println(is + "jdoMap = " + jdoMap); 482 out.println(is + "elementType = " + elementType); 483 out.println(is + "elementTypeCode = " + elementTypeCode); 484 out.println(is + "elementTypeMetaData = " + elementTypeMetaData); 485 out.println(is + "embeddedElement = " + embeddedElement); 486 out.println(is + "keyType = " + keyType); 487 out.println(is + "keyTypeCode = " + keyTypeCode); 488 out.println(is + "keyTypeMetaData = " + keyTypeMetaData); 489 out.println(is + "embeddedKey = " + embeddedKey); 490 out.println(is + "ordered = " + ordered); 491 out.println(is + "fetchGroup = " + fetchGroup); 492 out.println(is + "dependentValues = " + dependentValues); 493 out.println(is + "dependentKeys = " + dependentKeys); 494 out.println(is + "autoSet = " + MDStaticUtils.toAutoSetString(autoSet)); 495 496 out.println(is + "isMaster = " + isMaster); 497 out.println(is + "isDetail = " + isDetail); 498 out.println(is + "isManyToMany = " + isManyToMany); 499 out.println(is + "isReadOnly = " + isReadOnly); 500 out.println(is + "inverseFieldNo = " + inverseFieldNo); 501 502 out.println(is + "storeField = " + storeField); 503 } 504 505 509 public int compareTo(Object o) { 510 return name.compareTo(((FieldMetaData)o).name); 511 } 512 513 public void setType(Class type) { 514 this.type = type; 515 if (type == null) { 516 typeCode = 0; 517 } else { 518 typeCode = MDStaticUtils.toTypeCode(type); 519 } 520 } 521 522 public static void setStateMethodName(FieldMetaData fmd) { 523 switch (fmd.category) { 524 case MDStatics.CATEGORY_SIMPLE: 525 switch (fmd.typeCode) { 526 case MDStatics.INT: 527 528 fmd.stateGetMethodName = MDStatics.STATE_METHOD_INT; 529 break; 530 case MDStatics.LONG: 531 532 fmd.stateGetMethodName = MDStatics.STATE_METHOD_LONG; 533 break; 534 case MDStatics.SHORT: 535 536 fmd.stateGetMethodName = MDStatics.STATE_METHOD_SHORT; 537 break; 538 case MDStatics.STRING: 539 fmd.stateGetMethodName = MDStatics.STATE_METHOD_STRING; 540 break; 541 case MDStatics.BOOLEAN: 542 fmd.stateGetMethodName = MDStatics.STATE_METHOD_BOOLEAN; 543 break; 544 case MDStatics.BYTE: 545 546 fmd.stateGetMethodName = MDStatics.STATE_METHOD_BYTE; 547 break; 548 case MDStatics.CHAR: 549 fmd.stateGetMethodName = MDStatics.STATE_METHOD_CHAR; 550 break; 551 case MDStatics.DOUBLE: 552 fmd.stateGetMethodName = MDStatics.STATE_METHOD_DOUBLE; 553 break; 554 case MDStatics.FLOAT: 555 fmd.stateGetMethodName = MDStatics.STATE_METHOD_FLOAT; 556 break; 557 default: 558 fmd.stateGetMethodName = MDStatics.STATE_METHOD_OBJECT; 559 break; 560 } 561 break; 562 default: 563 fmd.stateGetMethodName = MDStatics.STATE_METHOD_OBJECT; 564 break; 565 } 566 } 567 568 public void setComponentType(Class componentType) { 569 this.componentType = componentType; 570 if (componentType == null) { 571 componentTypeCode = 0; 572 } else { 573 componentTypeCode = MDStaticUtils.toTypeCode(componentType); 574 } 575 } 576 577 public void setElementType(Class elementType) { 578 this.elementType = elementType; 579 if (elementType == null) { 580 elementTypeCode = 0; 581 } else { 582 elementTypeCode = MDStaticUtils.toTypeCode(elementType); 583 } 584 } 585 586 public void setKeyType(Class keyType) { 587 this.keyType = keyType; 588 if (keyType == null) { 589 keyTypeCode = 0; 590 } else { 591 keyTypeCode = MDStaticUtils.toTypeCode(keyType); 592 } 593 } 594 595 public void setScoField(boolean scoField) { 596 this.scoField = scoField; 597 } 598 599 603 public boolean isDirectRef() { 604 return category == MDStatics.CATEGORY_REF; 605 } 606 607 public void setAutoSet(int autoSet) { 608 this.autoSet = autoSet; 609 } 610 611 614 public boolean isElementTypePC() { 615 return elementTypeMetaData != null 616 || elementType == Object .class 617 || (elementType != null && elementType.isInterface()); 618 } 619 620 625 public boolean isMapKeyRef() { 626 return (category == MDStatics.CATEGORY_MAP ? isKeyTypePC() : false); 627 } 628 629 634 public boolean isMapValueRef() { 635 return (category == MDStatics.CATEGORY_MAP ? isElementTypePC() : false); 636 } 637 638 643 public boolean isClearOnRetainValues() { 644 return autoSet == MDStatics.AUTOSET_NO; 645 } 646 647 656 public boolean includeInAllFGs() { 657 return autoSet != AUTOSET_NO; 659 } 660 661 665 public boolean isDefaultFetchGroupTrue() { 666 return jdoField != null && jdoField.defaultFetchGroup == MDStatics.TRUE; 667 } 668 669 public boolean isJDODefaultFetchGroup() { 670 if (isEmbeddedRef()) return false; 671 if (defaultFetchGroupDefault || isDefaultFetchGroupTrue()) { 672 if (!defaultFetchGroup) { 673 return false; 674 } else { 675 return true; 676 } 677 } 678 return false; 679 } 680 681 709 713 public Object getPKDefaultValue() { 714 if (Debug.DEBUG) { 715 if (!primaryKey || classMetaData.identityType != MDStatics.IDENTITY_TYPE_APPLICATION) { 716 throw BindingSupportImpl.getInstance().internal( 717 "Not an application identity class: " + getQName()); 718 } 719 } 720 if (!primaryKey) { 721 throw BindingSupportImpl.getInstance().internal("Not a primary-key field: " + 722 getQName()); 723 } 724 return pkDefaultValue; 725 } 726 727 public void initPkDefaultValue(Object pkClassInst) { 728 if (Debug.DEBUG) { 729 if (!primaryKey || classMetaData.identityType != MDStatics.IDENTITY_TYPE_APPLICATION) { 730 throw BindingSupportImpl.getInstance().internal( 731 "Not an application identity class: " + getQName()); 732 } 733 } 734 if (!primaryKey) { 735 throw BindingSupportImpl.getInstance().internal("Not a primary-key field: " + 736 getQName()); 737 } 738 if (pkDefaultValue == null) { 739 try { 740 pkDefaultValue = classMetaData.objectIdClass.getField(getPkFieldName()).get( 741 pkClassInst); 742 } catch (Exception e) { 743 throw BindingSupportImpl.getInstance().exception("Unable to get primary key field from objectid-class: " + 744 getQName() + ": " + e, e); 745 } 746 } 747 } 748 749 public void setPkDefaultValue(Object pkDefaultValue) { 750 this.pkDefaultValue = pkDefaultValue; 751 } 752 753 public void writeExternal(ObjectOutput out) throws IOException { 754 out.writeObject(classMetaData); 758 out.writeObject(jdoField); 759 out.writeObject(name); 760 out.writeObject(origName); 761 out.writeInt(fieldNo); 762 out.writeInt(stateFieldNo); 763 out.writeInt(managedFieldNo); 764 out.writeBoolean(fake); 765 out.writeObject(fakeLinks); 766 out.writeInt(persistenceModifier); 767 out.writeInt(category); 768 out.writeBoolean(primaryField); 769 out.writeBoolean(secondaryField); 770 out.writeInt(typeCode); 771 if (MDStaticUtils.toSimpleClass(MDStaticUtils.toSimpleName(typeCode)) == null) { 772 out.writeObject(type); 773 } 774 out.writeObject(componentType); 775 out.writeInt(componentTypeCode); 776 out.writeObject(typeMetaData); 777 out.writeInt(modifiers); 778 out.writeInt(nullValue); 779 out.writeBoolean(defaultFetchGroup); 780 out.writeBoolean(defaultFetchGroupDefault); 781 out.writeBoolean(embedded); 782 out.writeObject(jdoCollection); 783 out.writeObject(jdoArray); 784 out.writeObject(elementType); 785 out.writeInt(elementTypeCode); 786 out.writeObject(elementTypeMetaData); 787 out.writeBoolean(embeddedElement); 788 out.writeObject(keyType); 789 out.writeInt(keyTypeCode); 790 out.writeObject(keyTypeMetaData); 791 out.writeBoolean(embeddedKey); 792 out.writeBoolean(ordered); 793 out.writeObject(fetchGroup); 794 out.writeBoolean(dependentValues); 795 out.writeBoolean(dependentKeys); 796 out.writeInt(autoSet); 797 out.writeBoolean(scoField); 798 out.writeBoolean(primaryKey); 799 out.writeBoolean(collectionDiffType); 800 if (stateGetMethodName == null) { 801 out.writeBoolean(false); 802 } else { 803 out.writeBoolean(true); 804 out.writeUTF(stateGetMethodName); 805 } 806 out.writeBoolean(isMaster); 807 out.writeBoolean(isDetail); 808 out.writeBoolean(isManyToMany); 809 out.writeBoolean(managed); 810 out.writeBoolean(isReadOnly); 811 out.writeInt(inverseFieldNo); 812 out.writeObject(simpleSCOFactory); 813 out.writeObject(collectionFactory); 814 out.writeObject(mapFactory); 815 out.writeBoolean(includeAllDataInDiff); 816 out.writeObject(inverseFieldMetaData); 817 out.writeObject(externalizer); 818 819 out.writeObject(managedEmbeddedFields); 820 out.writeObject(nullIndicatorFmd); 821 out.writeBoolean(embeddedFakeField); 822 out.writeObject(origFmd); 823 out.writeObject(embeddedFmds); 824 } 825 826 public void readExternal(ObjectInput in) throws IOException, 827 ClassNotFoundException { 828 classMetaData = (ClassMetaData)in.readObject(); 829 jdoField = (JdoField)in.readObject(); 830 name = (String )in.readObject(); 831 origName = (String )in.readObject(); 832 fieldNo = in.readInt(); 833 stateFieldNo = in.readInt(); 834 managedFieldNo = in.readInt(); 835 fake = in.readBoolean(); 836 fakeLinks = (FieldMetaData[])in.readObject(); 837 persistenceModifier = in.readInt(); 838 category = in.readInt(); 839 primaryField = in.readBoolean(); 840 secondaryField = in.readBoolean(); 841 typeCode = in.readInt(); 842 type = MDStaticUtils.toSimpleClass( 843 MDStaticUtils.toSimpleName(typeCode)); 844 if (type == null) { 845 type = (Class )in.readObject(); 846 } 847 componentType = (Class )in.readObject(); 848 componentTypeCode = in.readInt(); 849 typeMetaData = (ClassMetaData)in.readObject(); 850 modifiers = in.readInt(); 851 nullValue = in.readInt(); 852 defaultFetchGroup = in.readBoolean(); 853 defaultFetchGroupDefault = in.readBoolean(); 854 embedded = in.readBoolean(); 855 jdoCollection = (JdoCollection)in.readObject(); 856 jdoArray = (JdoArray)in.readObject(); 857 elementType = (Class )in.readObject(); 858 elementTypeCode = in.readInt(); 859 elementTypeMetaData = (ClassMetaData)in.readObject(); 860 embeddedElement = in.readBoolean(); 861 keyType = (Class )in.readObject(); 862 keyTypeCode = in.readInt(); 863 keyTypeMetaData = (ClassMetaData)in.readObject(); 864 embeddedKey = in.readBoolean(); 865 ordered = in.readBoolean(); 866 fetchGroup = (FetchGroup)in.readObject(); 867 dependentValues = in.readBoolean(); 868 dependentKeys = in.readBoolean(); 869 autoSet = in.readInt(); 870 scoField = in.readBoolean(); 871 primaryKey = in.readBoolean(); 872 collectionDiffType = in.readBoolean(); 873 if (in.readBoolean()) { 874 stateGetMethodName = in.readUTF(); 875 } else { 876 stateGetMethodName = null; 877 } 878 isMaster = in.readBoolean(); 879 isDetail = in.readBoolean(); 880 isManyToMany = in.readBoolean(); 881 managed = in.readBoolean(); 882 isReadOnly = in.readBoolean(); 883 inverseFieldNo = in.readInt(); 884 simpleSCOFactory = (VersantSCOFactory)in.readObject(); 885 collectionFactory = (VersantSCOCollectionFactory)in.readObject(); 886 mapFactory = (VersantSCOMapFactory)in.readObject(); 887 includeAllDataInDiff = in.readBoolean(); 888 inverseFieldMetaData = (FieldMetaData)in.readObject(); 889 externalizer = (Externalizer)in.readObject(); 890 891 managedEmbeddedFields = (FieldMetaData[]) in.readObject(); 892 nullIndicatorFmd = (FieldMetaData) in.readObject(); 893 embeddedFakeField = in.readBoolean(); 894 origFmd = (FieldMetaData)in.readObject(); 895 embeddedFmds = (FieldMetaData[])in.readObject(); 896 } 897 898 902 public String getCommentName() { 903 if (classMetaData.pcSuperMetaData == null) return name; 904 if (classMetaData.jdoClass == null) return getQName(); 905 return classMetaData.jdoClass.name + "." + name; 906 } 907 908 912 public Comparator getComparator() { 913 if (!comparatorInitDone) { 914 comparatorInitDone = true; 915 boolean set = SortedSet.class.isAssignableFrom(type); 916 boolean map = !set && SortedMap.class.isAssignableFrom(type); 917 if (set || map) { 918 Object o = classMetaData.getMetaDataInstance(); 919 if (o != null) { 920 Field f = getReflectField(); 921 try { 922 Object v = ClassHelper.get().getFieldValue(f, o); 923 if (v != null) { 924 if (set) { 925 comparator = ((SortedSet)v).comparator(); 926 } else { 927 comparator = ((SortedMap)v).comparator(); 928 } 929 } 930 } catch (Exception x) { 931 throw BindingSupportImpl.getInstance().invalidOperation("Unable get Field comparator with reflection: " + 932 getQName() + ": " + x, x); 933 } 934 } 935 } 936 } 937 return comparator; 938 } 939 940 944 public Field getReflectField() { 945 try { 946 Field f = classMetaData.cls.getDeclaredField(origName); 947 ClassHelper.get().setAccessible(f, true); 948 return f; 949 } catch (Exception x) { 950 throw BindingSupportImpl.getInstance().invalidOperation("Unable get Field with reflection: " + 951 getQName() + ": " + x, x); 952 } 953 } 954 955 public void addError(RuntimeException e, boolean quiet) { 956 if (Debug.DEBUG) e.printStackTrace(System.out); 957 if (error == null) { 958 errorTime = System.currentTimeMillis(); 959 error = e; 960 try { 961 Thread.sleep(1); 962 } catch (InterruptedException e1) { 963 } 965 } 966 if (!quiet) throw e; 967 } 968 969 public RuntimeException getFirstError() { 970 return error; 971 } 972 973 public long getFirstErrorTime() { 974 return errorTime; 975 } 976 977 public boolean hasErrors() { 978 return error != null; 979 } 980 981 984 public String getName() { 985 return name; 986 } 987 988 991 public boolean isOrdered() { 992 return ordered; 993 } 994 995 1001 public int getElementTypeCode() { 1002 return elementTypeCode; 1003 } 1004 1005 1008 public int getManagedFieldNo() { 1009 return managedFieldNo; 1010 } 1011 1012 1015 public boolean isKeyTypePC() { 1016 return keyTypeMetaData != null || keyType == Object .class 1017 || (keyType != null && keyType.isInterface()); 1018 } 1019 1020 1026 public int getKeyTypeCode() { 1027 return keyTypeCode; 1028 } 1029 1030 1034 public Class getElementType() { 1035 return elementType; 1036 } 1037 1038 1041 public Class getKeyType() { 1042 return keyType; 1043 } 1044 1045 1050 public boolean isManaged() { 1051 return managed; 1052 } 1053 1054 1058 public boolean isMaster() { 1059 return isMaster; 1060 } 1061 1062 1065 public boolean isManyToMany() { 1066 return isManyToMany; 1067 } 1068 1069 1073 public int getInverseFieldNo() { 1074 return inverseFieldNo; 1075 } 1076 1077 1081 public VersantFieldMetaData getInverseFieldMetaData() { 1082 return inverseFieldMetaData; 1083 } 1084 1085 public VersantSimpleSCO createSCO(PersistenceContext pm, 1086 VersantStateManager sm, FieldMetaData fmd, 1087 PersistenceCapable owner, Object data) { 1088 switch (fmd.category) { 1090 case MDStatics.CATEGORY_SIMPLE: 1091 return createSimpleSCO(pm, sm, fmd, owner, data); 1092 case MDStatics.CATEGORY_COLLECTION: 1093 return createCollectionSCO(pm, sm, fmd, owner, data); 1094 case MDStatics.CATEGORY_MAP: 1095 return createMapSCO(pm, sm, fmd, owner, data); 1096 } 1097 return null; 1098 } 1099 1100 public VersantSimpleSCO createSimpleSCO(PersistenceContext pm, 1101 VersantStateManager sm, FieldMetaData fmd, 1102 PersistenceCapable owner, Object data) { 1103 if (data == null) return null; 1104 if (data instanceof VersantAdvancedSCO) { 1105 VersantAdvancedSCO sco = (VersantAdvancedSCO)data; 1106 if (sco.getOwner() != null && sco.getOwner() == owner) { 1107 sco.reset(); 1109 return sco; 1110 } 1111 } 1112 return simpleSCOFactory.createSCO(owner, pm, sm, fmd, data); 1114 } 1115 1116 public VersantSimpleSCO createCollectionSCO( 1117 PersistenceContext pm, 1118 VersantStateManager sm, FieldMetaData fmd, 1119 PersistenceCapable owner, Object data) { 1120 if (data == null) return null; 1121 if (data instanceof VersantAdvancedSCO) { 1122 VersantAdvancedSCO sco = (VersantAdvancedSCO)data; 1123 if (sco.getOwner() != null && sco.getOwner() == owner) { 1124 sco.reset(); 1126 return sco; 1127 } 1128 } 1129 if (data instanceof CollectionData) { 1131 CollectionData collectionData = (CollectionData)data; 1132 return collectionFactory.createSCOCollection(owner, pm, sm, fmd, 1133 collectionData); 1134 } else if (data instanceof Object []) { 1135 Object [] objects = (Object [])data; 1136 CollectionData collectionData = new CollectionData(); 1137 collectionData.valueCount = objects.length; 1138 collectionData.values = objects; 1139 return collectionFactory.createSCOCollection(owner, pm, sm, fmd, 1140 collectionData); 1141 } else if (data instanceof Collection) { 1142 Collection collection = (Collection)data; 1143 return collectionFactory.createSCOCollection(owner, pm, sm, fmd, 1144 collection); 1145 1146 } else { 1147 throw BindingSupportImpl.getInstance().internal("data is not CollectionData, Object[] or Collection: " + fmd.getQName() + 1148 " data " + data); 1149 } 1150 } 1151 1152 public VersantSimpleSCO createMapSCO(PersistenceContext pm, 1153 VersantStateManager sm, FieldMetaData fmd, 1154 PersistenceCapable owner, Object data) { 1155 if (data == null) return null; 1156 if (data instanceof VersantAdvancedSCO) { 1157 VersantAdvancedSCO sco = (VersantAdvancedSCO)data; 1158 if (sco.getOwner() != null && sco.getOwner() == owner) { 1159 sco.reset(); 1161 return sco; 1162 } 1163 } 1164 if (data == null) return null; 1166 if (data instanceof MapData) { 1167 MapData mapData = (MapData)data; 1168 return mapFactory.createSCOHashMap(owner, pm, sm, fmd, mapData); 1169 } else if (data instanceof MapEntries) { 1170 MapEntries entries = (MapEntries)data; 1171 MapData mapData = new MapData(); 1172 mapData.entryCount = entries.keys.length; 1173 mapData.keys = entries.keys; 1174 mapData.values = entries.values; 1175 return mapFactory.createSCOHashMap(owner, pm, sm, fmd, mapData); 1176 } else if (data instanceof Map) { 1177 return mapFactory.createSCOHashMap(owner, pm, sm, fmd, (Map)data); 1178 1179 } else { 1180 throw BindingSupportImpl.getInstance().internal("data is not MapData, MapEntries or MAp: " + fmd.getQName() + 1181 " data " + data); 1182 } 1183 } 1184 1185 1191 public boolean isIncludeAllDataInDiff() { 1192 return includeAllDataInDiff; 1193 } 1194 1195 1199 public boolean isFake() { 1200 return fake; 1201 } 1202 1203 public void setScoFactory(Object factory) { 1204 this.scoFactory = factory; 1205 } 1206 1207 public boolean checkCustomFactory() { 1208 if (scoFactory != null) { 1209 switch (category) { 1210 case MDStatics.CATEGORY_SIMPLE: 1211 simpleSCOFactory = (VersantSCOFactory)scoFactory; 1212 break; 1213 case MDStatics.CATEGORY_COLLECTION: 1214 collectionFactory = (VersantSCOCollectionFactory)scoFactory; 1215 break; 1216 case MDStatics.CATEGORY_MAP: 1217 mapFactory = (VersantSCOMapFactory)scoFactory; 1218 break; 1219 default: 1220 throw BindingSupportImpl.getInstance().runtime("SCO factory '" + scoFactory.getClass().getName() + 1221 "' set on non SCO field. class: " + classMetaData.cls.getName() + 1222 " field: " + name); 1223 } 1224 return true; 1225 } else { 1226 return false; 1227 } 1228 } 1229 1230 1233 public Externalizer getSerializer(VersantPersistenceManagerImp pm) { 1234 if (Debug.DEBUG) { 1235 if (category != MDStatics.CATEGORY_EXTERNALIZED) { 1236 throw BindingSupportImpl.getInstance().internal("This field '" 1237 + name + "' is not a 'Serialized' field"); 1238 } 1239 } 1240 return externalizer; 1241 } 1242 1243 1244 1245 public boolean isEmbeddedRef() { 1246 return embedded && category == MDStatics.CATEGORY_REF; 1247 } 1248 1249 1253 public Field getObjectidClassField() { 1254 if (objectidClassField == null) { 1255 Class idClass = classMetaData.objectIdClass; 1256 Field field = getRField(idClass); 1257 if (field == null) { 1258 throw BindingSupportImpl.getInstance().runtime("Application id class '" 1259 + idClass.getName() 1260 + "' must have field: 'public " + type.getName() + 1261 " " + name + "'"); 1262 } 1263 if (!Modifier.isPublic(field.getModifiers())) { 1264 throw BindingSupportImpl.getInstance().runtime("Application id class '" 1265 + idClass.getName() 1266 + "' field '" + name + "' is not public"); 1267 } 1268 1269 if (type != field.getType()) { 1270 throw BindingSupportImpl.getInstance().runtime( 1271 "Application id class '" 1272 + idClass.getName() 1273 + "' field '" + name + "' has wrong type '" + 1274 type.getName() + "' (should be " + type + ")"); 1275 } 1276 objectidClassField = field; 1277 } 1278 return objectidClassField; 1279 } 1280 1281 private Field getRField(Class idClass) { 1282 for (; idClass != null; idClass = idClass.getSuperclass()) { 1283 Field[] fields = idClass.getFields(); 1284 Field ans = null; 1285 for (int i = 0; i < fields.length; i++) { 1286 Field field = fields[i]; 1287 if (field.getName().equals(getPkFieldName())) { 1288 if (Modifier.isPublic(field.getModifiers())) return field; 1289 ans = field; 1290 } 1291 1292 } 1293 if (ans != null) return ans; 1294 } 1295 return null; 1296 } 1297 1298 public FieldMetaData findEmbeddedFmd(String name) { 1299 if(embeddedFmds == null){ 1300 return null; 1301 } 1302 int low = 0; 1304 int high = embeddedFmds.length - 1; 1305 name = this.name+"/"+name; 1306 while (low <= high) { 1307 int mid = (low + high) / 2; 1308 FieldMetaData midVal = embeddedFmds[mid]; 1309 String name2 = midVal.name; 1310 int cmp = name2.compareTo(name); 1311 if (cmp < 0) { 1312 low = mid + 1; 1313 } else if (cmp > 0) { 1314 high = mid - 1; 1315 } else { 1316 return midVal; 1317 } 1318 } 1319 return null; 1320 } 1321 1322 public String getPkFieldName() { 1323 if (fake) return origFmd.name; 1324 return name; 1325 } 1326 1327 public void setNullIndicatorFmd(FieldMetaData fmd) { 1328 if (isEmbeddedRef()) { 1329 if (nullIndicatorFmd == null) { 1330 nullIndicatorFmd = fmd; 1331 } else { 1332 throw BindingSupportImpl.getInstance().invalidOperation( 1333 "Attempting to set more that one 'Null-Indicator' " + 1334 "field for Embedded field '" 1335 + classMetaData.qname + "." + name + "'. " + 1336 "Please correct the metadata."); 1337 } 1338 } else { 1339 throw BindingSupportImpl.getInstance().internal( 1340 "Not allowed to set NullIndicator '" 1341 + fmd.classMetaData.qname + "." + fmd.name 1342 + "' on a non-embedded ref: '" 1343 + classMetaData.qname + "." + name + "'"); 1344 } 1345 } 1346} 1347
| Popular Tags
|