FileDocCategorySizeDatePackage
ManagedConnection.javaAPI DocGlassfish v2 API29701Thu Jul 19 03:02:58 BST 2007com.sun.gjc.spi

ManagedConnection

public class ManagedConnection extends Object implements javax.resource.spi.DissociatableManagedConnection, javax.resource.spi.ManagedConnection, javax.resource.spi.LazyEnlistableManagedConnection
ManagedConnection implementation for Generic JDBC Connector.
author
Evani Sai Surya Kiran
version
1.0, 02/07/22

Fields Summary
public static final int
ISNOTAPOOLEDCONNECTION
public static final int
ISPOOLEDCONNECTION
public static final int
ISXACONNECTION
protected boolean
isDestroyed
protected boolean
isUsable
protected int
connectionCount
protected int
connectionType
protected PooledConnection
pc
protected Connection
actualConnection
protected Hashtable
connectionHandles
protected PrintWriter
logWriter
protected javax.resource.spi.security.PasswordCredential
passwdCredential
private javax.resource.spi.ManagedConnectionFactory
mcf
protected XAResource
xar
protected com.sun.gjc.spi.base.ConnectionHolder
myLogicalConnection
protected int
lastTransactionIsolationLevel
protected boolean
isClean
protected boolean
transactionInProgress
protected ConnectionEventListener
listener
protected ConnectionEvent
ce
private boolean
defaultAutoCommitValue
private boolean
lastAutoCommitValue
private boolean
markedForRemoval
private int
statementTimeout
protected static final Logger
_logger
protected com.sun.enterprise.util.i18n.StringManager
localStrings
Constructors Summary
public ManagedConnection(PooledConnection pooledConn, Connection sqlConn, javax.resource.spi.security.PasswordCredential passwdCred, javax.resource.spi.ManagedConnectionFactory mcf)
Constructor for ManagedConnection. The pooledConn parameter is expected to be null and sqlConn parameter is the actual connection in case where the actual connection is got from a non pooled datasource object. The pooledConn parameter is expected to be non null and sqlConn parameter is expected to be null in the case where the datasource object is a connection pool datasource or an xa datasource.

param
pooledConn PooledConnection object in case the physical connection is to be obtained from a pooled DataSource; null otherwise
param
sqlConn java.sql.Connection object in case the physical connection is to be obtained from a non pooled DataSource; null otherwise
param
passwdCred object conatining the user and password for allocating the connection
throws
ResourceException if the ManagedConnectionFactory object that created this ManagedConnection object is not the same as returned by PasswordCredential object passed


                                                                                                                                                                                                                                                                                                                             
        
                                
              
        if (pooledConn == null && sqlConn == null) {

            String i18nMsg = localStrings.getString(
                    "jdbc.conn_obj_null");
            throw new ResourceException(i18nMsg);
        }
                  
        if (connectionType == ISNOTAPOOLEDCONNECTION) {
            actualConnection = sqlConn;
        }

        pc = pooledConn;
        connectionHandles = new Hashtable();
        passwdCredential = passwdCred;

        this.mcf = mcf;
        if (passwdCredential != null &&
                this.mcf.equals(passwdCredential.getManagedConnectionFactory()) == false) {

            String i18nMsg = localStrings.getString(
                    "jdbc.mc_construct_err");
            throw new ResourceException(i18nMsg);
        }
        logWriter = mcf.getLogWriter();
        ce = new ConnectionEvent(this, ConnectionEvent.CONNECTION_CLOSED);
    
Methods Summary
voidXAEndOccurred()
This method is called by the XAResource object when its end method has been invoked.

        try {
            actualConnection.setAutoCommit(true);
        } catch (Exception e) {
            e.printStackTrace();
            connectionErrorOccurred(e, null);
        }
    
voidXAStartOccurred()
This method is called by the XAResource object when its start method has been invoked.

        try {
            actualConnection.setAutoCommit(false);
        } catch (Exception e) {
            e.printStackTrace();
            connectionErrorOccurred(e, null);
        }
    
public voidaddConnectionEventListener(ConnectionEventListener listener)
Adds a connection event listener to the ManagedConnection instance.

