/*******************************************************************************
 * Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved.
 * This program and the accompanying materials are made available under the 
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 ******************************************************************************/  
package org.eclipse.persistence.mappings;

import java.util.*;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.changetracking.ChangeTracker;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.indirection.ValueHolder;
import org.eclipse.persistence.indirection.ValueHolderInterface;
import org.eclipse.persistence.internal.descriptors.*;
import org.eclipse.persistence.internal.descriptors.changetracking.ObjectChangeListener;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.indirection.*;
import org.eclipse.persistence.internal.sessions.*;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.sessions.remote.*;
import org.eclipse.persistence.sessions.CopyGroup;
import org.eclipse.persistence.sessions.Project;

/**
 * <p><b>Purpose</b>: Abstract class for 1:1, variable 1:1 and reference mappings
 */
public abstract class ObjectReferenceMapping extends ForeignReferenceMapping {

    /** Keeps track if any of the fields are foreign keys. */
    protected boolean isForeignKeyRelationship;

    /** Keeps track of which fields are foreign keys on a per field basis (can have mixed foreign key relationships). */
    protected Vector<DatabaseField> foreignKeyFields;

    protected ObjectReferenceMapping() {
        super();
        this.setWeight(WEIGHT_TO_ONE);
    }

    /**
     * INTERNAL:
     * Used during building the backup shallow copy to copy the vector without re-registering the target objects.
     * For 1-1 or ref the reference is from the clone so it is already registered.
     */
    @Override
    public Object buildBackupCloneForPartObject(Object attributeValue, Object clone, Object backup, UnitOfWorkImpl unitOfWork) {
        return attributeValue;
    }

    /**
     * INTERNAL:
     * Require for cloning, the part must be cloned.
     * Ignore the objects, use the attribute value.
     */
    @Override
    public Object buildCloneForPartObject(Object attributeValue, Object original, CacheKey cacheKey, Object clone, AbstractSession cloningSession, Integer refreshCascade, boolean isExisting, boolean isFromSharedCache) {
        if (attributeValue == null) {
            return null;
        }
        if (cloningSession.isUnitOfWork()){
            return buildUnitofWorkCloneForPartObject(attributeValue, original, clone, refreshCascade, (UnitOfWorkImpl)cloningSession, isExisting);
        }
        // Not a unit Of Work clone so must have been a PROTECTED object
        if (this.referenceDescriptor.getCachePolicy().isProtectedIsolation()) {
            ClassDescriptor descriptor = this.referenceDescriptor;
            if (descriptor.hasInterfacePolicy()){
                descriptor = cloningSession.getClassDescriptor(attributeValue.getClass());
            }
            return cloningSession.createProtectedInstanceFromCachedData(attributeValue, refreshCascade, descriptor);
        }
        return attributeValue;
        
    }

    /**
     * INTERNAL:
     * Require for cloning, the part must be cloned.
     * Ignore the objects, use the attribute value.
     */
    public Object buildUnitofWorkCloneForPartObject(Object attributeValue, Object original, Object clone, Integer refreshCascade, UnitOfWorkImpl unitOfWork, boolean isExisting) {
        if (attributeValue == null) {
            return null;
        }
        if (refreshCascade != null ){
            switch(refreshCascade){
            case ObjectBuildingQuery.CascadeAllParts : 
                return unitOfWork.mergeClone(attributeValue, MergeManager.CASCADE_ALL_PARTS, true);
            case ObjectBuildingQuery.CascadePrivateParts :
                return unitOfWork.mergeClone(attributeValue, MergeManager.CASCADE_PRIVATE_PARTS, true);
            case ObjectBuildingQuery.CascadeByMapping :
                return unitOfWork.mergeClone(attributeValue, MergeManager.CASCADE_BY_MAPPING, true);
            default:
                return unitOfWork.mergeClone(attributeValue, MergeManager.NO_CASCADE, true);
            }
        }else{
            // Optimize registration to knowledge of existence.
            Object registeredObject = null;
            if (isExisting) {
                registeredObject = unitOfWork.registerExistingObject(attributeValue, true);
            } else {
                // Not known whether existing or not.
                registeredObject = unitOfWork.registerObject(attributeValue);
                // if the mapping is privately owned, keep track of the privately owned reference in the UnitOfWork
                if (isCandidateForPrivateOwnedRemoval() && unitOfWork.shouldDiscoverNewObjects() && registeredObject != null && unitOfWork.isCloneNewObject(registeredObject)) {
                    unitOfWork.addPrivateOwnedObject(this, registeredObject);
                }
            }
            return registeredObject;
        }
    }

    /**
     * INTERNAL:
     * Copy of the attribute of the object.
     * This is NOT used for unit of work but for templatizing an object.
     */
    @Override
    public void buildCopy(Object copy, Object original, CopyGroup group) {
        Object attributeValue = getRealAttributeValueFromObject(original, group.getSession());
        if ((attributeValue != null) && (group.shouldCascadeAllParts() || (group.shouldCascadePrivateParts() && isPrivateOwned()) || group.shouldCascadeTree())) {
            attributeValue = group.getSession().copyInternal(attributeValue, group);
        } else if (attributeValue != null) {
            // Check for copy of part, i.e. back reference.
            Object copyValue = group.getCopies().get(attributeValue);
            if (copyValue != null) {
                attributeValue = copyValue;
            }
        }
        // if value holder is used, then the value holder shared with original substituted for a new ValueHolder.
        getIndirectionPolicy().reset(copy);
        setRealAttributeValueInObject(copy, attributeValue);
    }

    /**
     * INTERNAL:
     * In case Query By Example is used, this method generates an expression from a attribute value pair.  Since
     * this is a ObjectReference mapping, a recursive call is made to the buildExpressionFromExample method of
     * ObjectBuilder.
     */
    @Override
    public Expression buildExpression(Object queryObject, QueryByExamplePolicy policy, Expression expressionBuilder, Map processedObjects, AbstractSession session) {
        String attributeName = this.getAttributeName();
        Object attributeValue = this.getRealAttributeValueFromObject(queryObject, session);

        if (!policy.shouldIncludeInQuery(queryObject.getClass(), attributeName, attributeValue)) {
            //the attribute name and value pair is not to be included in the query.
            return null;
        }

        if (attributeValue == null) {
            //even though it is null, it is to be always included in the query
            Expression expression = expressionBuilder.get(attributeName);
            return policy.completeExpressionForNull(expression);
        }

        ObjectBuilder objectBuilder = getReferenceDescriptor().getObjectBuilder();
        return objectBuilder.buildExpressionFromExample(attributeValue, policy, expressionBuilder.get(attributeName), processedObjects, session);
    }

