/*
 * 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
//     08/23/2010-2.2 Michael O'Brien
//        - 323043: application.xml module ordering may cause weaving not to occur causing an NPE.
//                       warn if expected "_persistence_//_vh" method not found
//                       instead of throwing NPE during deploy validation.
package org.eclipse.persistence.mappings.foundation;

import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.indirection.ValueHolderInterface;
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
import org.eclipse.persistence.internal.databaseaccess.FieldTypeDefinition;
import org.eclipse.persistence.internal.descriptors.DescriptorIterator;
import org.eclipse.persistence.internal.descriptors.FieldTransformation;
import org.eclipse.persistence.internal.descriptors.InstanceVariableAttributeAccessor;
import org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor;
import org.eclipse.persistence.internal.descriptors.MethodBasedFieldTransformation;
import org.eclipse.persistence.internal.descriptors.TransformerBasedFieldTransformation;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.indirection.BasicIndirectionPolicy;
import org.eclipse.persistence.internal.indirection.ContainerIndirectionPolicy;
import org.eclipse.persistence.internal.indirection.DatabaseValueHolder;
import org.eclipse.persistence.internal.indirection.IndirectionPolicy;
import org.eclipse.persistence.internal.indirection.NoIndirectionPolicy;
import org.eclipse.persistence.internal.queries.JoinedAttributeManager;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.security.PrivilegedNewInstanceFromClass;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.ChangeRecord;
import org.eclipse.persistence.internal.sessions.MergeManager;
import org.eclipse.persistence.internal.sessions.ObjectChangeSet;
import org.eclipse.persistence.internal.sessions.TransformationMappingChangeRecord;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.internal.sessions.remote.RemoteValueHolder;
import org.eclipse.persistence.mappings.Association;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.transformers.AttributeTransformer;
import org.eclipse.persistence.mappings.transformers.FieldTransformer;
import org.eclipse.persistence.mappings.transformers.MethodBasedAttributeTransformer;
import org.eclipse.persistence.mappings.transformers.MethodBasedFieldTransformer;
import org.eclipse.persistence.queries.ObjectBuildingQuery;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.queries.ReadObjectQuery;
import org.eclipse.persistence.queries.WriteObjectQuery;
import org.eclipse.persistence.sessions.CopyGroup;
import org.eclipse.persistence.sessions.DatabaseRecord;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.sessions.remote.DistributedSession;

/**
 * <p><b>Purpose</b>: A transformation mapping is used for a specialized translation between how
 * a value is represented in Java and its representation on the databae. Transformation mappings
 * should only be used when other mappings are inadequate.
 *
 * @author Sati
 * @since TOPLink/Java 1.0
 */
public abstract class AbstractTransformationMapping extends DatabaseMapping {

    /** Name of the class which implements AttributeTransformer to be used to retrieve the attribute value */
    protected String attributeTransformerClassName;

    /** attributeTransformerClassName is converter to an instance of AttributeTransformer */
    protected AttributeTransformer attributeTransformer;

    /** Stores field name and the class name of a FieldTransformer in a vector to preserve order */
    protected List<FieldTransformation> fieldTransformations;

    /** The TransformerClassNames are converted into instances of FieldTransformer */
    protected List<Object[]> fieldToTransformers;

    /** PERF: Indicates if this mapping's attribute is a simple value which cannot be modified only replaced. */
    protected boolean isMutable;

    /** Implements indirection behaviour */
    protected IndirectionPolicy indirectionPolicy;

    /**
     * PUBLIC:
     * Default constructor.
     */
    protected AbstractTransformationMapping() {
        fieldTransformations = new ArrayList();
        fieldToTransformers = new ArrayList();
        setIsMutable(true);
        dontUseIndirection();
        this.setWeight(WEIGHT_TRANSFORM);
    }

    /**
     * PUBLIC:
     * Add the field and the name of the method
     * that returns the value to be placed in said field
     * when the object is written to the database.
     * The method may take zero arguments, or it may
     * take a single argument of type
     * <code>org.eclipse.persistence.sessions.Session</code>.
     */
    public void addFieldTransformation(DatabaseField field, String methodName) {
        MethodBasedFieldTransformation transformation = new MethodBasedFieldTransformation();
        transformation.setField(field);
        transformation.setMethodName(methodName);
        getFieldTransformations().add(transformation);
    }

    /**
     * PUBLIC:
     * Add the name of field and the name of the method
     * that returns the value to be placed in said field
     * when the object is written to the database.
     * The method may take zero arguments, or it may
     * take a single argument of type
     * <code>org.eclipse.persistence.sessions.Session</code>.
     */
    public void addFieldTransformation(String fieldName, String methodName) {
        addFieldTransformation(new DatabaseField(fieldName), methodName);
    }

    /**
     * INTERNAL:
     * Add the name of a field and the name of a class which implements
     * the FieldTransformer interface. When the object is written, the transform
     * method will be called on the FieldTransformer to acquire the value to put
     * in the field.
     */
    public void addFieldTransformerClassName(String fieldName, String className) {
        addFieldTransformerClassName(new DatabaseField(fieldName), className);
    }

    /**
     * INTERNAL:
     * Add the name of a field and the name of a class which implements
     * the FieldTransformer interface. When the object is written, the transform
     * method will be called on the FieldTransformer to acquire the value to put
     * in the field.
     */
    public void addFieldTransformerClassName(DatabaseField field, String className) {
        TransformerBasedFieldTransformation transformation = new TransformerBasedFieldTransformation();
        transformation.setField(field);
        transformation.setTransformerClassName(className);

        getFieldTransformations().add(transformation);
    }

    /**
     * PUBLIC:
     * Add the name of field and the transformer
     * that returns the value to be placed in the field
     * when the object is written to the database.
     */
    public void addFieldTransformer(String fieldName, FieldTransformer transformer) {
        this.addFieldTransformer(new DatabaseField(fieldName), transformer);
    }

    /**
     * PUBLIC:
     * Add the field and the transformer
     * that returns the value to be placed in the field
     * when the object is written to the database.
     */
    public void addFieldTransformer(DatabaseField field, FieldTransformer transformer) {
        TransformerBasedFieldTransformation transformation = new TransformerBasedFieldTransformation(transformer);
        transformation.setField(field);

        getFieldTransformations().add(transformation);
    }

    /**
     * INTERNAL:
     * The referenced object is checked if it is instantiated or not
     */
    protected boolean areObjectsToBeProcessedInstantiated(Object object) {
        return this.indirectionPolicy.objectIsInstantiated(getAttributeValueFromObject(object));
    }