param
listener ConnectionEventListener
see
removeConnectionEventListener

        this.listener = listener;
    
public voidassociateConnection(java.lang.Object connection)
Used by the container to change the association of an application-level connection handle with a ManagedConnection instance.

param
connection ConnectionHolder30 to be associated with this ManagedConnection instance
throws
ResourceException if the physical connection is no more valid or the connection handle passed is null

        if (logWriter != null) {
            logWriter.println("In associateConnection");
        }
        checkIfValid();
        if (connection == null) {
            String i18nMsg = localStrings.getString(
                    "jdbc.conn_handle_null");
            throw new ResourceException(i18nMsg);
        }
        ConnectionHolder ch = (ConnectionHolder) connection;

        com.sun.gjc.spi.ManagedConnection mc = ch.getManagedConnection();
        isClean = false;

        ch.associateConnection(actualConnection, this);
        /**
         * The expectation from the above method is that the connection holder
         * replaces the actual sql connection it holds with the sql connection
         * handle being passed in this method call. Also, it replaces the reference
         * to the ManagedConnection instance with this ManagedConnection instance.
         * Any previous statements and result sets also need to be removed.
         */


        ch.setActive(true);
        incrementCount();

        //mc will be null in case we are lazily associating 
        if (mc != null) {
            mc.decrementCount();
        }
    
public voidcheckIfActive(com.sun.gjc.spi.base.ConnectionHolder ch)
This method is called by a Connection Handle to check if it is the active Connection Handle. If it is not the active Connection Handle, this method throws an SQLException. Else, it returns setting the active Connection Handle to the calling Connection Handle object to this object if the active Connection Handle is null.

param
ch ConnectionHolder30 that requests this ManagedConnection instance whether it can be active or not
throws
SQLException in case the physical is not valid or there is already an active connection handle

        if (isDestroyed || !isUsable) {

            String i18nMsg = localStrings.getString(
                    "jdbc.conn_not_usable");
            throw new SQLException(i18nMsg);
        }
    
voidcheckIfValid()
Checks if this ManagedConnection is valid or not and throws an exception if it is not valid. A ManagedConnection is not valid if destroy has not been called and no physical connection error has occurred rendering the physical connection unusable.

throws
ResourceException if destroy has been called on this ManagedConnection instance or if a physical connection error occurred rendering it unusable

        if (isDestroyed || !isUsable) {

            String i18nMsg = localStrings.getString(
                    "jdbc.mc_not_usable");
            throw new ResourceException(i18nMsg);
        }
    
public voidcleanup()
Application server calls this method to force any cleanup on the ManagedConnection instance. This method calls the invalidate method on all ConnectionHandles associated with this ManagedConnection.

throws
ResourceException if the physical connection is no more valid

        if (logWriter != null) {
            logWriter.println("In cleanup");
        }
        checkIfValid();

        /**
         * may need to set the autocommit to true for the non-pooled case.
         */
        //GJCINT
        isClean = true;

    
public voidconnectionClosed(java.lang.Exception e, com.sun.gjc.spi.base.ConnectionHolder connHolder30Object)
This method is called by the ConnectionHolder30 when its close method is called. This ManagedConnection instance invalidates the connection handle and sends a CONNECTION_CLOSED event to all the registered event listeners.

param
e Exception that may have occured while closing the connection handle
param
connHolder30Object ConnectionHolder30 that has been closed
throws
SQLException in case closing the sql connection got out of getConnection on the underlying PooledConnection throws an exception


        connHolder30Object.invalidate();
        decrementCount();
        ce.setConnectionHandle(connHolder30Object);

        if (markedForRemoval && !transactionInProgress) {
            BadConnectionEventListener bcel = (BadConnectionEventListener)listener;
            bcel.badConnectionClosed(ce);
            _logger.log(Level.INFO, "jdbc.markedForRemoval_conClosed");
            markedForRemoval = false;
        }else{
            listener.connectionClosed(ce);
        }
    