    /**
     * INTERNAL:
     * Return an ObjectReferenceChangeRecord describing the change, or null if no change.
     * Used to compute changes for deferred change tracking.
     */
    @Override
    public ChangeRecord compareForChange(Object clone, Object backUp, ObjectChangeSet owner, AbstractSession session) {
        Object cloneAttribute = null;
        Object backUpAttribute = null;

        cloneAttribute = getAttributeValueFromObject(clone);

        if (!owner.isNew()) {
            backUpAttribute = getAttributeValueFromObject(backUp);
            if ((backUpAttribute == null) && (cloneAttribute == null)) {
                return null;
            }
        }

        if ((cloneAttribute != null) && (!this.indirectionPolicy.objectIsInstantiated(cloneAttribute))) {
            //the clone's valueholder was never triggered so there will be no change
            return null;
        }
        Object cloneAttributeValue = null;
        Object backUpAttributeValue = null;

        if (cloneAttribute != null) {
            cloneAttributeValue = getRealAttributeValueFromAttribute(cloneAttribute, clone, session);
        }
        if (backUpAttribute != null) {
            backUpAttributeValue = getRealAttributeValueFromAttribute(backUpAttribute, backUp, session);
        }

        if ((cloneAttributeValue == backUpAttributeValue) && (!owner.isNew())) {// if it is new record the value
            return null;
        }

        ObjectReferenceChangeRecord record = internalBuildChangeRecord(cloneAttributeValue, owner, session);
        if (!owner.isNew()) {
            record.setOldValue(backUpAttributeValue);
        }
        return record;
    }

    /**
     * INTERNAL:
     * Directly build a change record based on the newValue without comparison
     */
    public ObjectReferenceChangeRecord internalBuildChangeRecord(Object newValue, ObjectChangeSet owner, AbstractSession session) {
        ObjectReferenceChangeRecord changeRecord = new ObjectReferenceChangeRecord(owner);
        changeRecord.setAttribute(getAttributeName());
        changeRecord.setMapping(this);
        setNewValueInChangeRecord(newValue, changeRecord, owner, session);
        return changeRecord;
    }

    /**
     * INTERNAL:
     * Set the newValue in the change record
     */
    public void setNewValueInChangeRecord(Object newValue, ObjectReferenceChangeRecord changeRecord, ObjectChangeSet owner, AbstractSession session) {
        if (newValue != null) {
            // Bug 2612571 - added more flexible manner of getting descriptor
            ObjectChangeSet newSet = getDescriptorForTarget(newValue, session).getObjectBuilder().createObjectChangeSet(newValue, (UnitOfWorkChangeSet)owner.getUOWChangeSet(), session);
            changeRecord.setNewValue(newSet);
        } else {
            changeRecord.setNewValue(null);
        }
    }

    /**
     * INTERNAL:
     * Compare the references of the two objects are the same, not the objects themselves.
     * Used for independent relationships.
     * This is used for testing and validation purposes.
     */
    @Override
    protected boolean compareObjectsWithoutPrivateOwned(Object firstObject, Object secondObject, AbstractSession session) {
        Object firstReferencedObject = getRealAttributeValueFromObject(firstObject, session);
        Object secondReferencedObject = getRealAttributeValueFromObject(secondObject, session);

        if ((firstReferencedObject == null) && (secondReferencedObject == null)) {
            return true;
        }

        if ((firstReferencedObject == null) || (secondReferencedObject == null)) {
            return false;
        }

        Object firstKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(firstReferencedObject, session);
        Object secondKey = getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(secondReferencedObject, session);

        if (firstKey == null) {
            if (secondKey == null) {
                return true;
            }
            return false;
        }

        return firstKey.equals(secondKey);
    }

    /**
     * INTERNAL:
     * Compare the references of the two objects are the same, and the objects themselves are the same.
     * Used for private relationships.
     * This is used for testing and validation purposes.
     */
    @Override
    protected boolean compareObjectsWithPrivateOwned(Object firstObject, Object secondObject, AbstractSession session) {
        Object firstPrivateObject = getRealAttributeValueFromObject(firstObject, session);
        Object secondPrivateObject = getRealAttributeValueFromObject(secondObject, session);

        return session.compareObjects(firstPrivateObject, secondPrivateObject);
    }

    /**
     * INTERNAL:
     * We are not using a remote valueholder
     * so we need to replace the reference object(s) with
     * the corresponding object(s) from the remote session.
     *
     * ObjectReferenceMappings need to unwrap and wrap the
     * reference object.
     */
    @Override
    public void fixRealObjectReferences(Object object, Map objectDescriptors, Map processedObjects, ObjectLevelReadQuery query, DistributedSession session) {
        //bug 4147755 getRealAttribute... / setReal...
        Object attributeValue = getRealAttributeValueFromObject(object, session);
        attributeValue = getReferenceDescriptor().getObjectBuilder().unwrapObject(attributeValue, session);

        ObjectLevelReadQuery tempQuery = query;
        if (!tempQuery.shouldMaintainCache()) {
            if ((!tempQuery.shouldCascadeParts()) || (tempQuery.shouldCascadePrivateParts() && (!isPrivateOwned()))) {
                tempQuery = null;
            }
        }
        Object remoteAttributeValue = session.getObjectCorrespondingTo(attributeValue, objectDescriptors, processedObjects, tempQuery);
        remoteAttributeValue = getReferenceDescriptor().getObjectBuilder().wrapObject(remoteAttributeValue, session);
        setRealAttributeValueInObject(object, remoteAttributeValue);
    }

    /**
     * INTERNAL:
     * Return a descriptor for the target of this mapping
     * @see org.eclipse.persistence.mappings.VariableOneToOneMapping
     * Bug 2612571
     */
    public ClassDescriptor getDescriptorForTarget(Object object, AbstractSession session) {
        return session.getDescriptor(object);
    }
    
    /**
     * INTERNAL:
     * Object reference must unwrap the reference object if required.
     */
    @Override
    public Object getRealAttributeValueFromAttribute(Object attributeValue, Object object, AbstractSession session) {
        Object value = super.getRealAttributeValueFromAttribute(attributeValue, object, session);
        value = getReferenceDescriptor().getObjectBuilder().unwrapObject(value, session);

        return value;
    }

    /**
     * INTERNAL:
     * Related mapping should implement this method to return true.
     */
    @Override
    public boolean isObjectReferenceMapping() {
        return true;
    }

    /**
     * INTERNAL:
     * Iterate on the attribute value.
     * The value holder has already been processed.
     */
    @Override
    public void iterateOnRealAttributeValue(DescriptorIterator iterator, Object realAttributeValue) {
        // This may be wrapped as the caller in iterate on foreign reference does not unwrap as the type is generic.
        Object unwrappedAttributeValue = getReferenceDescriptor().getObjectBuilder().unwrapObject(realAttributeValue, iterator.getSession());
        iterator.iterateReferenceObjectForMapping(unwrappedAttributeValue, this);
    }

    /**
     * Force instantiation of all indirections.
     */
    @Override
    public void loadAll(Object object, AbstractSession session, IdentityHashSet loaded) {
        Object value = getRealAttributeValueFromObject(object, session);
        if (value != null) {
            getReferenceDescriptor().getObjectBuilder().loadAll(value, session, loaded);
        }
    }
    
