/*
 * Created on Jun 12, 2003
 *
 * CommonClient.java is used to test the J2EE Connector
 * as implemented by JOnAS. This class implements some the Common Client Interface
 * (cci) classes. Each cci method simulates actual functionality and returns test 
 * results to the caller which is a JUnit test program.
 * 
 */
package fictional.resourceadapter;

import javax.naming.Reference;
import javax.naming.NamingException;
import javax.resource.ResourceException;
import javax.resource.NotSupportedException;
import javax.resource.spi.ConnectionManager;
import javax.resource.spi.ManagedConnectionFactory;
import javax.resource.spi.ConnectionRequestInfo;
//  interfaces implemented in this class
import javax.resource.cci.ConnectionFactory;
import javax.resource.cci.Connection;
import javax.resource.cci.ConnectionSpec;  // j2ee 1.5
import javax.resource.cci.RecordFactory;
import javax.resource.cci.ResourceAdapterMetaData;
import java.io.Serializable;
import javax.resource.Referenceable;
//  logger imports
import org.objectweb.jonas.common.Log;
import org.objectweb.util.monolog.api.Logger;
import org.objectweb.util.monolog.api.BasicLevel;
/**
 * @author Bob Kruse
 *
 * used to test the J2EE Connector as implemented by JOnAS.
 *
 */
public class CommonClient 
	implements 
    ConnectionFactory,
	ConnectionSpec,     // j2ee 1.5
	ResourceAdapterMetaData,
    Referenceable,  
	Serializable