voidconnectionErrorOccurred(java.lang.Exception e, com.sun.gjc.spi.base.ConnectionHolder connHolderObject)
This method is called by the ConnectionHolder30 when it detects a connecion related error.

param
e Exception that has occurred during an operation on the physical connection
param
connHolderObject ConnectionHolder that detected the physical connection error


        ConnectionEventListener cel = this.listener;
        ConnectionEvent ce = null;
        ce = e == null ? new ConnectionEvent(this, ConnectionEvent.CONNECTION_ERROR_OCCURRED)
                : new ConnectionEvent(this, ConnectionEvent.CONNECTION_ERROR_OCCURRED, e);
        if (connHolderObject != null) {
            ce.setConnectionHandle(connHolderObject);
        }

        cel.connectionErrorOccurred(ce);
        isUsable = false;
    
public voiddecrementCount()

        connectionCount--;
    
public voiddestroy()
Destroys the physical connection to the underlying resource manager.

throws
ResourceException if there is an error in closing the physical connection

        if (logWriter != null) {
            logWriter.println("In destroy");
        }
        //GJCINT
        if (isDestroyed) {
            return;
        }

        try {
            if (connectionType == ISXACONNECTION || connectionType == ISPOOLEDCONNECTION) {
                pc.close();
                pc = null;
                actualConnection = null;
            } else {
                actualConnection.close();
                actualConnection = null;
            }
        } catch (SQLException sqle) {
            isDestroyed = true;
            passwdCredential = null;
            connectionHandles = null;
            String i18nMsg = localStrings.getString(
                    "jdbc.error_in_destroy");
            ResourceException re = new ResourceException(
                    i18nMsg + sqle.getMessage(), sqle);
            throw re;
        }
        isDestroyed = true;
        passwdCredential = null;
        connectionHandles = null;
    
public voiddissociateConnections()

        myLogicalConnection.setManagedConnection(null);
    
java.sql.ConnectiongetActualConnection()
Returns the actual sql connection for this ManagedConnection.

return
the physical java.sql.Connection

        //GJCINT
        if (connectionType == ISXACONNECTION || connectionType == ISPOOLEDCONNECTION) {
            try {
                if (actualConnection == null) {
                    actualConnection = pc.getConnection();

                    //re-initialize lastAutoCommitValue such that resetAutoCommit() wont
                    // affect autoCommit of actualConnection
                    setLastAutoCommitValue(defaultAutoCommitValue);
                }

            } catch (SQLException sqle) {
                throw new ResourceException(sqle.getMessage(), sqle);
            }
        }
        return actualConnection;
    
public java.lang.ObjectgetConnection(javax.security.auth.Subject sub, javax.resource.spi.ConnectionRequestInfo cxReqInfo)
Creates a new connection handle for the underlying physical connection represented by the ManagedConnection instance.

param
sub Subject parameter needed for authentication
param
cxReqInfo ConnectionRequestInfo carries the user and password required for getting this connection.
return
Connection the connection handle Object
throws
ResourceException if there is an error in allocating the physical connection from the pooled connection
throws
javax.resource.spi.SecurityException if there is a mismatch between the password credentials or reauthentication is requested

        if (logWriter != null) {
            logWriter.println("In getConnection");
        }
        checkIfValid();
        /** Appserver any way doesnt bother about re-authentication today. So commenting this out now.
         com.sun.gjc.spi.ConnectionRequestInfo cxRequestInfo = (com.sun.gjc.spi.ConnectionRequestInfo) cxReqInfo;
         PasswordCredential passwdCred = SecurityUtils.getPasswordCredential(this.mcf, sub, cxRequestInfo);

         if(SecurityUtils.isPasswordCredentialEqual(this.passwdCredential, passwdCred) == false) {
         throw new javax.resource.spi.SecurityException("Re-authentication not supported");
         }
         **/

        //GJCINT
        getActualConnection();
        ManagedConnectionFactory spiMCF = (ManagedConnectionFactory) mcf;
        resetConnectionProperties(spiMCF);
        myLogicalConnection = spiMCF.getJdbcObjectsFactory().getConnection(
                actualConnection, this, cxReqInfo, spiMCF.isStatementWrappingEnabled());

        incrementCount();
        isClean = false;

        myLogicalConnection.setActive(true);

        return myLogicalConnection;
    
