/*
 * Created on Jul 10, 2003
 *
 * LocalTransactionImpl.java is used to test the J2EE Connector
 * as implemented by JOnAS. This class implements the LocalTransaction Interface
 *  
 */
package fictional.resourceadapter;

import javax.resource.ResourceException;
import javax.resource.spi.ManagedConnection;
import javax.resource.spi.ConnectionEvent;
import javax.resource.spi.LocalTransaction;

import org.objectweb.jonas.common.Log;
import org.objectweb.util.monolog.api.Logger;
import org.objectweb.util.monolog.api.BasicLevel;

/**
 * @author Bob Kruse
 *
 * Jtest Resource Adapter
 *
 * used to test the J2EE Connector as implemented by JOnAS.
 * 
 */
public class LocalTransactionImpl 
        implements javax.resource.spi.LocalTransaction,
                    javax.resource.cci.LocalTransaction,
        java.io.Serializable
{
    private ManagedConnection mc;
    private Logger logger = null;
    String cName = "LocalTransactionImpl";
    private boolean sendEvent;

    public LocalTransactionImpl(ManagedConnection MC, boolean se) { // constructor for LocalTransaction
        if (logger == null) {
            logger = Log.getLogger("fictional.resourceadapter");
        }
        logger.log(BasicLevel.DEBUG, impl(this)+".constructor");
        this.mc = MC;
        txState = RESET;
        sendEvent = se;
    }
    private String impl(Object obj) {
        if (obj instanceof LocalTransaction) {
            return "LocalTransactionImpl";
        } else if (obj instanceof LocalTransactionImpl) {
            return "LocalTransaction";
        } else
            return "LocalTransactionImpl. Is this an error";
    }        
    public void setSendEvent(boolean event) {
        sendEvent=event;
    }
    //
    // This LocalTransactionImpl instance STATE
    final private int RESET      = 0;
    final private int BEGUN      = 1;
    final private int ENDED      = 2;
    final private int PREPARED   = 3;
    final private int FORGOT     = 4;
    final private int COMMITTED  = 5;
    final private int ROLLEDBACK = 6;

    int txState;
    public int getTxState() {
        return txState;
    }
    public ManagedConnection getCurrentMc() {
        return mc;
    }
    public void begin() throws ResourceException
    {
        logger.log(BasicLevel.DEBUG, cName+".begin (enter) txState="+txState);
        int curState=txState;
        JtestResourceAdapter omc = (JtestResourceAdapter) mc;
        try {
            if (txState==RESET) {
                if (sendEvent) {
                    omc.sendEvent(ConnectionEvent.LOCAL_TRANSACTION_STARTED, null, omc.getCHandle());
                    txState=BEGUN;
                    logger.log(BasicLevel.DEBUG, cName
                       +".begin (exit) (sendEvent(LOCAL_TRANSACTION_STARTED="
                       +ConnectionEvent.LOCAL_TRANSACTION_STARTED+"))"
                       +" From State="+curState+" to State="+txState);
                } else {
                    txState=BEGUN;
                }
                omc.inLocalTrans=true;
            }
            else {
                IllegalStateException ex = new IllegalStateException("LocalTransaction Already active");
                logger.log(BasicLevel.DEBUG, cName+".begin (exit) error: State="+txState
                                     +" should be="+RESET+". "+ex.getMessage());
                throw ex;
            }

        } catch (Exception e) {
            logger.log(BasicLevel.DEBUG, cName
                   +".begin (exit) error: unable to sendEvent"
                   +" with 'LOCAL_TRANSACTION_STARTED' "+e.toString());
        }
    }
    public void commit() throws ResourceException
    {
        logger.log(BasicLevel.DEBUG, cName+".commit (enter) txState="+txState);
        int curState=txState;
        JtestResourceAdapter omc = (JtestResourceAdapter) mc;
        try {
            if (txState==BEGUN) {
                if (sendEvent) {
                    omc.sendEvent(ConnectionEvent.LOCAL_TRANSACTION_COMMITTED, null, omc.getCHandle());
                    txState=COMMITTED;
                    logger.log(BasicLevel.DEBUG, cName
                       +".commit (exit) (sendEvent(LOCAL_TRANSACTION_COMMITTED="
                       +ConnectionEvent.LOCAL_TRANSACTION_COMMITTED+"))"
                       +" From State="+curState+" to State="+txState);
                } else {
                    txState=COMMITTED;
                }
            }
            else {
                IllegalStateException ex = new IllegalStateException(
                          "LocalTransaction Illegal State during commit");
                logger.log(BasicLevel.DEBUG, cName+".commit (exit) error: State="+txState
                        +" should be="+BEGUN+". "+ex.getMessage());
                omc.inLocalTrans=false;
                throw ex;
            }
        } catch (Exception e) {
            logger.log(BasicLevel.DEBUG, cName
                   +".commit (exit) error: unable to sendEvent"
                   +" with 'LOCAL_TRANSACTION_COMMITTED' "+e.toString());
        }
        omc.inLocalTrans=false;
    }
    public void rollback() throws ResourceException
    {
        int curState=txState;
        logger.log(BasicLevel.DEBUG, cName+".rollback (enter) txState="+txState);
        JtestResourceAdapter omc = (JtestResourceAdapter) mc;
        try {
            if (txState == BEGUN) {
                if (sendEvent) {
                    omc.sendEvent(ConnectionEvent.LOCAL_TRANSACTION_ROLLEDBACK, null, omc.getCHandle());
                    txState=ROLLEDBACK;
                    logger.log(BasicLevel.DEBUG, cName
                       +".rollback (exit) (sendEvent(LOCAL_TRANSACTION_ROLLEDBACK="
                       +ConnectionEvent.LOCAL_TRANSACTION_ROLLEDBACK+"))"
                       +" From State="+curState+" to State="+txState);
                } else {
                    txState=ROLLEDBACK;
                }
            }
            else {
                IllegalStateException ex = new IllegalStateException(
                          "LocalTransaction Illegal State during rollback");
                logger.log(BasicLevel.DEBUG, cName+".rollback (exit) error: State="+txState
                        +" should be="+BEGUN+". "+ex.getMessage());
                omc.inLocalTrans=false;
                throw ex;
            }
        } catch (Exception e) {
            logger.log(BasicLevel.DEBUG, cName
                   +".rollback (exit) error: unable to sendEvent"
                   +" with 'LOCAL_TRANSACTION_ROLLEDBACK' "+e.toString());
        }
        omc.inLocalTrans=false;
    }
}
