/*
 * Created on Jul 10, 2003
 *
 * ConnectionImpl.java is used to test the J2EE Connector
 * as implemented by JOnAS. This class implements the Connection Interface
 * and ConnectionMetaData Interface (cci) classes.
 *  
 */
package fictional.resourceadapter;

import javax.resource.ResourceException;
import javax.resource.NotSupportedException;
import javax.resource.cci.*;
import javax.resource.spi.ManagedConnection;
import javax.resource.spi.ConnectionEvent;
import org.ow2.jonas.lib.util.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 ConnectionImpl 
        implements Connection,
        ConnectionMetaData,
        java.io.Serializable
{
    public String product="Fictional EIS"; // see J2eeConnectorTestBeanClient
    String version="1.1";
    String UserName="Fictional_User_Name";  //
    private ManagedConnection mc;
    public LocalTransactionImpl lt;
    boolean closed = false;  // connection is closed
    private Logger logger = null;
    String cName = "";
    private boolean autoCommitMode = false;

    //
    // *****************
    //    Connection    methods
    // *****************
    //
    public ConnectionImpl(Object mc) { // constructor for Connection
        if (logger == null) {
            logger = Log.getLogger("fictional.resourceadapter");
        }
        logger.log(BasicLevel.DEBUG, impl(this)+".constructor");
        this.mc=(ManagedConnection)mc;
    }
    private String impl(Object obj) {
        if (obj instanceof Connection) {
            return "ConnectionImpl";
        } else if (obj instanceof ConnectionImpl) {
            return "Connection";
        } else if (obj instanceof ConnectionMetaData) {
            return "ConnectionMetaData";
        } else
            return "ConnectionImpl. Is this an error";
    }        
    //
    // close connection handle
    //
    public void close() throws ResourceException 
    {
        logger.log(BasicLevel.DEBUG, impl(this)
            +".close with ConnectionEvent.CONNECTION_CLOSED="
            +ConnectionEvent.CONNECTION_CLOSED);
        closed = true;
        
        if (mc != null) {
            try {
                JtestResourceAdapter omc = (JtestResourceAdapter) mc;
                omc.sendEvent(ConnectionEvent.CONNECTION_CLOSED, null, this);
                mc=null;
                logger.log(BasicLevel.DEBUG, impl(this)
                       +".close sendevent 'CONNECTION_CLOSED'");
            } catch (ResourceException e) {
                logger.log(BasicLevel.DEBUG, impl(this)+".close error: unable to close");
                throw e; 
            }
        } else {
            logger.log(BasicLevel.DEBUG, impl(this)+".close error: mc=null");
        }
        return;
    }
    //
    // close physical connection
    //
    // The connectionErrorOccurred method indicates that the associated 
    // ManagedConnection instance is now invalid and unusable.
    // mc.sendEvent method makes the call to connectionErrorOccurred
    //
    public void close(int eType) throws ResourceException 
    {
        logger.log(BasicLevel.DEBUG, impl(this)+".close("+eType+")");
        closed = true;
        
        if (mc != null) {
            try {
                JtestResourceAdapter omc = (JtestResourceAdapter) mc;
                omc.sendEvent(eType, null, this);
                mc=null;
                logger.log(BasicLevel.DEBUG, impl(this)
                       +".close(CONNECTION_ERROR_OCCURRED="
                       +ConnectionEvent.CONNECTION_ERROR_OCCURRED+") to "
                       +"close physical connection");
            } catch (ResourceException e) {
                logger.log(BasicLevel.DEBUG, impl(this)
                       +".close error: unable to close physical connection"
                       +" with 'CONNECTION_ERROR_OCCURRED'");
                throw e; 
            }
        } else {
            logger.log(BasicLevel.DEBUG, impl(this)+".close error: mc=null already");
        }
        return;
    }
    public Interaction createInteraction() throws ResourceException 
    {
      logger.log(BasicLevel.DEBUG, impl(this)+".createInteraction");
      Interaction gi=new JtestInteraction(this, mc);
      // TODO Interaction gi = new Interaction(this, this.mc, lw);
      return gi;
    }
    public ConnectionMetaData getMetaData() throws ResourceException 
    {
        logger.log(BasicLevel.DEBUG, impl(this)+".getMetaData");
        ConnectionMetaData eisInfo = (ConnectionMetaData)new ConnectionImpl(mc);
        return eisInfo;
    }
    public LocalTransaction getLocalTransaction() 
                throws ResourceException
    {
        try {
            JtestResourceAdapter jmc = (JtestResourceAdapter)mc;
            lt = (LocalTransactionImpl) jmc.getLocalTransaction(true);
            logger.log(BasicLevel.DEBUG, impl(this)+".getLocalTransaction lt="+lt);
        } catch (Exception e) {
            logger.log(BasicLevel.DEBUG, impl(this)+".getLocalTransaction error: "
                +e.getMessage()+" <<<<<<<<<<<<");
        }
        return (lt);
    }
    public ResultSetInfo getResultSetInfo() throws ResourceException
    {
        logger.log(BasicLevel.DEBUG, impl(this)+".getResultSetInfo");
        NotSupportedException nse = new NotSupportedException("getResultSetInfo is not supported");
        throw nse;
    }
    public void associateConnection(ManagedConnection mc) throws IllegalStateException
    {
        logger.log(BasicLevel.DEBUG, impl(this)+".associateConnection");
        this.mc=mc;
    }
    public ManagedConnection getMC()  throws ResourceException
    {
        logger.log(BasicLevel.DEBUG, impl(this)+".getMC mc="+this.mc);
        return this.mc;
    }
    public void setAutoCommit(boolean a) {
        autoCommitMode=a;
    }
    public boolean getAutoCommit() {
        return autoCommitMode;
    }
    //
    // **********************
    //    ConnectionMetaData    methods
    // **********************
    //
    //  The method getUserName returns the user name for an active connection as 
    //  known to the underlying EIS instance. The name corresponds the resource 
    //  principal under whose security context a connection to the EIS
    //  instance has been established.  (page 109 CA 1.0)
    //
    public String getEISProductName()
                                       throws ResourceException
    {
        return (product);
    }
    public String getEISProductVersion()
                                          throws ResourceException
    {
        return (version);
    }
    public String getUserName()
                                          throws ResourceException
    {
        return (UserName);
    }
}
