alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Glassfish example source code file (ManagedConnectionFactory.java)

This example Glassfish source code file (ManagedConnectionFactory.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Glassfish tags/keywords

class, configproperty, configproperty, exception, in, io, jvm_option_statement_wrapping_not_set, jvm_option_statement_wrapping_on, log, logging, object, reflection, resourceexception, resourceexception, sql, string, string, the, the, util

The Glassfish ManagedConnectionFactory.java source code

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package com.sun.gjc.spi;

import com.sun.appserv.connectors.internal.spi.MCFLifecycleListener;
import com.sun.enterprise.util.i18n.StringManager;
import com.sun.gjc.common.DataSourceObjectBuilder;
import com.sun.gjc.common.DataSourceSpec;
import com.sun.gjc.monitoring.JdbcStatsProvider;
import com.sun.gjc.util.SQLTraceDelegator;
import com.sun.gjc.util.SecurityUtils;
import com.sun.logging.LogDomains;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import javax.resource.ResourceException;
import javax.resource.spi.ConnectionRequestInfo;
import javax.resource.spi.security.PasswordCredential;
import javax.sql.PooledConnection;
import java.sql.Connection;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.Timer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.resource.spi.ConfigProperty;
import javax.resource.spi.ResourceAdapterAssociation;
import org.glassfish.api.jdbc.ConnectionValidation;
import org.glassfish.api.jdbc.SQLTraceListener;
import org.glassfish.api.monitoring.ContainerMonitoring;
import org.glassfish.external.probe.provider.PluginPoint;
import org.glassfish.external.probe.provider.StatsProviderManager;
import org.glassfish.resource.common.PoolInfo;

/**
 * <code>ManagedConnectionFactory implementation for Generic JDBC Connector.
 * This class is extended by the DataSource specific <code>ManagedConnection factories
 * and the <code>ManagedConnectionFactory for the DriverManager.
 *
 * @author Evani Sai Surya Kiran, Aditya Gore
 * @version 1.0, 02/08/03
 */

public abstract class ManagedConnectionFactory implements javax.resource.spi.ManagedConnectionFactory,
        javax.resource.spi.ValidatingManagedConnectionFactory, 
        MCFLifecycleListener, ResourceAdapterAssociation,
        java.io.Serializable, Externalizable {

    protected DataSourceSpec spec = new DataSourceSpec();
    protected transient DataSourceObjectBuilder dsObjBuilder;

    protected java.io.PrintWriter logWriter = null;
    protected transient javax.resource.spi.ResourceAdapter ra = null;

    private static Logger _logger;
    protected boolean statementWrapping;

    private JdbcObjectsFactory jdbcObjectsFactory = JdbcObjectsFactory.getInstance();
    protected SQLTraceDelegator sqlTraceDelegator;

    static {
        _logger = LogDomains.getLogger(ManagedConnectionFactory.class, LogDomains.RSR_LOGGER);
    }

    protected javax.resource.spi.LazyEnlistableConnectionManager cm_;
    protected boolean isLazyCm_;
    private int statementCacheSize = 0;
    private String statementCacheType = null;
    private long statementLeakTimeout = 0;
    private boolean statementLeakReclaim = false;

    //Jdbc Stats provider that is created
    private JdbcStatsProvider jdbcStatsProvider = null;

    protected static final StringManager localStrings =
            StringManager.getManager(DataSourceObjectBuilder.class);

    /**
     * Creates a Connection Factory instance. The <code>ConnectionManager implementation
     * of the resource adapter is used here.
     *
     * @return Generic JDBC Connector implementation of <code>javax.sql.DataSource
     */
    public Object createConnectionFactory() {
        logFine("In createConnectionFactory()");
        return jdbcObjectsFactory.getDataSourceInstance(this, null);
    }

    /**
     * Creates a Connection Factory instance. The <code>ConnectionManager implementation
     * of the application server is used here.
     *
     * @param cxManager <code>ConnectionManager passed by the application server
     * @return Generic JDBC Connector implementation of <code>javax.sql.DataSource
     */
    public Object createConnectionFactory(javax.resource.spi.ConnectionManager cxManager) {
        logFine("In createConnectionFactory(javax.resource.spi.ConnectionManager cxManager)");

        javax.sql.DataSource cf = jdbcObjectsFactory.getDataSourceInstance(this, cxManager);

        if (cxManager instanceof javax.resource.spi.LazyEnlistableConnectionManager) {
            cm_ = (javax.resource.spi.LazyEnlistableConnectionManager) cxManager;
            isLazyCm_ = true;
        }
        return cf;
    }

    /**
     * Creates a new physical connection to the underlying EIS resource
     * manager.
     *
     * @param subject       <code>Subject instance passed by the application server
     * @param cxRequestInfo <code>ConnectionRequestInfo which may be created
     *                      as a result of the invocation <code>getConnection(user, password)
     *                      on the <code>DataSource object
     * @return <code>ManagedConnection object created
     * @throws ResourceException if there is an error in instantiating the
     *                           <code>DataSource object used for the
     *                           creation of the <code>ManagedConnection object
     * @throws SecurityException if there ino <code>PasswordCredential object
     *                           satisfying this request
     * @throws ResourceException if there is an error in allocating the
     *                           physical connection
     */
    public abstract javax.resource.spi.ManagedConnection createManagedConnection
            (javax.security.auth.Subject subject, ConnectionRequestInfo cxRequestInfo) throws ResourceException;

    /**
     * Check if this <code>ManagedConnectionFactory is equal to
     * another <code>ManagedConnectionFactory.
     *
     * @param other <code>ManagedConnectionFactory object for checking equality with
     * @return true    if the property sets of both the
     *         <code>ManagedConnectionFactory objects are the same
     *         false	otherwise
     */
    public abstract boolean equals(Object other);

    /**
     * Get the log writer for this <code>ManagedConnectionFactory instance.
     *
     * @return <code>PrintWriter associated with this ManagedConnectionFactory instance
     * @see <code>setLogWriter
     */
    public java.io.PrintWriter getLogWriter() {
        return logWriter;
    }

    /**
     * Get the <code>ResourceAdapter for this ManagedConnectionFactory instance.
     *
     * @return <code>ResourceAdapter associated with this ManagedConnectionFactory instance
     * @see <code>setResourceAdapter
     */
    public javax.resource.spi.ResourceAdapter getResourceAdapter() {
        logFine("In getResourceAdapter");
        return ra;
    }

    /**
     * Returns the hash code for this <code>ManagedConnectionFactory.
     *
     * @return hash code for this <code>ManagedConnectionFactory
     */
    public int hashCode() {
        logFine("In hashCode");
        return spec.hashCode();
    }

    /**
     * Returns a matched <code>ManagedConnection from the candidate
     * set of <code>ManagedConnection objects.
     *
     * @param connectionSet <code>Set of  ManagedConnection
     *                      objects passed by the application server
     * @param subject       passed by the application server
     *                      for retrieving information required for matching
     * @param cxRequestInfo <code>ConnectionRequestInfo passed by the application server
     *                      for retrieving information required for matching
     * @return <code>ManagedConnection that is the best match satisfying this request
     * @throws ResourceException if there is an error accessing the <code>Subject
     *                           parameter or the <code>Set of ManagedConnection
     *                           objects passed by the application server
     */
    public javax.resource.spi.ManagedConnection matchManagedConnections(
            java.util.Set connectionSet, javax.security.auth.Subject subject, ConnectionRequestInfo cxRequestInfo)
            throws ResourceException {
        logFine("In matchManagedConnections");

        if (connectionSet == null) {
            return null;
        }


        PasswordCredential pc = SecurityUtils.getPasswordCredential(this, subject, cxRequestInfo);

        java.util.Iterator iter = connectionSet.iterator();
        com.sun.gjc.spi.ManagedConnection mc = null;

        while (iter.hasNext()) {
            try {
                mc = (com.sun.gjc.spi.ManagedConnection) iter.next();
            } catch (java.util.NoSuchElementException nsee) {
                _logger.log(Level.SEVERE, "jdbc.exc_iter");
                throw new ResourceException(nsee.getMessage());
            }
            if (pc == null && this.equals(mc.getManagedConnectionFactory())) {
                return mc;
            } else if (SecurityUtils.isPasswordCredentialEqual(pc, mc.getPasswordCredential())) {
                return mc;
            }
        }
        return null;
    }

    /**
     * This method returns a set of invalid <code>ManagedConnection
     * objects chosen from a specified set of <code>ManagedConnection
     * objects.
     *
     * @param connectionSet a set of <code>ManagedConnection objects
     *                      that need to be validated.
     * @return a set of invalid <code>ManagedConnection objects.
     * @throws ResourceException generic exception.
     */
    public Set getInvalidConnections(Set connectionSet) throws ResourceException {
        Iterator iter = connectionSet.iterator();
        Set<ManagedConnection> invalidConnections = new HashSet();
        while (iter.hasNext()) {
            ManagedConnection mc = (ManagedConnection) iter.next();
            try {
                isValid(mc);
            } catch (ResourceException re) {
                invalidConnections.add(mc);
                mc.connectionErrorOccurred(re, null);
                if (_logger.isLoggable(Level.FINE)) {
                    _logger.log(Level.FINE, "jdbc.invalid_connection", re);
                }
            }
        }
        return invalidConnections;
    }

    //GJCINT

    /**
     * Checks if a <code>ManagedConnection is to be validated or not
     * and validates it or returns.
     *
     * @param mc <code>ManagedConnection to be validated
     * @throws ResourceException if the connection is not valid or
     *                           if validation method is not proper
     */
    void isValid(com.sun.gjc.spi.ManagedConnection mc) throws ResourceException {

        if (mc == null || mc.isTransactionInProgress()) {
            return;
        }

        String conVal = spec.getDetail(DataSourceSpec.CONNECTIONVALIDATIONREQUIRED);

        boolean connectionValidationRequired =
                (conVal == null) ? false : Boolean.valueOf(conVal.toLowerCase());
        if (!connectionValidationRequired) {
            return;
        }


        String validationMethod = spec.getDetail(DataSourceSpec.VALIDATIONMETHOD).toLowerCase();

        mc.checkIfValid();
        /**
         * The above call checks if the actual physical connection
         * is usable or not.
         */
        java.sql.Connection con = mc.getActualConnection();

        if(validationMethod.equals("custom-validation")) {
            isValidByCustomValidation(con, spec.getDetail(DataSourceSpec.VALIDATIONCLASSNAME));
        } else if (validationMethod.equals("auto-commit")) {
            isValidByAutoCommit(con);
        } else if (validationMethod.equals("meta-data")) {
            isValidByMetaData(con);
        } else if (validationMethod.equals("table")) {
            isValidByTableQuery(con, spec.getDetail(DataSourceSpec.VALIDATIONTABLENAME));
        } else {
            throw new ResourceException("The validation method is not proper");
        }
    }
    
    /**
     * Checks if a <code>java.sql.Connection is valid or not
     * by doing a custom validation using the validation class name specified.
     *
     * @param con <code>java.sql.Connection to be validated
     * @throws ResourceException if the connection is not valid
     */    
    protected void isValidByCustomValidation(java.sql.Connection con, 
            String validationClassName) throws ResourceException {
        boolean isValid = false;
        if (con == null) {
            throw new ResourceException("The connection is not valid as "
                    + "the connection is null");
        }
        
        try {
            Class validationClass = Thread.currentThread().getContextClassLoader().loadClass(validationClassName);
            ConnectionValidation valClass = (ConnectionValidation) validationClass.newInstance();
            isValid = valClass.isConnectionValid(con);
        } catch (Exception e) {
            _logger.log(Level.INFO, "jdbc.exc_custom_validation", validationClassName);
            throw new ResourceException(e);
        }
        if (!isValid) {
            _logger.log(Level.INFO, "jdbc.exc_custom_validation", validationClassName);
            throw new ResourceException("Custom validation detected invalid connection");
        }
    }

    /**
     * Checks if a <code>java.sql.Connection is valid or not
     * by checking its auto commit property.
     *
     * @param con <code>java.sql.Connection to be validated
     * @throws ResourceException if the connection is not valid
     */
    protected void isValidByAutoCommit(java.sql.Connection con) throws ResourceException {
        if (con == null) {
            throw new ResourceException("The connection is not valid as "
                    + "the connection is null");
        }

        try {
            // Notice that using something like
            // dbCon.setAutoCommit(dbCon.getAutoCommit()) will cause problems with
            // some drivers like sybase
            // We do not validate connections that are already enlisted
            //in a transaction
            // We cycle autocommit to true and false to by-pass drivers that
            // might cache the call to set autocomitt
            // Also notice that some XA data sources will throw and exception if
            // you try to call setAutoCommit, for them this method is not recommended

            boolean ac = con.getAutoCommit();
            if (ac) {
                con.setAutoCommit(false);
            } else {
                con.rollback(); // prevents uncompleted transaction exceptions
                con.setAutoCommit(true);
            }

            con.setAutoCommit(ac);

        } catch (Exception sqle) {
            _logger.log(Level.INFO, "jdbc.exc_autocommit_validation");
            throw new ResourceException(sqle);
        }
    }

    /**
     * Checks if a <code>java.sql.Connection is valid or not
     * by checking its meta data.
     *
     * @param con <code>java.sql.Connection to be validated
     * @throws ResourceException if the connection is not valid
     */
    protected void isValidByMetaData(java.sql.Connection con) throws ResourceException {
        if (con == null) {
            throw new ResourceException("The connection is not valid as "
                    + "the connection is null");
        }

        try {
            con.getMetaData();
        } catch (Exception sqle) {
            _logger.log(Level.INFO, "jdbc.exc_metadata_validation");
            throw new ResourceException(sqle);
        }
    }

    /**
     * Checks if a <code>java.sql.Connection is valid or not
     * by querying a table.
     *
     * @param con       <code>java.sql.Connection to be validated
     * @param tableName table which should be queried
     * @throws ResourceException if the connection is not valid
     */
    protected void isValidByTableQuery(java.sql.Connection con,
                                       String tableName) throws ResourceException {
        if (con == null) {
            throw new ResourceException("The connection is not valid as "
                    + "the connection is null");
        }

        java.sql.PreparedStatement stmt = null;
        java.sql.ResultSet rs = null;
        try {
            stmt = con.prepareStatement("SELECT COUNT(*) FROM " + tableName);
            rs = stmt.executeQuery();
        } catch (Exception sqle) {
            _logger.log(Level.INFO, "jdbc.exc_table_validation", tableName);
            throw new ResourceException(sqle);
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
            } catch (Exception e1) {
            }

            try {
                if (stmt != null) {
                    stmt.close();
                }
            } catch (Exception e2) {
            }
        }
    }

    /**
     * Sets the isolation level specified in the <code>ConnectionRequestInfo
     * for the <code>ManagedConnection passed.
     *
     * @param mc <code>ManagedConnection
     * @throws ResourceException if the isolation property is invalid
     *                           or if the isolation cannot be set over the connection
     */
    protected void setIsolation(com.sun.gjc.spi.ManagedConnection mc) throws ResourceException {

        java.sql.Connection con = mc.getActualConnection();
        if (con == null) {
            return;
        }

        String tranIsolation = spec.getDetail(DataSourceSpec.TRANSACTIONISOLATION);
        if (tranIsolation != null && !tranIsolation.equals("")) {
            int tranIsolationInt = getTransactionIsolationInt(tranIsolation);
            try {
                con.setTransactionIsolation(tranIsolationInt);
                mc.setLastTransactionIsolationLevel(tranIsolationInt);
            } catch (java.sql.SQLException sqle) {
                _logger.log(Level.SEVERE, "jdbc.exc_tx_iso", sqle);
                throw new ResourceException("The transaction isolation could "
                        + "not be set: " + sqle.getMessage());
            }
        }
    }

    /**
     * Resets the isolation level for the <code>ManagedConnection passed.
     * If the transaction level is to be guaranteed to be the same as the one
     * present when this <code>ManagedConnection was created, as specified
     * by the <code>ConnectionRequestInfo passed, it sets the transaction
     * isolation level from the <code>ConnectionRequestInfo passed. Else,
     * it sets it to the transaction isolation passed.
     *
     * @param mc       <code>ManagedConnection
     * @param tranIsol int
     * @throws ResourceException if the isolation property is invalid
     *                           or if the isolation cannot be set over the connection
     */
    void resetIsolation(com.sun.gjc.spi.ManagedConnection mc, int tranIsol) throws ResourceException {

        java.sql.Connection con = mc.getActualConnection();
        if (con == null) {
            return;
        }

        String tranIsolation = spec.getDetail(DataSourceSpec.TRANSACTIONISOLATION);
        if (tranIsolation != null && !tranIsolation.equals("")) {
            String guaranteeIsolationLevel = spec.getDetail(DataSourceSpec.GUARANTEEISOLATIONLEVEL);

            if (guaranteeIsolationLevel != null && !guaranteeIsolationLevel.equals("")) {
                boolean guarantee = Boolean.valueOf(guaranteeIsolationLevel.toLowerCase());

                if (guarantee) {
                    int tranIsolationInt = getTransactionIsolationInt(tranIsolation);
                    try {
                        if (tranIsolationInt != con.getTransactionIsolation()) {
                            con.setTransactionIsolation(tranIsolationInt);
                        }
                    } catch (java.sql.SQLException sqle) {
                        _logger.log(Level.SEVERE, "jdbc.exc_tx_iso", sqle);
                        throw new ResourceException("The isolation level could not be set: "
                                + sqle.getMessage());
                    }
                } else {
                    try {
                        if (tranIsol != con.getTransactionIsolation()) {
                            con.setTransactionIsolation(tranIsol);
                        }
                    } catch (java.sql.SQLException sqle) {
                        _logger.log(Level.SEVERE, "jdbc.exc_tx_iso", sqle);
                        throw new ResourceException("The isolation level could not be set: "
                                + sqle.getMessage());
                    }
                }
            }
        }
    }

    private void detectSqlTraceListeners() {
        //Check for sql-trace-listeners attribute.
        String sqlTraceListeners = getSqlTraceListeners();
        String delimiter = ",";
        
        if(sqlTraceListeners != null && !sqlTraceListeners.equals("null")) {
            sqlTraceDelegator = new SQLTraceDelegator(getPoolName(), getApplicationName(), getModuleName());
            StringTokenizer st = new StringTokenizer(sqlTraceListeners, delimiter);
            while (st.hasMoreTokens()) {
                String sqlTraceListener = st.nextToken().trim();            
                if(!sqlTraceListener.equals("")) {
                    Class listenerClass = null;
                    SQLTraceListener listener = null;
                    Constructor[] constructors = null;
                    Class[] parameterTypes = null;                    
                    Object[] initargs = null;
                    //Load the listener class 
                    try {
                        listenerClass = Thread.currentThread().getContextClassLoader().loadClass(sqlTraceListener);
                    } catch (ClassNotFoundException ex) {
                        _logger.log(Level.SEVERE, "jdbc.sql_trace_listener_cnfe", sqlTraceListener);
                    }
                    Class intf[] = listenerClass.getInterfaces();
                    for (int i = 0; i < intf.length; i++) {
                        Class interfaceName = intf[i];
                        if (interfaceName.getName().equals("org.glassfish.api.jdbc.SQLTraceListener")) {

                            try {

                                constructors = listenerClass.getConstructors();
                                for (Constructor constructor : constructors) {
                                    parameterTypes = constructor.getParameterTypes();
                                    //For now only the no argument constructors are allowed.
                                    //TODO should this be documented?
                                    if (parameterTypes != null && parameterTypes.length == 0) {
                                        listener = (SQLTraceListener) constructor.newInstance(initargs);
                                    }
                                }
                            } catch (InstantiationException ex) {
                                _logger.log(Level.SEVERE, "jdbc.sql_trace_listener_exception", ex.getMessage());
                            } catch (IllegalAccessException ex) {
                                _logger.log(Level.SEVERE, "jdbc.sql_trace_listener_exception", ex.getMessage());
                            } catch (IllegalArgumentException ex) {
                                _logger.log(Level.SEVERE, "jdbc.sql_trace_listener_exception", ex.getMessage());
                            } catch (InvocationTargetException ex) {
                                _logger.log(Level.SEVERE, "jdbc.sql_trace_listener_exception", ex.getMessage());
                            } catch (SecurityException ex) {
                                _logger.log(Level.SEVERE, "jdbc.sql_trace_listener_exception", ex.getMessage());
                            }
                            sqlTraceDelegator.registerSQLTraceListener(listener);
                        }
                    }
                }
            }
        }
    }


    /**
     * Gets the integer equivalent of the string specifying
     * the transaction isolation.
     *
     * @param tranIsolation string specifying the isolation level
     * @return tranIsolationInt    the <code>java.sql.Connection constant
     *         for the string specifying the isolation.
     */
    private int getTransactionIsolationInt(String tranIsolation) throws ResourceException {
        if (tranIsolation.equalsIgnoreCase("read-uncommitted")) {
            return java.sql.Connection.TRANSACTION_READ_UNCOMMITTED;
        } else if (tranIsolation.equalsIgnoreCase("read-committed")) {
            return java.sql.Connection.TRANSACTION_READ_COMMITTED;
        } else if (tranIsolation.equalsIgnoreCase("repeatable-read")) {
            return java.sql.Connection.TRANSACTION_REPEATABLE_READ;
        } else if (tranIsolation.equalsIgnoreCase("serializable")) {
            return java.sql.Connection.TRANSACTION_SERIALIZABLE;
        } else {
            throw new ResourceException("Invalid transaction isolation; the transaction "
                    + "isolation level can be empty or any of the following: "
                    + "read-uncommitted, read-committed, repeatable-read, serializable");
        }
    }

    /**
     * Common operation performed by all the child MCFs before returning a created mc
     */
    protected void validateAndSetIsolation(ManagedConnection mc) throws ResourceException {
        isValid(mc);
        setIsolation(mc);
    }

    private void detectStatementCachingSupport() {
        String cacheSize = getStatementCacheSize();
        String cacheType = getStatementCacheType();
        if(cacheSize != null){
            try{
                statementCacheSize = Integer.valueOf(cacheSize);
                //TODO-SC FINE log-level with Pool Name (if possible)
                if(_logger.isLoggable(Level.FINE)) {
                    _logger.log(Level.FINE, "StatementCaching Size : " + statementCacheSize);
                }
                if(cacheType == null || cacheType.trim().equals("")) {
                    if(_logger.isLoggable(Level.FINE)) {
                        _logger.fine(" Default StatementCaching Type : " +
                                localStrings.getString("jdbc.statement-cache.default.datastructure"));
                    }
                } else {
                    if(_logger.isLoggable(Level.FINE)) {
                        _logger.fine("StatementCaching Type : " + cacheType);
                    }
                }
            }catch(NumberFormatException nfe){
                if(_logger.isLoggable(Level.FINE)) {
                    _logger.fine("Exception while setting StatementCacheSize : " +
                        nfe.getMessage());
                }
                //ignore
            }
        } 
    }

    /**
     * Set the log writer for this <code>ManagedConnectionFactory instance.
     *
     * @param out <code>PrintWriter passed by the application server
     * @see <code>getLogWriter
     */
    public void setLogWriter(java.io.PrintWriter out) {
        logWriter = out;
    }

    /**
     * Set the associated <code>ResourceAdapter JavaBean.
     *
     * @param ra <code>ResourceAdapter associated with this
     *           <code>ManagedConnectionFactory instance
     * @see <code>getResourceAdapter
     */
    public void setResourceAdapter(javax.resource.spi.ResourceAdapter ra) {
        this.ra = ra;
    }

    /**
     * Sets the user name
     *
     * @param user <code>String
     */
    @ConfigProperty(type = String.class, defaultValue = "APP")
    public void setUser(String user) {
        spec.setDetail(DataSourceSpec.USERNAME, user);
    }

    /**
     * Gets the user name
     *
     * @return user
     */
    public String getUser() {
        return spec.getDetail(DataSourceSpec.USERNAME);
    }

    /**
     * Sets the password
     *
     * @param passwd <code>String
     */
    @ConfigProperty(type = String.class, defaultValue = "APP")
    public void setPassword(String passwd) {
        spec.setDetail(DataSourceSpec.PASSWORD, passwd);
    }

    /**
     * Gets the password
     *
     * @return passwd
     */
    public String getPassword() {
        return spec.getDetail(DataSourceSpec.PASSWORD);
    }

    /**
     * Sets the class name of the data source
     *
     * @param className <code>String
     */
    @ConfigProperty(type = String.class, defaultValue = "org.apache.derby.jdbc.ClientConnectionPoolDataSource")
    public void setClassName(String className) {
        spec.setDetail(DataSourceSpec.CLASSNAME, className);
    }

    /**
     * Gets the class name of the data source
     *
     * @return className
     */
    public String getClassName() {
        return spec.getDetail(DataSourceSpec.CLASSNAME);
    }

    /**
     * Sets if connection validation is required or not
     *
     * @param conVldReq <code>String
     */
    @ConfigProperty(type = String.class, defaultValue = "false")
    public void setConnectionValidationRequired(String conVldReq) {
        spec.setDetail(DataSourceSpec.CONNECTIONVALIDATIONREQUIRED, conVldReq);
    }

    /**
     * Returns if connection validation is required or not
     *
     * @return connection validation requirement
     */
    public String getConnectionValidationRequired() {
        return spec.getDetail(DataSourceSpec.CONNECTIONVALIDATIONREQUIRED);
    }

    /**
     * Sets the validation method required
     *
     * @param validationMethod <code>String
     */
    @ConfigProperty(type = String.class, defaultValue = "")
    public void setValidationMethod(String validationMethod) {
        spec.setDetail(DataSourceSpec.VALIDATIONMETHOD, validationMethod);
    }

    /**
     * Returns the connection validation method type
     *
     * @return validation method
     */
    public String getValidationMethod() {
        return spec.getDetail(DataSourceSpec.VALIDATIONMETHOD);
    }

    /**
     * Sets the table checked for during validation
     *
     * @param table <code>String
     */
    @ConfigProperty(type = String.class, defaultValue = "")
    public void setValidationTableName(String table) {
        spec.setDetail(DataSourceSpec.VALIDATIONTABLENAME, table);
    }

    /**
     * Returns the table checked for during validation
     *
     * @return table
     */
    public String getValidationTableName() {
        return spec.getDetail(DataSourceSpec.VALIDATIONTABLENAME);
    }

    /**
     * Sets the validation class name checked for during validation
     *
     * @param table <code>String
     */
    public void setValidationClassName(String className) {
        try {
            Class validationClass = Thread.currentThread().getContextClassLoader().loadClass(className);
            boolean isAssignable = ConnectionValidation.class.isAssignableFrom(validationClass);
            if (isAssignable) {
                spec.setDetail(DataSourceSpec.VALIDATIONCLASSNAME, className);
            } else {
                //Validation Failed
                _logger.log(Level.SEVERE, "jdbc.set_custom_validation_class_name_failure", className);
                throw new ResourceException("The Custom validation class name is" +
                        "not valid as it does not implement " +
                        ConnectionValidation.class.getName());
            }
        } catch (ResourceException ex) {
            _logger.log(Level.SEVERE, "jdbc.set_custom_validation_class_name_failure",
                    ex.getMessage());
        } catch (ClassNotFoundException ex) {
            _logger.log(Level.SEVERE, "jdbc.set_custom_validation_class_name_failure",
                    ex.getMessage());
        }
    }

    /**
     * Returns the validation class name checked for during validation
     *
     * @return table
     */
    public String getValidationClassName() {
        return spec.getDetail(DataSourceSpec.VALIDATIONCLASSNAME);
    }

    /**
     * Sets the transaction isolation level
     *
     * @param trnIsolation <code>String
     */
    @ConfigProperty(type = String.class, defaultValue = "")
    public void setTransactionIsolation(String trnIsolation) {
        spec.setDetail(DataSourceSpec.TRANSACTIONISOLATION, trnIsolation);
    }

    /**
     * Returns the transaction isolation level
     *
     * @return transaction isolation level
     */
    public String getTransactionIsolation() {
        return spec.getDetail(DataSourceSpec.TRANSACTIONISOLATION);
    }

    /**
     * Sets if the transaction isolation level is to be guaranteed
     *
     * @param guaranteeIsolation <code>String
     */
    @ConfigProperty(type = String.class, defaultValue = "")
    public void setGuaranteeIsolationLevel(String guaranteeIsolation) {
        spec.setDetail(DataSourceSpec.GUARANTEEISOLATIONLEVEL, guaranteeIsolation);
    }

    /**
     * Returns the transaction isolation level
     *
     * @return isolation level guarantee
     */
    public String getGuaranteeIsolationLevel() {
        return spec.getDetail(DataSourceSpec.GUARANTEEISOLATIONLEVEL);
    }

    protected boolean isEqual(PasswordCredential pc, String user,
                              String password) {

        //if equal get direct connection else
        //get connection with user and password.

        String thisUser = (pc == null) ? null : pc.getUserName();
        char[] passwordArray = (pc == null) ? null : pc.getPassword();
        char[] tmpPasswordArray = (password == null) ? null : password.toCharArray();

        return (isStringEqual(thisUser, user) &&
                Arrays.equals(passwordArray, tmpPasswordArray));

    }

    private boolean isStringEqual(String str1, String str2) {
        return str1 == null ? str2 == null : str1.equals(str2);
    }

    /**
     * Sets the server name.
     *
     * @param serverName <code>String
     * @see <code>getServerName
     */
    @ConfigProperty(type = String.class, defaultValue = "localhost")
    public void setServerName(String serverName) {
        spec.setDetail(DataSourceSpec.SERVERNAME, serverName);
    }

    /**
     * Gets the server name.
     *
     * @return serverName
     * @see <code>setServerName
     */
    public String getServerName() {
        return spec.getDetail(DataSourceSpec.SERVERNAME);
    }

    /**
     * Sets the port number.
     *
     * @param portNumber <code>String
     * @see <code>getPortNumber
     */
    @ConfigProperty(type = String.class, defaultValue = "1527")
    public void setPortNumber(String portNumber) {
        spec.setDetail(DataSourceSpec.PORTNUMBER, portNumber);
    }

    /**
     * Gets the port number.
     *
     * @return portNumber
     * @see <code>setPortNumber
     */
    public String getPortNumber() {
        return spec.getDetail(DataSourceSpec.PORTNUMBER);
    }

    public void setJdbc30DataSource(String booleanValue) {
        spec.setDetail(DataSourceSpec.JDBC30DATASOURCE, booleanValue);
    }

    public String getJdbc30DataSource() {
        return spec.getDetail(DataSourceSpec.JDBC30DATASOURCE);
    }

    /**
     * Sets the database name.
     *
     * @param databaseName <code>String
     * @see <code>getDatabaseName
     */
    @ConfigProperty(type = String.class, defaultValue = "testdb")
    public void setDatabaseName(String databaseName) {
        spec.setDetail(DataSourceSpec.DATABASENAME, databaseName);
    }

    /**
     * Gets the database name.
     *
     * @return databaseName
     * @see <code>setDatabaseName
     */
    public String getDatabaseName() {
        return spec.getDetail(DataSourceSpec.DATABASENAME);
    }

    /**
     * Sets the data source name.
     *
     * @param dsn <code>String
     * @see <code>getDataSourceName
     */
    @ConfigProperty(type = String.class, defaultValue = "")
    public void setDataSourceName(String dsn) {
        spec.setDetail(DataSourceSpec.DATASOURCENAME, dsn);
    }

    /**
     * Gets the data source name.
     *
     * @return dsn
     * @see <code>setDataSourceName
     */
    public String getDataSourceName() {
        return spec.getDetail(DataSourceSpec.DATASOURCENAME);
    }

    /**
     * Set Statement Wrapping value
     *
     * @param wrapping <code>String
     * @see <code> getStatementWrapping 
     */
    public void setStatementWrapping(String wrapping) {
        spec.setDetail(DataSourceSpec.STATEMENTWRAPPING, wrapping);
        computeStatementWrappingStatus();
    }

    /**
     * Gets the statement wrapping value
     *
     * @return String representing "true" or "false"
     * @see <code>setStatementWrapping
     */
    public String getStatementWrapping() {
        return spec.getDetail(DataSourceSpec.STATEMENTWRAPPING);
    }

    public void setStatementCacheSize(String value){
        spec.setDetail(DataSourceSpec.STATEMENTCACHESIZE, value);
        detectStatementCachingSupport();
    }

    public String getStatementCacheSize(){
        return spec.getDetail(DataSourceSpec.STATEMENTCACHESIZE);
    }

    public void setStatementLeakTimeoutInSeconds(String value){
        spec.setDetail(DataSourceSpec.STATEMENTLEAKTIMEOUTINSECONDS, value);
        detectStatementLeakSupport();
    }

    public String getStatementLeakTimeoutInSeconds(){
        return spec.getDetail(DataSourceSpec.STATEMENTLEAKTIMEOUTINSECONDS);
    }

    public void setStatementLeakReclaim(String value) {
        spec.setDetail(DataSourceSpec.STATEMENTLEAKRECLAIM, value);
    }

    public String getStatementLeakReclaim() {
        return spec.getDetail(DataSourceSpec.STATEMENTLEAKRECLAIM);
    }

    public void setPoolMonitoringSubTreeRoot(String value) {
        spec.setDetail(DataSourceSpec.POOLMONITORINGSUBTREEROOT, value);
    }

    public String getPoolMonitoringSubTreeRoot() {
        return spec.getDetail(DataSourceSpec.POOLMONITORINGSUBTREEROOT);
    }

    public String getApplicationName() {
        return spec.getDetail(DataSourceSpec.APPLICATIONNAME);
    }

    public void setApplicationName(String value) {
        spec.setDetail(DataSourceSpec.APPLICATIONNAME, value);
    }

    public String getModuleName() {
        return spec.getDetail(DataSourceSpec.MODULENAME);
    }

    public void setModuleName(String value) {
        spec.setDetail(DataSourceSpec.MODULENAME, value);
    }

    public String getPoolName() {
        return spec.getDetail(DataSourceSpec.POOLNAME);
    }

    public void setPoolName(String value) {
        spec.setDetail(DataSourceSpec.POOLNAME, value);
    }

    public String getStatementCacheType() {
        return spec.getDetail(DataSourceSpec.STATEMENTCACHETYPE);
    }

    public void setStatementCacheType(String statementCacheType) {
        spec.setDetail(DataSourceSpec.STATEMENTCACHETYPE, statementCacheType);
    }

    public String getNumberOfTopQueriesToReport() {
        return spec.getDetail(DataSourceSpec.NUMBEROFTOPQUERIESTOREPORT);
    }

    public void setNumberOfTopQueriesToReport(String numTopQueriesToReport) {
        spec.setDetail(DataSourceSpec.NUMBEROFTOPQUERIESTOREPORT, numTopQueriesToReport);
    }

    public String getTimeToKeepQueriesInMinutes() {
        return spec.getDetail(DataSourceSpec.TIMETOKEEPQUERIESINMINUTES);
    }

    public void setTimeToKeepQueriesInMinutes(String timeToKeepQueries) {
        spec.setDetail(DataSourceSpec.TIMETOKEEPQUERIESINMINUTES, timeToKeepQueries);
    }
    
    public String getInitSql() {
        return spec.getDetail(DataSourceSpec.INITSQL);
    }

    public void setInitSql(String initSql) {
        //TODO remove case where "null" is checked. Might be a CLI/GUI bug.
        if(initSql != null && !initSql.equalsIgnoreCase("null") && 
                !initSql.equals("")) {
            spec.setDetail(DataSourceSpec.INITSQL, initSql);
        }
    }
    
    /**
     * Set StatementTimeout value
     *
     * @param timeout <code>String
     * @see <code> getStatementTimeout 
     */
    public void setStatementTimeout(String timeout) {
        spec.setDetail(DataSourceSpec.STATEMENTTIMEOUT, timeout);
    }

    /**
     * Gets the StatementTimeout value
     *
     * @return String representing "true" or "false"
     * @see <code>setStatementTimeout
     */
    public String getStatementTimeout() {
        return spec.getDetail(DataSourceSpec.STATEMENTTIMEOUT);
    }
    
    public String getSqlTraceListeners() {
        return spec.getDetail(DataSourceSpec.SQLTRACELISTENERS);
    }

    public void setSqlTraceListeners(String sqlTraceListeners) {
        if(sqlTraceListeners != null) {
            spec.setDetail(DataSourceSpec.SQLTRACELISTENERS, sqlTraceListeners);
            detectSqlTraceListeners();
        }
    }
    
    /**
     * Sets the description.
     *
     * @param desc <code>String
     * @see <code>getDescription
     */
    @ConfigProperty(type = String.class, defaultValue = "Derby driver for datasource")
    public void setDescription(String desc) {
        spec.setDetail(DataSourceSpec.DESCRIPTION, desc);
    }

    /**
     * Gets the description.
     *
     * @return desc
     * @see <code>setDescription
     */
    public String getDescription() {
        return spec.getDetail(DataSourceSpec.DESCRIPTION);
    }

    /**
     * Sets the network protocol.
     *
     * @param nwProtocol <code>String
     * @see <code>getNetworkProtocol
     */
    @ConfigProperty(type = String.class, defaultValue = "")
    public void setNetworkProtocol(String nwProtocol) {
        spec.setDetail(DataSourceSpec.NETWORKPROTOCOL, nwProtocol);
    }

    /**
     * Gets the network protocol.
     *
     * @return nwProtocol
     * @see <code>setNetworkProtocol
     */
    public String getNetworkProtocol() {
        return spec.getDetail(DataSourceSpec.NETWORKPROTOCOL);
    }

    /**
     * Sets the role name.
     *
     * @param roleName <code>String
     * @see <code>getRoleName
     */
    @ConfigProperty(type = String.class, defaultValue = "")
    public void setRoleName(String roleName) {
        spec.setDetail(DataSourceSpec.ROLENAME, roleName);
    }

    /**
     * Gets the role name.
     *
     * @return roleName
     * @see <code>setRoleName
     */
    public String getRoleName() {
        return spec.getDetail(DataSourceSpec.ROLENAME);
    }

    /**
     * Sets the login timeout.
     *
     * @param loginTimeOut <code>String
     * @see <code>getLoginTimeOut
     */
    @ConfigProperty(type = String.class, defaultValue = "0")
    public void setLoginTimeOut(String loginTimeOut) {
        spec.setDetail(DataSourceSpec.LOGINTIMEOUT, loginTimeOut);
    }

    /**
     * Gets the login timeout.
     *
     * @return loginTimeout
     * @see <code>setLoginTimeOut
     */
    public String getLoginTimeOut() {
        return spec.getDetail(DataSourceSpec.LOGINTIMEOUT);
    }

    /**
     * Sets the delimiter.
     *
     * @param delim <code>String
     * @see <code>getDelimiter
     */
    @ConfigProperty(type = String.class, defaultValue = "#")
    public void setDelimiter(String delim) {
        spec.setDetail(DataSourceSpec.DELIMITER, delim);
    }

    /**
     * Gets the delimiter.
     *
     * @return delim
     * @see <code>setDelimiter
     */
    public String getDelimiter() {
        return spec.getDetail(DataSourceSpec.DELIMITER);
    }

    public void setEscapeCharacter(String escapeCharacter){
        spec.setDetail(DataSourceSpec.ESCAPECHARACTER, escapeCharacter);
    }

    public String getEscapeCharacter(){
        return spec.getDetail(DataSourceSpec.ESCAPECHARACTER);
    }

      /**
     * Sets the driver specific properties.
     *
     * @param driverProps <code>String
     * @see <code>getDriverProperties
     */
    @ConfigProperty(type = String.class, defaultValue = "")
    public void setDriverProperties(String driverProps) {
        spec.setDetail(DataSourceSpec.DRIVERPROPERTIES, driverProps);
    }

    /**
     * Gets the driver specific properties.
     *
     * @return driverProps
     * @see <code>setDriverProperties
     */
    public String getDriverProperties() {
        return spec.getDetail(DataSourceSpec.DRIVERPROPERTIES);
    }

    protected PoolInfo getPoolInfo(){
        return new PoolInfo(getPoolName(), getApplicationName(), getModuleName());    
    }

    protected ManagedConnection constructManagedConnection(PooledConnection pc,
                                                           Connection sqlCon, PasswordCredential passCred,
                                                           ManagedConnectionFactory mcf) throws ResourceException {
        return new com.sun.gjc.spi.ManagedConnection(pc, sqlCon, passCred, mcf, 
                getPoolInfo(), statementCacheSize, statementCacheType, sqlTraceDelegator,
                statementLeakTimeout, statementLeakReclaim);
    }

    /**
     * Returns the underlying datasource
     *
     * @return DataSource of jdbc vendor
     * @throws ResourceException
     */
    public Object getDataSource() throws ResourceException {
        if (dsObjBuilder == null) {
            dsObjBuilder = new DataSourceObjectBuilder(spec);
        }
        return dsObjBuilder.constructDataSourceObject();
    }

    protected static final int JVM_OPTION_STATEMENT_WRAPPING_ON = 1;
    protected static final int JVM_OPTION_STATEMENT_WRAPPING_OFF = 0;
    protected static final int JVM_OPTION_STATEMENT_WRAPPING_NOT_SET = -1;

    /**
     * This wrapStatement flag is used to enable disable wrapping the
     * statement objects. This can be enabled by passing jvm option,
     * com.sun.appserv.jdbc.wrapstatement = true.
     * This can be disabled by removing this option or by passing non true
     * value.
     * By default this will be disabled
     */
    private static int wrapStatement = JVM_OPTION_STATEMENT_WRAPPING_NOT_SET;

    static {
        wrapStatement = getStatementWrappingJVMOption();
    }

    /**
     * Gets the Statement Wrapping JVM Option (available in 8.2)<br>
     * Which will be deprecated in future versions.
     *
     * @return int representing the JVM Option value of statement wrapping.
     */
    private static int getStatementWrappingJVMOption() {
        int result = JVM_OPTION_STATEMENT_WRAPPING_NOT_SET;
        String str = System.getProperty(
                "com.sun.appserv.jdbc.wrapJdbcObjects");
        if ("true".equalsIgnoreCase(str)) {
            result = JVM_OPTION_STATEMENT_WRAPPING_ON;
        } else if ("false".equalsIgnoreCase(str)) {
            result = JVM_OPTION_STATEMENT_WRAPPING_OFF;
        }
        return result;
    }

    /**
     * 9.1 has attribute "wrap-statements" which will be overriden
     * when JVM option is specified as "true" or "false"
     * JVM Option will be deprecated in future versions.
     */
    protected void computeStatementWrappingStatus() {

        boolean poolProperty = false;
        String statementWrappingString = getStatementWrapping();
        if (statementWrappingString != null)
            poolProperty = Boolean.valueOf(statementWrappingString);

        if (wrapStatement == JVM_OPTION_STATEMENT_WRAPPING_ON ||
                (wrapStatement == JVM_OPTION_STATEMENT_WRAPPING_NOT_SET && poolProperty)) {
            statementWrapping = true;
        } else {
            statementWrapping = false;
        }
    }

    /**
     * Returns whether statement wrapping is enabled or not.<br>
     *
     * @return boolean representing statementwrapping status
     */
    public boolean isStatementWrappingEnabled() {
        return statementWrapping;
    }

    public JdbcObjectsFactory getJdbcObjectsFactory() {
        return jdbcObjectsFactory;
    }
    protected void logFine(String logMessage){
        if(_logger.isLoggable(Level.FINE)) {
            _logger.log(Level.FINE, logMessage);
        }
    }

    @Override
    public void mcfCreated() {
        String poolMonitoringSubTreeRoot = getPoolMonitoringSubTreeRoot();
        String sqlTraceListeners = getSqlTraceListeners();

        //Default values used in case sql tracing is OFF
        int sqlTraceCacheSize = 0;
        long timeToKeepQueries = 0;
        if(sqlTraceListeners != null && !sqlTraceListeners.equals("null")) {
            if(getNumberOfTopQueriesToReport() != null && !getNumberOfTopQueriesToReport().equals("null")) {
                //Some value is set for this property
                sqlTraceCacheSize = Integer.parseInt(getNumberOfTopQueriesToReport());
            } else {
                //No property by this name. default to 10 queries
                sqlTraceCacheSize = 10;
            }
            if(getTimeToKeepQueriesInMinutes() != null && !getTimeToKeepQueriesInMinutes().equals("null")) {
                //Time-To-Keep-Queries property has been set
                timeToKeepQueries = Integer.parseInt(getTimeToKeepQueriesInMinutes());
            } else {
                //Default to 5 minutes after which cache is pruned.
                timeToKeepQueries = 5;
                //Time to keep queries is set to 5 minutes because the timer
                //task will keep running till mcf is destroyed even if
                //monitoring is turned OFF.
            }
        }
        if(_logger.isLoggable(Level.FINEST)) {
            _logger.finest("MCF Created");
        }
        if (statementCacheSize > 0 ||
                (sqlTraceListeners != null && !sqlTraceListeners.equals("null")) ||
                statementLeakTimeout > 0) {
            jdbcStatsProvider = new JdbcStatsProvider(getPoolName(), getApplicationName(), getModuleName(),
                    sqlTraceCacheSize, timeToKeepQueries);
            //get the poolname and use it to initialize the stats provider n register
            StatsProviderManager.register(
                    ContainerMonitoring.JDBC_CONNECTION_POOL,
                    PluginPoint.SERVER,
                    poolMonitoringSubTreeRoot, jdbcStatsProvider);
            if(jdbcStatsProvider.getSqlTraceCache() != null) {
                if(_logger.isLoggable(Level.FINEST)) {
                    _logger.finest("Scheduling timer task for sql trace caching");
                }
                Timer timer = ((com.sun.gjc.spi.ResourceAdapter) ra).getTimer();
                jdbcStatsProvider.getSqlTraceCache().scheduleTimerTask(timer);
            }
            if(_logger.isLoggable(Level.FINEST)) {
                _logger.finest("Registered JDBCRA Stats Provider");
            }
        }
    }

    @Override
    public void mcfDestroyed() {
        if(_logger.isLoggable(Level.FINEST)) {
            _logger.finest("MCF Destroyed");
        }
        if(jdbcStatsProvider != null) {
            if(jdbcStatsProvider.getSqlTraceCache() != null) {
                if(_logger.isLoggable(Level.FINEST)) {
                    _logger.finest("Canceling timer task for sql trace caching");
                }
                jdbcStatsProvider.getSqlTraceCache().cancelTimerTask();
            }
            StatsProviderManager.unregister(jdbcStatsProvider);
            jdbcStatsProvider = null;
            if(_logger.isLoggable(Level.FINEST)) {
                _logger.finest("Unregistered JDBCRA Stats Provider");
            }
        }
    }

    private void detectStatementLeakSupport() {
        String stmtLeakTimeout = getStatementLeakTimeoutInSeconds();
        String stmtLeakReclaim = getStatementLeakReclaim();
        if (stmtLeakTimeout != null) {
            statementLeakTimeout = Integer.valueOf(stmtLeakTimeout) * 1000L;
            statementLeakReclaim = Boolean.valueOf(stmtLeakReclaim);
            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "StatementLeakTimeout in seconds: "
                        + statementLeakTimeout + " & StatementLeakReclaim: "
                        + statementLeakReclaim + " for pool : " + getPoolInfo());
            }
        }
    }

    public void writeExternal(ObjectOutput out) throws IOException {
    }

    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        ra = com.sun.gjc.spi.ResourceAdapter.getInstance();
    }
}

Other Glassfish examples (source code examples)

Here is a short list of links related to this Glassfish ManagedConnectionFactory.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.