All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.persistence.internal.indirection.TransformerBasedValueHolder Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * 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 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 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).
     * 

* 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 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; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy