/*
 * 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.lang.reflect.InvocationTargetException;

import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.transformers.AttributeTransformer;

/**
 *  @version $Header: TransformerBasedValueHolder.java 30-aug-2006.11:32:36 gyorke Exp $
 *  @author  mmacivor
 *  @since   release specific (what release of product did this appear in)
 *  This class is to replace the MethodBasedValueHolder for TransformationMappings
 *  Holds on to an AttributeTransformer and uses it to generate the attribute value when triggered.
 *  That Transformer may be a MethodBasedAttributeTransformer or a user defined implementation.
 *
 */
public class TransformerBasedValueHolder<T> extends DatabaseValueHolder<T> {

    /**
     * Stores the method to be executed. The method can take
     * one (the row) or two parameters (the row and session).
     */
    protected transient AttributeTransformer transformer;

    /**
     * Stores the object which owns this attribute.
     */
    protected transient Object object;

    /**
     * Initialize the method-based value holder.
     * @param theTransformer The method that returns the object when executed.
     * @param theObject the Object which owns this attribute.
     * @param theRow The row representation of the object.
     * @param theSession The session to the database that stores the object.
     */
    public TransformerBasedValueHolder(AttributeTransformer theTransformer, Object theObject, AbstractRecord theRow, AbstractSession theSession) {
        super();
        row = theRow;
        session = theSession;

        // Make sure not to put a ClientSession or IsolatedClientSession in
        // the shared cache (indirectly).
        // Skip this if unitOfWork, for we use session.isUnitOfWork() to implement
        // isTransactionalValueholder(), saving us from needing a boolean instance variable.
        // If unitOfWork this safety measure is deferred until merge time with
        // releaseWrappedValuehHolder.
        // Note that if isolated session & query will return itself, which is safe
        // for if isolated this valueholder is not in the shared cache.
        if (!session.isUnitOfWork()) {
            this.session = session.getRootSession(null);
        }
        transformer = theTransformer;
        object = theObject;
    }

    /**
     * Return the method.
     */
    protected AttributeTransformer getTransformer() {
        return transformer;
    }

    /**
    * Return the receiver.
    */
    protected Object getObject() {
        return object;
    }

    /**
     * Instantiate the object by executing the method on the transformer.
     */
    @Override
    protected T instantiate() throws DescriptorException {
        return instantiate(getObject(), getSession());
    }

    @SuppressWarnings({"unchecked"})
    protected T instantiate(Object object, AbstractSession session) throws DescriptorException {
        try {
            return (T) transformer.buildAttributeValue(getRow(), object, session);
        } catch (DescriptorException ex) {
            Throwable nestedException = ex.getInternalException();
            if (nestedException instanceof IllegalAccessException) {
                throw DescriptorException.illegalAccessWhileInstantiatingMethodBasedProxy(nestedException);
            } else if (nestedException instanceof IllegalArgumentException) {
                throw DescriptorException.illegalArgumentWhileInstantiatingMethodBasedProxy(nestedException);
            } else if (nestedException instanceof InvocationTargetException) {
                throw DescriptorException.targetInvocationWhileInstantiatingMethodBasedProxy(nestedException);
            } else {
                throw ex;
            }
        }
    }

    /**
     * Triggers UnitOfWork valueholders directly without triggering the wrapped
     * valueholder (this).
     * <p>
     * When in transaction and/or for pessimistic locking the UnitOfWorkValueHolder
     * needs to be triggered directly without triggering the wrapped valueholder.
     * However only the wrapped valueholder knows how to trigger the indirection,
     * i.e. it may be a batchValueHolder, and it stores all the info like the row
     * and the query.
     * Note: This method is not thread-safe.  It must be used in a synchronized manner
     */
    @Override
    public T instantiateForUnitOfWorkValueHolder(UnitOfWorkValueHolder<T> unitOfWorkValueHolder) {
        return instantiate(getObject(), unitOfWorkValueHolder.getUnitOfWork());
    }

    /**
     * INTERNAL:
     * Answers if this valueholder is a pessimistic locking one.  Such valueholders
     * are special in that they can be triggered multiple times by different
     * UnitsOfWork.  Each time a lock query will be issued.  Hence even if
     * instantiated it may have to be instantiated again, and once instantiated
     * all fields can not be reset.
     * Note: This method is not thread-safe.  It must be used in a synchronized manner
     */
    @Override
    public boolean isPessimisticLockingValueHolder() {
        // there is no way to tell, as a transformation mapping may have
        // a reference class or query to check, but by design there is no
        // way we can access at it.
        return false;
    }

    /**
     * Set the transformer.
     */
    protected void setTransformer(AttributeTransformer theTransformer) {
        transformer = theTransformer;
    }

    /**
     * Set the receiver.
     */
    protected void setObject(Object theObject) {
        object = theObject;
    }
}
