/** Compare the attributes. Return true if they are alike. Ignore the order of the elements. */ private boolean compareAttributeValuesWithoutOrder( Object collection1, Object collection2, AbstractSession session) { ContainerPolicy cp = this.getContainerPolicy(); Vector vector2 = cp.vectorFor(collection2, session); // "clone" it so we can clear out the slots for (Object iter1 = cp.iteratorFor(collection1); cp.hasNext(iter1); ) { Object element1 = cp.next(iter1, session); boolean found = false; for (int i = 0; i < vector2.size(); i++) { if (this.compareElements(element1, vector2.elementAt(i), session)) { found = true; vector2.setElementAt(XXX, i); // clear out the matching element break; // matching element found - skip the rest of them } } if (!found) { return false; } } // look for elements that were not in collection1 for (Enumeration stream = vector2.elements(); stream.hasMoreElements(); ) { if (stream.nextElement() != XXX) { return false; } } return true; }
/** * Build and return the change record that results from comparing the two collection attributes. * The order of the elements is significant. */ private ChangeRecord compareAttributeValuesForChangeWithOrder( Object cloneCollection, Object backupCollection, ObjectChangeSet owner, AbstractSession session) { ContainerPolicy cp = this.getContainerPolicy(); Vector cloneVector = cp.vectorFor( cloneCollection, session); // convert it to a Vector so we can preserve the order and use indexes Vector backupVector = cp.vectorFor(backupCollection, session); // "clone" it so we can clear out the slots EISOrderedCollectionChangeRecord changeRecord = new EISOrderedCollectionChangeRecord( owner, this.getAttributeName(), this.getDatabaseMapping()); for (int i = 0; i < cloneVector.size(); i++) { Object cloneElement = cloneVector.elementAt(i); boolean found = false; for (int j = 0; j < backupVector.size(); j++) { if (this.compareElementsForChange(cloneElement, backupVector.elementAt(j), session)) { // the clone element was found in the backup collection found = true; backupVector.setElementAt(XXX, j); // clear out the matching backup element changeRecord.addMovedChangeSet(this.buildChangeSet(cloneElement, owner, session), j, i); break; // matching backup element found - skip the rest of them } } if (!found) { // the clone element was not found, so it must have been added changeRecord.addAddedChangeSet(this.buildChangeSet(cloneElement, owner, session), i); } } for (int i = 0; i < backupVector.size(); i++) { Object backupElement = backupVector.elementAt(i); if (backupElement != XXX) { // the backup element was not in the clone collection, so it must have been removed changeRecord.addRemovedChangeSet(this.buildChangeSet(backupElement, owner, session), i); } } if (changeRecord.hasChanges()) { return changeRecord; } else { return null; } }
/** * Compare the attributes. Return true if they are alike. The order of the elements is * significant. */ private boolean compareAttributeValuesWithOrder( Object collection1, Object collection2, AbstractSession session) { ContainerPolicy cp = this.getContainerPolicy(); Object iter1 = cp.iteratorFor(collection1); Object iter2 = cp.iteratorFor(collection2); while (cp.hasNext(iter1)) { if (!this.compareElements(cp.next(iter1, session), cp.next(iter2, session), session)) { return false; } } return true; }
/** * Merge changes from the source to the target object. Make the necessary removals and adds and * map key modifications. */ private void mergeChangesIntoObjectWithoutOrder( Object target, ChangeRecord changeRecord, Object source, MergeManager mergeManager) { EISCollectionChangeRecord sdkChangeRecord = (EISCollectionChangeRecord) changeRecord; ContainerPolicy cp = this.getContainerPolicy(); AbstractSession session = mergeManager.getSession(); Object targetCollection = null; if (sdkChangeRecord.getOwner().isNew()) { targetCollection = cp.containerInstance(sdkChangeRecord.getAdds().size()); } else { targetCollection = this.getRealCollectionAttributeValueFromObject(target, session); } Vector removes = sdkChangeRecord.getRemoves(); Vector adds = sdkChangeRecord.getAdds(); Vector changedMapKeys = sdkChangeRecord.getChangedMapKeys(); synchronized (targetCollection) { for (Enumeration stream = removes.elements(); stream.hasMoreElements(); ) { Object removeElement = this.buildRemovedElementFromChangeSet(stream.nextElement(), mergeManager); Object targetElement = null; for (Object iter = cp.iteratorFor(targetCollection); cp.hasNext(iter); ) { targetElement = cp.next(iter, session); if (this.compareElements(targetElement, removeElement, session)) { break; // matching element found - skip the rest of them } } if (targetElement != null) { // a matching element was found, remove it cp.removeFrom(targetElement, targetCollection, session); } } for (Enumeration stream = adds.elements(); stream.hasMoreElements(); ) { Object addElement = this.buildAddedElementFromChangeSet(stream.nextElement(), mergeManager); cp.addInto(addElement, targetCollection, session); } for (Enumeration stream = changedMapKeys.elements(); stream.hasMoreElements(); ) { Object changedMapKeyElement = this.buildAddedElementFromChangeSet(stream.nextElement(), mergeManager); Object originalElement = ((UnitOfWorkImpl) session).getOriginalVersionOfObject(changedMapKeyElement); cp.removeFrom(originalElement, targetCollection, session); cp.addInto(changedMapKeyElement, targetCollection, session); } } // reset the attribute to allow for set method to re-morph changes if the collection is not // being stored directly this.setRealAttributeValueInObject(target, targetCollection); }
/** * Build and return the change record that results from comparing the two collection attributes. * Ignore the order of the elements. */ private ChangeRecord compareAttributeValuesForChangeWithoutOrder( Object cloneCollection, Object backupCollection, ObjectChangeSet owner, AbstractSession session) { ContainerPolicy cp = this.getContainerPolicy(); Vector backupVector = cp.vectorFor(backupCollection, session); // "clone" it so we can clear out the slots EISCollectionChangeRecord changeRecord = new EISCollectionChangeRecord(owner, this.getAttributeName(), this.getDatabaseMapping()); for (Object cloneIter = cp.iteratorFor(cloneCollection); cp.hasNext(cloneIter); ) { Object cloneElement = cp.next(cloneIter, session); boolean found = false; for (int i = 0; i < backupVector.size(); i++) { if (this.compareElementsForChange(cloneElement, backupVector.elementAt(i), session)) { // the clone element was found in the backup collection found = true; backupVector.setElementAt(XXX, i); // clear out the matching backup element if (this.mapKeyHasChanged(cloneElement, session)) { changeRecord.addChangedMapKeyChangeSet( this.buildChangeSet(cloneElement, owner, session)); } break; // matching backup element found - skip the rest of them } } if (!found) { // the clone element was not found, so it must have been added changeRecord.addAddedChangeSet(this.buildChangeSet(cloneElement, owner, session)); } } for (int i = 0; i < backupVector.size(); i++) { Object backupElement = backupVector.elementAt(i); if (backupElement != XXX) { // the backup element was not in the clone collection, so it must have been removed changeRecord.addRemovedChangeSet(this.buildChangeSet(backupElement, owner, session)); } } if (changeRecord.hasChanges()) { return changeRecord; } else { return null; } }
/** * Merge changes from the source to the target object. Simply replace the entire target * collection. */ private void mergeChangesIntoObjectWithOrder( Object target, ChangeRecord changeRecord, Object source, MergeManager mergeManager) { ContainerPolicy cp = this.getContainerPolicy(); AbstractSession session = mergeManager.getSession(); Vector changes = ((EISOrderedCollectionChangeRecord) changeRecord).getNewCollection(); Object targetCollection = cp.containerInstance(changes.size()); for (Enumeration stream = changes.elements(); stream.hasMoreElements(); ) { Object targetElement = this.buildAddedElementFromChangeSet(stream.nextElement(), mergeManager); cp.addInto(targetElement, targetCollection, session); } // reset the attribute to allow for set method to re-morph changes if the collection is not // being stored directly this.setRealAttributeValueInObject(target, targetCollection); }
/** * Compare the attributes. Return true if they are alike. Assume the passed-in attributes are * non-null. */ private boolean compareAttributeValues( Object collection1, Object collection2, AbstractSession session) { ContainerPolicy cp = this.getContainerPolicy(); if (cp.sizeFor(collection1) != cp.sizeFor(collection2)) { return false; } // if they are both empty, go no further... if (cp.sizeFor(collection1) == 0) { return true; } if (cp.hasOrder()) { return this.compareAttributeValuesWithOrder(collection1, collection2, session); } else { return this.compareAttributeValuesWithoutOrder(collection1, collection2, session); } }
/** * INTERNAL: Build and return the change record that results from comparing the two collection * attributes. */ public ChangeRecord compareForChange( Object clone, Object backup, ObjectChangeSet owner, AbstractSession session) { ContainerPolicy cp = this.getContainerPolicy(); Object cloneCollection = this.getRealCollectionAttributeValueFromObject(clone, session); Object backupCollection = null; if (owner.isNew()) { backupCollection = cp.containerInstance(1); } else { backupCollection = this.getRealCollectionAttributeValueFromObject(backup, session); } if (cp.hasOrder()) { return this.compareAttributeValuesForChangeWithOrder( cloneCollection, backupCollection, owner, session); } else { return this.compareAttributeValuesForChangeWithoutOrder( cloneCollection, backupCollection, owner, session); } }
/** * INTERNAL: Merge changes from the source to the target object. Simply replace the entire target * collection. */ public void mergeIntoObject( Object target, boolean isTargetUnInitialized, Object source, MergeManager mergeManager) { ContainerPolicy cp = this.getContainerPolicy(); AbstractSession session = mergeManager.getSession(); Object sourceCollection = this.getRealCollectionAttributeValueFromObject(source, session); Object targetCollection = cp.containerInstance(cp.sizeFor(sourceCollection)); for (Object iter = cp.iteratorFor(sourceCollection); cp.hasNext(iter); ) { Object targetElement = this.buildElementFromElement(cp.next(iter, session), mergeManager); cp.addInto(targetElement, targetCollection, session); } // reset the attribute to allow for set method to re-morph changes if the collection is not // being stored directly this.setRealAttributeValueInObject(target, targetCollection); }