/*
 * Copyright (c) 1998, 2021 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 v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.indirection;

import java.util.*;
import org.eclipse.persistence.descriptors.changetracking.*;
import org.eclipse.persistence.mappings.*;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.indirection.*;
import org.eclipse.persistence.sessions.remote.*;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.internal.descriptors.*;
import org.eclipse.persistence.internal.queries.*;
import org.eclipse.persistence.internal.sessions.remote.*;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.MergeManager;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;

/**
 * <h2>Purpose</h2>:
 * TransparentIndirectionPolicy implements the behavior necessary for a
 * a CollectionMapping to use
 * IndirectContainers to delay the reading of objects from the database
 * until they are actually needed.
 *
 * @see CollectionMapping
 * @see IndirectContainer
 * @author Big Country
 * @since TOPLink/Java 2.5
 */
public class TransparentIndirectionPolicy extends IndirectionPolicy {
    //3732
    protected static Integer defaultContainerSize;

    /** PERF: Cache the mappings container policy. */
    protected ContainerPolicy containerPolicy;

    /**
     * IndirectList and IndirectSet can be configured not to instantiate the list from the
     * database when you add and remove from them.  IndirectList defaults to this behavior. When
     * Set to true, the collection associated with this TransparentIndirection will be setup so as
     * not to instantiate for adds and removes.  The weakness of this setting for an IndirectSet is
     * that when the set is not instantiated, if a duplicate element is added, it will not be
     * detected until commit time.
     */
    protected Boolean useLazyInstantiation;

    /**
     * INTERNAL:
     * Construct a new indirection policy.
     */
    public TransparentIndirectionPolicy() {
        super();
    }

    /**
     * INTERNAL:
     *    Return a backup clone of the attribute.
     */
    @Override
    public Object backupCloneAttribute(Object attributeValue, Object clone, Object backup, UnitOfWorkImpl unitOfWork) {
        // delay instantiation until absolutely necessary
        if ((!(attributeValue instanceof IndirectContainer)) || objectIsInstantiated(attributeValue)) {
            return super.backupCloneAttribute(attributeValue, clone, backup, unitOfWork);
        } else {
            return buildBackupClone((IndirectContainer)attributeValue);
        }
    }

    /**
     * INTERNAL:
     * Return a backup clone of a clone container that has not been
     * read from the database yet.
     * This is used by the indirection policy to hook together a UOW
     * clone with its backup clone - only when the clone (the working
     * copy returned to the user) instantiates its contents from the
     * database will these contents be copied to the backup clone.
     */
    protected Object buildBackupClone(IndirectContainer container) {
        ValueHolderInterface<Object> containerValueHolder = container.getValueHolder();
        // CR#2852176 Use a BackupValueHolder to handle replacing of the original.
        BackupValueHolder<Object> backupValueHolder = new BackupValueHolder<>(containerValueHolder);
        if (containerValueHolder instanceof UnitOfWorkValueHolder) {
           ((UnitOfWorkValueHolder<Object>) containerValueHolder).setBackupValueHolder(backupValueHolder);
        }
        return this.buildIndirectContainer(backupValueHolder);
    }

    /**
     * Construct and return an instance of the specified
     * indirect container class.
     */
    protected IndirectContainer buildIndirectContainer() {
        IndirectContainer container = null;
        //3732
        if (defaultContainerSize != null) {
            container = (IndirectContainer)getContainerPolicy().containerInstance(getDefaultContainerSize());
        } else {
            container = (IndirectContainer)getContainerPolicy().containerInstance();
        }
        if (container instanceof IndirectCollection){
            if (this.useLazyInstantiation != null){
                ((IndirectCollection)container).setUseLazyInstantiation(this.useLazyInstantiation);
            }
        }
        return container;
    }

    /**
     * Return a new IndirectContainer with the specified value holder.
     */
    protected Object buildIndirectContainer(ValueHolderInterface valueHolder) {
        IndirectContainer result = buildIndirectContainer();
        result.setValueHolder(valueHolder);
        return result;
    }

