1 21 package oracle.toplink.essentials.mappings; 23 24 import java.util.*; 25 import oracle.toplink.essentials.exceptions.*; 26 import oracle.toplink.essentials.expressions.*; 27 import oracle.toplink.essentials.internal.databaseaccess.Platform; 28 import oracle.toplink.essentials.internal.descriptors.*; 29 import oracle.toplink.essentials.internal.expressions.*; 30 import oracle.toplink.essentials.internal.helper.*; 31 import oracle.toplink.essentials.internal.queryframework.*; 32 import oracle.toplink.essentials.internal.sessions.*; 33 import oracle.toplink.essentials.mappings.converters.*; 34 import oracle.toplink.essentials.queryframework.*; 35 import oracle.toplink.essentials.sessions.ObjectCopyingPolicy; 36 import oracle.toplink.essentials.sessions.DatabaseRecord; 37 import oracle.toplink.essentials.internal.sessions.AbstractRecord; 38 import oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl; 39 import oracle.toplink.essentials.internal.sessions.AbstractSession; 40 import oracle.toplink.essentials.descriptors.ClassDescriptor; 41 42 55 public class DirectCollectionMapping extends CollectionMapping implements RelationalMapping { 56 57 58 protected static final String Delete = "delete"; 59 protected static final String Insert = "insert"; 60 protected static final String DeleteAll = "deleteAll"; 61 62 63 protected Converter valueConverter; 64 65 66 protected transient DatabaseTable referenceTable; 67 68 69 protected transient DatabaseField directField; 70 protected transient Vector sourceKeyFields; 71 protected transient Vector referenceKeyFields; 72 73 74 protected transient DataModifyQuery insertQuery; 75 76 protected transient ModifyQuery changeSetDeleteQuery; 77 78 protected transient boolean hasCustomDeleteQuery; 79 protected transient boolean hasCustomInsertQuery; 80 81 85 public DirectCollectionMapping() { 86 this.insertQuery = new DataModifyQuery(); 87 this.sourceKeyFields = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(1); 88 this.referenceKeyFields = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(1); 89 this.selectionQuery = new DirectReadQuery(); 90 this.hasCustomInsertQuery = false; 91 this.isPrivateOwned = true; 92 } 93 94 public boolean isRelationalMapping() { 95 return true; 96 } 97 98 103 public Converter getValueConverter() { 104 return valueConverter; 105 } 106 107 112 public void setValueConverter(Converter valueConverter) { 113 this.valueConverter = valueConverter; 114 } 115 116 123 public void addReferenceKeyFieldName(String referenceForeignKeyFieldName, String sourcePrimaryKeyFieldName) { 124 getSourceKeyFields().addElement(new DatabaseField(sourcePrimaryKeyFieldName)); 125 getReferenceKeyFields().addElement(new DatabaseField(referenceForeignKeyFieldName)); 126 } 127 128 133 public void buildCopy(Object copy, Object original, ObjectCopyingPolicy policy) { 134 Object attributeValue = getRealCollectionAttributeValueFromObject(original, policy.getSession()); 135 attributeValue = getContainerPolicy().cloneFor(attributeValue); 136 setRealAttributeValueInObject(copy, attributeValue); 137 } 138 139 146 protected Object buildElementClone(Object element, UnitOfWorkImpl unitOfWork, boolean isExisting) { 147 Object cloneValue = element; 148 if ((getValueConverter() != null) && getValueConverter().isMutable()) { 149 cloneValue = getValueConverter().convertDataValueToObjectValue(getValueConverter().convertObjectValueToDataValue(cloneValue, unitOfWork), unitOfWork); 150 } 151 return cloneValue; 152 } 153 154 158 public void cascadePerformRemoveIfRequired(Object object, UnitOfWorkImpl uow, IdentityHashtable visitedObjects) { 159 } 161 162 166 public void cascadeRegisterNewIfRequired(Object object, UnitOfWorkImpl uow, IdentityHashtable visitedObjects) { 167 } 169 170 174 public Object clone() { 175 DirectCollectionMapping clone = (DirectCollectionMapping)super.clone(); 176 177 clone.setSourceKeyFields(cloneFields(getSourceKeyFields())); 178 clone.setReferenceKeyFields(cloneFields(getReferenceKeyFields())); 179 180 return clone; 181 } 182 183 187 public void compareCollectionsForChange(Object oldCollection, Object newCollection, ChangeRecord changeRecord, AbstractSession session){ 188 ContainerPolicy cp = getContainerPolicy(); 189 int numberOfNewNulls = 0; 190 191 HashMap originalKeyValues = new HashMap(10); 192 HashMap cloneKeyValues = new HashMap(10); 193 194 if (oldCollection != null){ 195 Object backUpIter = cp.iteratorFor(oldCollection); 196 197 while (cp.hasNext(backUpIter)) { Object secondObject = cp.next(backUpIter, session); 199 200 if (secondObject == null) { 202 numberOfNewNulls--; 203 } else { 204 Integer count = (Integer )originalKeyValues.get(secondObject); 205 if (count == null) { 206 originalKeyValues.put(secondObject, new Integer (1)); 207 } else { 208 originalKeyValues.put(secondObject, new Integer (count.intValue() + 1)); 209 } 210 } 211 } 212 } 213 HashMap databaseCount = (HashMap)originalKeyValues.clone(); 217 int databaseNullCount = Math.abs(numberOfNewNulls); 218 219 if (newCollection != null){ 220 Object cloneIter = cp.iteratorFor(newCollection); 221 222 227 while (cp.hasNext(cloneIter)) { Object firstObject = cp.next(cloneIter, session); 229 230 if (firstObject == null) { 232 numberOfNewNulls++; 233 } else { 234 Integer count = (Integer )originalKeyValues.get(firstObject); 235 if (count == null) { Integer cloneCount = (Integer )cloneKeyValues.get(firstObject); 237 238 if (cloneCount == null) { 240 cloneKeyValues.put(firstObject, new Integer (1)); 241 } else { 242 cloneKeyValues.put(firstObject, new Integer (cloneCount.intValue() + 1)); 243 } 244 } else if (count.intValue() == 1) { 245 originalKeyValues.remove(firstObject); 247 } else { 248 originalKeyValues.put(firstObject, new Integer (count.intValue() - 1)); 249 } 250 } 251 } 252 } 253 if (cloneKeyValues.isEmpty() && originalKeyValues.isEmpty() && (numberOfNewNulls == 0) && (!changeRecord.getOwner().isNew())) { 254 return; 255 } 256 ((DirectCollectionChangeRecord)changeRecord).addAdditionChange(cloneKeyValues, databaseCount); 257 ((DirectCollectionChangeRecord)changeRecord).addRemoveChange(originalKeyValues, databaseCount); 258 if (numberOfNewNulls != 0) { 260 Vector changeList = null; 261 ((DirectCollectionChangeRecord)changeRecord).getCommitAddMap().put(DirectCollectionChangeRecord.Null, new Integer (databaseNullCount)); 262 if (numberOfNewNulls > 0) { 263 ((DirectCollectionChangeRecord)changeRecord).addAdditionChange(DirectCollectionChangeRecord.Null, new Integer (numberOfNewNulls)); 264 } else { 265 numberOfNewNulls *= -1; 266 ((DirectCollectionChangeRecord)changeRecord).addRemoveChange(DirectCollectionChangeRecord.Null, new Integer (numberOfNewNulls)); 267 } 268 } 269 } 270 271 277 public ChangeRecord compareForChange(Object clone, Object backUp, ObjectChangeSet owner, AbstractSession session) { 278 Object cloneAttribute = null; 279 Object backUpAttribute = null; 280 int numberOfNewNulls = 0; 281 282 ContainerPolicy cp = getContainerPolicy(); 283 284 cloneAttribute = getAttributeValueFromObject(clone); 285 286 if ((cloneAttribute != null) && (!getIndirectionPolicy().objectIsInstantiated(cloneAttribute))) { 287 return null; 288 } 289 290 Object cloneObjectCollection = getRealCollectionAttributeValueFromObject(clone, session); 291 292 Object backUpCollection = null; 293 294 if (!owner.isNew()) { 295 backUpAttribute = getAttributeValueFromObject(backUp); 296 297 if ((backUpAttribute == null) && (cloneAttribute == null)) { 298 return null; 299 } 300 301 backUpCollection = getRealCollectionAttributeValueFromObject(backUp, session); 302 } 303 DirectCollectionChangeRecord changeRecord = new DirectCollectionChangeRecord(owner); 304 changeRecord.setAttribute(getAttributeName()); 305 changeRecord.setMapping(this); 306 compareCollectionsForChange(backUpCollection, cloneObjectCollection, changeRecord, session); 307 if (changeRecord.hasChanges()){ 308 return changeRecord; 309 } 310 return null; 311 } 312 313 317 public boolean compareObjects(Object firstObject, Object secondObject, AbstractSession session) { 318 Object firstCollection = getRealCollectionAttributeValueFromObject(firstObject, session); 319 Object secondCollection = getRealCollectionAttributeValueFromObject(secondObject, session); 320 ContainerPolicy containerPolicy = getContainerPolicy(); 321 322 if (containerPolicy.sizeFor(firstCollection) != containerPolicy.sizeFor(secondCollection)) { 323 return false; 324 } 325 326 HashMap firstCounter = new HashMap(); 327 HashMap secondCounter = new HashMap(); 328 for (Object iter = containerPolicy.iteratorFor(firstCollection);containerPolicy.hasNext(iter);) { 329 Object object = containerPolicy.next(iter, session); 330 if (firstCounter.containsKey(object)){ 331 int count = ((Integer )firstCounter.get(object)).intValue(); 332 firstCounter.put(object, new Integer (++count)); 333 }else{ 334 firstCounter.put(object, new Integer (1)); 335 } 336 } 337 for (Object iter = containerPolicy.iteratorFor(secondCollection);containerPolicy.hasNext(iter);) { 338 Object object = containerPolicy.next(iter, session); 339 if (secondCounter.containsKey(object)){ 340 int count = ((Integer )secondCounter.get(object)).intValue(); 341 secondCounter.put(object, new Integer (++count)); 342 }else{ 343 secondCounter.put(object, new Integer (1)); 344 } 345 } 346 for (Iterator iterator = firstCounter.keySet().iterator(); iterator.hasNext();){ 347 Object object = iterator.next(); 348 349 if (!secondCounter.containsKey(object) || ( ((Integer )secondCounter.get(object)).intValue() != ((Integer )firstCounter.get(object)).intValue()) ) { 350 return false; 351 }else{ 352 iterator.remove(); 353 secondCounter.remove(object); 354 } 355 } 356 if ( !firstCounter.isEmpty() || !secondCounter.isEmpty() ) { 357 return false; 358 } 359 return true; 360 } 361 362 369 public void convertClassNamesToClasses(ClassLoader classLoader){ 370 super.convertClassNamesToClasses(classLoader); 371 if (valueConverter != null && valueConverter instanceof TypeConversionConverter){ 372 ((TypeConversionConverter)valueConverter).convertClassNamesToClasses(classLoader); 373 } 374 }; 375 376 377 382 protected Vector extractKeyFromReferenceRow(AbstractRecord row, AbstractSession session) { 383 Vector key = new Vector(getReferenceKeyFields().size()); 384 385 for (int index = 0; index < getReferenceKeyFields().size(); index++) { 386 DatabaseField relationField = (DatabaseField)getReferenceKeyFields().elementAt(index); 387 DatabaseField sourceField = (DatabaseField)getSourceKeyFields().elementAt(index); 388 Object value = row.get(relationField); 389 390 try { 392 value = session.getDatasourcePlatform().getConversionManager().convertObject(value, getDescriptor().getObjectBuilder().getFieldClassification(sourceField)); 393 } catch (ConversionException e) { 394 throw ConversionException.couldNotBeConverted(this, getDescriptor(), e); 395 } 396 397 key.addElement(value); 398 } 399 400 return key; 401 } 402 403 408 protected Vector extractPrimaryKeyFromRow(AbstractRecord row, AbstractSession session) { 409 Vector key = new Vector(getSourceKeyFields().size()); 410 411 for (Enumeration fieldEnum = getSourceKeyFields().elements(); fieldEnum.hasMoreElements();) { 412 DatabaseField field = (DatabaseField)fieldEnum.nextElement(); 413 Object value = row.get(field); 414 415 try { 417 value = session.getDatasourcePlatform().getConversionManager().convertObject(value, getDescriptor().getObjectBuilder().getFieldClassification(field)); 418 } catch (ConversionException e) { 419 throw ConversionException.couldNotBeConverted(this, getDescriptor(), e); 420 } 421 422 key.addElement(value); 423 } 424 425 return key; 426 } 427 428 protected ModifyQuery getDeleteQuery() { 429 if (changeSetDeleteQuery == null) { 430 changeSetDeleteQuery = new DataModifyQuery(); 431 } 432 return changeSetDeleteQuery; 433 } 434 435 440 public DatabaseField getDirectField() { 441 return directField; 442 } 443 444 448 public String getDirectFieldName() { 449 if (getDirectField() == null) { 450 return null; 451 } 452 return getDirectField().getQualifiedName(); 453 } 454 455 protected DataModifyQuery getInsertQuery() { 456 return insertQuery; 457 } 458 459 463 public Class getReferenceClass() { 464 return null; 465 } 466 467 public String getReferenceClassName() { 468 return null; 469 } 470 471 475 public ClassDescriptor getReferenceDescriptor() { 476 return null; 477 } 478 479 484 public Vector getReferenceKeyFieldNames() { 485 Vector fieldNames = new Vector(getReferenceKeyFields().size()); 486 for (Enumeration fieldsEnum = getReferenceKeyFields().elements(); 487 fieldsEnum.hasMoreElements();) { 488 fieldNames.addElement(((DatabaseField)fieldsEnum.nextElement()).getQualifiedName()); 489 } 490 491 return fieldNames; 492 } 493 494 498 public Vector getReferenceKeyFields() { 499 return referenceKeyFields; 500 } 501 502 507 public DatabaseTable getReferenceTable() { 508 return referenceTable; 509 } 510 511 515 public String getReferenceTableName() { 516 if (getReferenceTable() == null) { 517 return null; 518 } 519 return getReferenceTable().getName(); 520 } 521 522 524 528 public String getReferenceTableQualifiedName() { if (getReferenceTable() == null) { 530 return null; 531 } 532 return getReferenceTable().getQualifiedName(); 533 } 534 535 541 public DatabaseMapping getRelationshipPartner() { 542 return null; 543 } 544 545 550 public Vector getSourceKeyFieldNames() { 551 Vector fieldNames = new Vector(getSourceKeyFields().size()); 552 for (Enumeration fieldsEnum = getSourceKeyFields().elements(); 553 fieldsEnum.hasMoreElements();) { 554 fieldNames.addElement(((DatabaseField)fieldsEnum.nextElement()).getQualifiedName()); 555 } 556 557 return fieldNames; 558 } 559 560 564 public Vector getSourceKeyFields() { 565 return sourceKeyFields; 566 } 567 568 protected boolean hasCustomDeleteQuery() { 569 return hasCustomDeleteQuery; 570 } 571 572 protected boolean hasCustomInsertQuery() { 573 return hasCustomInsertQuery; 574 } 575 576 580 public void initialize(AbstractSession session) throws DescriptorException { 581 if (isKeyForSourceSpecified()) { 582 initializeSourceKeys(session); 583 } else { 584 initializeSourceKeysWithDefaults(session); 585 } 586 587 initializeReferenceTable(session); 588 initializeReferenceKeys(session); 589 initializeDirectField(session); 590 if (shouldInitializeSelectionCriteria()) { 591 initializeSelectionCriteria(session); 592 initializeSelectionStatement(session); 593 } 594 if (!getSelectionQuery().hasSessionName()) { 595 getSelectionQuery().setSessionName(session.getName()); 596 } 597 if ((getValueConverter() != null) && (getSelectionQuery() instanceof DirectReadQuery)) { 598 ((DirectReadQuery)getSelectionQuery()).setValueConverter(getValueConverter()); 599 } 600 initializeDeleteAllQuery(session); 601 initializeDeleteQuery(session); 602 initializeInsertQuery(session); 603 if (getValueConverter() != null) { 604 getValueConverter().initialize(this, session); 605 } 606 super.initialize(session); 607 } 608 609 613 protected void initializeDeleteAllQuery(AbstractSession session) { 614 if (!getDeleteAllQuery().hasSessionName()) { 615 getDeleteAllQuery().setSessionName(session.getName()); 616 } 617 618 if (hasCustomDeleteAllQuery()) { 619 return; 620 } 621 622 Expression expression = null; 623 Expression subExp1; 624 Expression subExp2; 625 Expression subExpression; 626 Expression builder = new ExpressionBuilder(); 627 SQLDeleteStatement statement = new SQLDeleteStatement(); 628 629 for (int index = 0; index < getReferenceKeyFields().size(); index++) { 631 DatabaseField referenceKey = (DatabaseField)getReferenceKeyFields().elementAt(index); 632 DatabaseField sourceKey = (DatabaseField)getSourceKeyFields().elementAt(index); 633 634 subExp1 = builder.getField(referenceKey); 635 subExp2 = builder.getParameter(sourceKey); 636 subExpression = subExp1.equal(subExp2); 637 638 if (expression == null) { 639 expression = subExpression; 640 } else { 641 expression = expression.and(subExpression); 642 } 643 } 644 645 statement.setWhereClause(expression); 646 statement.setTable(getReferenceTable()); 647 getDeleteAllQuery().setSQLStatement(statement); 648 } 649 650 protected void initializeDeleteQuery(AbstractSession session) { 651 if (!getDeleteQuery().hasSessionName()) { 652 getDeleteQuery().setSessionName(session.getName()); 653 } 654 655 if (hasCustomDeleteQuery()) { 656 return; 657 } 658 659 Expression builder = new ExpressionBuilder(); 660 Expression directExp = builder.getField(getDirectField()).equal(builder.getParameter(getDirectField())); 661 Expression expression = null; 662 SQLDeleteStatement statement = new SQLDeleteStatement(); 663 664 for (int index = 0; index < getReferenceKeyFields().size(); index++) { 666 DatabaseField referenceKey = (DatabaseField)getReferenceKeyFields().elementAt(index); 667 DatabaseField sourceKey = (DatabaseField)getSourceKeyFields().elementAt(index); 668 669 Expression subExp1 = builder.getField(referenceKey); 670 Expression subExp2 = builder.getParameter(sourceKey); 671 Expression subExpression = subExp1.equal(subExp2); 672 673 expression = subExpression.and(expression); 674 } 675 expression = expression.and(directExp); 676 statement.setWhereClause(expression); 677 statement.setTable(getReferenceTable()); 678 getDeleteQuery().setSQLStatement(statement); 679 } 680 681 684 protected void initializeDirectField(AbstractSession session) throws DescriptorException { 685 if (getDirectField() == null) { 686 throw DescriptorException.directFieldNameNotSet(this); 687 } 688 689 getDirectField().setTable(getReferenceTable()); 690 getDirectField().setIndex(0); 691 } 692 693 697 protected void initializeInsertQuery(AbstractSession session) { 698 if (!getInsertQuery().hasSessionName()) { 699 getInsertQuery().setSessionName(session.getName()); 700 } 701 702 if (hasCustomInsertQuery()) { 703 return; 704 } 705 706 SQLInsertStatement statement = new SQLInsertStatement(); 707 statement.setTable(getReferenceTable()); 708 AbstractRecord directRow = new DatabaseRecord(); 709 for (Enumeration referenceEnum = getReferenceKeyFields().elements(); 710 referenceEnum.hasMoreElements();) { 711 directRow.put((DatabaseField)referenceEnum.nextElement(), null); 712 } 713 directRow.put(getDirectField(), null); 714 statement.setModifyRow(directRow); 715 getInsertQuery().setSQLStatement(statement); 716 getInsertQuery().setModifyRow(directRow); 717 } 718 719 722 protected void initializeReferenceDescriptor(AbstractSession session) { 723 ; 724 } 725 726 729 protected void initializeReferenceKeys(AbstractSession session) throws DescriptorException { 730 if (getReferenceKeyFields().size() == 0) { 731 throw DescriptorException.noReferenceKeyIsSpecified(this); 732 } 733 734 for (Enumeration referenceEnum = getReferenceKeyFields().elements(); 735 referenceEnum.hasMoreElements();) { 736 DatabaseField field = (DatabaseField)referenceEnum.nextElement(); 737 if (field.hasTableName() && (!(field.getTableName().equals(getReferenceTable().getName())))) { 738 throw DescriptorException.referenceKeyFieldNotProperlySpecified(field, this); 739 } 740 field.setTable(getReferenceTable()); 741 } 742 } 743 744 747 protected void initializeReferenceTable(AbstractSession session) throws DescriptorException { 748 Platform platform = session.getDatasourcePlatform(); 749 750 if (getReferenceTable() == null) { 751 throw DescriptorException.referenceTableNotSpecified(this); 752 } 753 754 if (platform.getTableQualifier().length() == 0) { 755 return; 756 } 757 758 if (getReferenceTable().getTableQualifier().length() == 0) { 759 getReferenceTable().setTableQualifier(platform.getTableQualifier()); 760 } 761 } 762 763 protected void initializeSelectionCriteria(AbstractSession session) { 764 Expression exp1; 765 Expression exp2; 766 Expression expression; 767 Expression criteria = null; 768 Enumeration referenceKeysEnum; 769 Enumeration sourceKeysEnum; 770 ExpressionBuilder base = new ExpressionBuilder(); 771 TableExpression table = (TableExpression)base.getTable(getReferenceTable()); 772 773 referenceKeysEnum = getReferenceKeyFields().elements(); 774 sourceKeysEnum = getSourceKeyFields().elements(); 775 776 for (; referenceKeysEnum.hasMoreElements();) { 777 DatabaseField referenceKey = (DatabaseField)referenceKeysEnum.nextElement(); 778 DatabaseField sourceKey = (DatabaseField)sourceKeysEnum.nextElement(); 779 780 exp1 = table.getField(referenceKey); 781 exp2 = base.getParameter(sourceKey); 782 expression = exp1.equal(exp2); 783 784 if (criteria == null) { 785 criteria = expression; 786 } else { 787 criteria = expression.and(criteria); 788 } 789 } 790 791 setSelectionCriteria(criteria); 792 } 793 794 797 protected void initializeSelectionQuery(AbstractSession session) { 798 } 800 801 protected void initializeSelectionStatement(AbstractSession session) { 802 SQLSelectStatement statement = new SQLSelectStatement(); 803 statement.addTable(getReferenceTable()); 804 statement.addField((DatabaseField)getDirectField().clone()); 805 statement.setWhereClause(getSelectionCriteria()); 806 statement.normalize(session, null); 807 getSelectionQuery().setSQLStatement(statement); 808 } 809 810 813 protected void initializeSourceKeys(AbstractSession session) { 814 for (Enumeration sourceKeyEnum = getSourceKeyFields().elements(); 815 sourceKeyEnum.hasMoreElements();) { 816 getDescriptor().buildField((DatabaseField)sourceKeyEnum.nextElement()); 817 } 818 } 819 820 824 protected void initializeSourceKeysWithDefaults(AbstractSession session) { 825 List primaryKeyFields = getDescriptor().getPrimaryKeyFields(); 826 for (int index = 0; index < primaryKeyFields.size(); index++) { 827 getSourceKeyFields().addElement(primaryKeyFields.get(index)); 828 } 829 } 830 831 834 public boolean isDirectCollectionMapping() { 835 return true; 836 } 837 838 842 protected boolean isKeyForSourceSpecified() { 843 return !getSourceKeyFields().isEmpty(); 844 } 845 846 850 public boolean isPrivateOwned() { 851 return true; 852 } 853 854 860 public void iterateOnRealAttributeValue(DescriptorIterator iterator, Object realAttributeValue) { 861 if (iterator.shouldIterateOnPrimitives()) { 862 super.iterateOnRealAttributeValue(iterator, realAttributeValue); 863 } 864 } 865 866 870 public void iterateOnElement(DescriptorIterator iterator, Object element) { 871 iterator.iteratePrimitiveForMapping(element, this); 872 } 873 874 880 public void mergeChangesIntoObject(Object target, ChangeRecord changeRecord, Object source, MergeManager mergeManager) { 881 ContainerPolicy containerPolicy = getContainerPolicy(); 882 Object valueOfTarget = null; 883 AbstractSession session = mergeManager.getSession(); 884 885 HashMap addObjects = ((DirectCollectionChangeRecord)changeRecord).getAddObjectMap(); 887 HashMap removeObjects = ((DirectCollectionChangeRecord)changeRecord).getRemoveObjectMap(); 888 889 if ((isAttributeValueInstantiated(target)) && (!changeRecord.getOwner().isNew())) { 891 valueOfTarget = getRealCollectionAttributeValueFromObject(target, session); 892 } else { 893 valueOfTarget = containerPolicy.containerInstance(addObjects.size()); 895 } 896 if (!isAttributeValueInstantiated(target)) { 897 if (mergeManager.shouldMergeChangesIntoDistributedCache()) { 898 return; 899 } 900 for (Object iterator = containerPolicy.iteratorFor(getRealCollectionAttributeValueFromObject(source, session)); 901 containerPolicy.hasNext(iterator);) { 902 containerPolicy.addInto(containerPolicy.next(iterator, session), valueOfTarget, session); 903 } 904 } else { 905 synchronized (valueOfTarget) { 906 for (Iterator iterator = addObjects.keySet().iterator(); iterator.hasNext(); ){ 908 Object object = iterator.next(); 909 int objectCount = ((Integer )addObjects.get(object)).intValue(); 910 for (int i = 0; i < objectCount; ++i) { 911 if (mergeManager.shouldMergeChangesIntoDistributedCache()) { 912 if (!containerPolicy.contains(object, valueOfTarget, session)) { 914 containerPolicy.addInto(object, valueOfTarget, session); 915 } 916 } else { 917 containerPolicy.addInto(object, valueOfTarget, session); 918 } 919 } 920 } 921 for (Iterator iterator = removeObjects.keySet().iterator(); iterator.hasNext(); ){ 922 Object object = iterator.next(); 923 int objectCount = ((Integer )removeObjects.get(object)).intValue(); 924 for (int i = 0; i < objectCount; ++i) { 925 containerPolicy.removeFrom(object, valueOfTarget, session); 926 } 927 } 928 } 929 } 930 setRealAttributeValueInObject(target, valueOfTarget); 931 } 932 933 937 public void mergeIntoObject(Object target, boolean isTargetUnInitialized, Object source, MergeManager mergeManager) { 938 if (isTargetUnInitialized) { 939 if (mergeManager.shouldMergeWorkingCopyIntoOriginal() && (!isAttributeValueInstantiated(source))) { 941 setAttributeValueInObject(target, getIndirectionPolicy().getOriginalIndirectionObject(getAttributeValueFromObject(source), mergeManager.getSession())); 942 return; 943 } 944 } 945 if (!shouldMergeCascadeReference(mergeManager)) { 946 return; 948 } 949 if (mergeManager.shouldMergeOriginalIntoWorkingCopy()) { 950 if (!isAttributeValueInstantiated(target)) { 951 return; 954 } 955 } else if (!isAttributeValueInstantiated(source)) { 956 return; 959 } 960 961 ContainerPolicy containerPolicy = getContainerPolicy(); 962 Object valueOfSource = getRealCollectionAttributeValueFromObject(source, mergeManager.getSession()); 963 964 Object valueOfTarget = getRealCollectionAttributeValueFromObject(target, mergeManager.getSession()); 966 Object newContainer = containerPolicy.containerInstance(containerPolicy.sizeFor(valueOfSource)); 967 boolean fireChangeEvents = false; 968 valueOfTarget = newContainer; 969 for (Object sourceValuesIterator = containerPolicy.iteratorFor(valueOfSource); 970 containerPolicy.hasNext(sourceValuesIterator);) { 971 Object sourceValue = containerPolicy.next(sourceValuesIterator, mergeManager.getSession()); 972 containerPolicy.addInto(sourceValue, valueOfTarget, mergeManager.getSession()); 973 } 974 975 setRealAttributeValueInObject(target, valueOfTarget); 977 } 978 979 984 public void performDataModificationEvent(Object [] event, AbstractSession session) throws DatabaseException, DescriptorException { 985 if (event[0] == Delete){ 987 session.executeQuery((DataModifyQuery)event[1], (AbstractRecord)event[(2)]); 988 } else if (event[0] == Insert) { 989 session.executeQuery((DataModifyQuery)event[1], (AbstractRecord)event[(2)]); 990 } else if (event[0] == DeleteAll) { 991 preDelete((DeleteObjectQuery)event[1]); 992 } else { 993 throw DescriptorException.invalidDataModificationEventCode(event[0], this); 994 } 995 } 996 997 1001 public void postInsert(WriteObjectQuery query) throws DatabaseException { 1002 Object objects; 1003 AbstractRecord databaseRow = new DatabaseRecord(); 1004 1005 if (isReadOnly()) { 1006 return; 1007 } 1008 1009 objects = getRealCollectionAttributeValueFromObject(query.getObject(), query.getSession()); 1010 ContainerPolicy containerPolicy = getContainerPolicy(); 1011 if (containerPolicy.isEmpty(objects)) { 1012 return; 1013 } 1014 1015 prepareTranslationRow(query.getTranslationRow(), query.getObject(), query.getSession()); 1016 for (int index = 0; index < getReferenceKeyFields().size(); index++) { 1018 DatabaseField referenceKey = (DatabaseField)getReferenceKeyFields().elementAt(index); 1019 DatabaseField sourceKey = (DatabaseField)getSourceKeyFields().elementAt(index); 1020 Object sourceKeyValue = query.getTranslationRow().get(sourceKey); 1021 databaseRow.put(referenceKey, sourceKeyValue); 1022 } 1023 1024 for (Object iter = containerPolicy.iteratorFor(objects); containerPolicy.hasNext(iter);) { 1026 Object object = containerPolicy.next(iter, query.getSession()); 1027 if (getValueConverter() != null) { 1028 object = getValueConverter().convertObjectValueToDataValue(object, query.getSession()); 1029 } 1030 databaseRow.put(getDirectField(), object); 1031 1032 if (query.shouldCascadeOnlyDependentParts()) { 1034 Object [] event = new Object [3]; 1036 event[0] = Insert; 1037 event[1] = getInsertQuery(); 1038 event[2] = databaseRow.clone(); 1039 query.getSession().getCommitManager().addDataModificationEvent(this, event); 1040 } else { 1041 query.getSession().executeQuery(getInsertQuery(), databaseRow); 1042 } 1043 } 1044 } 1045 1046 1050 public void postUpdate(WriteObjectQuery writeQuery) throws DatabaseException { 1051 if (isReadOnly()) { 1052 return; 1053 } 1054 1055 if (writeQuery.getObjectChangeSet() != null){ 1056 postUpdateWithChangeSet(writeQuery); 1057 return; 1058 } 1059 if (!isAttributeValueInstantiated(writeQuery.getObject())) { 1061 return; 1062 } 1063 1064 if (writeQuery.getSession().isUnitOfWork()) { 1065 if (compareObjects(writeQuery.getObject(), writeQuery.getBackupClone(), writeQuery.getSession())) { 1066 return; } 1068 } 1069 1070 DeleteObjectQuery deleteQuery = new DeleteObjectQuery(); 1071 deleteQuery.setObject(writeQuery.getObject()); 1072 deleteQuery.setSession(writeQuery.getSession()); 1073 deleteQuery.setTranslationRow(writeQuery.getTranslationRow()); 1074 1075 if (writeQuery.shouldCascadeOnlyDependentParts()) { 1076 Object [] event = new Object [3]; 1078 event[0] = DeleteAll; 1079 event[1] = deleteQuery; 1080 writeQuery.getSession().getCommitManager().addDataModificationEvent(this, event); 1081 } else { 1082 preDelete(deleteQuery); 1083 } 1084 postInsert(writeQuery); 1085 } 1086 1087 1091 protected void postUpdateWithChangeSet(WriteObjectQuery writeQuery) throws DatabaseException { 1092 1093 ObjectChangeSet changeSet = writeQuery.getObjectChangeSet(); 1094 DirectCollectionChangeRecord changeRecord = (DirectCollectionChangeRecord)changeSet.getChangesForAttributeNamed(this.getAttributeName()); 1095 if (changeRecord == null){ 1096 return; 1097 } 1098 for (int index = 0; index < getReferenceKeyFields().size(); index++) { 1099 DatabaseField referenceKey = (DatabaseField)getReferenceKeyFields().elementAt(index); 1100 DatabaseField sourceKey = (DatabaseField)getSourceKeyFields().elementAt(index); 1101 Object sourceKeyValue = writeQuery.getTranslationRow().get(sourceKey); 1102 writeQuery.getTranslationRow().put(referenceKey, sourceKeyValue); 1103 } 1104 for (Iterator iterator = changeRecord.getRemoveObjectMap().keySet().iterator(); iterator.hasNext();){ 1105 Object object = iterator.next(); 1106 AbstractRecord thisRow = (AbstractRecord)writeQuery.getTranslationRow().clone(); 1107 Object value = object; 1108 if (getValueConverter() != null){ 1109 value = getValueConverter().convertObjectValueToDataValue(value, writeQuery.getSession()); 1110 } 1111 if (value == DirectCollectionChangeRecord.Null){ 1112 thisRow.add(getDirectField(), null); 1113 }else{ 1114 thisRow.add(getDirectField(), value); 1115 } 1116 Object [] event = new Object [3]; 1118 event[0] = Delete; 1119 event[1] = getDeleteQuery(); 1120 event[2] = thisRow; 1121 writeQuery.getSession().getCommitManager().addDataModificationEvent(this, event); 1122 Integer count = (Integer )changeRecord.getCommitAddMap().get(object); 1123 if (count != null){ 1124 for (int counter = count.intValue(); counter > 0; --counter){ 1125 thisRow = (AbstractRecord)writeQuery.getTranslationRow().clone(); 1126 thisRow.add(getDirectField(), value); 1127 event = new Object [3]; 1129 event[0] = Insert; 1130 event[1] = getInsertQuery(); 1131 event[2] = thisRow; 1132 writeQuery.getSession().getCommitManager().addDataModificationEvent(this, event); 1133 } 1134 } 1135 } 1136 for (Iterator iterator = changeRecord.getAddObjectMap().keySet().iterator(); iterator.hasNext();){ 1137 Object object = iterator.next(); 1138 Integer count = (Integer )changeRecord.getAddObjectMap().get(object); 1139 for (int counter = count.intValue(); counter > 0; --counter){ 1140 AbstractRecord thisRow = (AbstractRecord)writeQuery.getTranslationRow().clone(); 1141 Object value = object; 1142 if (getValueConverter() != null){ 1143 value = getValueConverter().convertObjectValueToDataValue(value, writeQuery.getSession()); 1144 } 1145 if (value == DirectCollectionChangeRecord.Null){ thisRow.add(getDirectField(), null); 1147 }else{ 1148 thisRow.add(getDirectField(), value); 1149 } 1150 Object [] event = new Object [3]; 1152 event[0] = Insert; 1153 event[1] = getInsertQuery(); 1154 event[2] = thisRow; 1155 writeQuery.getSession().getCommitManager().addDataModificationEvent(this, event); 1156 } 1157 } 1158 } 1159 1160 1164 public void preDelete(DeleteObjectQuery query) throws DatabaseException { 1165 if (isReadOnly()) { 1166 return; 1167 } 1168 1169 prepareTranslationRow(query.getTranslationRow(), query.getObject(), query.getSession()); 1170 query.getSession().executeQuery(getDeleteAllQuery(), query.getTranslationRow()); 1171 } 1172 1173 1177 protected void prepareTranslationRow(AbstractRecord translationRow, Object object, AbstractSession session) { 1178 for (Enumeration sourceFieldsEnum = getSourceKeyFields().elements(); 1180 sourceFieldsEnum.hasMoreElements();) { 1181 DatabaseField sourceKey = (DatabaseField)sourceFieldsEnum.nextElement(); 1182 if (!translationRow.containsKey(sourceKey)) { 1183 Object value = getDescriptor().getObjectBuilder().extractValueFromObjectForField(object, sourceKey, session); 1184 translationRow.put(sourceKey, value); 1185 } 1186 } 1187 } 1188 1189 protected void setDeleteQuery(ModifyQuery query) { 1190 this.changeSetDeleteQuery = query; 1191 } 1192 1193 1203 public void setDeleteSQLString(String sqlString) { 1204 DataModifyQuery query = new DataModifyQuery(); 1205 query.setSQLString(sqlString); 1206 setCustomDeleteQuery(query); 1207 } 1208 1209 1214 public void setContainerPolicy(ContainerPolicy containerPolicy) { 1215 this.containerPolicy = containerPolicy; 1216 ((DataReadQuery)getSelectionQuery()).setContainerPolicy(containerPolicy); 1217 } 1218 1219 1226 public void setCustomDeleteQuery(ModifyQuery query) { 1227 setDeleteQuery(query); 1228 setHasCustomDeleteQuery(true); 1229 } 1230 1231 1236 public void setCustomInsertQuery(DataModifyQuery query) { 1237 setInsertQuery(query); 1238 setHasCustomInsertQuery(true); 1239 } 1240 1241 protected void setDirectField(DatabaseField field) { 1242 directField = field; 1243 } 1244 1245 1250 public void setDirectFieldName(String fieldName) { 1251 setDirectField(new DatabaseField(fieldName)); 1252 } 1253 1254 protected void setHasCustomDeleteQuery(boolean bool) { 1255 hasCustomDeleteQuery = bool; 1256 } 1257 1258 protected void setHasCustomInsertQuery(boolean bool) { 1259 hasCustomInsertQuery = bool; 1260 } 1261 1262 protected void setInsertQuery(DataModifyQuery insertQuery) { 1263 this.insertQuery = insertQuery; 1264 } 1265 1266 1275 public void setInsertSQLString(String sqlString) { 1276 DataModifyQuery query = new DataModifyQuery(); 1277 query.setSQLString(sqlString); 1278 setCustomInsertQuery(query); 1279 } 1280 1281 1285 public void setReferenceClass(Class referenceClass) { 1286 return; 1287 } 1288 1289 public void setReferenceClassName(String referenceClassName) { 1290 return; 1291 } 1292 1293 1299 public void setReferenceKeyFieldName(String fieldName) { 1300 getReferenceKeyFields().addElement(new DatabaseField(fieldName)); 1301 } 1302 1303 1308 public void setReferenceKeyFieldNames(Vector fieldNames) { 1309 Vector fields = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(fieldNames.size()); 1310 for (Enumeration fieldNamesEnum = fieldNames.elements(); fieldNamesEnum.hasMoreElements();) { 1311 fields.addElement(new DatabaseField((String )fieldNamesEnum.nextElement())); 1312 } 1313 1314 setReferenceKeyFields(fields); 1315 } 1316 1317 1321 public void setReferenceKeyFields(Vector aVector) { 1322 this.referenceKeyFields = aVector; 1323 } 1324 1325 protected void setReferenceTable(DatabaseTable table) { 1326 referenceTable = table; 1327 } 1328 1329 1333 public void setReferenceTableName(String tableName) { 1334 if (tableName == null) { 1335 setReferenceTable(null); 1336 } else { 1337 setReferenceTable(new DatabaseTable(tableName)); 1338 } 1339 } 1340 1341 1347 public void setSessionName(String name) { 1348 super.setSessionName(name); 1349 getInsertQuery().setSessionName(name); 1350 } 1351 1352 1357 public void setSourceKeyFieldNames(Vector fieldNames) { 1358 Vector fields = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(fieldNames.size()); 1359 for (Enumeration fieldNamesEnum = fieldNames.elements(); fieldNamesEnum.hasMoreElements();) { 1360 fields.addElement(new DatabaseField((String )fieldNamesEnum.nextElement())); 1361 } 1362 1363 setSourceKeyFields(fields); 1364 } 1365 1366 1370 public void setSourceKeyFields(Vector sourceKeyFields) { 1371 this.sourceKeyFields = sourceKeyFields; 1372 } 1373 1374 1380 public void calculateDeferredChanges(ChangeRecord changeRecord, AbstractSession session){ 1381 DirectCollectionChangeRecord collectionRecord = (DirectCollectionChangeRecord) changeRecord; 1382 compareCollectionsForChange(collectionRecord.getOriginalCollection(), collectionRecord.getLatestCollection(), collectionRecord, session); 1383 } 1384 1385 1391 public void simpleAddToCollectionChangeRecord(Object referenceKey, Object objectToAdd, ObjectChangeSet changeSet, AbstractSession session) { 1392 DirectCollectionChangeRecord collectionChangeRecord = (DirectCollectionChangeRecord)changeSet.getChangesForAttributeNamed(getAttributeName()); 1393 if (collectionChangeRecord == null) { 1394 collectionChangeRecord = new DirectCollectionChangeRecord(changeSet); 1395 collectionChangeRecord.setAttribute(getAttributeName()); 1396 collectionChangeRecord.setMapping(this); 1397 changeSet.addChange(collectionChangeRecord); 1398 Object collection = getRealAttributeValueFromObject(changeSet.getUnitOfWorkClone(), session); 1399 collectionChangeRecord.storeDatabaseCounts(collection, getContainerPolicy(), session); 1400 } 1401 collectionChangeRecord.addAdditionChange(objectToAdd, new Integer (1)); 1402 } 1403 1404 1409 public void simpleRemoveFromCollectionChangeRecord(Object referenceKey, Object objectToRemove, ObjectChangeSet changeSet, AbstractSession session) { 1410 DirectCollectionChangeRecord collectionChangeRecord = (DirectCollectionChangeRecord)changeSet.getChangesForAttributeNamed(getAttributeName()); 1411 if (collectionChangeRecord == null) { 1412 collectionChangeRecord = new DirectCollectionChangeRecord(changeSet); 1413 collectionChangeRecord.setAttribute(getAttributeName()); 1414 collectionChangeRecord.setMapping(this); 1415 changeSet.addChange(collectionChangeRecord); 1416 Object collection = getRealAttributeValueFromObject(changeSet.getUnitOfWorkClone(), session); 1417 collectionChangeRecord.storeDatabaseCounts(collection, getContainerPolicy(), session); 1418 } 1419 collectionChangeRecord.addRemoveChange(objectToRemove, new Integer (1)); 1420 } 1421 1422 1432 public void updateChangeRecord(Object clone, Object newValue, Object oldValue, ObjectChangeSet objectChangeSet, UnitOfWorkImpl uow) { 1433 DirectCollectionChangeRecord collectionChangeRecord = (DirectCollectionChangeRecord)objectChangeSet.getChangesForAttributeNamed(this.getAttributeName()); 1434 if (collectionChangeRecord == null) { 1435 collectionChangeRecord = new DirectCollectionChangeRecord(objectChangeSet); 1436 collectionChangeRecord.setAttribute(getAttributeName()); 1437 collectionChangeRecord.setMapping(this); 1438 objectChangeSet.addChange(collectionChangeRecord); 1439 } 1440 if (collectionChangeRecord.getOriginalCollection() == null){ 1441 collectionChangeRecord.setOriginalCollection(oldValue); 1442 } 1443 collectionChangeRecord.setLatestCollection(newValue); 1444 1445 objectChangeSet.deferredDetectionRequiredOn(getAttributeName()); 1446 } 1447 1448 1455 public void useCollectionClass(Class concreteClass) { 1456 ContainerPolicy policy = ContainerPolicy.buildPolicyFor(concreteClass); 1457 setContainerPolicy(policy); 1458 } 1459 1460 1466 public void useMapClass(Class concreteClass, String methodName) { 1467 throw ValidationException.illegalUseOfMapInDirectCollection(this, concreteClass, methodName); 1468 } 1469 1470 1476 public Object valueFromRow(AbstractRecord row, JoinedAttributeManager joinManager, ObjectBuildingQuery query, AbstractSession session) throws DatabaseException { 1477 ReadQuery targetQuery = getSelectionQuery(); 1478 return getIndirectionPolicy().valueFromQuery(targetQuery, row, query.getSession()); 1479 } 1480 1481 1485 public boolean verifyDelete(Object object, AbstractSession session) throws DatabaseException { 1486 if (isReadOnly()) { 1488 return true; 1489 } 1490 1491 AbstractRecord row = getDescriptor().getObjectBuilder().buildRowForTranslation(object, session); 1492 Object value = session.executeQuery(getSelectionQuery(), row); 1493 1494 return getContainerPolicy().isEmpty(value); 1495 } 1496 1497 1502 public void addToCollectionChangeRecord(Object newKey, Object newValue, ObjectChangeSet objectChangeSet, UnitOfWorkImpl uow) { 1503 if (newValue == null) { 1504 newValue = DirectCollectionChangeRecord.Null; 1505 } 1506 ClassDescriptor descriptor; 1507 DirectCollectionChangeRecord collectionChangeRecord = (DirectCollectionChangeRecord)objectChangeSet.getChangesForAttributeNamed(this.getAttributeName()); 1508 if (collectionChangeRecord == null) { 1509 collectionChangeRecord = new DirectCollectionChangeRecord(objectChangeSet); 1510 collectionChangeRecord.setAttribute(getAttributeName()); 1511 collectionChangeRecord.setMapping(this); 1512 objectChangeSet.addChange(collectionChangeRecord); 1513 Object collection = getRealAttributeValueFromObject(objectChangeSet.getUnitOfWorkClone(), uow); 1514 collectionChangeRecord.storeDatabaseCounts(collection, getContainerPolicy(), uow); 1515 } 1516 collectionChangeRecord.addAdditionChange(newValue, new Integer (1)); 1517 } 1518 1519 1523 public boolean isCascadedLockingSupported() { 1524 return true; 1525 } 1526 1527 1531 public boolean isChangeTrackingSupported() { 1532 return true; 1533 } 1534 1535 1540 public void removeFromCollectionChangeRecord(Object newKey, Object newValue, ObjectChangeSet objectChangeSet, UnitOfWorkImpl uow) { 1541 if (newValue == null) { 1542 newValue = DirectCollectionChangeRecord.Null; 1543 } 1544 ClassDescriptor descriptor; 1545 DirectCollectionChangeRecord collectionChangeRecord = (DirectCollectionChangeRecord)objectChangeSet.getChangesForAttributeNamed(this.getAttributeName()); 1546 if (collectionChangeRecord == null) { 1547 collectionChangeRecord = new DirectCollectionChangeRecord(objectChangeSet); 1548 collectionChangeRecord.setAttribute(getAttributeName()); 1549 collectionChangeRecord.setMapping(this); 1550 objectChangeSet.addChange(collectionChangeRecord); 1551 Object collection = getRealAttributeValueFromObject(objectChangeSet.getUnitOfWorkClone(), uow); 1552 collectionChangeRecord.storeDatabaseCounts(collection, getContainerPolicy(), uow); 1553 } 1554 collectionChangeRecord.addRemoveChange(newValue, new Integer (1)); 1555 } 1556 1557} 1558 | Popular Tags |