/*
 * Copyright (c) 1998, 2019 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 extends DatabaseValueHolder {

    /**
     * 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 Object instantiate() throws DescriptorException {
        return instantiate(getObject(), getSession());
    }

    protected Object instantiate(Object object, AbstractSession session) throws DescriptorException {
        try {
            return 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 Object instantiateForUnitOfWorkValueHolder(UnitOfWorkValueHolder 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;
    }
}