    /**
     * INTERNAL: This method can be used when an Indirection Object is required
     * to be built from a provided ValueHolderInterface object. This may be used
     * for custom value holder types. Certain policies like the
     * TransparentIndirectionPolicy may wrap the valueholder in another object.
     */

    @Override
    public Object buildIndirectObject(ValueHolderInterface valueHolder){
        return buildIndirectContainer(valueHolder);
    }
    /**
     * Return a clone of the attribute.
     * @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 Object cloneAttribute(Object attributeValue, Object original, CacheKey cacheKey, Object clone, Integer refreshCascade, AbstractSession cloningSession, boolean buildDirectlyFromRow) {
        ValueHolderInterface<Object> valueHolder = null;
        Object container = null;
        IndirectList indirectList = null;
        IndirectContainer indirectContainer = null;
        if (attributeValue instanceof IndirectContainer) {
            indirectContainer = (IndirectContainer)attributeValue;
            valueHolder = indirectContainer.getValueHolder();
            if (indirectContainer instanceof IndirectList) {
                indirectList = (IndirectList)indirectContainer;
            }
        }
        if (!buildDirectlyFromRow && cloningSession.isUnitOfWork() && ((UnitOfWorkImpl)cloningSession).isOriginalNewObject(original)) {
            // CR#3156435 Throw a meaningful exception if a serialized/dead value holder is detected.
            // This can occur if an existing serialized object is attempt to be registered as new.
            if ((valueHolder instanceof DatabaseValueHolder)
                    && (! valueHolder.isInstantiated())
                    && (((DatabaseValueHolder<?>) valueHolder).getSession() == null)
                    && (! ((DatabaseValueHolder<?>) valueHolder).isSerializedRemoteUnitOfWorkValueHolder())) {
                throw DescriptorException.attemptToRegisterDeadIndirection(original, this.mapping);
            }
            if (this.mapping.getRelationshipPartner() == null) {
                container = this.mapping.buildCloneForPartObject(attributeValue, original, cacheKey, clone, cloningSession, refreshCascade, false, false);
            } else {
                if (indirectContainer == null) {
                    valueHolder = new ValueHolder<>(attributeValue);
                }
                AbstractRecord row = null;
                if (valueHolder instanceof DatabaseValueHolder) {
                    row = ((DatabaseValueHolder<?>)valueHolder).getRow();
                }

                //If a new object is being cloned then we must build a new UOWValueHolder
                //  this is so that new clones can also have their relationships managed
                // here the code instantiates the valueholder in a privledged manner because a
                // UOWValueHolder will assume the objects in the collection are existing if the valueholder
                //  Goes through it's own instantiation process.
                DatabaseValueHolder<Object> newValueHolder = this.mapping.createCloneValueHolder(valueHolder, original, clone, row, cloningSession, buildDirectlyFromRow);
                container = buildIndirectContainer(newValueHolder);
                Object cloneCollection = this.mapping.buildCloneForPartObject(attributeValue, original, cacheKey, clone, cloningSession, refreshCascade, false, false);
                newValueHolder.privilegedSetValue(cloneCollection);
                newValueHolder.setInstantiated();
            }
        } else {
            if (indirectContainer == null) {
                valueHolder = new ValueHolder<>(attributeValue);
            }
            AbstractRecord row = null;
            if (valueHolder instanceof DatabaseValueHolder) {
                row = ((DatabaseValueHolder<?>)valueHolder).getRow();
            }
            DatabaseValueHolder<?> uowValueHolder = this.mapping.createCloneValueHolder(valueHolder, original, clone, row, cloningSession, buildDirectlyFromRow);
            if ((indirectContainer == null) || !buildDirectlyFromRow) {
                container = buildIndirectContainer(uowValueHolder);
            } else {
                // PERF: If building from rows inside uow, there is no original,
                // so just use the already built indirect collection.
                indirectContainer.setValueHolder(uowValueHolder);
                container = indirectContainer;
            }
        }
        if (cloningSession.isUnitOfWork()){
            // Set the change listener.
            if ((this.mapping.getDescriptor().getObjectChangePolicy().isObjectChangeTrackingPolicy())
                    && (((ChangeTracker)clone)._persistence_getPropertyChangeListener() != null)
                    && (container instanceof CollectionChangeTracker) ) {
                ((CollectionChangeTracker)container).setTrackedAttributeName(this.mapping.getAttributeName());
                ((CollectionChangeTracker)container)._persistence_setPropertyChangeListener(((ChangeTracker)clone)._persistence_getPropertyChangeListener());
            }
            if (indirectList != null) {
                ((IndirectList)container).setIsListOrderBrokenInDb(indirectList.isListOrderBrokenInDb());
            }
        }
        return container;
    }

    /**
     * INTERNAL:
     *    Return whether the container policy is valid for the indirection policy.
     * In this case, the container policy MUST be configured
     * for an IndirectContainer.
     */
    protected boolean containerPolicyIsValid() {
        if (Helper.classImplementsInterface(this.getContainerClass(), ClassConstants.IndirectContainer_Class)) {
            return true;
        }
        return false;
    }

