FileDocCategorySizeDatePackage
CollectionChangeRecord.javaAPI DocGlassfish v2 API22932Tue May 22 16:54:42 BST 2007oracle.toplink.essentials.internal.sessions

CollectionChangeRecord

public class CollectionChangeRecord extends ChangeRecord implements CollectionChangeRecord

Purpose: This class holds the record of the changes made to a collection attribute of an object.

Description: Collections must be compared to each other and added and removed objects must be recorded seperately

see
OtherRelatedClasses prototype.changeset.DirectToFieldChangeRecord,prototype.changeset.SingleObjectChangeRecord

Fields Summary
protected IdentityHashtable
addObjectList
Contains the added values to the collection and their corresponding ChangeSets.
protected transient Vector
orderedAddObjects
Contains the added values to the collection and their corresponding ChangeSets in order.
protected IdentityHashtable
orderedAddObjectIndices
Contains the added values index to the collection.
protected Hashtable
orderedRemoveObjects
Contains the removed values to the collection and their corresponding ChangeSets.
protected transient Vector
orderedRemoveObjectIndices
Contains the removed values index to the collection.
protected transient List
addOverFlow
Contains a list of extra adds. These extra adds are used by attribute change tracking to replicate behaviour when someone adds the same object to a list and removes it once In this case the object should still appear once in the change set.
protected IdentityHashtable
removeObjectList
Contains the removed values from the collection and their corresponding ChangeSets.
protected transient Vector
sdkAddObjects
Contain the same added values as in addObjectList. It is only used by SDK mapping of this change record.
protected transient Vector
sdkRemoveObjects
Contain the same added values as in addObjectList. It is only used by SDK mapping of this change record.
protected transient Object
originalCollection
Used for change tracking when customer sets entire collection
protected transient Object
latestCollection
Used for change tracking when customer sets entire collection
Constructors Summary
public CollectionChangeRecord()
This default constructor is reference internally by SDK XML project to mapp this class

        super();
    
public CollectionChangeRecord(ObjectChangeSet owner)
Constructor for the ChangeRecord representing a collection mapping

param
owner prototype.changeset.ObjectChangeSet the changeSet that uses this record

        this.owner = owner;
    
Methods Summary
public voidaddAdditionChange(java.util.IdentityHashMap objectChanges, oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet changeSet, oracle.toplink.essentials.internal.sessions.AbstractSession session)
This method takes a IdentityHashtable of objects, converts these into ObjectChangeSets.

param
objectChanges prototype.changeset.ObjectChangeSet

        Iterator enumtr = objectChanges.keySet().iterator();
        while (enumtr.hasNext()) {
            Object object = enumtr.next();
            ObjectChangeSet change = session.getDescriptor(object.getClass()).getObjectBuilder().createObjectChangeSet(object, changeSet, session);
            if (change.hasKeys()){
                // if change set has keys this is a map comparison.  Maps are
                // not support in change tracking so do not need to prevent duplicates
                // when map support is added this will have to be refactored
                getAddObjectList().put(change, change);
            }else{
                if (getRemoveObjectList().contains(change)){
                    getRemoveObjectList().remove(change);
                }else{
                    getAddObjectList().put(change, change);
                }
            }
        }
    