    /**
     * INTERNAL:
     * Merge changes from the source to the target object. Which is the original from the parent UnitOfWork
     */
    @Override
    public void mergeChangesIntoObject(Object target, ChangeRecord changeRecord, Object source, MergeManager mergeManager, AbstractSession targetSession) {
        if (this.descriptor.getCachePolicy().isProtectedIsolation()&& !this.isCacheable && !targetSession.isProtectedSession()){
            setAttributeValueInObject(target, this.indirectionPolicy.buildIndirectObject(new ValueHolder(null)));
            return;
        }
        Object targetValueOfSource = null;

        // The target object must be completely merged before setting it otherwise
        // another thread can pick up the partial object.
        if (shouldMergeCascadeParts(mergeManager)) {
            ObjectChangeSet set = (ObjectChangeSet)((ObjectReferenceChangeRecord)changeRecord).getNewValue();
            if (set != null) {
                if (mergeManager.shouldMergeChangesIntoDistributedCache()) {
                    //Let's try and find it first.  We may have merged it already. In which case merge
                    //changes will  stop the recursion
                    targetValueOfSource = set.getTargetVersionOfSourceObject(mergeManager, targetSession, false);
                    if ((targetValueOfSource == null) && (set.isNew() || set.isAggregate()) && set.containsChangesFromSynchronization()) {
                        if (!mergeManager.isAlreadyMerged(set, targetSession)) {
                            // if we haven't merged this object already then build a new object
                            // otherwise leave it as null which will stop the recursion
                            // CR 2855
                            // CR 3424 Need to build the right instance based on class type instead of refernceDescriptor
                            Class objectClass = set.getClassType(mergeManager.getSession());
                            targetValueOfSource = mergeManager.getSession().getDescriptor(objectClass).getObjectBuilder().buildNewInstance();
                            //Store the changeset to prevent us from creating this new object again
                            mergeManager.recordMerge(set, targetValueOfSource, targetSession);
                        } else {
                            //CR 4012
                            //we have all ready created the object, must be in a cyclic
                            //merge on a new object so get it out of the already merged collection
                            targetValueOfSource = mergeManager.getMergedObject(set, targetSession);
                        }
                    } else {
                        // If We have not found it anywhere else load it from the database
                        targetValueOfSource = set.getTargetVersionOfSourceObject(mergeManager, targetSession, true);
                    }
                    if (set.containsChangesFromSynchronization()) {
                        mergeManager.mergeChanges(targetValueOfSource, set, targetSession);
                    }
                    //bug:3604593 - ensure reference not changed source is invalidated if target object not found
                    if (targetValueOfSource == null) {
                      mergeManager.getSession().getIdentityMapAccessorInstance().invalidateObject(target);
                      return;
                    }
                } else {
                    mergeManager.mergeChanges(set.getUnitOfWorkClone(), set, targetSession);
                }
            }
        }
        if ((targetValueOfSource == null) && (((ObjectReferenceChangeRecord)changeRecord).getNewValue() != null)) {
            targetValueOfSource = ((ObjectChangeSet)((ObjectReferenceChangeRecord)changeRecord).getNewValue()).getTargetVersionOfSourceObject(mergeManager, targetSession);
        }

        // Register new object in nested units of work must not be registered into the parent,
        // so this records them in the merge to parent case.
        if (isPrivateOwned() && (source != null)) {
            mergeManager.registerRemovedNewObjectIfRequired(getRealAttributeValueFromObject(source, mergeManager.getSession()));
        }

        targetValueOfSource = getReferenceDescriptor().getObjectBuilder().wrapObject(targetValueOfSource, targetSession);
        // if value holder is used, then the value holder shared with original substituted for a new ValueHolder.
        getIndirectionPolicy().reset(target);
        setRealAttributeValueInObject(target, targetValueOfSource);
    }

    /**
     * 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,
            // or for new objects.
            if (mergeManager.shouldMergeWorkingCopyIntoOriginal()) {
                if (!isAttributeValueInstantiated(source)) {
                    setAttributeValueInObject(target, this.indirectionPolicy.getOriginalIndirectionObject(getAttributeValueFromObject(source), targetSession));
                    return;
                } else {
                    // Must clear the old value holder to cause it to be reset.
                    this.indirectionPolicy.reset(target);
                }
            }
        }
        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)) {
                // This will occur when the clone's value has not been instantiated yet and we do not need
                // the refresh that attribute
                if (shouldRefreshCascadeParts(mergeManager)){
                    Object attributeValue = getAttributeValueFromObject(source);
                    Integer refreshCascade = null;
                    if (selectionQuery != null && selectionQuery.isObjectBuildingQuery() && ((ObjectBuildingQuery)selectionQuery).shouldRefreshIdentityMapResult()){
                        refreshCascade = selectionQuery.getCascadePolicy();
                    }
                  Object clonedAttributeValue = this.indirectionPolicy.cloneAttribute(attributeValue, source, null, target, refreshCascade, mergeManager.getSession(), false); // building clone from an original not a row. 
                    setAttributeValueInObject(target, clonedAttributeValue);
                }
                return;
            }
        } else if (!isAttributeValueInstantiated(source)) {
            // I am merging from a clone into an original.  No need to do merge if the attribute was never
            // modified
            return;
        }

        Object valueOfSource = getRealAttributeValueFromObject(source, mergeManager.getSession());

        Object targetValueOfSource = null;

        // The target object must be completely merged before setting it otherwise
        // another thread can pick up the partial object.
        if (shouldMergeCascadeParts(mergeManager) && (valueOfSource != null)) {
            if ((mergeManager.getSession().isUnitOfWork()) && (((UnitOfWorkImpl)mergeManager.getSession()).getUnitOfWorkChangeSet() != null)) {
                // If it is a unit of work, we have to check if I have a change Set fot this object
                Object targetValue = mergeManager.mergeChanges(mergeManager.getObjectToMerge(valueOfSource, referenceDescriptor, targetSession), (ObjectChangeSet)((UnitOfWorkChangeSet)((UnitOfWorkImpl)mergeManager.getSession()).getUnitOfWorkChangeSet()).getObjectChangeSetForClone(valueOfSource), targetSession);
                if (target == source && targetValue != valueOfSource && (this.descriptor.getObjectChangePolicy().isObjectChangeTrackingPolicy()) && (target instanceof ChangeTracker) && (((ChangeTracker)target)._persistence_getPropertyChangeListener() != null)) {
                    ObjectChangeListener listener = (ObjectChangeListener)((ChangeTracker)target)._persistence_getPropertyChangeListener();
                    if (listener != null){
                        //update the ChangeSet recorded within the parents ObjectChangeSet as the parent is referenceing the ChangeSet
                        //for a detached or new Entity.
                        this.descriptor.getObjectChangePolicy().updateListenerForSelfMerge(listener, this, valueOfSource, targetValue, (UnitOfWorkImpl) mergeManager.getSession());
                    }
                }
        } else {
                mergeManager.mergeChanges(mergeManager.getObjectToMerge(valueOfSource, referenceDescriptor, targetSession), null, targetSession);
            }
        }

        if (valueOfSource != null) {
            // Need to do this after merge so that an object exists in the database
            targetValueOfSource = mergeManager.getTargetVersionOfSourceObject(valueOfSource, referenceDescriptor, targetSession);
        }
        
        // If merge into the unit of work, must only merge and raise the event is the value changed.
        if ((mergeManager.shouldMergeCloneIntoWorkingCopy() || mergeManager.shouldMergeCloneWithReferencesIntoWorkingCopy()) && !mergeManager.isForRefresh()
                && this.descriptor.getObjectChangePolicy().isObjectChangeTrackingPolicy()) {
            // Object level or attribute level so lets see if we need to raise the event?
            Object valueOfTarget = getRealAttributeValueFromObject(target, mergeManager.getSession());
            if (valueOfTarget != targetValueOfSource) { //equality comparison cause both are uow clones
                this.descriptor.getObjectChangePolicy().raiseInternalPropertyChangeEvent(target, getAttributeName(), valueOfTarget, targetValueOfSource);
            } else {
                // No change.
                return;
            }
        }
 
        targetValueOfSource = this.referenceDescriptor.getObjectBuilder().wrapObject(targetValueOfSource, mergeManager.getSession());
        setRealAttributeValueInObject(target, targetValueOfSource);
    }
    
    /**
     * INTERNAL:
     * Return all the fields populated by this mapping, these are foreign keys only.
     */
    @Override
    protected Vector<DatabaseField> collectFields() {
        return getForeignKeyFields();
    }

