// transactedCASLR.java
// Stateless Session bean

package org.objectweb.jonas.jtests.beans.j2eeca;

import javax.ejb.CreateException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.InitialContext;
import javax.resource.cci.LocalTransaction;
import javax.resource.spi.ConnectionEvent;
import javax.transaction.xa.Xid;

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

import fictional.resourceadapter.CommonClient;
import fictional.resourceadapter.ConnectionImpl;
import fictional.resourceadapter.JtestResourceAdapter;
import fictional.resourceadapter.LocalTransactionImpl;
import fictional.resourceadapter.XAResourceImpl;


/**
 *
 */
public class transactedCASLR implements SessionBean {

    static private Logger logger = null;
    SessionContext ejbContext;
    private JtestResourceAdapter mcf = null; //Managed Connection Factory
    private CommonClient csp = null;   //ConnectionSpec
    private CommonClient cccf = null;  //Common Client Connection Factory
    private ConnectionImpl conn = null;
    InitialContext ic=null;
    String cName = "transactedCASLR";
    final public int NoTransaction = 0;
    final public int LoTransaction = 1;
    final public int XATransaction = 2;
    final public int CLOSE_HANDLE = 0;
    final public int CLOSE_PHYSICAL = 1;
    public int TransactionType = 0;

    // ------------------------------------------------------------------
    // SessionBean implementation
    // ------------------------------------------------------------------


    public void setSessionContext(SessionContext ctx) {
        if (logger == null) {
            logger = Log.getLogger("org.objectweb.jonas.jtests.j2eeca");
        }
        logger.log(BasicLevel.DEBUG, cName+".setSessionContext");
        ejbContext = ctx;
    }
        

    public void ejbRemove() {
        logger.log(BasicLevel.DEBUG, "");
    }
        

    public void ejbCreate() throws CreateException {
        logger.log(BasicLevel.DEBUG, "");
    }

    public void ejbPassivate() {
        logger.log(BasicLevel.DEBUG, "");
    }

    public void ejbActivate() {
        logger.log(BasicLevel.DEBUG, "");
    }
    /**
     * closeUp
     */
    public void closeUp(int closeType) {
        logger.log(BasicLevel.DEBUG, cName+
                             ".closeUp (enter) closeType="+closeType);
        try {
            if (closeType==CLOSE_PHYSICAL) {
                // The CONNECTION_ERROR_OCCURRED indicates that the associated 
                // ManagedConnection instance is now invalid and unusable.
                conn.close(ConnectionEvent.CONNECTION_ERROR_OCCURRED);
                logger.log(BasicLevel.DEBUG, cName+
                    ".closeUp (exit) : closed physical connection closeType="+closeType+
                    " ConnectionEvent.CONNECTION_ERROR_OCCURRED="+
                      ConnectionEvent.CONNECTION_ERROR_OCCURRED);
            } else {
                // The CONNECTION_CLOSED indicates that connection handle
                // is closed, but physical connection still exists
                conn.close();
                logger.log(BasicLevel.DEBUG, cName+
                             ".closeUp (exit) : closed connection closeType="+closeType);
            }
        } catch (Exception e) {
            logger.log(BasicLevel.DEBUG, cName+".closeUp (exit) error: close "+
                        "handle/physical connection failed closeType="+closeType);
        }
    }
    
    // ------------------------------------------------------------------
    // transacted implementation
    // ------------------------------------------------------------------