    /**
     * 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.
     * OneToOneMappings should not be using transparent direction.
     */
    @Override
    public Object extractPrimaryKeyForReferenceObject(Object referenceObject, AbstractSession session) {
        throw DescriptorException.invalidUseOfTransparentIndirection(this.getMapping());
    }

    /**
     * INTERNAL:
     *    Return the reference row for the reference object.
     * This allows the new row to be built without instantiating
     * the reference object.
     * Return null if the object has already been instantiated.
     */
    @Override
    public AbstractRecord extractReferenceRow(Object referenceObject) {
        if (this.objectIsInstantiated(referenceObject)) {
            return null;
        } else {
            return ((DatabaseValueHolder<?>)((IndirectContainer)referenceObject).getValueHolder()).getRow();
        }
    }

    /**
     * INTERNAL:
     * An object has been serialized from the server to the client.
     * Replace the transient attributes of the remote value holders
     * with client-side objects.
     */
    @Override
    public void fixObjectReferences(Object object, Map<Object, ObjectDescriptor> objectDescriptors, Map<Object, Object> processedObjects, ObjectLevelReadQuery query, DistributedSession session) {
        Object container = getMapping().getAttributeValueFromObject(object);
        if (container instanceof IndirectContainer && ((((IndirectContainer) container).getValueHolder() instanceof RemoteValueHolder)) ) {
            RemoteValueHolder<?> valueHolder = (RemoteValueHolder)((IndirectContainer)container).getValueHolder();
            valueHolder.setSession(session);
            valueHolder.setMapping(getMapping());
            if ((!query.shouldMaintainCache()) && ((!query.shouldCascadeParts()) || (query.shouldCascadePrivateParts() && (!this.mapping.isPrivateOwned())))) {
                valueHolder.setQuery(null);
            } else {
                valueHolder.setQuery(query);
            }

            // set to uninstantiated since no objects are serialized past remote value holders
            valueHolder.setUninstantiated();
        } else {
            this.mapping.fixRealObjectReferences(object, objectDescriptors, processedObjects, query, session);
        }
    }

    /**
     * INTERNAL:
     *    Return the container class for the mapping.
     */
    protected Class getContainerClass() {
        return this.getContainerPolicy().getContainerClass();
    }

    /**
     * INTERNAL:
     *    Return the container policy for the mapping.
     */
    protected ContainerPolicy getContainerPolicy() {
        if (this.containerPolicy == null) {
            this.containerPolicy = getCollectionMapping().getContainerPolicy();
        }
        return this.containerPolicy;
    }

    /**
     * INTERNAL:
     * Return the the size to of container to create.  Default to using default constructor.
     */
    protected static int getDefaultContainerSize() {
        //3732
        return defaultContainerSize;
    }

    /**
     * INTERNAL:
     *    Return the original indirection object for a unit of work indirection object.
     */
    @Override
    public Object getOriginalIndirectionObject(Object unitOfWorkIndirectionObject, AbstractSession session) {
        IndirectContainer container = (IndirectContainer)unitOfWorkIndirectionObject;
        if (container.getValueHolder() instanceof UnitOfWorkValueHolder) {
            return buildIndirectContainer((ValueHolderInterface<?>) getOriginalValueHolder(unitOfWorkIndirectionObject, session));
        } else {
            return container;
        }
    }

