Search in sources :

Example 6 with ObjectChangeListener

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);
}
Also used : PropertyChangeEvent(java.beans.PropertyChangeEvent) ObjectChangeSet(org.eclipse.persistence.internal.sessions.ObjectChangeSet) ObjectChangeListener(org.eclipse.persistence.internal.descriptors.changetracking.ObjectChangeListener) ValueHolder(org.eclipse.persistence.indirection.ValueHolder) ChangeTracker(org.eclipse.persistence.descriptors.changetracking.ChangeTracker) OrderedListContainerPolicy(org.eclipse.persistence.internal.queries.OrderedListContainerPolicy) ContainerPolicy(org.eclipse.persistence.internal.queries.ContainerPolicy) AttributeChangeListener(org.eclipse.persistence.internal.descriptors.changetracking.AttributeChangeListener) CollectionChangeEvent(org.eclipse.persistence.descriptors.changetracking.CollectionChangeEvent) DirectCollectionChangeRecord(org.eclipse.persistence.internal.sessions.DirectCollectionChangeRecord)

Aggregations

ObjectChangeListener (org.eclipse.persistence.internal.descriptors.changetracking.ObjectChangeListener)6 ChangeTracker (org.eclipse.persistence.descriptors.changetracking.ChangeTracker)3 ValueHolder (org.eclipse.persistence.indirection.ValueHolder)3 AggregateObjectChangeListener (org.eclipse.persistence.internal.descriptors.changetracking.AggregateObjectChangeListener)3 AttributeChangeListener (org.eclipse.persistence.internal.descriptors.changetracking.AttributeChangeListener)2 ObjectChangeSet (org.eclipse.persistence.internal.sessions.ObjectChangeSet)2 PropertyChangeEvent (java.beans.PropertyChangeEvent)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 FetchGroupManager (org.eclipse.persistence.descriptors.FetchGroupManager)1 CollectionChangeEvent (org.eclipse.persistence.descriptors.changetracking.CollectionChangeEvent)1 MapChangeEvent (org.eclipse.persistence.descriptors.changetracking.MapChangeEvent)1 ObjectBuilder (org.eclipse.persistence.internal.descriptors.ObjectBuilder)1 DatabaseValueHolder (org.eclipse.persistence.internal.indirection.DatabaseValueHolder)1 ContainerPolicy (org.eclipse.persistence.internal.queries.ContainerPolicy)1 OrderedListContainerPolicy (org.eclipse.persistence.internal.queries.OrderedListContainerPolicy)1 DirectCollectionChangeRecord (org.eclipse.persistence.internal.sessions.DirectCollectionChangeRecord)1 DirectMapChangeRecord (org.eclipse.persistence.internal.sessions.DirectMapChangeRecord)1 DatabaseMapping (org.eclipse.persistence.mappings.DatabaseMapping)1