    /**
     * method1
     */
    public void method1(String rar_jndi_name, String testName) 
            throws Exception
    {
        logger.log(BasicLevel.DEBUG, "============================ "+testName);

        if ("FictionalXATransaction".equals(rar_jndi_name)) 
            TransactionType = XATransaction;
        else if ("FictionalLoTransaction".equals(rar_jndi_name)) 
            TransactionType = LoTransaction;
        else 
            TransactionType = NoTransaction;

        try {
            ic = new InitialContext();
        } catch (Exception e1) {
            logger.log(BasicLevel.DEBUG, cName+".method1 error: InitialContext failed");
            throw e1;
        }
        try {
            cccf = (CommonClient)ic.lookup(rar_jndi_name);
            logger.log(BasicLevel.DEBUG, cName+".method1 : found "+rar_jndi_name);
        } catch (Exception e2) {
            logger.log(BasicLevel.DEBUG, cName+".method1 error: lookup failed for "+rar_jndi_name);
            throw e2;
        }
        
        try {
            csp = new CommonClient(); // get a new ConnectionSpec

        } catch (Exception e3) {
            logger.log(BasicLevel.DEBUG, cName+".method1 : new connection spec failed");
            throw e3;
        }
        try {
            conn = (ConnectionImpl)cccf.getConnection();
            logger.log(BasicLevel.DEBUG, cName+".method1 : getConnection conn="+conn);
            if (conn==null) {
                logger.log(BasicLevel.DEBUG, cName+".method1 error: getConnection returned null connection.");
                throw new Exception("");
            }
        } catch (Exception e4) {
            logger.log(BasicLevel.DEBUG, cName+".method1 error: getConnection failed "
                    +e4.toString());
            throw e4;
        }
    }
    public String getXid() {
        ConnectionImpl conni = (ConnectionImpl)conn;
        try {
            JtestResourceAdapter mc = (JtestResourceAdapter)conni.getMC(); //get ManagedConnection
            XAResourceImpl xar = mc.getCurrentXar();
            if (xar==null) {
                logger.log(BasicLevel.DEBUG, cName+".getXid error: failed xar==null");
                return "FAIL";
            } else {
                Xid xid = xar.getCurrentXid();
                logger.log(BasicLevel.DEBUG, cName+".getXid ");
                return "OK";
            }
        } catch (Exception e) {
            logger.log(BasicLevel.DEBUG, cName+".getXid error: failed");
            return "FAIL";
        }
    }
    /**
     * After the newly created ManagedConnectionFactory instance has been configured with
     * its property set, the application server creates a new ConnectionManager instance.
     * true returned if ConnectionManager is valid
     */
    public boolean getCMInstance()
    {
        mcf = (JtestResourceAdapter) cccf.getMcf();  // ManagedConnectionFactory    
        if (mcf.getCM()==null) {                     // ConnectionManager not null
            logger.log(BasicLevel.DEBUG, cName+".getCMInstance error: ConnectionManager is null");
            return false;
        }
        else {
            logger.log(BasicLevel.DEBUG, cName+".getCMInstance ConnectionManager is o.k.");
            return true;
        }
    }
    LocalTransactionImpl lt=null;
    public void beginLoTransaction() {
        logger.log(BasicLevel.DEBUG, cName+".beginLoTransaction (enter)");
        try {
            LocalTransaction l = conn.getLocalTransaction();
            lt = (LocalTransactionImpl) l;
            lt.begin();
            int s=lt.getTxState();
            logger.log(BasicLevel.DEBUG, cName+".beginLoTransaction (exit) State="+s);
        } catch (Exception e) {
            logger.log(BasicLevel.DEBUG, cName+".beginLoTransaction (exit) error:"
                  +" "+e.toString());
                    
        }
    }
    public void commitLoTransaction() throws Exception
    {
        logger.log(BasicLevel.DEBUG, cName+".commitLoTransaction (enter)");
        try {
            if (lt==null) {
                Exception e = new Exception("Undefined LocalTransaction");
                throw e;
            }
            lt.commit();
            int s=lt.getTxState();
            logger.log(BasicLevel.DEBUG, cName+".commitLoTransaction (exit) ="+s);
        } catch (Exception e) {
            logger.log(BasicLevel.DEBUG, cName+".commitLoTransaction (exit) error: State error."
                  +" "+e.getMessage());
            throw e;        
        }
        lt=null;
    }
    public void rollbackLoTransaction() {
        logger.log(BasicLevel.DEBUG, cName+".rollbackLoTransaction (enter)");
        try {
            if (lt==null) {
                Exception e = new Exception("Undefined LocalTransaction");
                throw e;
            }
            lt.rollback();
            int s=lt.getTxState();
            logger.log(BasicLevel.DEBUG, cName+".rollbackLoTransaction (exit) State="+s);
        } catch (Exception e) {
            logger.log(BasicLevel.DEBUG, cName+".rollbackLoTransaction (exit) error: State error"
                  +" "+e.getMessage());
                    
        }
        lt=null;
    }
}