protected intgetConnectionType(javax.sql.PooledConnection pooledConn)
This method determines the type of the connection being held in this ManagedConnection.

param
pooledConn PooledConnection
return
connection type

        if (pooledConn == null) {
            return ISNOTAPOOLEDCONNECTION;
        } else if (pooledConn instanceof XAConnection) {
            return ISXACONNECTION;
        } else {
            return ISPOOLEDCONNECTION;
        }
    
public booleangetLastAutoCommitValue()

        return lastAutoCommitValue;
    
public javax.resource.spi.LocalTransactiongetLocalTransaction()
Returns an LocalTransaction instance. The LocalTransaction interface is used by the container to manage local transactions for a RM instance.

return
LocalTransaction instance
throws
ResourceException if the physical connection is not valid

        if (logWriter != null) {
            logWriter.println("In getLocalTransaction");
        }
        checkIfValid();
        return new com.sun.gjc.spi.LocalTransaction(this);
    
public java.io.PrintWritergetLogWriter()
Gets the log writer for this ManagedConnection instance.

return
PrintWriter instance associated with this ManagedConnection instance
throws
ResourceException if the physical connection is not valid
see
setLogWriter

        if (logWriter != null) {
            logWriter.println("In getLogWriter");
        }
        checkIfValid();

        return logWriter;
    
public com.sun.gjc.spi.ManagedConnectionFactorygetManagedConnectionFactory()
Returns the ManagedConnectionFactory instance that created this ManagedConnection instance.

return
ManagedConnectionFactory instance that created this ManagedConnection instance

        return (com.sun.gjc.spi.ManagedConnectionFactory) mcf;
    
public javax.resource.spi.ManagedConnectionFactorygetMcf()

        return mcf;
    
public javax.resource.spi.ManagedConnectionMetaDatagetMetaData()
Gets the metadata information for this connection's underlying EIS resource manager instance.

return
ManagedConnectionMetaData instance
throws
ResourceException if the physical connection is not valid

        if (logWriter != null) {
            logWriter.println("In getMetaData");
        }
        checkIfValid();

        return new com.sun.gjc.spi.ManagedConnectionMetaData(this);
    
javax.resource.spi.security.PasswordCredentialgetPasswordCredential()
Returns the PasswordCredential object associated with this ManagedConnection.

return
PasswordCredential associated with this ManagedConnection instance

        return passwdCredential;
    
public intgetStatementTimeout()

        return statementTimeout;
    
public javax.transaction.xa.XAResourcegetXAResource()
Returns an XAResource instance.

return
XAResource instance
throws
ResourceException if the physical connection is not valid or there is an error in allocating the XAResource instance
throws
NotSupportedException if underlying datasource is not an XADataSource

        if (logWriter != null) {
            logWriter.println("In getXAResource");
        }
        checkIfValid();

        if (connectionType == ISXACONNECTION) {
            try {
                if (xar == null) {
                    /**
                     * Using the wrapper XAResource.
                     */
                    xar = new com.sun.gjc.spi.XAResourceImpl(((XAConnection) pc).getXAResource(), this);
                }
                return xar;
            } catch (SQLException sqle) {
                throw new ResourceException(sqle.getMessage(), sqle);
            }
        } else {
            throw new NotSupportedException("Cannot get an XAResource from a non XA connection");
        }
    
public voidincrementCount()

        connectionCount++;
    
public voidinitializeConnectionType(int _connectionType)
sets the connection type of this connection. This method is called by the MCF while creating this ManagedConnection. Saves us a costly instanceof operation in the getConnectionType

        connectionType = _connectionType;
    
protected voidinvalidateAllConnectionHandles()
This method removes all the connection handles from the table of connection handles and invalidates all of them so that any operation on those connection handles throws an exception.

