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);
}
}
}
}
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);
}
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);
}
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);
}
Aggregations