    /**
     * INTERNAL:
     * Returns the foreign key names associated with the mapping.
     * These are the fields that will be populated by the 1-1 mapping when writing.
     */
    public Vector<DatabaseField> getForeignKeyFields() {
        return foreignKeyFields;
    }

    /**
    * INTERNAL:
    * Set the foreign key fields associated with the mapping.
    * These are the fields that will be populated by the 1-1 mapping when writing.
    */
    protected void setForeignKeyFields(Vector<DatabaseField> foreignKeyFields) {
        this.foreignKeyFields = foreignKeyFields;
        if (!foreignKeyFields.isEmpty()) {
            setIsForeignKeyRelationship(true);
        }
    }

    /**
     * INTERNAL:
     * Return if the 1-1 mapping has a foreign key dependency to its target.
     * This is true if any of the foreign key fields are true foreign keys,
     * i.e. populated on write from the targets primary key.
     */
    public boolean isForeignKeyRelationship() {
        return isForeignKeyRelationship;
    }

    /**
     * INTERNAL:
     * Set if the 1-1 mapping has a foreign key dependency to its target.
     * This is true if any of the foreign key fields are true foreign keys,
     * i.e. populated on write from the targets primary key.
     */
    public void setIsForeignKeyRelationship(boolean isForeignKeyRelationship) {
        this.isForeignKeyRelationship = isForeignKeyRelationship;
    }

    /**
     * INTERNAL:
     * Insert privately owned parts
     */
    @Override
    public void preInsert(WriteObjectQuery query) throws DatabaseException, OptimisticLockException {
        if (isForeignKeyRelationship()) {
            insert(query);
        }
    }

    /**
     * INTERNAL:
     * Reads the private owned object.
     */
    protected Object readPrivateOwnedForObject(ObjectLevelModifyQuery modifyQuery) throws DatabaseException {
        if (modifyQuery.getSession().isUnitOfWork()) {
            if (modifyQuery.getObjectChangeSet() != null) {
                ObjectReferenceChangeRecord record = (ObjectReferenceChangeRecord) modifyQuery.getObjectChangeSet().getChangesForAttributeNamed(getAttributeName());
                if (record != null) {
                    return record.getOldValue();
                } 
            } else { // Old commit.
                return getRealAttributeValueFromObject(modifyQuery.getBackupClone(), modifyQuery.getSession());
            }
        }
        
        return null;
    }

    /**
     * INTERNAL:
     * Update privately owned parts
     */
    @Override
    public void preUpdate(WriteObjectQuery query) throws DatabaseException, OptimisticLockException {
        if (!isAttributeValueInstantiated(query.getObject())) {
            return;
        }

        if (isPrivateOwned()) {
            Object objectInDatabase = readPrivateOwnedForObject(query);
            if (objectInDatabase != null) {
                query.setProperty(this, objectInDatabase);
            }
        }

        if (!isForeignKeyRelationship()) {
            return;
        }

        update(query);
    }

    /**
     * INTERNAL:
     * Overridden by mappings that require additional processing of the change record after the record has been calculated.
     */
    @Override
    public void postCalculateChanges(org.eclipse.persistence.sessions.changesets.ChangeRecord changeRecord, UnitOfWorkImpl uow) {
        // no need for private owned check.  This code is only registered for private owned mappings.
        // targets are added to and/or removed to/from the source.
        Object oldValue = ((ObjectReferenceChangeRecord)changeRecord).getOldValue();
        if (oldValue != null) {
            uow.addDeletedPrivateOwnedObjects(this, oldValue);
        }
    }

    /**
     * INTERNAL:
     * Overridden by mappings that require additional processing of the change record after the record has been calculated.
     */
    @Override
    public void recordPrivateOwnedRemovals(Object object, UnitOfWorkImpl uow) {
        Object target = getRealAttributeValueFromObject(object, uow);
        if (target != null){
            this.referenceDescriptor.getObjectBuilder().recordPrivateOwnedRemovals(target, uow, false);
        }
    }

    /**
     * INTERNAL:
     * Delete privately owned parts
     */
    @Override
    public void postDelete(DeleteObjectQuery query) throws DatabaseException, OptimisticLockException {
        // Deletion takes place only if it has privately owned parts and mapping is not read only.
        if (!shouldObjectModifyCascadeToParts(query)) {
            return;
        }

        Object object = query.getProperty(this);
        // The object is stored in the query by preDeleteForObjectUsing(...).
        if (isForeignKeyRelationship()) {
            if (object != null) {
                query.removeProperty(this);
                AbstractSession session = query.getSession();
                //if the query is being passed from an aggregate collection descriptor then 
                // The delete will have been cascaded at update time.  This will cause sub objects
                // to be ignored, and real only classes to throw exceptions.
                // If it is an aggregate Collection then delay deletes until they should be deleted
                //CR 2811	
                if (query.isCascadeOfAggregateDelete()) {
                    session.getCommitManager().addObjectToDelete(object);
                } else {
                    // PERF: Avoid query execution if already deleted.
                    if (session.getCommitManager().isCommitCompletedInPostOrIgnore(object)) {
                        return;
                    }
                    if (this.isCascadeOnDeleteSetOnDatabase && !hasRelationTableMechanism() && session.isUnitOfWork()) {
                        ((UnitOfWorkImpl)session).getCascadeDeleteObjects().add(object);
                    }
                    DeleteObjectQuery deleteQuery = new DeleteObjectQuery();
                    deleteQuery.setIsExecutionClone(true);
                    deleteQuery.setObject(object);
                    deleteQuery.setCascadePolicy(query.getCascadePolicy());
                    session.executeQuery(deleteQuery);
                }
            }
        }
    }

    /**
     * INTERNAL:
     * Insert privately owned parts
     */
    @Override
    public void postInsert(WriteObjectQuery query) throws DatabaseException, OptimisticLockException {
        if (!isForeignKeyRelationship()) {
            insert(query);
        }
    }

    /**
     * INTERNAL:
     * Update privately owned parts
     */
    @Override
    public void postUpdate(WriteObjectQuery query) throws DatabaseException, OptimisticLockException {
        if (!isAttributeValueInstantiated(query.getObject())) {
            return;
        }

        if (!isForeignKeyRelationship()) {
            update(query);
        }

        // If a private owned reference was changed the old value will be set on the query as a property.
        Object objectInDatabase = query.getProperty(this);
        if (objectInDatabase != null) {
            query.removeProperty(this);
        } else {
            return;
        }

        // If there is no change (old commit), it must be determined if the value changed.
        if (query.getObjectChangeSet() == null) {
            Object objectInMemory = getRealAttributeValueFromObject(query.getObject(), query.getSession());
    
            // delete the object in the database if it is no more a referenced object.						
            if (objectInDatabase != objectInMemory) {
    
                Object keyForObjectInDatabase = getPrimaryKeyForObject(objectInDatabase, query.getSession());
                Object keyForObjectInMemory = null;
                if (objectInMemory != null) {
                    keyForObjectInMemory = getPrimaryKeyForObject(objectInMemory, query.getSession());
                }
    
                if ((keyForObjectInMemory != null) && keyForObjectInDatabase.equals(keyForObjectInMemory)) {
                    return;
                }
            } else {
                return;
            }
        }            
            
        if (!query.shouldCascadeOnlyDependentParts()) {
            query.getSession().deleteObject(objectInDatabase);
        }
    }