    /**
     * INTERNAL:
     *    Return the original indirection object for a unit of work indirection object.
     */
    @Override
    public Object getOriginalIndirectionObjectForMerge(Object unitOfWorkIndirectionObject, AbstractSession session) {
        IndirectContainer container = (IndirectContainer) getOriginalIndirectionObject(unitOfWorkIndirectionObject, session);
        DatabaseValueHolder<?> holder = (DatabaseValueHolder<?>)container.getValueHolder();
        if (holder != null && holder.getSession()!= null){
            holder.setSession(session);
        }
        return container;
    }

    /**
     * INTERNAL: Return the original valueHolder object. Access to the
     * underlying valueholder may be required when serializing the valueholder
     * or converting the valueHolder to another type.
     */
    @Override
    public Object getOriginalValueHolder(Object unitOfWorkIndirectionObject, AbstractSession session) {
        if (! (unitOfWorkIndirectionObject instanceof IndirectContainer)){
            return new ValueHolder<>();
        }
        IndirectContainer container = (IndirectContainer)unitOfWorkIndirectionObject;
        if (container.getValueHolder() instanceof WrappingValueHolder) {
            ValueHolderInterface<?> valueHolder = ((WrappingValueHolder<?>)container.getValueHolder()).getWrappedValueHolder();
            if ((valueHolder == null) && session.isRemoteUnitOfWork()) {
                RemoteSessionController controller = ((RemoteUnitOfWork)session).getParentSessionController();
                valueHolder = controller.getRemoteValueHolders().get(((UnitOfWorkValueHolder<?>)container.getValueHolder()).getWrappedValueHolderRemoteID());
            }
            if (!session.isProtectedSession()){
                while (valueHolder instanceof WrappingValueHolder && ((WrappingValueHolder<?>)valueHolder).getWrappedValueHolder() != null){
                    valueHolder = ((WrappingValueHolder<?>)valueHolder).getWrappedValueHolder();
                }
            }
            // EL bug 470161
            if (valueHolder instanceof DatabaseValueHolder) {
                ((DatabaseValueHolder<?>) valueHolder).releaseWrappedValueHolder(session);
            }
            return valueHolder;
        } else {
            return container.getValueHolder();
        }
    }

    /**
     * INTERNAL:
     * Return the "real" attribute value, as opposed to any wrapper.
     * This will trigger the wrapper to instantiate the value.
     */
    @Override
    public Object getRealAttributeValueFromObject(Object object, Object attribute) {
        // PERF: do not instantiate - this.getContainerPolicy().sizeFor(object);// forgive me for this hack: but we have to do something to trigger the database read
        return attribute;
    }

    /**
     * INTERNAL:
     * Trigger the instantiation of the value.
     */
    @Override
    public void instantiateObject(Object object, Object attribute) {
        getContainerPolicy().sizeFor(attribute);
    }

    /**
     * INTERNAL:
     * The method validateAttributeOfInstantiatedObject(Object attributeValue) fixes the value of the attributeValue
     * in cases where it is null and indirection requires that it contain some specific data structure.  Return whether this will happen.
     * This method is used to help determine if indirection has been triggered
     * @see #validateAttributeOfInstantiatedObject(Object)
     */
    @Override
    public boolean isAttributeValueFullyBuilt(Object attributeValue){
        return attributeValue != null;
    }

    public Boolean getUseLazyInstantiation() {
        return useLazyInstantiation;
    }

    /**
     * INTERNAL:
     * Extract and return the appropriate value from the
     * specified remote value holder.
     */
    @Override
    public Object getValueFromRemoteValueHolder(RemoteValueHolder<?> remoteValueHolder) {
        Object result = remoteValueHolder.getServerIndirectionObject();
        this.getContainerPolicy().sizeFor(result);// forgive me for this hack: but we have to do something to trigger the database read
        return result;
    }

