Search in sources :

Example 1 with OrderedChangeObject

use of org.eclipse.persistence.internal.sessions.OrderedChangeObject in project eclipselink by eclipse-ee4j.

the class OrderedListContainerPolicy method mergeChanges.

/**
 * INTERNAL:
 * Merge changes from the source to the target object. Because this is a
 * collection mapping, values are added to or removed from the collection
 * based on the change set.
 */
@Override
protected void mergeChanges(CollectionChangeRecord changeRecord, Object valueOfTarget, boolean shouldMergeCascadeParts, MergeManager mergeManager, AbstractSession targetSession) {
    ObjectChangeSet objectChanges;
    if (changeRecord.orderHasBeenRepaired() && valueOfTarget instanceof IndirectList) {
        ((IndirectList) valueOfTarget).setIsListOrderBrokenInDb(false);
    }
    if (!changeRecord.getOrderedChangeObjectList().isEmpty()) {
        Iterator<OrderedChangeObject> objects = changeRecord.getOrderedChangeObjectList().iterator();
        while (objects.hasNext()) {
            OrderedChangeObject changeObject = objects.next();
            objectChanges = changeObject.getChangeSet();
            if (changeObject.getChangeType() == CollectionChangeEvent.REMOVE) {
                boolean objectRemoved = changeRecord.getRemoveObjectList().containsKey(objectChanges);
                Object objectToRemove = objectChanges.getTargetVersionOfSourceObject(mergeManager, targetSession);
                // This should not happen unless identity is lost.
                if (objectToRemove != null) {
                    Integer index = changeObject.getIndex();
                    if (index != null) {
                        if (objectToRemove.equals(get(index, valueOfTarget, mergeManager.getSession()))) {
                            removeFromAtIndex(index, valueOfTarget);
                        } else {
                            // Object is in the cache, but the collection doesn't have it at the location we expect
                            // Collection is invalid with respect to these changes, so invalidate the parent and abort
                            Object key = changeRecord.getOwner().getId();
                            targetSession.getIdentityMapAccessor().invalidateObject(key, changeRecord.getOwner().getClassType(targetSession));
                            return;
                        }
                    } else {
                        removeFrom(objectToRemove, valueOfTarget, targetSession);
                    }
                    if ((!mergeManager.shouldMergeChangesIntoDistributedCache()) && changeRecord.getMapping().isPrivateOwned()) {
                        // Check that the object was actually removed and not moved.
                        if (objectRemoved) {
                            mergeManager.registerRemovedNewObjectIfRequired(objectChanges.getUnitOfWorkClone());
                        }
                    }
                }
            } else {
                // getChangeType == add
                boolean objectAdded = changeRecord.getAddObjectList().containsKey(objectChanges);
                Object object = null;
                // The object was actually added and not moved.
                if (objectAdded && shouldMergeCascadeParts) {
                    object = mergeCascadeParts(objectChanges, mergeManager, targetSession);
                }
                if (object == null) {
                    // Retrieve the object to be added to the collection.
                    object = objectChanges.getTargetVersionOfSourceObject(mergeManager, targetSession);
                }
                // not moved.
                if (objectAdded && mergeManager.shouldMergeChangesIntoDistributedCache()) {
                    // during merge into distributed cache
                    if (!contains(object, valueOfTarget, mergeManager.getSession())) {
                        addIntoAtIndex(changeObject.getIndex(), object, valueOfTarget, mergeManager.getSession());
                    }
                } else {
                    addIntoAtIndex(changeObject.getIndex(), object, valueOfTarget, targetSession);
                }
            }
        }
    } else {
        // Deferred change tracking merge behavior
        // Step 1 - iterate over the removed changes and remove them from the container.
        List<Integer> removedIndices = changeRecord.getOrderedRemoveObjectIndices();
        if (removedIndices.isEmpty()) {
            // Check if we have removed objects via a
            // simpleRemoveFromCollectionChangeRecord API call.
            Iterator<ObjectChangeSet> removedObjects = changeRecord.getRemoveObjectList().keySet().iterator();
            while (removedObjects.hasNext()) {
                objectChanges = removedObjects.next();
                removeFrom(objectChanges.getOldKey(), objectChanges.getTargetVersionOfSourceObject(mergeManager, targetSession), valueOfTarget, targetSession);
                registerRemoveNewObjectIfRequired(objectChanges, mergeManager);
            }
        } else {
            for (int i = removedIndices.size() - 1; i >= 0; i--) {
                Integer index = removedIndices.get(i);
                objectChanges = (ObjectChangeSet) changeRecord.getOrderedRemoveObject(index);
                Object objectToRemove = objectChanges.getTargetVersionOfSourceObject(mergeManager, targetSession);
                if ((objectToRemove != null) && (objectToRemove.equals(get(index, valueOfTarget, mergeManager.getSession())))) {
                    removeFromAtIndex(index, valueOfTarget);
                    // The object was actually removed and not moved.
                    if (changeRecord.getRemoveObjectList().containsKey(objectChanges)) {
                        registerRemoveNewObjectIfRequired(objectChanges, mergeManager);
                    }
                } else {
                    // Object is either not in the cache, or not at the location we expect
                    // Collection is invalid with respect to these changes, so invalidate the parent and abort
                    Object key = changeRecord.getOwner().getId();
                    targetSession.getIdentityMapAccessor().invalidateObject(key, changeRecord.getOwner().getClassType(targetSession));
                    return;
                }
            }
        }
        // Step 2 - iterate over the added changes and add them to the container.
        for (ObjectChangeSet addChangeSet : changeRecord.getOrderedAddObjects()) {
            objectChanges = addChangeSet;
            boolean objectAdded = changeRecord.getAddObjectList().containsKey(objectChanges);
            Object object = null;
            // The object was actually added and not moved.
            if (objectAdded && shouldMergeCascadeParts) {
                object = mergeCascadeParts(objectChanges, mergeManager, targetSession);
            }
            if (object == null) {
                // Retrieve the object to be added to the collection.
                object = objectChanges.getTargetVersionOfSourceObject(mergeManager, targetSession);
            }
            // not moved.
            if (objectAdded && mergeManager.shouldMergeChangesIntoDistributedCache()) {
                // during merge into distributed cache
                if (!contains(object, valueOfTarget, mergeManager.getSession())) {
                    addIntoAtIndex(changeRecord.getOrderedAddObjectIndex(objectChanges), object, valueOfTarget, mergeManager.getSession());
                }
            } else {
                addIntoAtIndex(changeRecord.getOrderedAddObjectIndex(objectChanges), object, valueOfTarget, targetSession);
            }
        }
    }
}
Also used : OrderedChangeObject(org.eclipse.persistence.internal.sessions.OrderedChangeObject) ObjectChangeSet(org.eclipse.persistence.internal.sessions.ObjectChangeSet) IndexedObject(org.eclipse.persistence.internal.helper.IndexedObject) OrderedChangeObject(org.eclipse.persistence.internal.sessions.OrderedChangeObject) IndirectList(org.eclipse.persistence.indirection.IndirectList)