    /**
     * INTERNAL:
     * Delete privately owned parts
     */
    @Override
    public void preDelete(DeleteObjectQuery query) throws DatabaseException, OptimisticLockException {
        // Deletion takes place according the the cascading policy
        if (!shouldObjectModifyCascadeToParts(query)) {
            return;
        }

        AbstractSession session = query.getSession();
        // Get the privately owned parts.
        Object objectInMemory = getRealAttributeValueFromObject(query.getObject(), session);
        Object objectFromDatabase = null;

        // Because the value in memory may have been changed we check the previous value or database value.
        objectFromDatabase = readPrivateOwnedForObject(query);

        // If the value was changed, both values must be deleted (uow will have inserted the new one).
        if ((objectFromDatabase != null) && (objectFromDatabase != objectInMemory)) {
            // Also check pk as may not be maintaining identity.	
            Object keyForObjectInMemory = null;
            Object keyForObjectInDatabase = getPrimaryKeyForObject(objectFromDatabase, session);

            if (objectInMemory != null) {
                keyForObjectInMemory = getPrimaryKeyForObject(objectInMemory, session);
            }
            if ((keyForObjectInMemory == null) || !keyForObjectInDatabase.equals(keyForObjectInMemory)) {
                if (objectFromDatabase != null) {
                    if (this.isCascadeOnDeleteSetOnDatabase && !hasRelationTableMechanism() && session.isUnitOfWork()) {
                        ((UnitOfWorkImpl)session).getCascadeDeleteObjects().add(objectFromDatabase);
                    }
                    DeleteObjectQuery deleteQuery = new DeleteObjectQuery();
                    deleteQuery.setIsExecutionClone(true);
                    deleteQuery.setObject(objectFromDatabase);
                    deleteQuery.setCascadePolicy(query.getCascadePolicy());
                    session.executeQuery(deleteQuery);
                }
            }
        }

        if (!isForeignKeyRelationship()) {
            if (objectInMemory != null) {
                if (this.isCascadeOnDeleteSetOnDatabase && !hasRelationTableMechanism() && session.isUnitOfWork()) {
                    ((UnitOfWorkImpl)session).getCascadeDeleteObjects().add(objectInMemory);
                }
                // PERF: Avoid query execution if already deleted.
                if (session.getCommitManager().isCommitCompletedInPostOrIgnore(objectInMemory)) {
                    return;
                }
                DeleteObjectQuery deleteQuery = new DeleteObjectQuery();
                deleteQuery.setIsExecutionClone(true);
                deleteQuery.setObject(objectInMemory);
                deleteQuery.setCascadePolicy(query.getCascadePolicy());
                session.executeQuery(deleteQuery);
            }
        } else {
            // The actual deletion of part takes place in postDeleteForObjectUsing(...).
            if (objectInMemory != null) {
                query.setProperty(this, objectInMemory);
            }
        }
    }


    /**
     * INTERNAL:
     * Record deletion dependencies for foreign key constraints.
     * This is used during deletion to resolve deletion cycles.
     */
    @Override
    public void earlyPreDelete(DeleteObjectQuery query, Object object) {
        AbstractSession session = query.getSession();
        // Avoid instantiating objects.
        Object attributeValue = getAttributeValueFromObject(object);
        Object targetObject = null;
        if (!this.indirectionPolicy.objectIsInstantiated(attributeValue) && !this.indirectionPolicy.objectIsEasilyInstantiated(attributeValue)) {
            AbstractRecord referenceRow = this.indirectionPolicy.extractReferenceRow(attributeValue);
            targetObject = this.selectionQuery.checkEarlyReturn(session, referenceRow);
        } else {
            targetObject = getRealAttributeValueFromAttribute(attributeValue, object, session);
        }
        UnitOfWorkImpl unitOfWork = (UnitOfWorkImpl)session;
        if ((targetObject != null) && unitOfWork.getDeletedObjects().containsKey(targetObject)) {
            unitOfWork.addDeletionDependency(targetObject, object);
        }
    }
    