throws
ResourceException if there is a problem in retrieving the connection handles

        Set handles = connectionHandles.keySet();
        Iterator iter = handles.iterator();
        try {
            while (iter.hasNext()) {
                ConnectionHolder ch = (ConnectionHolder) iter.next();
                ch.invalidate();
            }
        } catch (java.util.NoSuchElementException nsee) {
            throw new ResourceException("Could not find the connection handle: " + nsee.getMessage());
        }
        connectionHandles.clear();
    
public booleanisTransactionInProgress()
Checks if a this ManagedConnection is involved in a transaction or not.

        return transactionInProgress;
    
public voidmarkForRemoval(boolean flag)

        markedForRemoval = flag;
    
public voidremoveConnectionEventListener(ConnectionEventListener listener)
Removes an already registered connection event listener from the ManagedConnection instance.

param
listener ConnectionEventListener to be removed
see
addConnectionEventListener

    
private voidresetAutoCommit()
To reset AutoCommit of actual connection. If the last-auto-commit value is different from default-auto-commit value, reset will happen. If there is a transaction in progress (because of connection sharing), reset will not happen.

throws
ResourceException

        if (defaultAutoCommitValue != getLastAutoCommitValue() && !(isTransactionInProgress())) {
            try {
                actualConnection.setAutoCommit(defaultAutoCommitValue);
            } catch (SQLException sqle) {
                String i18nMsg = localStrings.getString(
                        "jdbc.error_during_setAutoCommit");
                throw new ResourceException(i18nMsg + sqle.getMessage(), sqle);
            }
            setLastAutoCommitValue(defaultAutoCommitValue);
        }
    
private voidresetConnectionProperties(javax.resource.spi.ManagedConnectionFactory spiMCF)
Resett connection properties as connections are pooled by application server

param
spiMCF
throws
ResourceException

        /**
         * The following code in the if statement first checks if this ManagedConnection
         * is clean or not. If it is, it resets the transaction isolation level to what
         * it was when it was when this ManagedConnection was cleaned up depending on the
         * ConnectionRequestInfo passed.
         */
        if (isClean) {
            spiMCF.resetIsolation(this, lastTransactionIsolationLevel);
        }

        // reset the autocommit value of the connection if application has modified it.
        resetAutoCommit();

        String statementTimeoutString = spiMCF.getStatementTimeout();
        if (statementTimeoutString != null ){
            int timeoutValue = Integer.valueOf(statementTimeoutString);
	    if(timeoutValue >= 0){
                statementTimeout = timeoutValue;
            }
        }
    
public voidsetLastAutoCommitValue(boolean lastAutoCommitValue)
To keep track of last auto commit value. Helps to reset the auto-commit-value while giving new connection-handle.

param
lastAutoCommitValue

        this.lastAutoCommitValue = lastAutoCommitValue;
    
public voidsetLastTransactionIsolationLevel(int isolationLevel)

        lastTransactionIsolationLevel = isolationLevel;
    
public voidsetLogWriter(java.io.PrintWriter out)
Sets the log writer for this ManagedConnection instance.

param
out PrintWriter to be associated with this ManagedConnection instance
throws
ResourceException if the physical connection is not valid
see
getLogWriter

        checkIfValid();
        logWriter = out;
    
voidtransactionCompleted()
This method is called from XAResource wrapper object when its XAResource.end() has been called or from LocalTransaction object when its end() method is called.

        try {
            transactionInProgress = false;
            if (connectionType == ISPOOLEDCONNECTION || connectionType == ISXACONNECTION) {
                 if (connectionCount <= 0) {
                    try {
                        actualConnection.close();
                        actualConnection = null;
                    } catch (SQLException sqle) {
                        actualConnection = null;
                    }
                }
            }
        } catch (java.lang.NullPointerException e) {
            _logger.log(Level.FINE, "jdbc.duplicateTxCompleted");
        }

        if (markedForRemoval) {
            connectionErrorOccurred(null, null);
            _logger.log(Level.INFO, "jdbc.markedForRemoval_txCompleted");
            markedForRemoval = false;
        }

        isClean = true;
    
voidtransactionStarted()
This method is called from XAResource wrapper object when its XAResource.start() has been called or from LocalTransaction object when its begin() method is called.

        transactionInProgress = true;