Example 2 with OrderedChangeObject

use of org.eclipse.persistence.internal.sessions.OrderedChangeObject in project eclipselink by eclipse-ee4j.

the class OrderedListContainerPolicy method recordAddToCollectionInChangeRecord.

/**
 * This method is used to bridge the behavior between Attribute Change Tracking and
 * deferred change tracking with respect to adding the same instance multiple times.
 * Each ContainerPolicy type will implement specific behavior for the collection
 * type it is wrapping.  These methods are only valid for collections containing object references
 */
@Override
public void recordAddToCollectionInChangeRecord(ObjectChangeSet changeSetToAdd, CollectionChangeRecord collectionChangeRecord) {
    OrderedChangeObject orderedChangeObject = new OrderedChangeObject(CollectionChangeEvent.ADD, null, changeSetToAdd);
    collectionChangeRecord.getOrderedChangeObjectList().add(orderedChangeObject);
}
Also used : OrderedChangeObject(org.eclipse.persistence.internal.sessions.OrderedChangeObject)

Example 3 with OrderedChangeObject

use of org.eclipse.persistence.internal.sessions.OrderedChangeObject in project eclipselink by eclipse-ee4j.

the class OrderedListContainerPolicy method recordRemoveFromCollectionInChangeRecord.

@Override
public void recordRemoveFromCollectionInChangeRecord(ObjectChangeSet changeSetToRemove, CollectionChangeRecord collectionChangeRecord) {
    OrderedChangeObject orderedChangeObject = new OrderedChangeObject(CollectionChangeEvent.REMOVE, null, changeSetToRemove);
    collectionChangeRecord.getOrderedChangeObjectList().add(orderedChangeObject);
}
Also used : OrderedChangeObject(org.eclipse.persistence.internal.sessions.OrderedChangeObject)

Example 4 with OrderedChangeObject

use of org.eclipse.persistence.internal.sessions.OrderedChangeObject in project eclipselink by eclipse-ee4j.

the class OrderedListContainerPolicy method recordUpdateToCollectionInChangeRecord.

@Override
public void recordUpdateToCollectionInChangeRecord(CollectionChangeEvent event, ObjectChangeSet changeSet, CollectionChangeRecord collectionChangeRecord) {
    int changeType = event.getChangeType();
    if (changeType == CollectionChangeEvent.ADD) {
        super.recordAddToCollectionInChangeRecord(changeSet, collectionChangeRecord);
    } else if (changeType == CollectionChangeEvent.REMOVE) {
        super.recordRemoveFromCollectionInChangeRecord(changeSet, collectionChangeRecord);
    } else {
        throw ValidationException.wrongCollectionChangeEventType(changeType);
    }
    OrderedChangeObject orderedChangeObject = new OrderedChangeObject(changeType, event.getIndex(), changeSet, event.getNewValue());
    collectionChangeRecord.getOrderedChangeObjectList().add(orderedChangeObject);
}
Also used : OrderedChangeObject(org.eclipse.persistence.internal.sessions.OrderedChangeObject)

Aggregations

OrderedChangeObject (org.eclipse.persistence.internal.sessions.OrderedChangeObject)4 IndirectList (org.eclipse.persistence.indirection.IndirectList)1 IndexedObject (org.eclipse.persistence.internal.helper.IndexedObject)1 ObjectChangeSet (org.eclipse.persistence.internal.sessions.ObjectChangeSet)1