1 21 package oracle.toplink.essentials.descriptors; 23 24 import java.io.*; 25 import java.lang.reflect.*; 26 import java.security.AccessController ; 27 import java.security.PrivilegedActionException ; 28 import java.util.*; 29 import oracle.toplink.essentials.exceptions.*; 30 import oracle.toplink.essentials.expressions.*; 31 import oracle.toplink.essentials.internal.descriptors.OptimisticLockingPolicy; 32 import oracle.toplink.essentials.internal.expressions.*; 33 import oracle.toplink.essentials.internal.helper.*; 34 import oracle.toplink.essentials.internal.queryframework.*; 35 import oracle.toplink.essentials.mappings.*; 36 import oracle.toplink.essentials.queryframework.*; 37 import oracle.toplink.essentials.internal.sessions.AbstractRecord; 38 import oracle.toplink.essentials.internal.sessions.AbstractSession; 39 import oracle.toplink.essentials.internal.security.PrivilegedAccessHelper; 40 import oracle.toplink.essentials.internal.security.PrivilegedClassForName; 41 42 55 public class InheritancePolicy implements Serializable, Cloneable { 56 protected Class parentClass; 57 protected String parentClassName; 58 protected ClassDescriptor parentDescriptor; 59 protected Vector childDescriptors; 60 protected transient DatabaseField classIndicatorField; 61 protected transient Map classIndicatorMapping; 62 protected transient Map classNameIndicatorMapping; 63 protected transient boolean shouldUseClassNameAsIndicator; 64 protected transient Boolean shouldReadSubclasses; 65 protected transient DatabaseTable readAllSubclassesView; 66 protected transient Vector allChildClassIndicators; 67 protected transient Expression onlyInstancesExpression; 68 protected transient Expression withAllSubclassesExpression; 69 protected transient Vector allTables; 71 protected transient List childrenTables; 73 protected transient Map childrenTablesJoinExpressions; 75 protected transient Expression childrenJoinExpression; 77 78 79 protected transient ClassExtractor classExtractor; 80 protected ClassDescriptor descriptor; 81 protected boolean shouldAlwaysUseOuterJoin; 82 83 protected boolean useDescriptorsToValidateInheritedObjects; 85 86 protected boolean isJoinedStrategy; 88 89 94 public InheritancePolicy() { 95 this.classIndicatorMapping = new HashMap(10); 96 this.classNameIndicatorMapping = new HashMap(10); 97 this.shouldUseClassNameAsIndicator = false; 98 this.allChildClassIndicators = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(); 99 this.childDescriptors = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(5); 100 this.setJoinedStrategy(); 101 } 102 103 108 public InheritancePolicy(ClassDescriptor descriptor) { 109 this(); 110 this.descriptor = descriptor; 111 } 112 113 117 public void addChildDescriptor(ClassDescriptor childDescriptor) { 118 getChildDescriptors().addElement(childDescriptor); 119 } 120 121 126 protected void addChildTableJoinExpression(DatabaseTable table, Expression expression) { 127 if(childrenTablesJoinExpressions == null) { 128 childrenTablesJoinExpressions = new HashMap(); 129 childrenTables = new ArrayList(); 131 allTables = new Vector(getDescriptor().getTables()); 133 } 134 childrenTables.add(table); 135 allTables.add(table); 136 childrenTablesJoinExpressions.put(table, expression); 137 childrenJoinExpression = expression.and(childrenJoinExpression); 138 } 139 140 144 public void addChildTableJoinExpressionToAllParents(DatabaseTable table, Expression expression) { 145 ClassDescriptor parentDescriptor = getParentDescriptor(); 146 while(parentDescriptor != null) { 147 InheritancePolicy parentPolicy = parentDescriptor.getInheritancePolicy(); 148 parentPolicy.addChildTableJoinExpression(table, expression); 149 parentDescriptor = parentPolicy.getParentDescriptor(); 150 } 151 } 152 153 162 public void addClassIndicator(Class childClass, Object typeValue) { 163 getClassIndicatorMapping().put(typeValue, childClass); 166 getClassIndicatorMapping().put(childClass, typeValue); 167 } 168 169 173 public void addClassNameIndicator(String childClassName, Object typeValue) { 174 getClassNameIndicatorMapping().put(childClassName, typeValue); 175 } 176 177 184 public void addClassIndicatorFieldToInsertRow(AbstractRecord databaseRow) { 185 if (hasClassExtractor()) { 186 return; 187 } 188 189 DatabaseField field = getClassIndicatorField(); 190 databaseRow.put(field, null); 191 } 192 193 199 public void addClassIndicatorFieldToRow(AbstractRecord databaseRow) { 200 if (hasClassExtractor()) { 201 return; 202 } 203 204 DatabaseField field = getClassIndicatorField(); 205 Object value = getClassIndicatorValue(); 206 207 databaseRow.put(field, value); 208 } 209 210 214 protected void addClassIndicatorTypeToParent(Object indicator) { 215 ClassDescriptor parentDescriptor = getDescriptor().getInheritancePolicy().getParentDescriptor(); 216 217 if (parentDescriptor.getInheritancePolicy().isChildDescriptor()) { 218 if (parentDescriptor.getInheritancePolicy().shouldReadSubclasses()) { 219 parentDescriptor.getInheritancePolicy().getAllChildClassIndicators().addElement(indicator); 220 } 221 parentDescriptor.getInheritancePolicy().addClassIndicatorTypeToParent(indicator); 222 } 223 } 224 225 229 protected void addFieldsToParent(Vector fields) { 230 if (isChildDescriptor()) { 231 if (getParentDescriptor().isInvalid()) { 232 return; 233 } 234 ClassDescriptor parentDescriptor = getParentDescriptor(); 235 if (parentDescriptor.getInheritancePolicy().shouldReadSubclasses()) { 236 Helper.addAllUniqueToVector(parentDescriptor.getAllFields(), fields); 237 } 238 parentDescriptor.getInheritancePolicy().addFieldsToParent(fields); 239 } 240 } 241 242 247 public SQLSelectStatement buildClassIndicatorSelectStatement(ObjectLevelReadQuery query) { 248 SQLSelectStatement selectStatement; 249 selectStatement = new SQLSelectStatement(); 250 selectStatement.useDistinct(); 251 selectStatement.addTable(classIndicatorField.getTable()); 252 selectStatement.addField(getClassIndicatorField()); 253 IdentityHashtable clonedExpressions = new IdentityHashtable(); 255 selectStatement.setWhereClause(((ExpressionQueryMechanism)query.getQueryMechanism()).buildBaseSelectionCriteria(false, clonedExpressions)); 256 appendWithAllSubclassesExpression(selectStatement); 257 selectStatement.setTranslationRow(query.getTranslationRow()); 258 selectStatement.normalize(query.getSession(), getDescriptor(), clonedExpressions); 259 ExpressionQueryMechanism m = (ExpressionQueryMechanism)query.getQueryMechanism(); 260 261 return selectStatement; 262 } 263 264 268 public void appendWithAllSubclassesExpression(SQLSelectStatement selectStatement) { 269 if (getWithAllSubclassesExpression() != null) { 270 if (selectStatement.getWhereClause() == null) { 272 selectStatement.setWhereClause((Expression)getWithAllSubclassesExpression().clone()); 273 } else { 274 selectStatement.setWhereClause(selectStatement.getWhereClause().and(getWithAllSubclassesExpression())); 275 } 276 } 277 } 278 279 284 public SQLSelectStatement buildViewSelectStatement(ObjectLevelReadQuery query) { 285 IdentityHashtable clonedExpressions = new IdentityHashtable(); 287 ExpressionQueryMechanism mechanism = (ExpressionQueryMechanism)query.getQueryMechanism(); 288 289 SQLSelectStatement selectStatement = mechanism.buildBaseSelectStatement(false, clonedExpressions); 291 selectStatement.setTables(oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(1)); 292 selectStatement.addTable(getReadAllSubclassesView()); 293 294 if (getWithAllSubclassesExpression() != null) { 296 Expression branchIndicator = (Expression)getWithAllSubclassesExpression().clone(); 297 if (branchIndicator != null) { 298 selectStatement.setWhereClause(branchIndicator.and(selectStatement.getWhereClause())); 299 } 300 } 301 302 selectStatement.setFields(mechanism.getSelectionFields(selectStatement, true)); 303 selectStatement.normalizeForView(query.getSession(), getDescriptor(), clonedExpressions); 304 ((ObjectLevelReadQuery)query).getJoinedAttributeManager().computeJoiningMappingIndexes(false, query.getSession(), 0); 306 307 return selectStatement; 308 } 309 310 314 public Class classFromRow(AbstractRecord rowFromDatabase, AbstractSession session) throws DescriptorException { 315 if (hasClassExtractor()) { 316 return getClassExtractor().extractClassFromRow(rowFromDatabase, session); 317 } 318 319 Object classFieldValue = session.getDatasourcePlatform().getConversionManager().convertObject(rowFromDatabase.get(getClassIndicatorField()), getClassIndicatorField().getType()); 320 321 if (classFieldValue == null) { 322 throw DescriptorException.missingClassIndicatorField(rowFromDatabase, getDescriptor()); 323 } 324 325 Class concreteClass; 326 if (!shouldUseClassNameAsIndicator()) { 327 concreteClass = (Class )getClassIndicatorMapping().get(classFieldValue); 328 if (concreteClass == null) { 329 throw DescriptorException.missingClassForIndicatorFieldValue(classFieldValue, getDescriptor()); 330 } 331 } else { 332 try { 333 String className = (String )classFieldValue; 334 concreteClass = getDescriptor().getJavaClass().getClassLoader().loadClass(className); 338 if (concreteClass == null) { 339 throw DescriptorException.missingClassForIndicatorFieldValue(classFieldValue, getDescriptor()); 340 } 341 } catch (ClassNotFoundException e) { 342 throw DescriptorException.missingClassForIndicatorFieldValue(classFieldValue, getDescriptor()); 343 } catch (ClassCastException e) { 344 throw DescriptorException.missingClassForIndicatorFieldValue(classFieldValue, getDescriptor()); 345 } 346 } 347 348 return concreteClass; 349 } 350 351 355 public Object clone() { 356 InheritancePolicy clone = null; 357 358 try { 359 clone = (InheritancePolicy)super.clone(); 360 if (hasClassIndicator()) { 361 clone.setClassIndicatorField((DatabaseField)clone.getClassIndicatorField().clone()); 362 } 363 } catch (Exception exception) { 364 throw new InternalError ("clone failed"); 365 } 366 367 return clone; 368 } 369 370 377 public void convertClassNamesToClasses(ClassLoader classLoader){ 378 if (parentClassName == null){ 379 return; 380 } 381 Class parentClass = null; 382 try{ 383 if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ 384 try { 385 parentClass = (Class )AccessController.doPrivileged(new PrivilegedClassForName(parentClassName, true, classLoader)); 386 } catch (PrivilegedActionException exception) { 387 throw ValidationException.classNotFoundWhileConvertingClassNames(parentClassName, exception.getException()); 388 } 389 } else { 390 parentClass = oracle.toplink.essentials.internal.security.PrivilegedAccessHelper.getClassForName(parentClassName, true, classLoader); 391 } 392 } catch (ClassNotFoundException exc){ 393 throw ValidationException.classNotFoundWhileConvertingClassNames(parentClassName, exc); 394 } 395 setParentClass(parentClass); 396 } 397 398 404 public void dontReadSubclassesOnQueries() { 405 setShouldReadSubclasses(false); 406 } 407 408 415 public void dontUseClassNameAsIndicator() { 416 setShouldUseClassNameAsIndicator(false); 417 } 418 419 424 protected Vector getAllChildClassIndicators() { 425 return allChildClassIndicators; 426 } 427 428 434 public Vector getAllChildDescriptors() { 435 Vector allChildDescriptors = new Vector(this.getAllChildClassIndicators().size()); 437 return getAllChildDescriptors(allChildDescriptors); 438 } 439 440 444 protected Vector getAllChildDescriptors(Vector allChildDescriptors) { 445 for (Enumeration enumtr = getChildDescriptors().elements(); enumtr.hasMoreElements();) { 446 ClassDescriptor childDescriptor = (ClassDescriptor)enumtr.nextElement(); 447 allChildDescriptors.addElement(childDescriptor); 448 childDescriptor.getInheritancePolicyOrNull().getAllChildDescriptors(allChildDescriptors); 449 } 450 return allChildDescriptors; 451 } 452 453 457 public List getChildrenTables() { 458 return childrenTables; 459 } 460 461 465 public Map getChildrenTablesJoinExpressions() { 466 return childrenTablesJoinExpressions; 467 } 468 469 473 public Expression getChildrenJoinExpression() { 474 return childrenJoinExpression; 475 } 476 477 481 public Vector getAllTables() { 482 if(allTables == null) { 483 return this.getDescriptor().getTables(); 484 } else { 485 return allTables; 486 } 487 } 488 489 494 public Vector getChildDescriptors() { 495 return childDescriptors; 496 } 497 498 502 protected Method getClassExtractionMethod() { 503 if (classExtractor instanceof MethodClassExtractor) { 504 return ((MethodClassExtractor)classExtractor).getClassExtractionMethod(); 505 } else { 506 return null; 507 } 508 } 509 510 525 public String getClassExtractionMethodName() { 526 if (classExtractor instanceof MethodClassExtractor) { 527 return ((MethodClassExtractor)classExtractor).getClassExtractionMethodName(); 528 } else { 529 return null; 530 } 531 } 532 533 548 public ClassExtractor getClassExtractor() { 549 return classExtractor; 550 } 551 552 567 public void setClassExtractor(ClassExtractor classExtractor) { 568 this.classExtractor = classExtractor; 569 } 570 571 576 public Vector getClassIndicatorAssociations() { 577 Vector associations = new Vector(getClassNameIndicatorMapping().size() / 2); 578 Iterator classesEnum = getClassNameIndicatorMapping().keySet().iterator(); 579 Iterator valuesEnum = getClassNameIndicatorMapping().values().iterator(); 580 while (classesEnum.hasNext()) { 581 Object className = classesEnum.next(); 582 583 if (className instanceof Class ) { 585 className = ((Class )className).getName(); 586 } 587 Object value = valuesEnum.next(); 588 associations.addElement(new TypedAssociation(className, value)); 589 } 590 591 return associations; 592 } 593 594 598 public DatabaseField getClassIndicatorField() { 599 return classIndicatorField; 600 } 601 602 607 public String getClassIndicatorFieldName() { 608 if (getClassIndicatorField() == null) { 609 return null; 610 } else { 611 return getClassIndicatorField().getQualifiedName(); 612 } 613 } 614 615 619 public Map getClassIndicatorMapping() { 620 return getClassIndicatorMapping(ConversionManager.getDefaultManager()); 621 } 622 623 627 public Map getClassIndicatorMapping(ConversionManager conversionManager) { 628 if (classIndicatorMapping.isEmpty() && !classNameIndicatorMapping.isEmpty()) { 629 Iterator keysEnum = classNameIndicatorMapping.keySet().iterator(); 630 Iterator valuesEnum = classNameIndicatorMapping.values().iterator(); 631 while (keysEnum.hasNext()) { 632 Object key = keysEnum.next(); 633 Object value = valuesEnum.next(); 634 Class theClass = (Class )conversionManager.convertObject((String )key, ClassConstants.CLASS); 635 classIndicatorMapping.put(theClass, value); 636 classIndicatorMapping.put(value, theClass); 637 } 638 } 639 return classIndicatorMapping; 640 } 641 642 646 public Map getClassNameIndicatorMapping() { 647 if (classNameIndicatorMapping.isEmpty() && !classIndicatorMapping.isEmpty()) { 648 Iterator keysEnum = classIndicatorMapping.keySet().iterator(); 649 Iterator valuesEnum = classIndicatorMapping.values().iterator(); 650 while (keysEnum.hasNext()) { 651 Object key = keysEnum.next(); 652 Object value = valuesEnum.next(); 653 if (key instanceof Class ) { 654 String className = ((Class )key).getName(); 655 classNameIndicatorMapping.put(className, value); 656 } 657 } 658 } 659 660 return classNameIndicatorMapping; 661 } 662 663 667 protected Object getClassIndicatorValue() { 668 return getClassIndicatorValue(getDescriptor().getJavaClass()); 669 } 670 671 676 protected Object getClassIndicatorValue(Class javaClass) { 677 if (shouldUseClassNameAsIndicator()) { 678 return javaClass.getName(); 679 } else { 680 return getClassIndicatorMapping().get(javaClass); 681 } 682 } 683 684 688 public ClassDescriptor getDescriptor() { 689 return descriptor; 690 } 691 692 696 public Expression getOnlyInstancesExpression() { 697 return onlyInstancesExpression; 698 } 699 700 704 public Class getParentClass() { 705 return parentClass; 706 } 707 708 712 public String getParentClassName() { 713 if ((parentClassName == null) && (parentClass != null)) { 714 parentClassName = parentClass.getName(); 715 } 716 return parentClassName; 717 } 718 719 723 public ClassDescriptor getParentDescriptor() { 724 return parentDescriptor; 725 } 726 727 733 public DatabaseTable getReadAllSubclassesView() { 734 return readAllSubclassesView; 735 } 736 737 743 public String getReadAllSubclassesViewName() { 744 if (getReadAllSubclassesView() == null) { 745 return null; 746 } 747 return getReadAllSubclassesView().getName(); 748 } 749 750 754 public ClassDescriptor getRootParentDescriptor() { 755 if (isRootParentDescriptor()) { 756 return getDescriptor(); 757 } else { 758 return getParentDescriptor().getInheritancePolicy().getRootParentDescriptor(); 759 } 760 } 761 762 766 public ClassDescriptor getSubclassDescriptor(Class theClass) { 767 if (hasChildren()) { 768 for (Iterator enumtr = getChildDescriptors().iterator(); enumtr.hasNext();) { 769 ClassDescriptor childDescriptor = (ClassDescriptor)enumtr.next(); 770 if (childDescriptor.getJavaClass().equals(theClass)) { 771 return childDescriptor; 772 } else { 773 ClassDescriptor descriptor = childDescriptor.getInheritancePolicy().getSubclassDescriptor(theClass); 774 if (descriptor != null) { 775 return descriptor; 776 } 777 } 778 } 779 } 780 return null; 781 } 782 783 788 public boolean getUseDescriptorsToValidateInheritedObjects() { 789 return useDescriptorsToValidateInheritedObjects; 790 } 791 792 796 public Expression getWithAllSubclassesExpression() { 797 return withAllSubclassesExpression; 798 } 799 800 804 public boolean hasChildren() { 805 return !getChildDescriptors().isEmpty(); 806 } 807 808 811 public boolean hasClassExtractor() { 812 return getClassExtractor() != null; 813 } 814 815 819 public boolean hasClassIndicator() { 820 return getClassIndicatorField() != null; 821 } 822 823 828 public boolean hasMultipleTableChild() { 829 return childrenTables != null; 830 } 831 832 836 public boolean hasView() { 837 return getReadAllSubclassesView() != null; 838 } 839 840 845 public void initialize(AbstractSession session) { 846 if ((shouldReadSubclasses == null) || shouldReadSubclasses()) { 848 setShouldReadSubclasses(!getChildDescriptors().isEmpty()); 849 } 850 851 if (isChildDescriptor()) { 852 getDescriptor().setMappings(Helper.concatenateVectors(getParentDescriptor().getMappings(), getDescriptor().getMappings())); 853 getDescriptor().setQueryKeys(Helper.concatenateMaps(getParentDescriptor().getQueryKeys(), getDescriptor().getQueryKeys())); 854 addFieldsToParent(getDescriptor().getFields()); 855 Vector parentsFields = (Vector)getParentDescriptor().getFields().clone(); 857 858 Helper.addAllUniqueToVector(parentsFields, getDescriptor().getFields()); 860 getDescriptor().setFields(parentsFields); 861 862 if (getClassIndicatorValue() != null) { 863 if (shouldReadSubclasses()) { 864 getAllChildClassIndicators().addElement(getClassIndicatorValue()); 865 } 866 addClassIndicatorTypeToParent(getClassIndicatorValue()); 867 } 868 869 if (!getDescriptor().usesOptimisticLocking() && getParentDescriptor().usesOptimisticLocking()) { 871 getDescriptor().setOptimisticLockingPolicy((OptimisticLockingPolicy)getParentDescriptor().getOptimisticLockingPolicy().clone()); 872 getDescriptor().getOptimisticLockingPolicy().setDescriptor(getDescriptor()); 873 } 874 875 CMPPolicy parentCMPPolicy = getDescriptor().getInheritancePolicy().getParentDescriptor().getCMPPolicy(); 877 if (parentCMPPolicy != null) { 878 CMPPolicy cmpPolicy = getDescriptor().getCMPPolicy(); 879 if (cmpPolicy == null) { 880 cmpPolicy = new CMPPolicy(); 881 getDescriptor().setCMPPolicy(cmpPolicy); 882 } 883 } 884 } 885 886 initializeOnlyInstancesExpression(); 887 initializeWithAllSubclassesExpression(); 888 } 889 890 894 protected void initializeClassExtractor(AbstractSession session) throws DescriptorException { 895 if (getClassExtractor() == null) { 896 if (isChildDescriptor()) { 897 setClassExtractor(getParentDescriptor().getInheritancePolicy().getClassExtractor()); 898 } 899 } else { 900 getClassExtractor().initialize(getDescriptor(), session); 901 } 902 } 903 904 908 protected void initializeOnlyInstancesExpression() throws DescriptorException { 909 if (getOnlyInstancesExpression() == null) { 910 if (hasClassExtractor()) { 911 return; 912 } 913 Object typeValue = getClassIndicatorValue(); 914 if (typeValue == null) { 915 if (shouldReadSubclasses()) { 916 return; } 918 919 throw DescriptorException.valueNotFoundInClassIndicatorMapping(getParentDescriptor(), getDescriptor()); 920 } 921 922 DatabaseField typeField = getClassIndicatorField(); 923 if (typeField == null) { 924 throw DescriptorException.classIndicatorFieldNotFound(getParentDescriptor(), getDescriptor()); 925 } 926 927 if (shouldAlwaysUseOuterJoin()) { 929 setOnlyInstancesExpression(new ExpressionBuilder().getField(typeField).equalOuterJoin(typeValue)); 930 } else { 931 setOnlyInstancesExpression(new ExpressionBuilder().getField(typeField).equal(typeValue)); 932 } 933 } 934 935 if (!shouldReadSubclasses()) { 937 getDescriptor().getQueryManager().setAdditionalJoinExpression(getOnlyInstancesExpression().and(getDescriptor().getQueryManager().getAdditionalJoinExpression())); 938 } 939 } 940 941 945 protected void initializeWithAllSubclassesExpression() throws DescriptorException { 946 if (getWithAllSubclassesExpression() == null) { 947 if (hasClassExtractor()) { 948 return; 949 } 950 if (isChildDescriptor() && shouldReadSubclasses()) { 951 setWithAllSubclassesExpression(new ExpressionBuilder().getField(getClassIndicatorField()).in(getAllChildClassIndicators())); 952 } 953 } 954 } 955 956 960 public boolean isChildDescriptor() { 961 return getParentClassName() != null; 962 } 963 964 971 public boolean isJoinedStrategy() { 972 return isJoinedStrategy; 973 } 974 975 979 public boolean isRootParentDescriptor() { 980 return getParentDescriptor() == null; 981 } 982 983 988 public void postInitialize(AbstractSession session) { 989 } 990 991 996 public void preInitialize(AbstractSession session) throws DescriptorException { 997 if (isChildDescriptor()) { 999 getDescriptor().setTables(Helper.concatenateUniqueVectors((Vector)getParentDescriptor().getTables(), getDescriptor().getTables())); 1002 1003 setClassIndicatorMapping(getParentDescriptor().getInheritancePolicy().getClassIndicatorMapping(session.getDatasourcePlatform().getConversionManager())); 1004 setShouldUseClassNameAsIndicator(getParentDescriptor().getInheritancePolicy().shouldUseClassNameAsIndicator()); 1005 1006 getDescriptor().setPrimaryKeyFields(getParentDescriptor().getPrimaryKeyFields()); 1008 getDescriptor().setAdditionalTablePrimaryKeyFields(Helper.concatenateMaps(getParentDescriptor().getAdditionalTablePrimaryKeyFields(), getDescriptor().getAdditionalTablePrimaryKeyFields())); 1009 1010 Expression localExpression = getDescriptor().getQueryManager().getMultipleTableJoinExpression(); 1011 Expression parentExpression = getParentDescriptor().getQueryManager().getMultipleTableJoinExpression(); 1012 1013 if (localExpression != null) { 1014 getDescriptor().getQueryManager().setInternalMultipleTableJoinExpression(localExpression.and(parentExpression)); 1015 } else if (parentExpression != null) { 1016 getDescriptor().getQueryManager().setInternalMultipleTableJoinExpression(parentExpression); 1017 } 1018 1019 Expression localAdditionalExpression = getDescriptor().getQueryManager().getAdditionalJoinExpression(); 1020 Expression parentAdditionalExpression = getParentDescriptor().getQueryManager().getAdditionalJoinExpression(); 1021 1022 if (localAdditionalExpression != null) { 1023 getDescriptor().getQueryManager().setAdditionalJoinExpression(localAdditionalExpression.and(parentAdditionalExpression)); 1024 } else if (parentAdditionalExpression != null) { 1025 getDescriptor().getQueryManager().setAdditionalJoinExpression(parentAdditionalExpression); 1026 } 1027 1028 setClassIndicatorField(getParentDescriptor().getInheritancePolicy().getClassIndicatorField()); 1029 1030 if (!getDescriptor().usesSequenceNumbers()) { 1032 getDescriptor().setSequenceNumberField(getParentDescriptor().getSequenceNumberField()); 1033 getDescriptor().setSequenceNumberName(getParentDescriptor().getSequenceNumberName()); 1034 } 1035 } 1036 1037 initializeClassExtractor(session); 1038 1039 if (!isChildDescriptor()) { 1040 if ((getClassIndicatorField() == null) && (!hasClassExtractor())) { 1042 session.getIntegrityChecker().handleError(DescriptorException.classIndicatorFieldNotFound(getDescriptor(), getDescriptor())); 1043 } 1044 if (getClassIndicatorField() != null) { 1045 getDescriptor().buildField(getClassIndicatorField()); 1046 if (shouldUseClassNameAsIndicator()) { 1048 getClassIndicatorField().setType(ClassConstants.STRING); 1049 } else if (!getClassIndicatorMapping(session.getDatasourcePlatform().getConversionManager()).isEmpty()) { 1050 Class type = null; 1051 Iterator fieldValuesEnum = getClassIndicatorMapping(session.getDatasourcePlatform().getConversionManager()).values().iterator(); 1052 while (fieldValuesEnum.hasNext() && (type == null)) { 1053 Object value = fieldValuesEnum.next(); 1054 if (value.getClass() != getClass().getClass()) { 1055 type = value.getClass(); 1056 } 1057 } 1058 getClassIndicatorField().setType(type); 1059 } 1060 getDescriptor().getFields().addElement(getClassIndicatorField()); 1061 } 1062 } 1063 } 1064 1065 1071 public void readSubclassesOnQueries() { 1072 setShouldReadSubclasses(true); 1073 } 1074 1075 1080 public boolean requiresMultipleTableSubclassRead() { 1081 return hasMultipleTableChild() && shouldReadSubclasses(); 1082 } 1083 1084 1092 protected Vector selectAllRowUsingCustomMultipleTableSubclassRead(ReadAllQuery query) throws DatabaseException { 1093 Vector rows = new Vector(); 1094 if ((getOnlyInstancesExpression() != null) || (! shouldReadSubclasses())) { 1097 ReadAllQuery concreteQuery = (ReadAllQuery)query.clone(); 1098 concreteQuery.setReferenceClass(getDescriptor().getJavaClass()); 1099 concreteQuery.setDescriptor(getDescriptor()); 1100 1101 Vector concreteRows = ((ExpressionQueryMechanism)concreteQuery.getQueryMechanism()).selectAllRowsFromConcreteTable(); 1102 rows = Helper.concatenateVectors(rows, concreteRows); 1103 } 1104 1105 for (Enumeration childrenEnum = getChildDescriptors().elements(); 1107 childrenEnum.hasMoreElements();) { 1108 ClassDescriptor concreteDescriptor = (ClassDescriptor)childrenEnum.nextElement(); 1109 Vector concreteRows = concreteDescriptor.getInheritancePolicy().selectAllRowUsingCustomMultipleTableSubclassRead(query); 1110 rows = Helper.concatenateVectors(rows, concreteRows); 1111 } 1112 1113 return rows; 1114 } 1115 1116 1123 protected Vector selectAllRowUsingDefaultMultipleTableSubclassRead(ReadAllQuery query) throws DatabaseException, QueryException { 1124 Vector classIndicators = ((ExpressionQueryMechanism)query.getQueryMechanism()).selectAllRowsFromTable(); 1127 1128 Vector classes = new Vector(); 1129 for (Enumeration rowsEnum = classIndicators.elements(); rowsEnum.hasMoreElements();) { 1130 AbstractRecord row = (AbstractRecord)rowsEnum.nextElement(); 1131 Class concreteClass = classFromRow(row, query.getSession()); 1132 if (!classes.contains(concreteClass)) { classes.addElement(concreteClass); 1134 } 1135 } 1136 1137 Vector rows = new Vector(); 1138 HashMap joinedMappingIndexes = null; 1147 if(query.getJoinedAttributeManager().hasJoinedAttributes()) { 1148 joinedMappingIndexes = new HashMap(); 1149 } 1150 for (Enumeration classesEnum = classes.elements(); classesEnum.hasMoreElements();) { 1151 Class concreteClass = (Class )classesEnum.nextElement(); 1152 ClassDescriptor concreteDescriptor = query.getSession().getDescriptor(concreteClass); 1153 if (concreteDescriptor == null) { 1154 throw QueryException.noDescriptorForClassFromInheritancePolicy(query, concreteClass); 1155 } 1156 ReadAllQuery concreteQuery = (ReadAllQuery)query.clone(); 1157 concreteQuery.setReferenceClass(concreteClass); 1158 concreteQuery.setDescriptor(concreteDescriptor); 1159 1160 Vector concreteRows = ((ExpressionQueryMechanism)concreteQuery.getQueryMechanism()).selectAllRowsFromConcreteTable(); 1161 rows = Helper.concatenateVectors(rows, concreteRows); 1162 1163 if(joinedMappingIndexes != null) { 1164 Iterator it = concreteQuery.getJoinedAttributeManager().getJoinedMappingIndexes_().entrySet().iterator(); 1165 while(it.hasNext()) { 1166 Map.Entry entry = (Map.Entry)it.next(); 1167 HashMap map = (HashMap)joinedMappingIndexes.get(entry.getKey()); 1168 if(map == null) { 1169 map = new HashMap(classes.size()); 1170 joinedMappingIndexes.put(entry.getKey(), map); 1171 } 1172 map.put(concreteClass, entry.getValue()); 1173 } 1174 } 1175 } 1176 if(joinedMappingIndexes != null) { 1177 query.getJoinedAttributeManager().setJoinedMappingIndexes_(joinedMappingIndexes); 1178 } 1179 1180 return rows; 1181 } 1182 1183 1190 public Vector selectAllRowUsingMultipleTableSubclassRead(ReadAllQuery query) throws DatabaseException { 1191 if (hasClassExtractor()) { 1192 return selectAllRowUsingCustomMultipleTableSubclassRead(query); 1193 } else { 1194 return selectAllRowUsingDefaultMultipleTableSubclassRead(query); 1195 } 1196 } 1197 1198 1205 protected AbstractRecord selectOneRowUsingCustomMultipleTableSubclassRead(ReadObjectQuery query) throws DatabaseException { 1206 if ((getOnlyInstancesExpression() != null) || (! shouldReadSubclasses())) { 1209 ReadObjectQuery concreteQuery = (ReadObjectQuery)query.clone(); 1210 concreteQuery.setReferenceClass(getDescriptor().getJavaClass()); 1211 concreteQuery.setDescriptor(getDescriptor()); 1212 1213 AbstractRecord row = ((ExpressionQueryMechanism)concreteQuery.getQueryMechanism()).selectOneRowFromConcreteTable(); 1214 1215 if (row != null) { 1216 return row; 1217 } 1218 } 1219 1220 for (Enumeration childrenEnum = getChildDescriptors().elements(); 1222 childrenEnum.hasMoreElements();) { 1223 ClassDescriptor concreteDescriptor = (ClassDescriptor)childrenEnum.nextElement(); 1224 AbstractRecord row = concreteDescriptor.getInheritancePolicy().selectOneRowUsingCustomMultipleTableSubclassRead(query); 1225 1226 if (row != null) { 1227 return row; 1228 } 1229 } 1230 1231 return null; 1232 } 1233 1234 1239 protected AbstractRecord selectOneRowUsingDefaultMultipleTableSubclassRead(ReadObjectQuery query) throws DatabaseException, QueryException { 1240 AbstractRecord typeRow = ((ExpressionQueryMechanism)query.getQueryMechanism()).selectOneRowFromTable(); 1243 1244 if (typeRow == null) { 1245 return null; 1246 } 1247 1248 Class concreteClass = classFromRow(typeRow, query.getSession()); 1249 ClassDescriptor concreteDescriptor = query.getSession().getDescriptor(concreteClass); 1250 if (concreteDescriptor == null) { 1251 throw QueryException.noDescriptorForClassFromInheritancePolicy(query, concreteClass); 1252 } 1253 1254 ReadObjectQuery concreteQuery = (ReadObjectQuery)query.clone(); 1255 concreteQuery.setReferenceClass(concreteClass); 1256 concreteQuery.setDescriptor(concreteDescriptor); 1257 1258 AbstractRecord resultRow = ((ExpressionQueryMechanism)concreteQuery.getQueryMechanism()).selectOneRowFromConcreteTable(); 1259 1260 return resultRow; 1261 } 1262 1263 1268 public AbstractRecord selectOneRowUsingMultipleTableSubclassRead(ReadObjectQuery query) throws DatabaseException, QueryException { 1269 if (hasClassExtractor()) { 1270 return selectOneRowUsingCustomMultipleTableSubclassRead(query); 1271 } else { 1272 return selectOneRowUsingDefaultMultipleTableSubclassRead(query); 1273 } 1274 } 1275 1276 1279 protected void setAllChildClassIndicators(Vector allChildClassIndicators) { 1280 this.allChildClassIndicators = allChildClassIndicators; 1281 } 1282 1283 1286 public void setChildDescriptors(Vector theChildDescriptors) { 1287 childDescriptors = theChildDescriptors; 1288 } 1289 1290 1305 public void setClassExtractionMethodName(String staticClassClassExtractionMethod) { 1306 if ((staticClassClassExtractionMethod == null) || (staticClassClassExtractionMethod.length() == 0)) { 1307 return; 1308 } 1309 if (!(getClassExtractor() instanceof MethodClassExtractor)) { 1310 setClassExtractor(new MethodClassExtractor()); 1311 } 1312 ((MethodClassExtractor)getClassExtractor()).setClassExtractionMethodName(staticClassClassExtractionMethod); 1313 } 1314 1315 1319 public void setClassIndicatorAssociations(Vector classIndicatorAssociations) { 1320 setClassNameIndicatorMapping(new HashMap(classIndicatorAssociations.size() + 1)); 1321 setClassIndicatorMapping(new HashMap((classIndicatorAssociations.size() * 2) + 1)); 1322 for (Enumeration associationsEnum = classIndicatorAssociations.elements(); 1323 associationsEnum.hasMoreElements();) { 1324 Association association = (Association)associationsEnum.nextElement(); 1325 Object classValue = association.getKey(); 1326 if (classValue instanceof Class ) { 1327 addClassIndicator((Class )association.getKey(), association.getValue()); 1329 } else { 1330 addClassNameIndicator((String )association.getKey(), association.getValue()); 1331 } 1332 } 1333 } 1334 1335 1340 public void setClassIndicatorField(DatabaseField classIndicatorField) { 1341 this.classIndicatorField = classIndicatorField; 1342 } 1343 1344 1349 public void setClassIndicatorFieldName(String fieldName) { 1350 if (fieldName == null) { 1351 setClassIndicatorField(null); 1352 } else { 1353 setClassIndicatorField(new DatabaseField(fieldName)); 1354 } 1355 } 1356 1357 1362 public void setClassIndicatorMapping(Map classIndicatorMapping) { 1363 this.classIndicatorMapping = classIndicatorMapping; 1364 } 1365 1366 1370 public void setClassNameIndicatorMapping(Map classNameIndicatorMapping) { 1371 this.classNameIndicatorMapping = classNameIndicatorMapping; 1372 } 1373 1374 1378 public void setDescriptor(ClassDescriptor descriptor) { 1379 this.descriptor = descriptor; 1380 } 1381 1382 1387 public void setJoinedStrategy() { 1388 isJoinedStrategy = true; 1389 } 1390 1391 1396 public void setOnlyInstancesExpression(Expression onlyInstancesExpression) { 1397 this.onlyInstancesExpression = onlyInstancesExpression; 1398 } 1399 1400 1408 public void setParentClass(Class parentClass) { 1409 this.parentClass = parentClass; 1410 if (parentClass != null) { 1411 setParentClassName(parentClass.getName()); 1412 } 1413 } 1414 1415 1420 public void setParentClassName(String parentClassName) { 1421 this.parentClassName = parentClassName; 1422 } 1423 1424 1427 public void setParentDescriptor(ClassDescriptor parentDescriptor) { 1428 this.parentDescriptor = parentDescriptor; 1429 } 1430 1431 1437 protected void setReadAllSubclassesView(DatabaseTable readAllSubclassesView) { 1438 this.readAllSubclassesView = readAllSubclassesView; 1439 } 1440 1441 1447 public void setReadAllSubclassesViewName(String readAllSubclassesViewName) { 1448 if (readAllSubclassesViewName == null) { 1449 setReadAllSubclassesView(null); 1450 } else { 1451 setReadAllSubclassesView(new DatabaseTable(readAllSubclassesViewName)); 1452 } 1453 } 1454 1455 1461 public void setShouldReadSubclasses(Boolean shouldReadSubclasses) { 1462 this.shouldReadSubclasses = shouldReadSubclasses; 1463 } 1464 1465 1471 public void setShouldReadSubclasses(boolean shouldReadSubclasses) { 1472 this.shouldReadSubclasses = Boolean.valueOf(shouldReadSubclasses); 1473 } 1474 1475 1483 public void setShouldUseClassNameAsIndicator(boolean shouldUseClassNameAsIndicator) { 1484 this.shouldUseClassNameAsIndicator = shouldUseClassNameAsIndicator; 1485 } 1486 1487 1492 1493 public void setAlwaysUseOuterJoinForClassType(boolean choice) { 1495 this.shouldAlwaysUseOuterJoin = choice; 1496 } 1497 1498 1505 public void setSingleTableStrategy() { 1506 isJoinedStrategy = false; 1507 } 1508 1509 1514 public void setUseDescriptorsToValidateInheritedObjects(boolean useDescriptorsToValidateInheritedObjects) { 1515 this.useDescriptorsToValidateInheritedObjects = useDescriptorsToValidateInheritedObjects; 1517 } 1518 1519 1524 public void setWithAllSubclassesExpression(Expression withAllSubclassesExpression) { 1525 this.withAllSubclassesExpression = withAllSubclassesExpression; 1526 } 1527 1528 1532 public boolean shouldReadSubclasses() { 1533 if (shouldReadSubclasses == null) { 1534 return true; 1535 } 1536 return shouldReadSubclasses.booleanValue(); 1537 } 1538 1539 1543 public Boolean shouldReadSubclassesValue() { 1544 return shouldReadSubclasses; 1545 } 1546 1547 1551 1552 public boolean shouldAlwaysUseOuterJoin() { 1554 return this.shouldAlwaysUseOuterJoin; 1555 } 1556 1557 1565 public boolean shouldUseClassNameAsIndicator() { 1566 return shouldUseClassNameAsIndicator; 1567 } 1568 1569 1572 public String toString() { 1573 return Helper.getShortClassName(getClass()) + "(" + getDescriptor() + ")"; 1574 } 1575 1576 1584 public void useClassNameAsIndicator() { 1585 setShouldUseClassNameAsIndicator(true); 1586 } 1587} 1588 | Popular Tags |