/*
 * Created on December 10, 2003
 *
 * XAResourceImpl.java is used to test the J2EE Connector
 * as implemented by JOnAS. This class implements the XAResource Interface
 *  
 */
package ersatz.resourceadapter;

import javax.resource.spi.ManagedConnection;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import javax.transaction.xa.XAException;

/**
 * @author Bob Kruse
 *
 * Jtest Resource Adapter
 *
 * used to test the J2EE Connector as implemented by JOnAS.
 * 
 */
public class XAResourceImpl 
        implements XAResource,
        java.io.Serializable
{
    private ManagedConnection mc;
    String cName = "XAResourceImpl";
    int timeout = 0;
    Xid currentXid;
    protected Xid xidArray[];
    // This XAResourceImpl instance STATE
    final private int RESET      = 0;
    final private int STARTED    = 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 xFlags;
    int recoverFlag;
    int xidState;

    public XAResourceImpl(ManagedConnection MC) { // constructor for XAResource
        Utility.log(cName+".constructor");
        this.mc = MC;
        xidState = RESET;
    }

    public int getXidState() {
        return xidState;
    }
    public Xid getCurrentXid() {
        return currentXid;
    }
    public ManagedConnection getCurrentMc() {
        return mc;
    }
    public void commit(Xid xid, boolean onePhase) throws XAException
    {
        int curState=xidState;
        if (xidState>RESET) {
            xidState=COMMITTED;
            Utility.log(cName+".commit From State="+curState+
                   " to State="+xidState+" xid="+xid+" onePhase="+onePhase);
        }
        else {
            Utility.log(cName+".commit error: State="+xidState
                    +" should be="+STARTED+"or more. xid="+xid+" onePhase="+onePhase);
        }
    }
    public void end(Xid xid, int flags) throws XAException
    {
        int curState=xidState;
        xidState=ENDED;
        ManagedConnectionImpl jmc = (ManagedConnectionImpl) mc;
        jmc.resetXar();
        Utility.log(cName+".end From State="+curState+
               " to State="+xidState+" for xid="+xid+" flags="+flags);
    }
    public void forget(Xid xid) throws XAException
    {
        Utility.log(cName+".forget State="+xidState);
        xidState=FORGOT;
    }
    public int prepare(Xid xid) throws XAException
    {
        Utility.log(cName+".prepare State="+xidState);
        xidState=PREPARED;
        //return 1;
        return XA_OK;
    }
    /**
     *  Obtain a list of prepared transaction branches from a resource manager. 
     */
    public Xid[] recover(int flag) throws XAException
    {
        recoverFlag=flag;
        Utility.log(cName+".recover State="+xidState);
        return xidArray;
    }
    public void rollback(Xid xid) throws XAException
    {
        int curState=xidState;
        if (xidState >= STARTED) {
            xidState=ROLLEDBACK;
            Utility.log(cName+".rollback From State="+curState+
                   " to State="+xidState+" xid="+xid);
        }
        else {
            Utility.log(cName+".rollback error: State="+xidState
                    +" should be="+STARTED+"or more. xid="+xid);
        }
    }
    public void start(Xid xid, int flags) throws XAException
    {
        Utility.log(cName+".start xid="+xid+" flags="+flags);
        currentXid=xid;
        xFlags=flags;
        int curState=xidState;
        if (xidState==RESET) {
            xidState=STARTED;
            Utility.log(cName+".start From State="+curState+
                       " to State="+xidState+" xid="+xid+" flags="+flags);
        }
        else {
            Utility.log(cName+".start error: State="+xidState
                                 +" should be="+RESET+" xid="+xid+" flags="+flags);
        }
    }
    public int getTransactionTimeout() throws XAException
    {
        Utility.log(cName+".getTransactionTimeout timeout="+timeout);
        return timeout;          
    }
    public boolean setTransactionTimeout(int seconds) throws XAException
    {
        timeout=seconds;
        Utility.log(cName+".setTransactionTimeout seconds="+seconds);
        return true;
    }
    /**
     *  Determine if the resource manager instance represented by the target object is the 
     *  same as the resource manager instance represented by the parameter xares  
     */
    public boolean isSameRM(XAResource xares) throws XAException
    {
        boolean a = true;
        Utility.log(cName+".isSameRM xares="+xares+" return="+a);
        return a;
    }
}