    /**
     * INTERNAL:
     * Clone the attribute from the clone and assign it to the backup.
     */
    @Override
    public void buildBackupClone(Object clone, Object backup, UnitOfWorkImpl unitOfWork) {
        // If mapping is a no-attribute transformation mapping, do nothing
        if (isWriteOnly()) {
            return;
        }
        Object attributeValue = getAttributeValueFromObject(clone);
        Object clonedAttributeValue = this.indirectionPolicy.backupCloneAttribute(attributeValue, clone, backup, unitOfWork);
        setAttributeValueInObject(backup, clonedAttributeValue);
    }

    /**
     * INTERNAL
     * Build a phantom row that contains only the fields
     * for the mapping, populated with the values generated by
     * invoking the field methods on the specified object.
     */
    protected AbstractRecord buildPhantomRowFrom(Object domainObject, AbstractSession session) {
        AbstractRecord row = new DatabaseRecord(this.fieldToTransformers.size());
        for (Object[] pair : this.fieldToTransformers) {
            DatabaseField field = (DatabaseField)pair[0];
            FieldTransformer transformer = (FieldTransformer)pair[1];
            Object fieldValue = this.invokeFieldTransformer(field, transformer, domainObject, session);
            row.put(field, fieldValue);
        }
        return row;
    }

    /**
     * INTERNAL:
     * Builds a shallow original object.  Only direct attributes and primary
     * keys are populated.  In this way the minimum original required for
     * instantiating a working copy clone can be built without placing it in
     * the shared cache (no concern over cycles).
     * @param original later the input to buildCloneFromRow
     */
    @Override
    public void buildShallowOriginalFromRow(AbstractRecord record, Object original, JoinedAttributeManager joinManager, ObjectBuildingQuery query, AbstractSession executionSession) {
        // In this case we know it is a primary key mapping, so hope that it
        // is essentially a direct mapping.  If it is a 1-1 with a
        // no-indirection pointer back to original, then will get a stack
        // overflow.
        // Only solution to this is to trigger the transformation using the root
        // session.
        UnitOfWorkImpl unitOfWork = (UnitOfWorkImpl)query.getSession();
        query.setSession(unitOfWork.getParent());
        try {
            readFromRowIntoObject(record, joinManager, original, null, query, executionSession, false);
        } finally {
            query.setSession(unitOfWork);
        }
    }

    /**
     * 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 buildCloneForPartObject(attributeValue, clone, null, backup, unitOfWork, null, true, true);
    }

    /**
     * INTERNAL:
     * Clone the attribute from the original and assign it to the clone.
     */
    @Override
    public void buildClone(Object original, CacheKey cacheKey, Object clone, Integer refreshCascade, AbstractSession cloningSession) {
        // If mapping is a no-attribute transformation mapping, do nothing
        if (isWriteOnly()) {
            return;
        }
        Object attributeValue = getAttributeValueFromObject(original);
        Object clonedAttributeValue = this.indirectionPolicy.cloneAttribute(attributeValue, original, cacheKey, clone, refreshCascade, cloningSession, false);// building clone from an original not a row.
        setAttributeValueInObject(clone, clonedAttributeValue);
    }

    /**
     * INTERNAL:
     * Extract value from the row and set the attribute to this value in the
     * working copy clone.
     * In order to bypass the shared cache when in transaction a UnitOfWork must
     * be able to populate working copies directly from the row.
     */
    @Override
    public void buildCloneFromRow(AbstractRecord record, JoinedAttributeManager joinManager, Object clone, CacheKey sharedCacheKey, ObjectBuildingQuery sourceQuery, UnitOfWorkImpl unitOfWork, AbstractSession executionSession) {
        // If mapping is a no-attribute transformation mapping, do nothing
        if (isWriteOnly()) {
            return;
        }

        // This will set the value in the clone automatically.
        Object attributeValue = readFromRowIntoObject(record, joinManager, clone, sharedCacheKey, sourceQuery, executionSession, true);
        if (usesIndirection()) {
            boolean wasCacheUsed = this.isCacheable && sharedCacheKey != null && this.descriptor.getCachePolicy().isProtectedIsolation()
                && sharedCacheKey.getObject() != null;
            //it would be better if wasCacheUsed could be calculated within readFromRowIntoObject but that would require changing the signature of all mappings just for
            //transformation mapping.
            if (!wasCacheUsed){
                //if the cache was used then the attribute has already been cloned by readFromRowIntoObject
                attributeValue = this.indirectionPolicy.cloneAttribute(attributeValue, null,// no original
                        null, clone, null, unitOfWork, true);// build clone directly from row.
            }
            setAttributeValueInObject(clone, attributeValue);
        }
    }

    /**
     * INTERNAL:
     * Require for cloning, the part must be cloned.
     * Ignore the attribute value, go right to the object itself.
     */
    @Override
    public Object buildCloneForPartObject(Object attributeValue, Object original, CacheKey cacheKey, Object clone, AbstractSession cloningSession, Integer refreshCascade, boolean isExisting, boolean isFromSharedCache) {
        if (isReadOnly() || !isMutable()) {
            return attributeValue;
        }
        AbstractRecord row = buildPhantomRowFrom(original, cloningSession);
        return invokeAttributeTransformer(row, clone, cloningSession);
    }