    /**
     * INTERNAL:
     * Cascade registerNew for Create through mappings that require the cascade
     */
    @Override
    public void cascadePerformRemoveIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects){
        cascadePerformRemoveIfRequired(object, uow, visitedObjects, true);
    }
    
    /**
     * INTERNAL:
     * Cascade remove through mappings that require the cascade.
     * @param object is either the source object, or attribute value if getAttributeValueFromObject is true.
     */
    public void cascadePerformRemoveIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects, boolean getAttributeValueFromObject) {
        if (!this.cascadeRemove) {
            return;
        }
        Object attributeValue = null;
        if (getAttributeValueFromObject) {
            attributeValue = getAttributeValueFromObject(object);
        } else {
            attributeValue = object;
        }
        if (attributeValue != null) {
            if (getAttributeValueFromObject) {
                attributeValue = this.indirectionPolicy.getRealAttributeValueFromObject(object, attributeValue);
            }
            if (attributeValue != null && (! visitedObjects.containsKey(attributeValue)) ){
                visitedObjects.put(attributeValue, attributeValue);
                if (this.isCascadeOnDeleteSetOnDatabase && !hasRelationTableMechanism()) {
                    uow.getCascadeDeleteObjects().add(attributeValue);
                }
                uow.performRemove(attributeValue, visitedObjects);
            }
        }
    }
    
    /**
     * INTERNAL:
     * Cascade removal of orphaned private owned objects from the UnitOfWorkChangeSet
     */
    @Override
    public void cascadePerformRemovePrivateOwnedObjectFromChangeSetIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects) {
        // if the object is not instantiated, do not instantiate or cascade
        Object attributeValue = getAttributeValueFromObject(object);
        if (attributeValue != null && this.indirectionPolicy.objectIsInstantiated(attributeValue)) {
            Object realValue = getRealAttributeValueFromObject(object, uow);
            if (!visitedObjects.containsKey(realValue)){
                visitedObjects.put(realValue, realValue);
                // remove private owned object from UnitOfWork ChangeSet
                uow.performRemovePrivateOwnedObjectFromChangeSet(realValue, visitedObjects);
            }
        }
    }
    
    /**
     * INTERNAL: 
     * This method is used to store the FK fields that can be cached that correspond to noncacheable mappings
     * the FK field values will be used to re-issue the query when cloning the shared cache entity
     */
    @Override
    public void collectQueryParameters(Set<DatabaseField> cacheFields){
        for (DatabaseField field : foreignKeyFields) {
            cacheFields.add(field);
        }
    }

    /**
     * INTERNAL:
     * Cascade discover and persist new objects during commit.
     */
    @Override
    public void cascadeDiscoverAndPersistUnregisteredNewObjects(Object object, Map newObjects, Map unregisteredExistingObjects, Map visitedObjects, UnitOfWorkImpl uow, Set cascadeErrors) {
        cascadeDiscoverAndPersistUnregisteredNewObjects(object, newObjects, unregisteredExistingObjects, visitedObjects, uow, true, cascadeErrors);
    }
    
    /**
     * INTERNAL:
     * Cascade discover and persist new objects during commit.
     */
    public void cascadeDiscoverAndPersistUnregisteredNewObjects(Object object, Map newObjects, Map unregisteredExistingObjects, Map visitedObjects, UnitOfWorkImpl uow, boolean getAttributeValueFromObject, Set cascadeErrors) {
        Object attributeValue = null;
        if (getAttributeValueFromObject){
            attributeValue = getAttributeValueFromObject(object);
        } else {
            attributeValue = object;
        }
        if (attributeValue != null && this.indirectionPolicy.objectIsInstantiated(attributeValue)) {
            if (getAttributeValueFromObject){
                attributeValue = this.indirectionPolicy.getRealAttributeValueFromObject(object, attributeValue);
            }
            // remove private owned object from uow list
            if (isCandidateForPrivateOwnedRemoval()) {
                uow.removePrivateOwnedObject(this, attributeValue);
            }
            uow.discoverAndPersistUnregisteredNewObjects(attributeValue, isCascadePersist(), newObjects, unregisteredExistingObjects, visitedObjects, cascadeErrors);
        }
    }
    
    /**
     * INTERNAL:
     * Cascade registerNew for Create through mappings that require the cascade
     */
    @Override
    public void cascadeRegisterNewIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects){
        cascadeRegisterNewIfRequired(object, uow, visitedObjects, true);
    }
    
    /**
     * INTERNAL:
     * Cascade registerNew for Create through mappings that require the cascade
     * @param object is either the source object, or attribute value if getAttributeValueFromObject is true.
     */
    public void cascadeRegisterNewIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects, boolean getAttributeValueFromObject) {
        if (!isCascadePersist()) {
            return;
        }
        Object attributeValue = null;
        if (getAttributeValueFromObject) {
            attributeValue = getAttributeValueFromObject(object);
        } else {
            attributeValue = object;
        }
        if ((attributeValue != null)
                // no need to check for new as persist must be cascaded.
                && (this.indirectionPolicy.objectIsInstantiated(attributeValue) || uow.isCloneNewObject(object))) {
            if (getAttributeValueFromObject){
                attributeValue = this.indirectionPolicy.getRealAttributeValueFromObject(object, attributeValue);
            }
            uow.registerNewObjectForPersist(attributeValue, visitedObjects);
            // add private owned object to uow list if mapping is a candidate and uow should discover new objects and the source object is new.
            if (isCandidateForPrivateOwnedRemoval() && uow.shouldDiscoverNewObjects() && (attributeValue != null) && uow.isCloneNewObject(object)) {
                uow.addPrivateOwnedObject(this, attributeValue);
            }
        }
    }
    
    /**
     * INTERNAL:
     */
    protected Object getPrimaryKeyForObject(Object object, AbstractSession session) {
        return getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(object, session);
    }

    /**
     * INTERNAL:
     * The returns if the mapping has any constraint dependencies, such as foreign keys and join tables.
     */
    @Override
    public boolean hasConstraintDependency() {
        return isForeignKeyRelationship();
    }

    /**
     * INTERNAL:
     * Builder the unit of work value holder.
     * @param buildDirectlyFromRow indicates that we are building the clone directly
     * from a row as opposed to building the original from the row, putting it in
     * the shared cache, and then cloning the original.
     */
    @Override
    public DatabaseValueHolder createCloneValueHolder(ValueHolderInterface attributeValue, Object original, Object clone, AbstractRecord row, AbstractSession cloningSession, boolean buildDirectlyFromRow) {
        DatabaseValueHolder valueHolder = null;
        if ((row == null) && (isPrimaryKeyMapping())) {
            // The row must be built if a primary key mapping for remote case.
            AbstractRecord rowFromTargetObject = extractPrimaryKeyRowForSourceObject(original, cloningSession);
            valueHolder = cloningSession.createCloneQueryValueHolder(attributeValue, clone, rowFromTargetObject, this);
        } else {
            valueHolder = cloningSession.createCloneQueryValueHolder(attributeValue, clone, row, this);
        }

        // In case of joined attributes it so happens that the attributeValue 
        // contains a registered clone, as valueFromRow was called with a
        // UnitOfWork.  So switch the values.
        // Note that this UOW valueholder starts off as instantiated but that
        // is fine, for the reality is that it is.
        if (buildDirectlyFromRow && attributeValue.isInstantiated()) {
            Object cloneAttributeValue = attributeValue.getValue();
            valueHolder.privilegedSetValue(cloneAttributeValue);
            valueHolder.setInstantiated();

            // PERF: Do not modify the original value-holder, it is never used.
        }
        return valueHolder;
    }

    /**
     * INTERNAL:
     * Extract the reference pk for rvh usage in remote model.
     */
    public AbstractRecord extractPrimaryKeyRowForSourceObject(Object domainObject, AbstractSession session) {
        AbstractRecord databaseRow = getDescriptor().getObjectBuilder().createRecord(session);
        writeFromObjectIntoRow(domainObject, databaseRow, session, WriteType.UNDEFINED);
        return databaseRow;
    }

    /**
     * INTERNAL:
     * Extract the reference pk for rvh usage in remote model.
     */
    public Object extractPrimaryKeysForReferenceObject(Object domainObject, AbstractSession session) {
        return this.indirectionPolicy.extractPrimaryKeyForReferenceObject(getAttributeValueFromObject(domainObject), session);
    }

    /**
     * INTERNAL:
     * Return the primary key for the reference object (i.e. the object
     * object referenced by domainObject and specified by mapping).
     * This key will be used by a RemoteValueHolder.
     */
    public Object extractPrimaryKeysForReferenceObjectFromRow(AbstractRecord row) {
        return null;
    }

    /**
     * INTERNAL:
     * Extract the reference pk for rvh usage in remote model.
     */
    public Object extractPrimaryKeysFromRealReferenceObject(Object object, AbstractSession session) {
        if (object == null) {
            return null;
        } else {
            Object implementation = getReferenceDescriptor().getObjectBuilder().unwrapObject(object, session);
            return getReferenceDescriptor().getObjectBuilder().extractPrimaryKeyFromObject(implementation, session);
        }
    }

    /**
     * INTERNAL:
     * Initialize the state of mapping.
     */
    @Override
    public void preInitialize(AbstractSession session) throws DescriptorException {
        super.preInitialize(session);
		//Bug#4251902 Make Proxy Indirection writable and readable to deployment xml.  If ProxyIndirectionPolicy does not
		//have any targetInterfaces, build a new set.
        if ((this.indirectionPolicy instanceof ProxyIndirectionPolicy) && !((ProxyIndirectionPolicy)this.indirectionPolicy).hasTargetInterfaces()) {
            useProxyIndirection();
        }
    }

    /**
     * INTERNAL:
      * Insert privately owned parts
     */
    protected void insert(WriteObjectQuery query) throws DatabaseException, OptimisticLockException {
        // Checks if privately owned parts should be inserted or not.
        if (!shouldObjectModifyCascadeToParts(query)) {
            return;
        }

        // Get the privately owned parts
        Object object = getRealAttributeValueFromObject(query.getObject(), query.getSession());

        if (object == null) {
            return;
        }
        AbstractSession session = query.getSession();
        // PERF: Avoid query execution if already written.
        if (session.getCommitManager().isCommitCompletedInPostOrIgnore(object)) {
            return;
        }
        ObjectChangeSet changeSet = null;
        // Get changeSet for referenced object.  Change record may not exist for new objects, so always lookup.
        if (session.isUnitOfWork() && (((UnitOfWorkImpl)session).getUnitOfWorkChangeSet() != null)) {
            UnitOfWorkChangeSet uowChangeSet = (UnitOfWorkChangeSet)((UnitOfWorkImpl)session).getUnitOfWorkChangeSet();
            changeSet = (ObjectChangeSet)uowChangeSet.getObjectChangeSetForClone(object);
            // PERF: If the changeSet is null it must be existing, if it is not new, then cascading is not required.
            if (changeSet == null || !changeSet.isNew()) {
                return;
            }
        }
        
        WriteObjectQuery writeQuery = null;
        // If private owned, the dependent objects should also be new.
        // However a bug was logged was put in to allow dependent objects to be existing in a unit of work,
        // so this allows existing dependent objects in the unit of work.
        if (this.isPrivateOwned && ((changeSet == null) || (changeSet.isNew()))) {
            // no identity check needed for private owned
            writeQuery = new InsertObjectQuery();
        } else {
            writeQuery = new WriteObjectQuery();
        }
        writeQuery.setIsExecutionClone(true);
        writeQuery.setObject(object);
        writeQuery.setObjectChangeSet(changeSet);
        writeQuery.setCascadePolicy(query.getCascadePolicy());
        session.executeQuery(writeQuery);
    }

    /**
     * INTERNAL:
     * Update the private owned part.
     */
    protected void update(WriteObjectQuery query) throws DatabaseException, OptimisticLockException {
        if (!shouldObjectModifyCascadeToParts(query)) {
            return;
        }
        Object sourceObject = query.getObject();
        Object attributeValue = getAttributeValueFromObject(sourceObject);
        // If objects are not instantiated that means they are not changed.
        if (!this.indirectionPolicy.objectIsInstantiated(attributeValue)) {
            return;
        }

        // Get the privately owned parts in the memory
        AbstractSession session = query.getSession();
        Object object = getRealAttributeValueFromAttribute(attributeValue, sourceObject, session);
        if (object != null) {
            ObjectChangeSet changeSet = query.getObjectChangeSet();
            if (changeSet != null) {
                ObjectReferenceChangeRecord changeRecord = (ObjectReferenceChangeRecord)query.getObjectChangeSet().getChangesForAttributeNamed(getAttributeName());
                if (changeRecord != null) {
                    changeSet = (ObjectChangeSet)changeRecord.getNewValue();
                    // PERF: If it is not new, then cascading is not required.
                    if (!changeSet.isNew()) {
                        return;
                    }
                } else {
                    // no changeRecord no change to reference.
                    return;
                }
            } else {
                UnitOfWorkChangeSet uowChangeSet = null;
                // Get changeSet for referenced object.
                if (session.isUnitOfWork() && (((UnitOfWorkImpl)session).getUnitOfWorkChangeSet() != null)) {
                    uowChangeSet = (UnitOfWorkChangeSet)((UnitOfWorkImpl)session).getUnitOfWorkChangeSet();
                    changeSet = (ObjectChangeSet)uowChangeSet.getObjectChangeSetForClone(object);
                    // PERF: If the changeSet is null it must be existing, if it is not new, then cascading is not required.
                    if (changeSet == null || !changeSet.isNew()) {
                        return;
                    }
                }
            }
            // PERF: Only write dependent object if they are new.
            if ((!query.shouldCascadeOnlyDependentParts()) || (changeSet == null) || changeSet.isNew()) {
                // PERF: Avoid query execution if already written.
                if (session.getCommitManager().isCommitCompletedInPostOrIgnore(object)) {
                    return;
                }
                WriteObjectQuery writeQuery = new WriteObjectQuery();
                writeQuery.setIsExecutionClone(true);
                writeQuery.setObject(object);
                writeQuery.setObjectChangeSet(changeSet);
                writeQuery.setCascadePolicy(query.getCascadePolicy());
                session.executeQuery(writeQuery);
            }
        }
    }

    /**
     * PUBLIC:
     * Indicates whether the mapping has RelationTableMechanism.
     */
    public boolean hasRelationTableMechanism() {
        return false;
    }

    /**
     * PUBLIC:
     * Set this mapping to use Proxy Indirection.
     *
     * Proxy Indirection uses the <CODE>Proxy</CODE> and <CODE>InvocationHandler</CODE> features
     * of JDK 1.3 to provide "transparent indirection" for 1:1 relationships.  In order to use Proxy
     * Indirection:<P>
     *
     * <UL>
     *        <LI>The target class must implement at least one public interface
     *        <LI>The attribute on the source class must be typed as that public interface
     *        <LI>get() and set() methods for the attribute must use the interface
     * </UL>
     *
     * With this policy, proxy objects are returned during object creation.  When a message other than
     * <CODE>toString</CODE> is called on the proxy the real object data is retrieved from the database.
     *
     * By default, use the target class' full list of interfaces for the proxy.
     *
     */
    public void useProxyIndirection() {
        Class[] targetInterfaces = getReferenceClass().getInterfaces();
        if (!getReferenceClass().isInterface() && getReferenceClass().getSuperclass() == null) {
            setIndirectionPolicy(new ProxyIndirectionPolicy(targetInterfaces));
        } else {
            HashSet targetInterfacesCol = new HashSet();        
            //Bug#4432781 Include all the interfaces and the super interfaces of the target class
            if (getReferenceClass().getSuperclass() != null) {
                buildTargetInterfaces(getReferenceClass(), targetInterfacesCol);
            }
			//Bug#4251902 Make Proxy Indirection writable and readable to deployment xml.  If
			//ReferenceClass is an interface, it needs to be included in the array.
            if (getReferenceClass().isInterface()) {
                targetInterfacesCol.add(getReferenceClass());
            }
            targetInterfaces = (Class[])targetInterfacesCol.toArray(targetInterfaces);
            setIndirectionPolicy(new ProxyIndirectionPolicy(targetInterfaces));
        }
    }

    /**
     * INTERNAL: This method will access the target relationship and create a
     * list of PKs of the target entities. This method is used in combination
     * with the CachedValueHolder to store references to PK's to be loaded from
     * a cache instead of a query.
     * @see ContainerPolicy.buildReferencesPKList()
     * @see MappedKeyMapContainerPolicy()
     */
    @Override
    public Object[] buildReferencesPKList(Object entity, Object attribute, AbstractSession session) {
        ClassDescriptor referenceDescriptor = getReferenceDescriptor();
        Object target = this.indirectionPolicy.getRealAttributeValueFromObject(entity, attribute);
        if (target != null){
            Object[] result = new Object[1];
            result[0] = referenceDescriptor.getObjectBuilder().extractPrimaryKeyFromObject(target, session);
            return result;
        }
        return new Object[]{};
    }

    /**
     * INTERNAL:
     * Build a list of all the interfaces and super interfaces for a given class.
     */
    public Collection buildTargetInterfaces(Class aClass, Collection targetInterfacesCol) {
        Class[] targetInterfaces = aClass.getInterfaces();
        for (int index = 0; index < targetInterfaces.length; index++) {
            targetInterfacesCol.add(targetInterfaces[index]);
        }
        if (aClass.getSuperclass() == null) {
            return targetInterfacesCol;
        } else {
            return buildTargetInterfaces(aClass.getSuperclass(), targetInterfacesCol);
        }
    }
    
    /**
     * PUBLIC:
     * Set this mapping to use Proxy Indirection.
     *
     * Proxy Indirection uses the <CODE>Proxy</CODE> and <CODE>InvocationHandler</CODE> features
     * of JDK 1.3 to provide "transparent indirection" for 1:1 relationships.  In order to use Proxy
     * Indirection:<P>
     *
     * <UL>
     *        <LI>The target class must implement at least one public interface
     *        <LI>The attribute on the source class must be typed as that public interface
     *        <LI>get() and set() methods for the attribute must use the interface
     * </UL>
     *
     * With this policy, proxy objects are returned during object creation.  When a message other than
     * <CODE>toString</CODE> is called on the proxy the real object data is retrieved from the database.
     *
     * @param    proxyInterfaces        The interfaces that the target class implements.  The attribute must be typed
     *                                as one of these interfaces.
     */
    public void useProxyIndirection(Class[] targetInterfaces) {
        setIndirectionPolicy(new ProxyIndirectionPolicy(targetInterfaces));
    }

    /**
     * PUBLIC:
     * Set this mapping to use Proxy Indirection.
     *
     * Proxy Indirection uses the <CODE>Proxy</CODE> and <CODE>InvocationHandler</CODE> features
     * of JDK 1.3 to provide "transparent indirection" for 1:1 relationships.  In order to use Proxy
     * Indirection:<P>
     *
     * <UL>
     *        <LI>The target class must implement at least one public interface
     *        <LI>The attribute on the source class must be typed as that public interface
     *        <LI>get() and set() methods for the attribute must use the interface
     * </UL>
     *
     * With this policy, proxy objects are returned during object creation.  When a message other than
     * <CODE>toString</CODE> is called on the proxy the real object data is retrieved from the database.
     *
     * @param    proxyInterface        The interface that the target class implements.  The attribute must be typed
     *                                as this interface.
     */
    public void useProxyIndirection(Class targetInterface) {
        Class[] targetInterfaces = new Class[] { targetInterface };
        setIndirectionPolicy(new ProxyIndirectionPolicy(targetInterfaces));
    }

    /**
     * INTERNAL: 
     * This method is used to load a relationship from a list of PKs.
     * This list may be available if the relationship has been cached.
     */
    @Override
    public Object valueFromPKList(Object[] pks, AbstractRecord foreignKeys, AbstractSession session) {
        if (pks.length == 0 || pks[0] == null) return null;
        ReadObjectQuery query = new ReadObjectQuery();
        query.setReferenceClass(getReferenceClass());
        query.setSelectionId(pks[0]);
        query.setIsExecutionClone(true);
        query.setSession(session);
        return session.executeQuery(query);
    }

    /**
     * INTERNAL: 
     * To verify if the specified object is deleted or not.
     */
    @Override
    public boolean verifyDelete(Object object, AbstractSession session) throws DatabaseException {
        if (isPrivateOwned() || isCascadeRemove()) {
            Object attributeValue = getRealAttributeValueFromObject(object, session);

            if (attributeValue != null) {
                return session.verifyDelete(attributeValue);
            }
        }

        return true;
    }

    /**
     * INTERNAL:
     * Get a value from the object and set that in the respective field of the row.
     * But before that check if the reference object is instantiated or not.
     */
    @Override
    public void writeFromObjectIntoRowForUpdate(WriteObjectQuery query, AbstractRecord databaseRow) {
        Object object = query.getObject();
        AbstractSession session = query.getSession();

        if (!isAttributeValueInstantiated(object)) {
            return;
        }

        if (session.isUnitOfWork()) {
            if (compareObjectsWithoutPrivateOwned(query.getBackupClone(), object, session)) {
                return;
            }
        }

        writeFromObjectIntoRow(object, databaseRow, session, WriteType.UPDATE);
    }

    /**
     * INTERNAL:
     * Get a value from the object and set that in the respective field of the row.
     */
    @Override
    public void writeFromObjectIntoRowForWhereClause(ObjectLevelModifyQuery query, AbstractRecord databaseRow) {
        if (isReadOnly()) {
            return;
        }

        if (query.isDeleteObjectQuery()) {
            writeFromObjectIntoRow(query.getObject(), databaseRow, query.getSession(), WriteType.UNDEFINED);
        } else {
            // If the original was never instantiated the backup clone has a ValueHolder of null 
            // so for this case we must extract from the original object.
            if (isAttributeValueInstantiated(query.getObject())) {
                writeFromObjectIntoRow(query.getBackupClone(), databaseRow, query.getSession(), WriteType.UNDEFINED);
            } else {
                writeFromObjectIntoRow(query.getObject(), databaseRow, query.getSession(), WriteType.UNDEFINED);
            }
        }
    }
    
    /**
     * INTERNAL:
     * Return if this mapping supports change tracking.
     */
    @Override
    public boolean isChangeTrackingSupported(Project project) {
        return true;
    }
    
    /**
     * INTERNAL:
     * Either create a new change record or update the change record with the new value.
     * This is used by attribute change tracking.
     */
    @Override
    public void updateChangeRecord(Object clone, Object newValue, Object oldValue, ObjectChangeSet objectChangeSet, UnitOfWorkImpl uow) {
        // Must ensure values are unwrapped.
        Object unwrappedNewValue = newValue;
        Object unwrappedOldValue = oldValue;
        if (newValue != null) {
            unwrappedNewValue = getReferenceDescriptor().getObjectBuilder().unwrapObject(newValue, uow);
        }
        if (oldValue != null) {
            unwrappedOldValue = getReferenceDescriptor().getObjectBuilder().unwrapObject(oldValue, uow);
        }
        ObjectReferenceChangeRecord changeRecord = (ObjectReferenceChangeRecord)objectChangeSet.getChangesForAttributeNamed(this.getAttributeName());
        if (changeRecord == null) {
            changeRecord = internalBuildChangeRecord(unwrappedNewValue, objectChangeSet, uow);
            changeRecord.setOldValue(unwrappedOldValue);
            objectChangeSet.addChange(changeRecord);
            
        } else {
            setNewValueInChangeRecord(unwrappedNewValue, changeRecord, objectChangeSet, uow);
        }
    }

    /**
     * INTERNAL:
     * Update a ChangeRecord to replace the ChangeSet for the old entity with the changeSet for the new Entity.  This is
     * used when an Entity is merged into itself and the Entity reference new or detached entities.
     */
    public void updateChangeRecordForSelfMerge(ChangeRecord changeRecord, Object source, Object target, UnitOfWorkChangeSet parentUOWChangeSet, UnitOfWorkImpl unitOfWork){
        ((ObjectReferenceChangeRecord)changeRecord).setNewValue(((UnitOfWorkChangeSet)unitOfWork.getUnitOfWorkChangeSet()).findOrCreateLocalObjectChangeSet(target, referenceDescriptor, unitOfWork.isCloneNewObject(target)));
    }

    /**
     * INTERNAL:
     * Directly build a change record without comparison
     */
    @Override
    public ChangeRecord buildChangeRecord(Object clone, ObjectChangeSet owner, AbstractSession session) {
        return internalBuildChangeRecord(getRealAttributeValueFromObject(clone, session), owner, session);
    }
}
