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

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

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 XAResourceImpl 
        implements XAResource,
        java.io.Serializable
{
    private ManagedConnection mc;
    private Logger logger = null;
    String cName = "XAResourceImpl";
    int timeout = 0;
    Xid currentXid;

    public XAResourceImpl(ManagedConnection MC) { // constructor for XAResource
        if (logger == null) {
            logger = Log.getLogger("fictional.resourceadapter");
        }
        logger.log(BasicLevel.DEBUG, impl(this)+".constructor");
        this.mc = MC;
        xidState = RESET;
    }
    private String impl(Object obj) {
        if (obj instanceof XAResource) {
            return "XAResource";
        } else if (obj instanceof XAResourceImpl) {
            return "XAResourceImpl";
        } else
            return "XAResourceImpl. Is this an error";
    }        

    //
    // *****************
    //    XAResource    methods
    // *****************
    //
    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 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;
            logger.log(BasicLevel.DEBUG, impl(this)+".commit From State="+curState+
                   " to State="+xidState+" xid="+xid+" onePhase="+onePhase);
        }
        else {
            logger.log(BasicLevel.DEBUG, impl(this)+".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;
        JtestResourceAdapter jmc = (JtestResourceAdapter) mc;
        jmc.resetXar();
        logger.log(BasicLevel.DEBUG, impl(this)+".end From State="+curState+
               " to State="+xidState+" for xid="+xid+" flags="+flags);
    }
    public void forget(Xid xid) throws XAException
    {
        logger.log(BasicLevel.DEBUG, impl(this)+".forget State="+xidState);
        xidState=FORGOT;
    }
    public int prepare(Xid xid) throws XAException
    {
        logger.log(BasicLevel.DEBUG, impl(this)+".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;
        logger.log(BasicLevel.DEBUG, impl(this)+".recover State="+xidState);
        return xidArray;
    }
    public void rollback(Xid xid) throws XAException
    {
        int curState=xidState;
        if (xidState >= STARTED) {
            xidState=ROLLEDBACK;
            logger.log(BasicLevel.DEBUG, impl(this)+".rollback From State="+curState+
                   " to State="+xidState+" xid="+xid);
        }
        else {
            logger.log(BasicLevel.DEBUG, impl(this)+".rollback error: State="+xidState
                    +" should be="+STARTED+"or more. xid="+xid);
        }
    }
    public void start(Xid xid, int flags) throws XAException
    {
        currentXid=xid;
        xFlags=flags;
        int curState=xidState;
        if (xidState==RESET) {
            xidState=STARTED;
            logger.log(BasicLevel.DEBUG, impl(this)+".start From State="+curState+
                       " to State="+xidState+" xid="+xid+" flags="+flags);
        }
        else {
            logger.log(BasicLevel.DEBUG, impl(this)+".start error: State="+xidState
                                 +" should be="+RESET+" xid="+xid+" flags="+flags);
        }
    }
    public int getTransactionTimeout() throws XAException
    {
        logger.log(BasicLevel.DEBUG, impl(this)+".getTransactionTimeout timeout="+timeout);
        return timeout;          
    }
    public boolean setTransactionTimeout(int seconds) throws XAException
    {
        timeout=seconds;
        logger.log(BasicLevel.DEBUG, impl(this)+".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;
        logger.log(BasicLevel.DEBUG, impl(this)+".isSameRM xares="+xares+" return="+a);
        return a;
    }
}