public voidaddOrderedAdditionChange(java.util.Vector objectChanges, oracle.toplink.essentials.internal.helper.IdentityHashtable objectChangesIndices, oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet changeSet, oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: This method takes a Vector of objects and converts them into ObjectChangeSets. This method should only be called from a ListContainerPolicy. Additions to the list are made by index, hence, the second IdentityHashtable of objectChangesIndices.

        Enumeration e = objectChanges.elements();
        
        while (e.hasMoreElements()) {
            Object object = e.nextElement();
            ObjectChangeSet change = session.getDescriptor(object.getClass()).getObjectBuilder().createObjectChangeSet(object, changeSet, session);
            
            getOrderedAddObjects().add(change);
            getOrderedAddObjectIndices().put(change, (Integer) objectChangesIndices.get(object));
        }
    
public voidaddOrderedRemoveChange(java.util.Vector indicesToRemove, java.util.Hashtable objectChanges, oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet changeSet, oracle.toplink.essentials.internal.sessions.AbstractSession session)
INTERNAL: This method takes a Hashtable of objects and converts them into ObjectChangeSets. This method should only be called from a ListContainerPolicy. Deletions from the list is made by index, hence, the second Vector of indicesToRemove.

        orderedRemoveObjectIndices = indicesToRemove;
        Enumeration e = orderedRemoveObjectIndices.elements();
        
        while (e.hasMoreElements()) {
            Integer index = (Integer) e.nextElement();
            Object object = objectChanges.get(index);
            ObjectChangeSet change = session.getDescriptor(object.getClass()).getObjectBuilder().createObjectChangeSet(object, changeSet, session);

            getOrderedRemoveObjects().put(index, change);
        }
    
public voidaddRemoveChange(java.util.IdentityHashMap objectChanges, oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet changeSet, oracle.toplink.essentials.internal.sessions.AbstractSession session)
This method takes a IdentityHashtable of objects, converts these into ObjectChangeSets.

param
objectChanges prototype.changeset.ObjectChangeSet

        // There is no need to keep track of removed new objects because it will not be in the backup,
        // It will not be in the backup because it is new.
        Iterator enumtr = objectChanges.keySet().iterator();
        while (enumtr.hasNext()) {
            Object object = enumtr.next();
            ClassDescriptor descriptor = session.getDescriptor(object.getClass());
            ObjectChangeSet change = descriptor.getObjectBuilder().createObjectChangeSet(object, changeSet, session);
            if (change.hasKeys()){
                // if change set has keys this is a map comparison.  Maps are
                // not support in change tracking so do not need to prevent duplicates
                // when map support is added this will have to be refactored
                getRemoveObjectList().put(change, change);
            }else{
                if (getAddObjectList().contains(change)){
                    getAddObjectList().remove(change);
                }else{
                    getRemoveObjectList().put(change, change);
                }
            }
        }
    
public oracle.toplink.essentials.internal.helper.IdentityHashtablegetAddObjectList()
ADVANCED: This method returns the collection of ChangeSets that were added to the collection.

return
java.util.Vector

        if (addObjectList == null) {
            // 2612538 - the default size of IdentityHashtable (32) is appropriate
            addObjectList = new IdentityHashtable();
        }
        return addObjectList;
    
public java.util.VectorgetAddObjectsForSDK()
INTERNAL: This method used by SDK mapping that only supports Collection type not IdentityHashtable. This method is mapped in oracle.toplink.essentials.internal.remotecommand.CommandProject

return
java.util.Vector

        if (sdkAddObjects == null) {
            sdkAddObjects = new Vector();

            for (Enumeration enumtr = this.getAddObjectList().keys(); enumtr.hasMoreElements();) {
                sdkAddObjects.add(enumtr.nextElement());
            }
        }
        return sdkAddObjects;
    
public java.util.ListgetAddOverFlow()
ADVANCED: This method returns the collection of ChangeSets that were added to the collection.

return
java.util.Vector

        if (addOverFlow == null) {
            addOverFlow = new ArrayList();
        }
        return addOverFlow;
    
public java.lang.ObjectgetLatestCollection()
Used for change tracking when cutomer sets entire collection This is the last collection that was set on the object

        return latestCollection;
    
public java.lang.IntegergetOrderedAddObjectIndex(oracle.toplink.essentials.internal.sessions.ObjectChangeSet changes)
ADVANCED: This method returns the index of an object added to the collection.

        return (Integer) getOrderedAddObjectIndices().get(changes);
    
public oracle.toplink.essentials.internal.helper.IdentityHashtablegetOrderedAddObjectIndices()
ADVANCED: This method returns the collection of ChangeSets that they were added to the collection.

        if (orderedAddObjectIndices == null) {
            orderedAddObjectIndices = new IdentityHashtable();
        }
        
        return orderedAddObjectIndices;
    
public java.util.VectorgetOrderedAddObjects()
ADVANCED: This method returns the collection of ChangeSets in the order they were added to the collection. This list includes those objects that were moved within the collection.

        if (orderedAddObjects == null) {
            orderedAddObjects = new Vector();
        }
        
        return orderedAddObjects;
    
public java.lang.ObjectgetOrderedRemoveObject(java.lang.Integer index)
ADVANCED: This method returns the index of an object removed from the collection.

        return getOrderedRemoveObjects().get(index);
    
public java.util.VectorgetOrderedRemoveObjectIndices()
ADVANCED: This method returns the ordered list of indices to remove from the collection.

        if (orderedRemoveObjectIndices == null) {
            orderedRemoveObjectIndices = new Vector();
        }
        
        return orderedRemoveObjectIndices;
    
public java.util.HashtablegetOrderedRemoveObjects()
ADVANCED: This method returns the collection of ChangeSets of objects removed from the collection.

        if (orderedRemoveObjects == null) {
            orderedRemoveObjects = new Hashtable();
        }
        
        return orderedRemoveObjects;
    
public java.lang.ObjectgetOriginalCollection()
Used for change tracking when cutomer sets entire collection This is the original collection that was set on the object when it was cloned

        return originalCollection;
    
public oracle.toplink.essentials.internal.helper.IdentityHashtablegetRemoveObjectList()
ADVANCED: This method returns the IdentityHashtable that contains the removed values from the collection and their corresponding ChangeSets.

return
java.util.Vector

        if (removeObjectList == null) {
            // 2612538 - the default size of IdentityHashtable (32) is appropriate
            removeObjectList = new IdentityHashtable();
        }
        return removeObjectList;
    
public java.util.VectorgetRemoveObjectsForSDK()
INTERNAL: This method used by SDK mapping that only supports Collection type not IdentityHashtable. This method is mapped in oracle.toplink.essentials.internal.remotecommand.CommandProject

return
java.util.Vector

        if (sdkRemoveObjects == null) {
            sdkRemoveObjects = new Vector();

            for (Enumeration enumtr = this.getRemoveObjectList().keys(); enumtr.hasMoreElements();) {
                sdkRemoveObjects.add(enumtr.nextElement());
            }
        }
        return sdkRemoveObjects;
    
public booleanhasChanges()
returns true if the change set has changes

        return (!(  getAddObjectList().isEmpty() && 
                    getRemoveObjectList().isEmpty() && 
                    getOrderedAddObjects().isEmpty() && 
                    getOrderedRemoveObjects().isEmpty())) 
                || getOwner().isNew();
    
public voidmergeRecord(oracle.toplink.essentials.internal.sessions.ChangeRecord mergeFromRecord, oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet mergeToChangeSet, oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet mergeFromChangeSet)
INTERNAL: This method will be used to merge one record into another

        Enumeration addEnum = ((CollectionChangeRecord)mergeFromRecord).getAddObjectList().keys();
        while (addEnum.hasMoreElements()) {
            ObjectChangeSet mergingObject = (ObjectChangeSet)addEnum.nextElement();
            ObjectChangeSet localChangeSet = mergeToChangeSet.findOrIntegrateObjectChangeSet(mergingObject, mergeFromChangeSet);
            if (getRemoveObjectList().containsKey(localChangeSet)) {
                getRemoveObjectList().remove(localChangeSet);
            } else {
                getAddObjectList().put(localChangeSet, localChangeSet);
            }
        }
        Enumeration removeEnum = ((CollectionChangeRecord)mergeFromRecord).getRemoveObjectList().keys();
        while (removeEnum.hasMoreElements()) {
            ObjectChangeSet mergingObject = (ObjectChangeSet)removeEnum.nextElement();
            ObjectChangeSet localChangeSet = mergeToChangeSet.findOrIntegrateObjectChangeSet(mergingObject, mergeFromChangeSet);
            if (getAddObjectList().containsKey(localChangeSet)) {
                getAddObjectList().remove(localChangeSet);
            } else {
                getRemoveObjectList().put(localChangeSet, localChangeSet);
            }
        }
    
public voidsetAddObjectList(oracle.toplink.essentials.internal.helper.IdentityHashtable objectChangesList)
Sets the Added objects list

param
newValue java.util.Vector

        this.addObjectList = objectChangesList;
    
public voidsetAddObjectsForSDK(java.util.Vector addObjects)
INTERNAL: This method used by SDK mapping that only supports Collection type not IdentityHashtable. This method is mapped in oracle.toplink.essentials.internal.remotecommand.CommandProject

param
java.util.Vector addObjects

        sdkAddObjects = addObjects;

        // build the equivalent addObjectList
        IdentityHashtable newList = new IdentityHashtable();
        for (int i = 0; i < sdkAddObjects.size(); i++) {
            Object change = sdkAddObjects.elementAt(i);
            newList.put(change, change);
        }
        this.setAddObjectList(newList);
    
public voidsetLatestCollection(java.lang.Object latestCollection)
Used for change tracking when cutomer sets entire collection This is the last collection that was set on the object

        this.latestCollection = latestCollection;
    
public voidsetOrderedAddObjectIndices(oracle.toplink.essentials.internal.helper.IdentityHashtable orderedAddObjectIndices)
ADVANCED: Sets collection of ChangeSets (and their respective index) that they were added to the collection.

        this.orderedAddObjectIndices = orderedAddObjectIndices;
    
public voidsetOrderedAddObjects(java.util.Vector orderedAddObjects)
ADVANCED: Sets collection of ChangeSets that they were added to the collection.

        this.orderedAddObjects = orderedAddObjects;
    
public voidsetOrderedRemoveObjects(java.util.Hashtable orderedRemoveObjects)
ADVANCED: Sets collection of ChangeSets that they were remvoved from the collection.

        this.orderedRemoveObjects = orderedRemoveObjects;
    
public voidsetOriginalCollection(java.lang.Object originalCollection)
Used for change tracking when cutomer sets entire collection This is the original collection that was set on the object when it was cloned

        this.originalCollection = originalCollection;
    
public voidsetRemoveObjectList(oracle.toplink.essentials.internal.helper.IdentityHashtable objectChangesList)
Sets the removed objects list

param
newValue java.util.Vector

        this.removeObjectList = objectChangesList;
    
public voidsetRemoveObjectsForSDK(java.util.Vector removeObjects)
INTERNAL: This method used by SDK mapping that only supports Collection type not IdentityHashtable. This method is mapped in oracle.toplink.essentials.internal.remotecommand.CommandProject

param
java.util.Vector removeObjects

        sdkRemoveObjects = removeObjects;

        // build the equivalent removeObjectList
        IdentityHashtable newList = new IdentityHashtable();
        for (int i = 0; i < sdkRemoveObjects.size(); i++) {
            Object change = sdkRemoveObjects.elementAt(i);
            newList.put(change, change);
        }
        this.setRemoveObjectList(newList);
    
public voidupdateReferences(oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet mergeToChangeSet, oracle.toplink.essentials.internal.sessions.UnitOfWorkChangeSet mergeFromChangeSet)
INTERNAL: This method will be used to update the objectsChangeSets references

        IdentityHashtable addList = new IdentityHashtable(getAddObjectList().size());
        IdentityHashtable removeList = new IdentityHashtable(getRemoveObjectList().size());
        
        // If we have ordered lists we need to iterate through those.
        if (getOrderedAddObjects().size() > 0 || getOrderedRemoveObjectIndices().size() > 0) {
            // Do the ordered adds first ...
            Vector orderedAddList = new Vector(getOrderedAddObjects().size());
            IdentityHashtable orderedAddListIndices = new IdentityHashtable(getOrderedAddObjectIndices().size());
            
            for (int i = 0; i < getOrderedAddObjects().size(); i++) {
                ObjectChangeSet changeSet = (ObjectChangeSet) getOrderedAddObjects().elementAt(i);
                ObjectChangeSet localChangeSet = mergeToChangeSet.findOrIntegrateObjectChangeSet(changeSet, mergeFromChangeSet);
                
                orderedAddList.add(localChangeSet);
                orderedAddListIndices.put(localChangeSet, getOrderedAddObjectIndices().get(changeSet));    
                
                // Object was actually added and not moved.
                if (getAddObjectList().contains(changeSet)) {
                    addList.put(localChangeSet, localChangeSet);
                }
            }
            
            setOrderedAddObjects(orderedAddList);
            setOrderedAddObjectIndices(orderedAddListIndices);
            
            // Do the ordered removes now ...
            Hashtable orderedRemoveList = new Hashtable(getOrderedRemoveObjects().size());
            Enumeration changes = getOrderedRemoveObjects().keys();
            
            while (changes.hasMoreElements()) {
                Object index = changes.nextElement();
                ObjectChangeSet changeSet = (ObjectChangeSet) getOrderedRemoveObjects().get(index);
                ObjectChangeSet localChangeSet = mergeToChangeSet.findOrIntegrateObjectChangeSet(changeSet, mergeFromChangeSet);
                
                orderedRemoveList.put(index, localChangeSet);
                
                // Object was actually removed and not moved.
                if (getRemoveObjectList().contains(changeSet)) {
                    removeList.put(localChangeSet, localChangeSet);
                }
            }
            
            setOrderedRemoveObjects(orderedRemoveList);
            // Don't need to worry about the vector of indices (Integer's), just leave them as is.
        } else {
            Enumeration changes = getAddObjectList().elements();
            while (changes.hasMoreElements()) {
                ObjectChangeSet localChangeSet = mergeToChangeSet.findOrIntegrateObjectChangeSet((ObjectChangeSet)changes.nextElement(), mergeFromChangeSet);
                addList.put(localChangeSet, localChangeSet);
            }
        
            changes = getRemoveObjectList().elements();
            while (changes.hasMoreElements()) {
                ObjectChangeSet localChangeSet = mergeToChangeSet.findOrIntegrateObjectChangeSet((ObjectChangeSet)changes.nextElement(), mergeFromChangeSet);
                removeList.put(localChangeSet, localChangeSet);
            }
        }
        
        setAddObjectList(addList);
        setRemoveObjectList(removeList);