{
	Reference reference;
    private ConnectionManager cm;
    private ManagedConnectionFactory mcf; // used in cm.allocateConnection
    private CommonClient cs;  // ConnectionSpec
    protected boolean managed = true;
    private Logger logger = null;
    private String userName = "";
    private String passWord = ""; 
    String cName = "";
    
    public CommonClient() {
        if (logger == null) {
            logger = Log.getLogger("fictional.resourceadapter");
        }
    }
    //
    // *****************
    //  ConnectionSpec    methods
    // *****************
    //
    public void setUserName(String u) {
        userName=u;
        cName = "ConnectionSpec";
        logger.log(BasicLevel.DEBUG, cName+".setUserName="+u);
    }
    public void setPassword(String p) {
        passWord=p;
        cName = "ConnectionSpec";
        logger.log(BasicLevel.DEBUG, cName+".setPassword="+p);
    }
    public String getUserName() {
        cName = "ConnectionSpec";
        logger.log(BasicLevel.DEBUG, cName+".getUserName="+userName);
        return userName;
    }
    public String getPassword() {
        cName = "ConnectionSpec";
        logger.log(BasicLevel.DEBUG, cName+".getPassword="+passWord);
        return passWord;
    }
	//
	// *****************
    // ConnectionFactory    methods
	// *****************
    //
	// Referenced classes of package javax.resource.cci:
	//  Connection, ConnectionSpec, RecordFactory, ResourceAdapterMetaData
	//  (below is constructor for ConnectionFactory
    //
    //  ConnectionFactory instance created during lookup() by Application Server
    // 
    public CommonClient(ManagedConnectionFactory mcf, ConnectionManager cm) {
        if (logger == null) {
            logger = Log.getLogger("fictional.resourceadapter");
        }
        this.mcf=mcf;
        this.cm=cm;
        
    }
	private String impl(Object obj) {
        if (obj instanceof ConnectionFactory) {
            return "ConnectionFactory";
        } else if (obj instanceof ConnectionSpec) {
            return "ConnectionSpec";
        } else if (obj instanceof ResourceAdapterMetaData) {
            return "ResourceAdapterMetaData";
        } else
            return "CommonClient. Is this an error";

	}
    //
    // Container Managed Sign-on calls getConnection() from the Application Component
    //
    // Container-managed sign-on when file "connector.xml / secured.jar" contains line below
    //
    //  <res-auth>Container</res-auth>
    //
    public Connection getConnection()
		throws ResourceException
	{
        cName = "ConnectionFactory";
        logger.log(BasicLevel.DEBUG, cName+".getConnection"+" (Container Managed Sign-on)");
		Connection conn = null;
        try {
            conn = (Connection)getConnection(null);
            return conn;
        } catch (ResourceException ex) {
            throw ex;
        }
	}
    //
    // Component Managed Sign-on calls getConnection(cs) directly from the Application Component
    //
    // Component-managed sign-on when file "connector.xml / secured.jar" contains line below
    //
    //  <res-auth>Application</res-auth>
    //
	public Connection getConnection(ConnectionSpec connectionspec)
		throws ResourceException
	{
        cName = "ConnectionFactory";
        JtestResourceAdapter jmcf = (JtestResourceAdapter)mcf; // ManagedConnectionFactory
        Connection conn = null;
        CommonClient cs;  // ConnectionSpec
        JtestResourceAdapter jcri=null; // ConnectionRequestInfo

        if (connectionspec==null) {
            jmcf.setRes_Auth("Container");
            logger.log(BasicLevel.DEBUG, cName+".getConnection detected res-auth='"+jmcf.getRes_Auth()+"'");
            // TODO what now? anything?
            // now pass null to cm.allocateConnection(mcf, null);
        } else {
            jmcf.setRes_Auth("Application");
            logger.log(BasicLevel.DEBUG, cName+".getConnection detected res-auth='"+jmcf.getRes_Auth()+"'");
            cs = (CommonClient)connectionspec;
            // load user and password into ConnectionRequestInfo instance
            jcri = new JtestResourceAdapter();  // ConnectionRequestInfo
            jcri.setUserName(cs.getUserName());
            jcri.setPassword(cs.getPassword());
            
        }
        logger.log(BasicLevel.DEBUG, cName+".getConnection calling cm.allocateConnection");
        try {
            ConnectionRequestInfo cri = (ConnectionRequestInfo) jcri;
            conn = (Connection)cm.allocateConnection(mcf, cri);
            if (conn==null) {
                logger.log(BasicLevel.DEBUG, cName+". getConnection, cm.allocateConnection"
                      +" error: Null connection object returned");
                throw new ResourceException("Null connection object returned by allocateConnection");
            }
            return conn;
        } catch (IllegalStateException is) {
            logger.log(BasicLevel.DEBUG, cName+".getConnection IllegalStateException"+is);
            throw is;
        } catch (ResourceException re) {
            logger.log(BasicLevel.DEBUG, cName+".getConnection ResourceException="+re);
            throw re; 
        }
	}

	public RecordFactory getRecordFactory()
		throws ResourceException
	{
        cName = "ConnectionFactory";
        logger.log(BasicLevel.DEBUG, cName+".getRecordFactory");
		NotSupportedException nse = new NotSupportedException(
			"RecordFactory is not currently supported");
		throw nse;
	}

	public ResourceAdapterMetaData getMetaData()
		throws ResourceException
	{
        cName = "ConnectionFactory";
        logger.log(BasicLevel.DEBUG, cName+".getMetaData");
		ResourceAdapterMetaData rd = null; // TODO  do something
		return rd;
	}
    public ManagedConnectionFactory getMcf() {
        ManagedConnectionFactory MCF = (ManagedConnectionFactory)mcf;
        return MCF;
    }
    //
    // *****************
    //    Reference
    // *****************
    //
	/** Required by the referencable attribute
	 *  @param  ref Reference object
	**/
	public void setReference(javax.naming.Reference ref) 
	{
	  this.reference = ref;
	}

	/** Required by the referencable attribute
	 *  @return  Reference object
	**/
	public Reference getReference() 
		throws NamingException
	{
	  return reference;
	}
   	//
	// ***********************
	// ResourceAdapterMetaData  methods
	// ***********************
	//
	public String getAdapterVersion() {
		return "1.0";
	}
	public String getAdapterVendorName() {
		return "Bull";
	}
	public String getAdapterName() {
		return "JOnAS Test Resource Adapter";
	}
	public String getAdapterShortDescription() {
		return "Test JOnAS Application Server compliance to J2EE Java Community Process (JSR112)";
	}
	public String getSpecVersion() {
		return "J2EE Java Community Process (JSR112)";
	}
	public String[] getInteractionSpecsSupported() {
		String[]s = {"JSR016","JSR112"};
		return s;
	}
	public boolean supportsExecuteWithInputAndOutputRecord() {
		return true;
	}
	public boolean supportsExecuteWithInputRecordOnly() {
		return true;
	}
	public boolean supportsLocalTransactionDemarcation() {
		return false;
	}
}
