use of org.eclipse.persistence.internal.descriptors.changetracking.ObjectChangeListener in project eclipselink by eclipse-ee4j.
the class DirectCollectionMapping method mergeIntoObject.
/**
* INTERNAL:
* Merge changes from the source to the target object.
*/
@Override
public void mergeIntoObject(Object target, boolean isTargetUnInitialized, Object source, MergeManager mergeManager, AbstractSession targetSession) {
if (this.descriptor.getCachePolicy().isProtectedIsolation() && !this.isCacheable && !targetSession.isProtectedSession()) {
setAttributeValueInObject(target, this.indirectionPolicy.buildIndirectObject(new ValueHolder<>(null)));
return;
}
if (isTargetUnInitialized) {
// This will happen if the target object was removed from the cache before the commit was attempted
if (mergeManager.shouldMergeWorkingCopyIntoOriginal() && (!isAttributeValueInstantiated(source))) {
setAttributeValueInObject(target, getIndirectionPolicy().getOriginalIndirectionObject(getAttributeValueFromObject(source), targetSession));
return;
}
}
if (!shouldMergeCascadeReference(mergeManager)) {
// This is only going to happen on mergeClone, and we should not attempt to merge the reference
return;
}
if (mergeManager.shouldRefreshRemoteObject() && usesIndirection()) {
mergeRemoteValueHolder(target, source, mergeManager);
return;
}
if (mergeManager.isForRefresh()) {
if (!isAttributeValueInstantiated(target)) {
// the refresh that attribute
return;
}
} else if (!isAttributeValueInstantiatedOrChanged(source)) {
// modified
return;
}
ContainerPolicy containerPolicy = getContainerPolicy();
Object valueOfSource = getRealCollectionAttributeValueFromObject(source, mergeManager.getSession());
// trigger instantiation of target attribute
Object valueOfTarget = getRealCollectionAttributeValueFromObject(target, mergeManager.getSession());
Object newContainer = containerPolicy.containerInstance(containerPolicy.sizeFor(valueOfSource));
boolean fireCollectionChangeEvents = false;
boolean firePropertyChangeEvent = false;
ObjectChangeListener listener = null;
if ((this.descriptor.getObjectChangePolicy().isObjectChangeTrackingPolicy()) && (target instanceof ChangeTracker) && (((ChangeTracker) target)._persistence_getPropertyChangeListener() != null)) {
listener = (ObjectChangeListener) ((ChangeTracker) target)._persistence_getPropertyChangeListener();
if (this.listOrderField == null) {
fireCollectionChangeEvents = true;
// Collections may not be indirect list or may have been replaced with user collection.
Object iterator = containerPolicy.iteratorFor(valueOfTarget);
// remove does not seem to use index.
Integer zero = 0;
while (containerPolicy.hasNext(iterator)) {
// Bug304251: let the containerPolicy build the proper remove CollectionChangeEvent
CollectionChangeEvent event = containerPolicy.createChangeEvent(target, getAttributeName(), valueOfTarget, containerPolicy.next(iterator, mergeManager.getSession()), CollectionChangeEvent.REMOVE, zero, false);
listener.internalPropertyChange(event);
}
if (newContainer instanceof ChangeTracker) {
((ChangeTracker) newContainer)._persistence_setPropertyChangeListener(((ChangeTracker) target)._persistence_getPropertyChangeListener());
}
if (valueOfTarget instanceof ChangeTracker) {
// remove listener
((ChangeTracker) valueOfTarget)._persistence_setPropertyChangeListener(null);
}
} else {
firePropertyChangeEvent = true;
}
}
Object originalValueOfTarget = valueOfTarget;
valueOfTarget = newContainer;
int i = 0;
for (Object sourceValuesIterator = containerPolicy.iteratorFor(valueOfSource); containerPolicy.hasNext(sourceValuesIterator); ) {
Object sourceValue = containerPolicy.next(sourceValuesIterator, mergeManager.getSession());
if (fireCollectionChangeEvents) {
// Bug304251: let the containerPolicy build the proper remove CollectionChangeEvent
CollectionChangeEvent event = containerPolicy.createChangeEvent(target, getAttributeName(), valueOfTarget, sourceValue, CollectionChangeEvent.ADD, i, false);
listener.internalPropertyChange(event);
}
containerPolicy.addInto(sourceValue, valueOfTarget, mergeManager.getSession());
i++;
}
if (fireCollectionChangeEvents && (this.descriptor.getObjectChangePolicy().isAttributeChangeTrackingPolicy())) {
// check that there were changes, if not then remove the record.
ObjectChangeSet changeSet = ((AttributeChangeListener) ((ChangeTracker) target)._persistence_getPropertyChangeListener()).getObjectChangeSet();
if (changeSet != null) {
DirectCollectionChangeRecord changeRecord = (DirectCollectionChangeRecord) changeSet.getChangesForAttributeNamed(getAttributeName());
if (changeRecord != null) {
if (!changeRecord.isDeferred()) {
if (!changeRecord.hasChanges()) {
changeSet.removeChange(getAttributeName());
}
} else {
// Must reset the latest collection.
changeRecord.setLatestCollection(valueOfTarget);
}
}
}
}
if (firePropertyChangeEvent) {
((ObjectChangeListener) ((ChangeTracker) target)._persistence_getPropertyChangeListener()).internalPropertyChange(new PropertyChangeEvent(target, getAttributeName(), originalValueOfTarget, valueOfTarget));
if (valueOfTarget instanceof ChangeTracker) {
((ChangeTracker) valueOfTarget)._persistence_setPropertyChangeListener(((ChangeTracker) target)._persistence_getPropertyChangeListener());
}
if (originalValueOfTarget instanceof ChangeTracker) {
// remove listener
((ChangeTracker) originalValueOfTarget)._persistence_setPropertyChangeListener(null);
}
}
// Must re-set variable to allow for set method to re-morph changes if the collection is not being stored directly.
setRealAttributeValueInObject(target, valueOfTarget);
}
Aggregations