    /**
     * INTERNAL:
     *    Set the value of the appropriate attribute of target to attributeValue.
     * If the Target has yet to be instantiated then we need to instantiate the target to ensure that
     * the backup clone is instantiated for comparison.
     */
    @Override
    public void setRealAttributeValueInObject(Object target, Object attributeValue) {

        /*
           Bug 3573808 - do NOT trigger the valueholder; SPECj benchmark
           deadlocks in this method.
           Re-ran the original testcase IndirectContainerTestDatabase
            testMergeCloneWithSerializedTransparentIndirection
           and it passes without triggering the valueholder. MWN

        //cr 3788
        // Trigger the valueholder when setting the value in an object
        Object object = this.getMapping().getAttributeValueFromObject(target);
        if (object instanceof IndirectContainer){
            ((IndirectContainer)object).getValueHolder().getValue();
        }
        */
        super.setRealAttributeValueInObject(target, attributeValue);
    }

    /**
     * INTERNAL:
     * set the source object into QueryBasedValueHolder.
     */
    @Override
    public void setSourceObject(Object sourceObject, Object attributeValue) {
        if( attributeValue instanceof IndirectContainer) {
            ValueHolderInterface valueHolder = ((IndirectContainer)attributeValue).getValueHolder();
            if (valueHolder instanceof QueryBasedValueHolder) {
                ((QueryBasedValueHolder<?>)valueHolder).setSourceObject(sourceObject);
            }
        }
    }

    /**
     * ADVANCED:
     * IndirectList and IndirectSet can be configured not to instantiate the list from the
     * database when you add and remove from them.  IndirectList defaults to this behavior. When
     * Set to true, the collection associated with this TransparentIndirection will be setup so as
     * not to instantiate for adds and removes.  The weakness of this setting for an IndirectSet is
     * that when the set is not instantiated, if a duplicate element is added, it will not be
     * detected until commit time.
     */
    @Override
    public void setUseLazyInstantiation(Boolean useLazyInstantiation) {
        this.useLazyInstantiation = useLazyInstantiation;
    }

    /**
     * ADVANCED:
     * IndirectList and IndirectSet can be configured not to instantiate the list from the
     * database when you add and remove from them.  IndirectList defaults to this behavior. When
     * Set to true, the collection associated with this TransparentIndirection will be setup so as
     * not to instantiate for adds and removes.  The weakness of this setting for an IndirectSet is
     * that when the set is not instantiated, if a duplicate element is added, it will not be
     * detected until commit time.
     */
    @Override
    public Boolean shouldUseLazyInstantiation() {
        return useLazyInstantiation;
    }

    /**
     * INTERNAL:
     * Iterate over the specified attribute value.
     */
    @Override
    public void iterateOnAttributeValue(DescriptorIterator iterator, Object attributeValue) {
        if (attributeValue instanceof IndirectContainer) {
            iterator.iterateIndirectContainerForMapping((IndirectContainer)attributeValue, this.getMapping());
        } else {// it must be a "real" collection
            super.iterateOnAttributeValue(iterator, attributeValue);
        }
    }

    /**
     * INTERNAL
     * Replace the client value holder with the server value holder,
     * after copying some of the settings from the client value holder.
     */
    @Override
    public void mergeRemoteValueHolder(Object clientSideDomainObject, Object serverSideDomainObject, MergeManager mergeManager) {
        // This will always be a transparent with a remote.
        IndirectContainer serverContainer = (IndirectContainer)getMapping().getAttributeValueFromObject(serverSideDomainObject);
        RemoteValueHolder<?> serverValueHolder = (RemoteValueHolder<?>)serverContainer.getValueHolder();
        mergeClientIntoServerValueHolder(serverValueHolder, mergeManager);

        getMapping().setAttributeValueInObject(clientSideDomainObject, serverContainer);
    }

    /**
     * INTERNAL:
     *    Return the null value of the appropriate attribute. That is, the
     * field from the database is NULL, return what should be
     * placed in the object's attribute as a result.
     * OneToOneMappings should not be using transparent direction.
     */
    @Override
    public Object nullValueFromRow() {
        throw DescriptorException.invalidUseOfTransparentIndirection(this.getMapping());
    }

