/*
 * Copyright (c) 1998, 2020 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
//     11/13/2009-2.0  mobrien - 294765: MapKey keyType DirectToField processing
//       should return attributeClassification class in getMapKeyTargetType when
//       accessor.attributeField is null in the absence of a MapKey annotation
//     11/10/2011-2.4 Guy Pelletier
//       - 357474: Address primaryKey option from tenant discriminator column
//     30/05/2012-2.4 Guy Pelletier
//       - 354678: Temp classloader is still being used during metadata processing
//     06/03/2013-2.5.1 Guy Pelletier
//       - 402380: 3 jpa21/advanced tests failed on server with
//         "java.lang.NoClassDefFoundError: org/eclipse/persistence/testing/models/jpa21/advanced/enums/Gender"
package org.eclipse.persistence.mappings.foundation;

import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.*;

import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.descriptors.DescriptorIterator;
import org.eclipse.persistence.internal.helper.DatabaseField;
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.UnitOfWorkImpl;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.remote.DistributedSession;

/**
 * <b>Purpose</b>: Maps an attribute or some other property to the corresponding
 * database field type. The list of field types that are supported by
 * EclipseLink's direct to field mapping is dependent on the relational database
 * being used.
 *
 * @see org.eclipse.persistence.mappings.foundation.AbstractDirectMapping
 * @see org.eclipse.persistence.mappings.MultitenantPrimaryKeyMapping
 *
 * @author Guy Pelletier
 * @since TopLink/Java 1.0
 */
public abstract class AbstractColumnMapping extends DatabaseMapping {

    /** DatabaseField which this mapping represents. */
    protected DatabaseField field;

    /** Allows user defined conversion between the object attribute value and the database value. */
    protected Converter converter;
    protected String converterClassName;

    /** Flag to support insertable JPA setting */
    protected boolean isInsertable = true;

    /** Flag to support updatable JPA setting */
    protected boolean isUpdatable = true;

    /**
     * Default constructor.
     */
    public AbstractColumnMapping() {
        super();
        this.setWeight(WEIGHT_DIRECT);
    }

    /**
     * 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 by this mapping 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() {
        AbstractColumnMapping clone = (AbstractColumnMapping)super.clone();

        // Field must be cloned so aggregates do not share fields.
        clone.setField(getField().clone());

        return clone;
    }

    /**
     * Returns the field this mapping represents.
     */
    @Override
    protected Vector<DatabaseField> collectFields() {
        Vector databaseField = new Vector(1);

        databaseField.addElement(field);
        return databaseField;
    }

    /**
     * INTERNAL:
     * Convert all the class-name-based settings in this mapping to actual class-based settings
     * This method is implemented by subclasses as necessary.
     */
    @Override
    public void convertClassNamesToClasses(ClassLoader classLoader){
        super.convertClassNamesToClasses(classLoader);

        // Field may have a type name that needs to be initialize.
        if (field != null) {
            field.convertClassNamesToClasses(classLoader);
        }

        // Convert and any Converter class names.
        convertConverterClassNamesToClasses(converter, classLoader);

        // Instantiate any custom converter class
        if (converterClassName != null) {
            Class converterClass;
            Converter converter;

            try {
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    try {
                        converterClass = AccessController.doPrivileged(new PrivilegedClassForName(converterClassName, true, classLoader));
                    } catch (PrivilegedActionException exception) {
                        throw ValidationException.classNotFoundWhileConvertingClassNames(converterClassName, exception.getException());
                    }

                    try {
                        converter = (Converter)AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(converterClass));
                    } catch (PrivilegedActionException exception) {
                        throw ValidationException.classNotFoundWhileConvertingClassNames(converterClassName, exception.getException());
                    }
                } else {
                    converterClass = PrivilegedAccessHelper.getClassForName(converterClassName, true, classLoader);
                    converter = (Converter)PrivilegedAccessHelper.newInstanceFromClass(converterClass);
                }
            } catch (ClassNotFoundException exc) {
                throw ValidationException.classNotFoundWhileConvertingClassNames(converterClassName, exc);
            } catch (Exception e) {
                // Catches IllegalAccessException and InstantiationException
                throw ValidationException.classNotFoundWhileConvertingClassNames(converterClassName, e);
            }

            setConverter(converter);
        }
    }

    /**
     * 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) {
    }

    /**
     * PUBLIC:
     * Return the converter on the mapping.
     * A converter can be used to convert between the object's value and database value of the attribute.
     */
    public Converter getConverter() {
        return converter;
    }

    /**
     * INTERNAL:
     * Returns the field which this mapping represents.
     */
    @Override
    public DatabaseField getField() {
        return field;
    }

    /**
     * INTERNAL:
     * Convert the object (attribute or property) value to a field value.
     */
    public abstract Object getFieldValue(Object objectValue, AbstractSession session);

    /**
     * INTERNAL:
     * Allows for subclasses to convert the the attribute or property value.
     */
    public abstract Object getObjectValue(Object fieldValue, Session session);

    /**
     * Indicates if the mapping has a converter set on it.
     *
     * @return true if there is a converter set on the mapping,
     * false otherwise.
     */
    public boolean hasConverter() {
        return converter != null;
    }

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

    /**
     * INTERNAL:
     * Return true if this mapping is insertable.
     */
    protected boolean isInsertable() {
        return isInsertable;
    }

    /**
     * INTERNAL:
     * Return true if this mapping is updatable.
     */
    protected boolean isUpdatable() {
        return isUpdatable;
    }

    /**
     * INTERNAL:
     * Iterate on the appropriate attribute.
     */
    @Override
    public void iterate(DescriptorIterator iterator) {
        // PERF: Only iterate when required.
        if (iterator.shouldIterateOnPrimitives()) {
            iterator.iteratePrimitiveForMapping(getAttributeValueFromObject(iterator.getVisitedParent()), this);
        }
    }

    /**
     * PUBLIC:
     * Set the converter on the mapping.
     * A converter can be used to convert between the object's value and database value of the attribute.
     */
    public void setConverter(Converter converter) {
        this.converter = converter;
    }

    /**
     * PUBLIC:
     * Set the converter class name on the mapping. It will be instantiated
     * during the convertClassNamesToClasses.
     * A converter can be used to convert between the object's value and
     * database value of the attribute.
     */
    public void setConverterClassName(String converterClassName) {
        this.converterClassName = converterClassName;
    }

    /**
     * ADVANCED:
     * Set the field in the mapping.
     * This can be used for advanced field types, such as XML nodes, or to set the field type.
     */
    public void setField(DatabaseField theField) {
        field = theField;
    }

    /**
     * INTERNAL:
     */
    @Override
    public String toString() {
        return getClass().getName() + "[" + getAttributeName() + "-->" + getField() + "]";
    }

    /**
     * INTERNAL:
     */
    protected abstract void writeValueIntoRow(AbstractRecord row, DatabaseField field, Object value);
}