    /**
     * 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) {
        // If mapping is a no-attribute transformation mapping, do nothing
        if (isWriteOnly()) {
            return;
        }

        Object clonedAttributeValue;
        // If the mapping is read-only, a direct pass through of the value will be performed.
        // This is done because the method invocation is not possible as the row will be
        // empty and we have no way to clone the value.
        // Since the value cannot change anyway we just pass it through.
        if (isReadOnly() || !isMutable()) {
            clonedAttributeValue = getRealAttributeValueFromObject(original, group.getSession());
        } else {
            AbstractRecord row = buildPhantomRowFrom(original, group.getSession());
            clonedAttributeValue = invokeAttributeTransformer(row, copy, group.getSession());
        }
        this.indirectionPolicy.reset(copy);
        setRealAttributeValueInObject(copy, clonedAttributeValue);
    }

    /**
     * INTERNAL:
     * Cascade perform delete through mappings that require the cascade
     */
    @Override
    public void cascadePerformRemoveIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects){
        //objects referenced by this mapping are not registered as they have
        // no identity, this is a no-op.
    }

    /**
     * INTERNAL:
     * Cascade registerNew for Create through mappings that require the cascade
     */
    @Override
    public void cascadeRegisterNewIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects){
        //Objects referenced through transformation mappings are not registered as
        // they have no identity, this is a no-op.
    }

    /**
     * INTERNAL:
     * The mapping clones itself to create deep copy.
     */
    @Override
    public Object clone() {
        AbstractTransformationMapping clone = (AbstractTransformationMapping)super.clone();
        clone.setFieldToTransformers(new ArrayList(this.fieldToTransformers.size()));

        for (Object[] pair : this.fieldToTransformers) {
            Object[] transformation = new Object[2];
            transformation[0] = pair[0];
            transformation[1] = pair[1];
            clone.getFieldToTransformers().add(transformation);
        }

        clone.setIndirectionPolicy((IndirectionPolicy)indirectionPolicy.clone());

        return clone;
    }

    /**
     * INTERNAL:
     * Return all the fields with this mapping.
     */
    @Override
    protected Vector collectFields() {
        Vector databaseFields = new Vector(this.fieldToTransformers.size());
        for (Object[] pair : this.fieldToTransformers) {
            databaseFields.add(pair[0]);
        }
        return databaseFields;
    }

    /**
     * INTERNAL:
     * Compare the attributes belonging to this mapping for the objects.
     */
    @Override
    public ChangeRecord compareForChange(Object clone, Object backUp, ObjectChangeSet owner, AbstractSession session) {
        if (isReadOnly() || isWriteOnly()) {
            return null;
        }
        Object cloneAttribute = getAttributeValueFromObject(clone);
        Object backUpAttribute = null;
        if ((cloneAttribute != null) && (!this.indirectionPolicy.objectIsInstantiated(cloneAttribute))) {
            return null;
        }
        boolean difference = false;
        Object backupValue = null;
        if (owner.isNew()) {
            difference = true;
        } else {
            if (backUp != null) {
                backUpAttribute = getAttributeValueFromObject(backUp);
                backupValue = this.indirectionPolicy.getRealAttributeValueFromObject(backUp, backUpAttribute);
            }
            boolean backUpIsInstantiated = ((backUpAttribute == null) || (this.indirectionPolicy.objectIsInstantiated(backUpAttribute)));
            Object cloneValue = this.indirectionPolicy.getRealAttributeValueFromObject(clone, cloneAttribute);
            if (backUpIsInstantiated) {
                if (cloneValue == backupValue) {
                    return null;
                }
                if (((cloneValue != null && (backupValue != null)) && cloneValue.equals(backupValue))) {
                    return null;
                }
            }

            for (Object[] pair : this.fieldToTransformers) {
                DatabaseField field = (DatabaseField)pair[0];
                FieldTransformer transformer = (FieldTransformer)pair[1];
                Object cloneFieldValue = null;
                Object backUpFieldValue = null;
                if (clone != null) {
                    cloneFieldValue = invokeFieldTransformer(field, transformer, clone, session);
                }
                if ((backUpIsInstantiated) && (backUp != null)) {
                    backUpFieldValue = invokeFieldTransformer(field, transformer, backUp, session);
                }

                if (cloneFieldValue == backUpFieldValue) {
                    continue; // skip this iteration, go to the next one
                }
                if ((cloneFieldValue == null) || (backUpFieldValue == null)) {
                    difference = true;
                    break; // There is a difference.
                }
                if (cloneFieldValue.equals(backUpFieldValue)) {
                    continue; // skip this iteration, go to the next one
                }
                if (Helper.comparePotentialArrays(cloneFieldValue, backUpFieldValue)) {
                    continue; // skip this iteration, go to the next one
                }
                difference = true;
                break; // There is a difference.
            }
        }
        if (difference) {
            return internalBuildChangeRecord(clone, backupValue, owner, session);
        }
        return null;
    }

    /**
     * INTERNAL:
     * Directly build a change record without comparison
     */
    @Override
    public ChangeRecord buildChangeRecord(Object clone, ObjectChangeSet owner, AbstractSession session) {
        return internalBuildChangeRecord(clone, null, owner, session);
    }

    /**
     * INTERNAL:
     * Build a change record.
     */
    public ChangeRecord internalBuildChangeRecord(Object clone, Object oldValue, ObjectChangeSet owner, AbstractSession session) {
        TransformationMappingChangeRecord changeRecord = new TransformationMappingChangeRecord(owner);
        changeRecord.setRow(buildPhantomRowFrom(clone, session));
        changeRecord.setAttribute(getAttributeName());
        changeRecord.setMapping(this);
        changeRecord.setOldValue(oldValue);
        return changeRecord;
    }

    /**
     * INTERNAL:
     * Compare the attributes belonging to this mapping for the objects.
     */
    @Override
    public boolean compareObjects(Object firstObject, Object secondObject, AbstractSession session) {
        if (!isWriteOnly()) {
            // PERF: Checks if attribute values are equal first before apply field translation.
            Object firstValue = getRealAttributeValueFromObject(firstObject, session);
            Object secondValue = getRealAttributeValueFromObject(secondObject, session);
            if (firstValue == secondValue) {
                return true;
            }
            if ((firstValue == null) || (secondValue == null)) {
                return false;
            }
            if (firstValue.equals(secondValue)) {
                return true;
            }
        }

        for (Object[] pair : this.fieldToTransformers) {
            DatabaseField field = (DatabaseField)pair[0];
            FieldTransformer transformer = (FieldTransformer)pair[1];
            Object firstFieldValue = invokeFieldTransformer(field, transformer, firstObject, session);
            Object secondFieldValue = invokeFieldTransformer(field, transformer, secondObject, session);

            if (firstFieldValue == secondFieldValue) {
                continue; // skip this iteration, go to the next one
            }
            if ((firstFieldValue == null) || (secondFieldValue == null)) {
                return false;
            }
            if (!firstFieldValue.equals(secondFieldValue)) {
                if (!Helper.comparePotentialArrays(firstFieldValue, secondFieldValue)) {
                    return false;
                }
            }
        }

        return true;
    }

    /**
     * INTERNAL:
     * Convert all the class-name-based settings in this mapping to actual class-based
     * settings
     * @param classLoader
     */
    @Override
    public void convertClassNamesToClasses(ClassLoader classLoader){
        super.convertClassNamesToClasses(classLoader);

        if (attributeTransformerClassName != null) {
            Class attributeTransformerClass = null;
            try {
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                    try {
                        attributeTransformerClass = AccessController.doPrivileged(new PrivilegedClassForName(attributeTransformerClassName, true, classLoader));
                    } catch (PrivilegedActionException exception) {
                        throw ValidationException.classNotFoundWhileConvertingClassNames(attributeTransformerClassName, exception.getException());
                    }
                } else {
                    attributeTransformerClass = PrivilegedAccessHelper.getClassForName(attributeTransformerClassName, true, classLoader);
                }
            } catch (ClassNotFoundException exc){
                throw ValidationException.classNotFoundWhileConvertingClassNames(attributeTransformerClassName, exc);
            }

            this.setAttributeTransformerClass(attributeTransformerClass);
        }

        for (FieldTransformation transformation : getFieldTransformations()) {
            if (transformation instanceof TransformerBasedFieldTransformation) {
                TransformerBasedFieldTransformation transformer = (TransformerBasedFieldTransformation)transformation;
                String transformerClassName = transformer.getTransformerClassName();
                if (transformerClassName == null) {
                    return;
                }
                Class transformerClass = null;
                try {
                    if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                        try {
                            transformerClass = AccessController.doPrivileged(new PrivilegedClassForName(transformerClassName, true, classLoader));
                        } catch (PrivilegedActionException exception) {
                            throw ValidationException.classNotFoundWhileConvertingClassNames(transformerClassName, exception.getException());
                        }
                    } else {
                        transformerClass = PrivilegedAccessHelper.getClassForName(transformerClassName, true, classLoader);
                    }
                } catch (ClassNotFoundException exc){
                    throw ValidationException.classNotFoundWhileConvertingClassNames(transformerClassName, exc);
                }
                transformer.setTransformerClass(transformerClass);
            }
        }
    }

    /**
     * INTERNAL:
     * Builder the unit of work value holder.
     * Ignore the original object.
     * @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) {
        return cloningSession.createCloneTransformationValueHolder(attributeValue, original, clone, this);
    }

    /**
     * PUBLIC:
     * Indirection means that a ValueHolder will be put in-between the attribute and the real object.
     * This defaults to false and only required for transformations that perform database access.
     */
    public void dontUseIndirection() {
        setIndirectionPolicy(new NoIndirectionPolicy());
    }

    /**
     * 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 objectDescriptors, Map processedObjects, ObjectLevelReadQuery query, DistributedSession session) {
        this.indirectionPolicy.fixObjectReferences(object, objectDescriptors, processedObjects, query, session);
    }

    /**
     * INTERNAL:
     * The attributeTransformer stores an instance of the class which implements
     * AttributeTransformer.
     */
    public AttributeTransformer getAttributeTransformer() {
        return attributeTransformer;
    }

    /**
     * PUBLIC:
     * Return the attribute transformation method name.
     */
    public String getAttributeMethodName() {
        if (this.attributeTransformer instanceof MethodBasedAttributeTransformer) {
            return ((MethodBasedAttributeTransformer)this.attributeTransformer).getMethodName();
        }
        return null;
    }

    /**
     * INTERNAL:
     * Return the attribute transformer's class.
     * This is used to map to XML.
     */
    public Class getAttributeTransformerClass() {
        if ((this.attributeTransformer == null) || (this.attributeTransformer instanceof MethodBasedAttributeTransformer)) {
            return null;
        }
        return this.attributeTransformer.getClass();
    }

    /**
     * INTERNAL:
     * Set the attribute transformer's class.
     * This is used to map from XML.
     */
    public void setAttributeTransformerClass(Class attributeTransformerClass) {
        if (attributeTransformerClass == null) {
            return;
        }
        try {
            Object instance = null;
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                try {
                    instance = AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(attributeTransformerClass));
                } catch (PrivilegedActionException ex) {
                    throw (Exception)ex.getCause();
                }
            } else {
                instance = PrivilegedAccessHelper.newInstanceFromClass(attributeTransformerClass);
            }
            setAttributeTransformer((AttributeTransformer)instance);
        } catch (Exception exception) {
            throw DescriptorException.attributeTransformerClassInvalid(attributeTransformerClass.getName(), this, exception);
        }
    }

    /**
     * INTERNAL:
     * Return the attribute transformer class name
     */
    public String getAttributeTransformerClassName() {
        return attributeTransformerClassName;
    }

    /**
     * INTERNAL:
     * Check for write-only, one-way transformation.
     */
    @Override
    public Object getAttributeValueFromObject(Object object) throws DescriptorException {
        if (isWriteOnly()) {
            return null;
        }
        Object attributeValue = super.getAttributeValueFromObject(object);
        return this.indirectionPolicy.validateAttributeOfInstantiatedObject(attributeValue);
    }

    /**
     * INTERNAL:
     * Returns a Vector which stores fieldnames and the respective method/transformer names.
     */
    public List<FieldTransformation> getFieldTransformations() {
        return fieldTransformations;
    }

    /**
     * INTERNAL:
     * @return a vector which stores fields and their respective transformers.
     */
    public List<Object[]> getFieldToTransformers() {
        return fieldToTransformers;
    }

    /**
     * INTERNAL:
     * Return the mapping's indirection policy.
     */
    public IndirectionPolicy getIndirectionPolicy() {
        return indirectionPolicy;
    }

    /**
     * INTERNAL:
     * Returns the real attribute value from the reference object's attribute value.
     * If the attribute is using indirection the value of the value-holder is returned.
     * If the value holder is not instantiated then it is instantiated.
     */
    @Override
    public Object getRealAttributeValueFromAttribute(Object attributeValue, Object object, AbstractSession session) {
        return this.indirectionPolicy.getRealAttributeValueFromObject(object, attributeValue);
    }

    /**
     * INTERNAL:
     * Trigger the instantiation of the attribute if lazy.
     */
    @Override
    public void instantiateAttribute(Object object, AbstractSession session) {
        this.indirectionPolicy.instantiateObject(object, getAttributeValueFromObject(object));
    }

    /**
     * INTERNAL:
     * Extract and return the appropriate value from the
     * specified remote value holder.
     */
    @Override
    public Object getValueFromRemoteValueHolder(RemoteValueHolder remoteValueHolder) {
        return this.indirectionPolicy.getValueFromRemoteValueHolder(remoteValueHolder);
    }

    /**
     * INTERNAL:
     * The mapping is initialized with the given session.
     */
    @Override
    public void initialize(AbstractSession session) throws DescriptorException {
        super.initialize(session);
        initializeAttributeTransformer(session);
        initializeFieldToTransformers(session);
        setFields(collectFields());
        this.indirectionPolicy.initialize();
        if (usesIndirection()) {
            for (DatabaseField field : this.fields) {
                field.setKeepInRow(true);
            }
        }
    }

    /**
     * INTERNAL:
     * Convert the attribute transformer class name into an AttributeTransformer
    * If the old-style method name in set, then use a MethodBasedAttributeTRansformer
     */
    protected void initializeAttributeTransformer(AbstractSession databaseSession) throws DescriptorException {
        if (isWriteOnly()) {
            return;
        }
        this.attributeTransformer.initialize(this);
    }

    /**
     * INTERNAL:
     * Required for reverse compatibility and test cases:
     * @return a hash table containing the fieldName and their respective method names
     */
    public Hashtable getFieldNameToMethodNames() {
        Hashtable table = new Hashtable(getFieldTransformations().size());
        Iterator transformations = getFieldTransformations().iterator();
        while (transformations.hasNext()) {
            FieldTransformation transformation = (FieldTransformation)transformations.next();
            if (transformation instanceof MethodBasedFieldTransformation) {
                table.put(transformation.getField().getQualifiedName(), ((MethodBasedFieldTransformation)transformation).getMethodName());
            }
        }
        return table;
    }

    /**
     * INTERNAL:
     * Convert the field names and their corresponding method names to
     * DatabaseFields and Methods.
     */
    protected void initializeFieldToTransformers(AbstractSession session) throws DescriptorException {
        for (Object[] pair : this.fieldToTransformers) {
            pair[0] = getDescriptor().buildField(((DatabaseField)pair[0]));
            ((FieldTransformer)pair[1]).initialize(this);
        }
        for (FieldTransformation transformation : getFieldTransformations()) {
            DatabaseField field = getDescriptor().buildField(transformation.getField());
            String transformerClassName = "MethodBasedFieldTransformer";
            FieldTransformer transformer = null;
            try {
                transformer = transformation.buildTransformer();
            } catch (ConversionException ex) {
                if (transformation instanceof TransformerBasedFieldTransformation) {
                    transformerClassName = ((TransformerBasedFieldTransformation)transformation).getTransformerClassName();
                }

                throw DescriptorException.fieldTransformerClassNotFound(transformerClassName, this, ex);
            } catch (Exception ex) {
                if (transformation instanceof TransformerBasedFieldTransformation) {
                    transformerClassName = ((TransformerBasedFieldTransformation)transformation).getTransformerClassName();
                }

                throw DescriptorException.fieldTransformerClassInvalid(transformerClassName, this, ex);
            }

            transformer.initialize(this);
            // Attempt to ensure a type is set on the field.
            if (field.getType() == null) {
                if (transformer instanceof MethodBasedFieldTransformer) {
                    field.setType(((MethodBasedFieldTransformer)transformer).getFieldType());
                } else if (field.getColumnDefinition() != null) {
                    // Search for the type for this field definition.
                    if (session.getDatasourcePlatform() instanceof DatabasePlatform) {
                        Iterator iterator = session.getPlatform().getFieldTypes().entrySet().iterator();
                        while (iterator.hasNext()) {
                            Map.Entry entry = (Map.Entry)iterator.next();
                            if (((FieldTypeDefinition)entry.getValue()).getName().equals(field.getColumnDefinition())) {
                                field.setType((Class)entry.getKey());
                                break;
                            }
                        }
                    }
                }
            }
            Object[] fieldToTransformer = new Object[2];
            fieldToTransformer[0] = field;
            fieldToTransformer[1] = transformer;

            this.fieldToTransformers.add(fieldToTransformer);
        }
    }

    /**
     * INTERNAL:
     * Invoke the buildAttributeValue method on the AttributeTransformer
     */
    public Object invokeAttributeTransformer(AbstractRecord record, Object domainObject, AbstractSession session) throws DescriptorException {
        return this.attributeTransformer.buildAttributeValue(record, domainObject, session);
    }

    /**
     * INTERNAL:
    * Invoke the buildFieldValue on the appropriate FieldTransformer
    */
    protected Object invokeFieldTransformer(DatabaseField field, FieldTransformer transformer, Object domainObject, AbstractSession session) throws DescriptorException {
        return transformer.buildFieldValue(domainObject, field.getName(), session);
    }

    protected Object invokeFieldTransformer(DatabaseField field, Object domainObject, AbstractSession session) {
        for (Object[] pair : this.fieldToTransformers) {
            if (field.equals(pair[0])) {
                return invokeFieldTransformer(field, (FieldTransformer)pair[1], domainObject, session);
            }
        }
        return null;
    }

    /**
     * PUBLIC:
     * Return true if the attribute for this mapping is not a simple atomic value that cannot be modified,
     * only replaced.
     * This is true by default for non-primitives, but can be set to false to avoid cloning
     * and change comparison in the unit of work.
     */
    public boolean isMutable() {
        return isMutable;
    }

    /**
     * INTERNAL:
     * Return true if read-only is explicitly set to true;
     * otherwise return whether the transformation has no fields
     * (no fields = read-only)
     */
    @Override
    public boolean isReadOnly() {
        if (super.isReadOnly()) {
            return true;
        } else {
            return getFieldTransformations().isEmpty() && this.fieldToTransformers.isEmpty();
        }
    }

    /**
     * INTERNAL:
     */
    @Override
    public boolean isTransformationMapping() {
        return true;
    }

    /**
     * INTERNAL:
     * Return if the transformation has no attribute, is write only.
     */
    @Override
    public boolean isWriteOnly() {
        return (getAttributeName() == null) && ((this.attributeTransformer == null) && (this.attributeTransformerClassName == null));
    }

    /**
     * INTERNAL:
     * Perform the iteration opperation on the iterators current objects attributes.
     * Only require if primitives are desired.
     */
    @Override
    public void iterate(DescriptorIterator iterator) {
        Object attributeValue = getAttributeValueFromObject(iterator.getVisitedParent());
        this.indirectionPolicy.iterateOnAttributeValue(iterator, attributeValue);
    }

    /**
     * INTERNAL:
     * Iterate on the attribute value.
     * The value holder has already been processed.
     */
    @Override
    public void iterateOnRealAttributeValue(DescriptorIterator iterator, Object realAttributeValue) {
        iterator.iteratePrimitiveForMapping(realAttributeValue, this);
    }

    /**
     * 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 (isWriteOnly()) {
            return;
        }
        // PERF: If not mutable then just set the value from the source.
        if (!isMutable() && (source != null)) {
            setRealAttributeValueInObject(target, getRealAttributeValueFromObject(source, mergeManager.getSession()));
            return;
        }
        AbstractRecord record = (AbstractRecord)((TransformationMappingChangeRecord)changeRecord).getRecord();
        Object attributeValue = invokeAttributeTransformer(record, target, targetSession);
        setRealAttributeValueInObject(target, attributeValue);
    }

    /**
     * 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 (isWriteOnly()) {
            return;
        }

        // do refresh check first as I may need to reset remote value holder
        if (mergeManager.shouldRefreshRemoteObject() && usesIndirection()) {
            this.indirectionPolicy.mergeRemoteValueHolder(target, source, mergeManager);
            return;
        }

        if (mergeManager.isForRefresh()) {
            if (!areObjectsToBeProcessedInstantiated(target)) {
                // This will occur when the clone's value has not been instantiated yet and we do not need
                // the refresh that attribute
                return;
            }
        } else if (!areObjectsToBeProcessedInstantiated(source)) {
            // I am merging from a clone into an original.  No need to do merge if the attribute was never
            // modified
            return;
        }

        if (isTargetUnInitialized) {
            // This will happen if the target object was removed from the cache before the commit was attempted
            if (mergeManager.shouldMergeWorkingCopyIntoOriginal() && (!areObjectsToBeProcessedInstantiated(source))) {
                setAttributeValueInObject(target, this.indirectionPolicy.getOriginalIndirectionObject(getAttributeValueFromObject(source), targetSession));
                return;
            }
        }
        if (isReadOnly()) {
            // if it is read only then we do not have any fields specified for the
            // transformer, without fields we can not build the row, so just copy
            // over the value  alternatively we could build the entire row for the object.
            setRealAttributeValueInObject(target, getRealAttributeValueFromObject(source, mergeManager.getSession()));
            return;
        }
        if (!isMutable()) {
            Object attribute = getRealAttributeValueFromObject(source, mergeManager.getSession());
            if (this.descriptor.getObjectChangePolicy().isObjectChangeTrackingPolicy()) {
                // Object level or attribute level so lets see if we need to raise the event?
                Object targetAttribute = getRealAttributeValueFromObject(target, mergeManager.getSession());
                if ((mergeManager.shouldMergeCloneIntoWorkingCopy() || mergeManager.shouldMergeCloneWithReferencesIntoWorkingCopy())  && !mergeManager.isForRefresh()
                        && (((targetAttribute == null) && (attribute != null)) || ((targetAttribute != null) && ((attribute == null) || ((!targetAttribute.equals(attribute)) && (!Helper.comparePotentialArrays(targetAttribute, attribute))))))) {
                    this.descriptor.getObjectChangePolicy().raiseInternalPropertyChangeEvent(target, getAttributeName(), targetAttribute, attribute);
                }
            }
            setRealAttributeValueInObject(target, attribute);
            return;
        }

        // This dumps the attribute into the row and back.
        AbstractRecord row = buildPhantomRowFrom(source, mergeManager.getSession());
        Object attributeValue = invokeAttributeTransformer(row, source, mergeManager.getSession());
        AbstractRecord targetRow = buildPhantomRowFrom(target, mergeManager.getSession());
        setRealAttributeValueInObject(target, attributeValue);
        //set the change after the set on the object as this mapping uses the object to build the change record.
        if (this.descriptor.getObjectChangePolicy().isObjectChangeTrackingPolicy()) {
            for (Enumeration keys = targetRow.keys(); keys.hasMoreElements(); ){
                Object field = keys.nextElement();
                if ((mergeManager.shouldMergeCloneIntoWorkingCopy() || mergeManager.shouldMergeCloneWithReferencesIntoWorkingCopy())
                        && (!row.get(field).equals(targetRow.get(field)))) {
                    this.descriptor.getObjectChangePolicy().raiseInternalPropertyChangeEvent(target, getAttributeName(), invokeAttributeTransformer(targetRow, source, mergeManager.getSession()), attributeValue);
                    break;
                }
            }
        }
    }

    /**
     * INTERNAL:
     * Allow for initialization of properties and validation.
     */
    @Override
    public void preInitialize(AbstractSession session) throws DescriptorException {
        if (isWriteOnly()) {
            return;// Allow for one-way transformations.
        }

        super.preInitialize(session);

        // PERF: Also auto-set mutable to false is the attribute type is a primitive.
        // This means it is not necessary to clone the value (through double transformation).
        if ((getAttributeClassification() != null) && (getAttributeClassification().isPrimitive() || Helper.isPrimitiveWrapper(getAttributeClassification()) || getAttributeClassification().equals(ClassConstants.STRING) || getAttributeClassification().equals(ClassConstants.BIGDECIMAL) || getAttributeClassification().equals(ClassConstants.NUMBER))) {
            setIsMutable(false);
        }
    }

    /**
     * INTERNAL:
     * Extracts value from return row and set the attribute to the value in the object.
     * Return row is merged into object after execution of insert or update call
     * according to ReturningPolicy.
     */
    public Object readFromReturnRowIntoObject(AbstractRecord row, Object object, ReadObjectQuery query, Collection handledMappings, ObjectChangeSet changeSet) throws DatabaseException {
        int size = this.fields.size();
        AbstractRecord transformationRow = new DatabaseRecord(size);
        for (int i = 0; i < size; i++) {
            DatabaseField field = this.fields.get(i);
            Object value;
            if (row.containsKey(field)) {
                value = row.get(field);
            } else {
                value = valueFromObject(object, field, query.getSession());
            }
            transformationRow.add(field, value);
        }

        if(changeSet != null && (!changeSet.isNew() || (query.getDescriptor() != null && query.getDescriptor().shouldUseFullChangeSetsForNewObjects()))) {
            TransformationMappingChangeRecord record = (TransformationMappingChangeRecord)changeSet.getChangesForAttributeNamed(attributeName);
            if (record == null) {
                record = new TransformationMappingChangeRecord(changeSet);
                record.setAttribute(attributeName);
                record.setMapping(this);
                record.setOldValue(getAttributeValueFromObject(object));
                changeSet.addChange(record);
            }
            record.setRow(transformationRow);
        }

        Object attributeValue = readFromRowIntoObject(transformationRow, null, object, null, query, query.getSession(), true);
        if (handledMappings != null) {
            handledMappings.add(this);
        }

        return attributeValue;
    }

    /**
     * INTERNAL:
     * Extract value from the row and set the attribute to the value in the object.
     */
    @Override
    public Object readFromRowIntoObject(AbstractRecord row, JoinedAttributeManager joinManager, Object object, CacheKey parentCacheKey, ObjectBuildingQuery query, AbstractSession executionSession, boolean isTargetProtected) throws DatabaseException {
        if (isWriteOnly()) {
            return null;
        }
        if (this.descriptor.getCachePolicy().isProtectedIsolation()) {
            if (this.isCacheable && isTargetProtected && parentCacheKey != null) {
                Object cached = parentCacheKey.getObject();
                if (cached != null) {
                    Object attributeValue =  getAttributeValueFromObject(cached);
                    Integer refreshCascade = null;
                    if (query != null && query.shouldRefreshIdentityMapResult()){
                        refreshCascade = query.getCascadePolicy();
                    }
                    return this.indirectionPolicy.cloneAttribute(attributeValue, cached, parentCacheKey, object, refreshCascade, executionSession, false);
                }
                return null;
            }
        }
        if (row != null && row.hasSopObject()) {
            return getAttributeValueFromObject(row.getSopObject());
        }
        Object attributeValue = this.indirectionPolicy.valueFromMethod(object, row, query.getSession());
        Object oldAttribute = null;
        if (executionSession.isUnitOfWork() && query.shouldRefreshIdentityMapResult()){
            oldAttribute = this.getAttributeValueFromObject(object);
        }
        try {
            this.attributeAccessor.setAttributeValueInObject(object, attributeValue);
        } catch (DescriptorException exception) {
            exception.setMapping(this);
            throw exception;
        }
        if (executionSession.isUnitOfWork() && query.shouldRefreshIdentityMapResult()){
            if (this.indirectionPolicy.objectIsInstantiatedOrChanged(oldAttribute)){
                this.indirectionPolicy.instantiateObject(object, attributeValue);
            }
        }
        return attributeValue;
    }

    /**
     * INTERNAL:
     * Needed for backwards compatibility
     */
    public Vector getFieldNameToMethodNameAssociations() {
        Vector associations = new Vector();
        for (Iterator source = getFieldTransformations().iterator(); source.hasNext();) {
            FieldTransformation tf = (FieldTransformation)source.next();
            if (tf instanceof MethodBasedFieldTransformation) {
                Association ass = new Association();
                ass.setKey(tf.getField().getQualifiedName());
                ass.setValue(((MethodBasedFieldTransformation)tf).getMethodName());
                associations.addElement(ass);
            }
        }
        return associations;
    }

    /**
     * INTERNAL:
     * needed for backwards compatibility
     */
    public void setFieldNameToMethodNameAssociations(Vector associations) {
        setFieldTransformations(org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(associations.size()));
        for (Iterator source = associations.iterator(); source.hasNext();) {
            Association ass = (Association)source.next();
            MethodBasedFieldTransformation tf = new MethodBasedFieldTransformation();
            tf.setField(new DatabaseField((String)ass.getKey()));
            tf.setMethodName((String)ass.getValue());
            getFieldTransformations().add(tf);
        }
    }

    /**
     * INTERNAL:
     * Once descriptors are serialized to the remote session. All its mappings and reference descriptors are traversed. Usually
     * mappings are initialized and serialized reference descriptors are replaced with local descriptors if they already exist on the
     * remote session.
     */
    @Override
    public void remoteInitialization(DistributedSession session) {
        setFieldToTransformers(new Vector());

        // Remote mappings is initialized here again because while serializing only the uninitialized data is passed
        // as the initialized data is not serializable.
        if (!isWriteOnly()) {
            super.remoteInitialization(session);
            initializeAttributeTransformer(session);
        }
        initializeFieldToTransformers(session);
    }

    /**
      * PUBLIC:
      * Set the AttributeTransformer, this transformer will be used to extract the value for the
      * object's attribute from the database row.
      */
    public void setAttributeTransformer(AttributeTransformer transformer) {
        attributeTransformer = transformer;
        if ((transformer != null) && !(transformer instanceof MethodBasedAttributeTransformer)) {
            attributeTransformerClassName = transformer.getClass().getName();
        }
    }

    /**
     * INTERNAL:
     * Set the Attribute Transformer Class Name
     * @param className
     */
    public void setAttributeTransformerClassName(String className) {
        attributeTransformerClassName = className;
    }


    /**
     * PUBLIC:
     * To set the attribute method name. The method is invoked internally by TopLink
     * to retrieve the value to store in the domain object. The method receives Record
     * as its parameter and optionally Session, and should extract the value from the
     * record to set into the object, but should not set the value on the object, only return it.
     */
    public void setAttributeTransformation(String methodName) {
        if ((methodName != null) && (!methodName.isEmpty())) {
            setAttributeTransformer(new MethodBasedAttributeTransformer(methodName));
        } else {
            setAttributeTransformer(null);
        }
    }

    /**
     * INTERNAL:
     * Check for write-only, one-way transformations.
     */
    @Override
    public void setAttributeValueInObject(Object object, Object value) {
        if (isWriteOnly()) {
            return;
        }

        super.setAttributeValueInObject(object, value);
    }

    /**
     * PUBLIC:
     * Set if the value of the attribute is atomic or a complex mutable object and can be modified without replacing the entire object.
     * This defaults to true for non-primitives, but can be set to false to optimize object cloning and change comparison.
     */
    public void setIsMutable(boolean mutable) {
        this.isMutable = mutable;
    }

    /**
     * INTERNAL:
     * Set the value of the attribute mapped by this mapping,
     * placing it inside a value holder if necessary.
     * If the value holder is not instantiated then it is instantiated.
     * Check for write-only, one-way transformations.
     */
    @Override
    public void setRealAttributeValueInObject(Object object, Object value) throws DescriptorException {
        if (isWriteOnly()) {
            return;
        }
        this.indirectionPolicy.setRealAttributeValueInObject(object, value);
    }

    /**
     * INTERNAL:
     * Set the field to method name associations.
     */
    public void setFieldTransformations(List<FieldTransformation> fieldTransformations) {
        this.fieldTransformations = fieldTransformations;
    }

    protected void setFieldToTransformers(List<Object[]> fieldToTransformers) {
        this.fieldToTransformers = fieldToTransformers;
    }

    /**
     * ADVANCED:
     * Set the indirection policy.
     */
    public void setIndirectionPolicy(IndirectionPolicy indirectionPolicy) {
        this.indirectionPolicy = indirectionPolicy;
        indirectionPolicy.setMapping(this);
    }

    /**
     * INTERNAL:
     * Will be used by Gromit. For details see usesIndirection().
     * @see #useBasicIndirection()
     * @see #dontUseIndirection()
     */
    public void setUsesIndirection(boolean usesIndirection) {
        if (usesIndirection) {
            useBasicIndirection();
        } else {
            dontUseIndirection();
        }
    }

    /**
     * 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) {
        TransformationMappingChangeRecord changeRecord = (TransformationMappingChangeRecord)objectChangeSet.getChangesForAttributeNamed(this.getAttributeName());
        Object updatedObject = descriptor.getInstantiationPolicy().buildNewInstance();
        this.setAttributeValueInObject(updatedObject, newValue);
        if (!isWriteOnly()) {
            if (changeRecord == null) {
                objectChangeSet.addChange(internalBuildChangeRecord(updatedObject, oldValue, objectChangeSet, uow));
            } else {
                changeRecord.setRow(this.buildPhantomRowFrom(updatedObject, uow));
            }
        }
    }

    /**
     * INTERNAL:
     * Return if this mapping supports change tracking.
     */
    @Override
    public boolean isChangeTrackingSupported(Project project) {
        return ! isMutable();
    }

    /**
     * INTERNAL:
     * Return whether the specified object is instantiated.
     */
    @Override
    public boolean isAttributeValueFromObjectInstantiated(Object object) {
        return this.indirectionPolicy.objectIsInstantiated(object);
    }

    /**
     * PUBLIC:
     * Indirection means that a ValueHolder will be put in-between the attribute and the real object.
     * This defaults to false and only required for transformations that perform database access.
     */
    public void useBasicIndirection() {
        setIndirectionPolicy(new BasicIndirectionPolicy());
    }

    /**
     * PUBLIC:
     * Indirection means that a IndirectContainer (wrapping a ValueHolder) will be put in-between
     * the attribute and the real object.
     * This allows for the reading of the target from the database to be delayed until accessed.
     * This defaults to true and is strongly suggested as it give a huge performance gain.
     */
    public void useContainerIndirection(Class containerClass) {
        ContainerIndirectionPolicy policy = new ContainerIndirectionPolicy();
        policy.setContainerClass(containerClass);
        setIndirectionPolicy(policy);
    }

    /**
     * PUBLIC:
     * Indirection means that a ValueHolder will be put in-between the attribute and the real object.
     * This defaults to false and only required for transformations that perform database access.
     * @see #useBasicIndirection()
     */
    public void useIndirection() {
        useBasicIndirection();
    }

    /**
     * PUBLIC:
     * Indirection means that a ValueHolder will be put in-between the attribute and the real object.
     * This defaults to false and only required for transformations that perform database access.
     * @see org.eclipse.persistence.internal.indirection.IndirectionPolicy
     */
    public boolean usesIndirection() {
        return this.indirectionPolicy.usesIndirection();
    }

    /**
     * INTERNAL:
     * Validate mapping declaration
     */
    @Override
    public void validateBeforeInitialization(AbstractSession session) throws DescriptorException {
        super.validateBeforeInitialization(session);

        if (isWriteOnly()) {
            return;
        }

        if ((this.attributeTransformer == null) && (this.attributeTransformerClassName == null)) {
            session.getIntegrityChecker().handleError(DescriptorException.noAttributeTransformationMethod(this));
        }

        if (getAttributeAccessor() instanceof InstanceVariableAttributeAccessor) {
            Class attributeType = ((InstanceVariableAttributeAccessor)getAttributeAccessor()).getAttributeType();
            this.indirectionPolicy.validateDeclaredAttributeType(attributeType, session.getIntegrityChecker());
        } else if (getAttributeAccessor().isMethodAttributeAccessor()) {
            // 323403
            Class returnType = ((MethodAttributeAccessor)getAttributeAccessor()).getGetMethodReturnType();
            this.indirectionPolicy.validateGetMethodReturnType(returnType, session.getIntegrityChecker());

            Class parameterType = ((MethodAttributeAccessor)getAttributeAccessor()).getSetMethodParameterType();
            this.indirectionPolicy.validateSetMethodParameterType(parameterType, session.getIntegrityChecker());
        }
    }

    /**
     * INTERNAL:
     * Get a value from the object and set that in the respective field of the row.
     */
    @Override
    public Object valueFromObject(Object object, DatabaseField field, AbstractSession session) {
        return invokeFieldTransformer(field, object, session);
    }

    /**
     * INTERNAL:
     * Get a value from the object and set that in the respective field of the row.
     */
    @Override
    public void writeFromObjectIntoRow(Object object, AbstractRecord row, AbstractSession session, WriteType writeType) {
        if (isReadOnly()) {
            return;
        }

        for (Object[] pair : this.fieldToTransformers) {
            DatabaseField field = (DatabaseField)pair[0];
            FieldTransformer transformer = (FieldTransformer)pair[1];
            Object fieldValue = invokeFieldTransformer(field, transformer, object, session);
            row.put(field, fieldValue);
        }
    }

    /**
     * INTERNAL:
     * Get a value from the object and set that in the respective field of the row.
     */
    @Override
    public void writeFromObjectIntoRowWithChangeRecord(ChangeRecord changeRecord, AbstractRecord row, AbstractSession session, WriteType writeType) {
        if (isReadOnly()) {
            return;
        }

        for (Object[] pair : this.fieldToTransformers) {
            DatabaseField field = (DatabaseField)pair[0];
            Object fieldValue = ((TransformationMappingChangeRecord)changeRecord).getRecord().get(field);
            row.put(field, fieldValue);
        }
    }

    /**
     * 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 record) {
        if (!areObjectsToBeProcessedInstantiated(query.getObject())) {
            return;
        }

        if (query.getSession().isUnitOfWork()) {
            if (compareObjects(query.getBackupClone(), query.getObject(), query.getSession())) {
                return;
            }
        }

        writeFromObjectIntoRow(query.getObject(), record, query.getSession(), WriteType.UPDATE);
    }

    /**
     * INTERNAL:
     * Write fields needed for insert into the template for with null values.
     */
    @Override
    public void writeInsertFieldsIntoRow(AbstractRecord record, AbstractSession session) {
        if (isReadOnly()) {
            return;
        }

        for (Object[] pair : this.fieldToTransformers) {
            DatabaseField field = (DatabaseField)pair[0];
            record.put(field, null);
        }
    }
}