    /**
     * INTERNAL:
     * Return whether the specified object is instantiated.
     */
    @Override
    public boolean objectIsInstantiated(Object object) {
        if (object instanceof IndirectContainer) {
            return ((IndirectContainer)object).isInstantiated();
        } else {
            return true;// it must be a "real" collection
        }
    }

    /**
     * INTERNAL:
     * Return whether the specified object can be instantiated without database access.
     */
    @Override
    public boolean objectIsEasilyInstantiated(Object object) {
        if (object instanceof IndirectContainer) {
            ValueHolderInterface<?> valueHolder = ((IndirectContainer)object).getValueHolder();
            if (valueHolder instanceof DatabaseValueHolder) {
                return ((DatabaseValueHolder<?>)valueHolder).isEasilyInstantiated();
            }
        }
        return true;
    }

    /**
     * INTERNAL:
     * Return whether the specified object is instantiated, or if it has changes.
     */
    @Override
    public boolean objectIsInstantiatedOrChanged(Object object) {
        return objectIsInstantiated(object) || ((object instanceof IndirectCollection) && ((IndirectCollection)object).hasDeferredChanges());
    }

    /**
     * ADVANCED:
     * Set the size to of container to create.  Default to using default constructor.
     */
    public static void setDefaultContainerSize(int defaultSize) {
        //3732
        defaultContainerSize = defaultSize;
    }

    /**
     * INTERNAL:
     * Return whether the type is appropriate for the indirection policy.
     * In this case, the attribute type MUST be
     * compatible with the one specified by the ContainerPolicy
     * (i.e. either the container policy class is a subclass of the
     * declared type [jdk1.1] or the container policy class implements
     * the declared interface [jdk1.2]).
     */
    protected boolean typeIsValid(Class<?> declaredType) {
        if (Helper.classIsSubclass(this.getContainerClass(), declaredType)) {
            return true;
        }
        if (Helper.classImplementsInterface(this.getContainerClass(), declaredType)) {
            return true;
        }
        return false;
    }

    /**
     * INTERNAL:
     * Return whether the indirection policy uses transparent indirection.
     */
    @Override
    public boolean usesTransparentIndirection(){
        return true;
    }

    /**
     * INTERNAL:
     * Verify that the value of the attribute within an instantiated object
     * is of the appropriate type for the indirection policy.
     * In this case, the attribute must be non-null and it must be at least a
     * subclass or implementor of the container type.
     * If the value is null return a new indirection object to be used for the attribute.
     */
    @Override
    public Object validateAttributeOfInstantiatedObject(Object attributeValue) {
        // PERF: If the value is null, create a new value holder instance for the attribute value,
        // this allows for indirection attributes to not be instantiated in the constructor as they
        // are typically replaced when reading or cloning so is very inefficient to initialize.
        if (attributeValue == null) {
            return buildIndirectContainer();
        }
        return attributeValue;
    }

    /**
     * INTERNAL:
     * Verify that the container policy is compatible with the
     * indirection policy. If it is incorrect, add an exception to the
     * integrity checker.
     */
    @Override
    public void validateContainerPolicy(IntegrityChecker checker) throws DescriptorException {
        super.validateContainerPolicy(checker);
        if (!this.containerPolicyIsValid()) {
            checker.handleError(DescriptorException.invalidContainerPolicyWithTransparentIndirection(this.getMapping(), this.getContainerPolicy()));
        }

        // Bug 2618982
        if (getContainerPolicy().isMapPolicy() && ((((ForeignReferenceMapping)getMapping()).getRelationshipPartnerAttributeName() != null) || (getMapping().getRelationshipPartner() != null))) {
            checker.handleError(DescriptorException.unsupportedTypeForBidirectionalRelationshipMaintenance(this.getMapping(), this.getContainerPolicy()));
        }
    }

