Package org.drools.persistence.marshalling.util

Source Code of org.drools.persistence.marshalling.util.UserTransactionProxy

package org.drools.persistence.marshalling.util;

import static org.drools.persistence.marshalling.util.EntityManagerFactoryProxy.getAllInterfaces;
import static org.drools.persistence.marshalling.util.EntityManagerFactoryProxy.updateManagedObjects;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Iterator;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.transaction.Status;
import javax.transaction.Synchronization;
import javax.transaction.UserTransaction;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import bitronix.tm.BitronixTransaction;
import bitronix.tm.BitronixTransactionManager;

public class UserTransactionProxy implements InvocationHandler {

    private static Logger logger = LoggerFactory.getLogger(UserTransactionProxy.class);
   
    private UserTransaction ut;
    private EntityManagerFactory emf;
   
    /**
     * This method creates a proxy for either a {@link EntityManagerFactory} or a {@link EntityManager} instance.
     * @param obj The original instance for which a proxy will be made.
     * @return Object a proxy instance of the given object.
     */
    public static Object newInstance( EntityManagerFactory emf) {
        UserTransaction ut = findUserTransaction();
        return Proxy.newProxyInstance(
                ut.getClass().getClassLoader(),
                getAllInterfaces(ut),
                new UserTransactionProxy(ut, emf));
    }
   
    public static final String DEFAULT_USER_TRANSACTION_NAME = "java:comp/UserTransaction";
   
    private static UserTransaction findUserTransaction() {
        try {
            InitialContext context = new InitialContext();
            return (UserTransaction) context.lookup( DEFAULT_USER_TRANSACTION_NAME );
        } catch ( NamingException ex ) {
            logger.debug( "No UserTransaction found at JNDI location [{}]",
                          DEFAULT_USER_TRANSACTION_NAME,
                          ex );
            return null;
        }
    }
   
    /**
     * This is the constructor that follows the InvocationHandler design pattern, so to speak. <br/>
     * It saves the @{link {@link EntityManager} or {@link EntityManagerFactory} for use later.
     * @param obj The object being proxied.
     */
    private UserTransactionProxy(UserTransaction ut, EntityManagerFactory emf ) {
        this.ut = ut;
        this.emf = emf;
    }
   
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        String methodName = method.getName();

        logger.trace(methodName);
        if( "commit".equals(methodName) && args == null) {
            BitronixTransaction bt = ((BitronixTransactionManager) ut).getCurrentTransaction();
            // Ensure that all actions have occurred so that we get what is _really_ commited to the db
            // (This code is straight from bitronix)
            Iterator<?> iter = bt.getSynchronizationScheduler().reverseIterator();
            while (iter.hasNext()) {
                Synchronization synchronization = (Synchronization) iter.next();
                try {
                    synchronization.beforeCompletion();
                } catch (RuntimeException ex) {
                    bt.setStatus(Status.STATUS_MARKED_ROLLBACK);
                    throw ex;
                }
            }
           
            String testMethodName = MarshallingTestUtil.getTestMethodName();
            if( testMethodName != null ) {
                EntityManager em = emf.createEntityManager();
                updateManagedObjects(testMethodName, em);
                em.close();
            }
            ut.commit();
            return result;
        }
        else {
            result = invoke(method, ut, args);
        }
       
        return result;
    }
   
    private Object invoke( Method method, Object object, Object[] args) throws Throwable {
        Object result = null;
        try {
            result = method.invoke(object, args);
        } catch( InvocationTargetException ite ) {
           logger.warn(method.getName() + " threw " + ite.getClass().getSimpleName() + ": " + ite.getMessage());
           throw ite;
        }
        return result;
    }
}
TOP

Related Classes of org.drools.persistence.marshalling.util.UserTransactionProxy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.