/*
 * Created on December 10, 2003
 *
 * LocalTransactionImpl.java is used to test the J2EE Connector
 * as implemented by JOnAS. This class implements 
 * javax.resource.spi.LocalTransaction and 
 * javax.resource.cci.LocalTransaction
 */
package ersatz.resourceadapter;

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

/**
 * @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
{
    private ManagedConnection mc;
    String cName = "LocalTransactionImpl";
    private boolean sendEvent;
    //
    // 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 LocalTransactionImpl(ManagedConnection MC, boolean se) {
        Utility.log(cName+".constructor");
        this.mc = MC;
        txState = RESET;
        sendEvent = se;
    }
    public void setSendEvent(boolean event) {
        sendEvent=event;
    }
    public int getTxState() {
        return txState;
    }
    public ManagedConnection getCurrentMc() {
        return mc;
    }
    public void begin() throws ResourceException
    {
        Utility.log(cName+".begin (enter) txState="+txState);
        int curState=txState;
        ManagedConnectionImpl omc = (ManagedConnectionImpl) mc;
        try {
            if (txState==RESET) {
                if (sendEvent) {
                    omc.sendEvent(ConnectionEvent.LOCAL_TRANSACTION_STARTED, null, omc.getCHandle());
                    txState=BEGUN;
                    Utility.log(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");
                Utility.log(cName+".begin (exit) error: State="+txState
                                     +" should be="+RESET+". "+ex.getMessage());
                throw ex;
            }

        } catch (Exception e) {
            Utility.log(cName
                   +".begin (exit) error: unable to sendEvent"
                   +" with 'LOCAL_TRANSACTION_STARTED' "+e.toString());
        }
    }
    public void commit() throws ResourceException
    {
        Utility.log(cName+".commit (enter) txState="+txState);
        int curState=txState;
        ManagedConnectionImpl omc = (ManagedConnectionImpl) mc;
        try {
            if (txState==BEGUN) {
                if (sendEvent) {
                    omc.sendEvent(ConnectionEvent.LOCAL_TRANSACTION_COMMITTED, null, omc.getCHandle());
                    txState=COMMITTED;
                    Utility.log(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");
                Utility.log(cName+".commit (exit) error: State="+txState
                        +" should be="+BEGUN+". "+ex.getMessage());
                omc.inLocalTrans=false;
                throw ex;
            }
        } catch (Exception e) {
            Utility.log(cName
                   +".commit (exit) error: unable to sendEvent"
                   +" with 'LOCAL_TRANSACTION_COMMITTED' "+e.toString());
        }
        omc.inLocalTrans=false;
    }
    public void rollback() throws ResourceException
    {
        int curState=txState;
        Utility.log(cName+".rollback (enter) txState="+txState);
        ManagedConnectionImpl omc = (ManagedConnectionImpl) mc;
        try {
            if (txState == BEGUN) {
                if (sendEvent) {
                    omc.sendEvent(ConnectionEvent.LOCAL_TRANSACTION_ROLLEDBACK, null, omc.getCHandle());
                    txState=ROLLEDBACK;
                    Utility.log(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");
                Utility.log(cName+".rollback (exit) error: State="+txState
                        +" should be="+BEGUN+". "+ex.getMessage());
                omc.inLocalTrans=false;
                throw ex;
            }
        } catch (Exception e) {
            Utility.log(cName
                   +".rollback (exit) error: unable to sendEvent"
                   +" with 'LOCAL_TRANSACTION_ROLLEDBACK' "+e.toString());
        }
        omc.inLocalTrans=false;
    }
}