    /**
     * INTERNAL:
     * Verify that attributeType is correct for the
     * indirection policy. If it is incorrect, add an exception to the
     * integrity checker.
     * In this case, the attribute type MUST be
     * compatible with the one specified by the ContainerPolicy.
     */
    @Override
    public void validateDeclaredAttributeType(Class<?> attributeType, IntegrityChecker checker) throws DescriptorException {
        super.validateDeclaredAttributeType(attributeType, checker);
        if (!this.typeIsValid(attributeType)) {
            checker.handleError(DescriptorException.attributeAndMappingWithTransparentIndirectionMismatch(this.getMapping(), attributeType, this.validTypeName()));
        }
    }

    /**
     * INTERNAL:
     * Verify that getter returnType is correct for the
     * indirection policy. If it is incorrect, add an exception
     * to the integrity checker.
     * In this case, the attribute type MUST be
     * compatible with the one specified by the ContainerPolicy.
     */
    @Override
    public void validateGetMethodReturnType(Class<?> returnType, IntegrityChecker checker) throws DescriptorException {
        super.validateGetMethodReturnType(returnType, checker);
        if (!this.typeIsValid(returnType)) {
            checker.handleError(DescriptorException.returnAndMappingWithTransparentIndirectionMismatch(this.getMapping(), returnType, this.validTypeName()));
        }
    }

    /**
     * INTERNAL:
     * Verify that setter parameterType is correct for the
     * indirection policy. If it is incorrect, add an exception
     * to the integrity checker.
     * In this case, the attribute type MUST be
     * compatible with the one specified by the ContainerPolicy.
     */
    @Override
    public void validateSetMethodParameterType(Class<?> parameterType, IntegrityChecker checker) throws DescriptorException {
        super.validateSetMethodParameterType(parameterType, checker);
        if (!this.typeIsValid(parameterType)) {
            checker.handleError(DescriptorException.parameterAndMappingWithTransparentIndirectionMismatch(this.getMapping(), parameterType, this.validTypeName()));
        }
    }

    /**
     * INTERNAL:
     *    Return the type that is appropriate for the indirection policy.
     */
    protected String validTypeName() {
        return Helper.getShortClassName(this.getContainerClass());
    }

    /**
     * INTERNAL:
     * Return the value to be stored in the object's attribute.
     *    This value is determined by the batchQuery.
     * In this case, wrap the query in an IndirectContainer for later invocation.
     */
    @Override
    public Object valueFromBatchQuery(ReadQuery batchQuery, AbstractRecord row, ObjectLevelReadQuery originalQuery, CacheKey parentCacheKey) {
        return this.buildIndirectContainer(new BatchValueHolder<>(batchQuery, row, getForeignReferenceMapping(), originalQuery, parentCacheKey));
    }

    /**
     * INTERNAL:
     * Return the value to be stored in the object's attribute.
     * This value is determined by invoking the appropriate
     * method on the object and passing it the row and session.
     * TransformationMappings should not be using transparent direction.
     */
    @Override
    public Object valueFromMethod(Object object, AbstractRecord row, AbstractSession session) {
        throw DescriptorException.invalidUseOfTransparentIndirection(this.getMapping());
    }

    /**
     * INTERNAL:
     * Return the value to be stored in the object's attribute.
     * This value is determined by the query.
     * In this case, wrap the query in an IndirectContainer for later invocation.
     */
    @Override
    public Object valueFromQuery(ReadQuery query, AbstractRecord row, AbstractSession session) {
        return this.buildIndirectContainer(new QueryBasedValueHolder<>(query, row, session));
    }

    /**
     * INTERNAL:
     * A combination of valueFromQuery and valueFromRow(object).
     * Sometimes the attribute is known (joining) but we still need to hang on
     * to the query (pessimistic locking).
     */
    @Override
    public Object valueFromQuery(ReadQuery query, AbstractRecord row, Object object, AbstractSession session) {
        return this.buildIndirectContainer(new QueryBasedValueHolder<>(query, object, row, session));
    }

    /**
     * INTERNAL:
     * Return the value to be stored in the object's attribute.
     * This allows wrapping of the real value, none is required for transparent.
     */
    @Override
    public Object valueFromRow(Object object) {
        return object;
    }
}
