/*
 * Copyright (c) 2021, 2022 Contributors to the Eclipse Foundation.
 * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.gjc.spi;

import static com.sun.gjc.common.DataSourceSpec.CONNECTIONVALIDATIONREQUIRED;
import static com.sun.gjc.common.DataSourceSpec.GUARANTEEISOLATIONLEVEL;
import static com.sun.gjc.common.DataSourceSpec.TRANSACTIONISOLATION;
import static com.sun.gjc.common.DataSourceSpec.VALIDATIONCLASSNAME;
import static com.sun.gjc.common.DataSourceSpec.VALIDATIONMETHOD;
import static com.sun.gjc.util.SecurityUtils.getPasswordCredential;
import static com.sun.gjc.util.SecurityUtils.isPasswordCredentialEqual;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.SEVERE;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.PrintWriter;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Locale;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.Timer;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.security.auth.Subject;
import javax.sql.DataSource;
import javax.sql.PooledConnection;

import org.glassfish.api.jdbc.ConnectionValidation;
import org.glassfish.api.jdbc.SQLTraceListener;
import org.glassfish.external.probe.provider.PluginPoint;
import org.glassfish.external.probe.provider.StatsProviderManager;
import org.glassfish.resourcebase.resources.api.PoolInfo;

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.logging.LogDomains;

import jakarta.resource.ResourceException;
import jakarta.resource.spi.ConfigProperty;
import jakarta.resource.spi.ConnectionManager;
import jakarta.resource.spi.ConnectionRequestInfo;
import jakarta.resource.spi.LazyEnlistableConnectionManager;
import jakarta.resource.spi.ManagedConnection;
import jakarta.resource.spi.ManagedConnectionFactory;
import jakarta.resource.spi.ResourceAdapter;
import jakarta.resource.spi.ResourceAdapterAssociation;
import jakarta.resource.spi.ResourceAllocationException;
import jakarta.resource.spi.ValidatingManagedConnectionFactory;
import jakarta.resource.spi.security.PasswordCredential;

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

public abstract class ManagedConnectionFactoryImpl
        implements ManagedConnectionFactory, ValidatingManagedConnectionFactory, MCFLifecycleListener,
        ResourceAdapterAssociation, Serializable, Externalizable {

    private static Logger _logger = LogDomains.getLogger(ManagedConnectionFactoryImpl.class, LogDomains.RSR_LOGGER);
    protected static final StringManager localStrings = StringManager.getManager(DataSourceObjectBuilder.class);

    protected DataSourceSpec spec = new DataSourceSpec();
    protected transient DataSourceObjectBuilder dataSourceObjectBuilder;
    protected PrintWriter logWriter;
    protected transient ResourceAdapter resourceAdapter;
    protected boolean statementWrapping;
    protected SQLTraceDelegator sqlTraceDelegator;
    protected LazyEnlistableConnectionManager connectionManager;
    protected boolean isLazyConnectionManager;

    private JdbcObjectsFactory jdbcObjectsFactory = JdbcObjectsFactory.getInstance();
    private int statementCacheSize;
    private String statementCacheType;
    private long statementLeakTimeout;
    private boolean statementLeakReclaim;

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

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

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

        DataSource connectionFactory = jdbcObjectsFactory.getDataSourceInstance(this, connectionManager);

        if (connectionManager instanceof LazyEnlistableConnectionManager) {
            this.connectionManager = (LazyEnlistableConnectionManager) connectionManager;
            isLazyConnectionManager = true;
        }

        return connectionFactory;
    }

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

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

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

    /**
     * Get the <code>ResourceAdapterImpl</code> for this
     * <code>ManagedConnectionFactoryImpl</code> instance.
     *
     * @return <code>ResourceAdapterImpl</code> associated with this
     * <code>ManagedConnectionFactoryImpl</code> instance
     * @see <code>setResourceAdapter</code>
     */
    @Override
    public jakarta.resource.spi.ResourceAdapter getResourceAdapter() {
        logFine("In getResourceAdapter");
        return resourceAdapter;
    }

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

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

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

        PasswordCredential passwordCredential = getPasswordCredential(this, subject, cxRequestInfo);

        Iterator<ManagedConnectionImpl> iter = connectionSet.iterator();
        ManagedConnectionImpl managedConnectionImpl = null;

        while (iter.hasNext()) {
            try {
                managedConnectionImpl = iter.next();
            } catch (NoSuchElementException nsee) {
                _logger.log(SEVERE, "jdbc.exc_iter");
                throw new ResourceException(nsee.getMessage());
            }
            if (passwordCredential == null && this.equals(managedConnectionImpl.getManagedConnectionFactory())) {
                return managedConnectionImpl;
            }

            if (isPasswordCredentialEqual(passwordCredential, managedConnectionImpl.getPasswordCredential())) {
                return managedConnectionImpl;
            }
        }

        return null;
    }

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

        return invalidConnections;
    }

    /**
     * Checks if a <code>ManagedConnection</code> is to be validated or not and
     * validates it or returns.
     *
     * @param managedConnectionImpl <code>ManagedConnection</code> to be validated
     * @throws ResourceException if the connection is not valid or if validation
     * method is not proper
     */
    void isValid(ManagedConnectionImpl managedConnectionImpl) throws ResourceException {
        if (managedConnectionImpl == null || managedConnectionImpl.isTransactionInProgress()) {
            return;
        }

        String conVal = spec.getDetail(CONNECTIONVALIDATIONREQUIRED);

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

        String validationMethod = spec.getDetail(VALIDATIONMETHOD).toLowerCase(Locale.getDefault());

        managedConnectionImpl.checkIfValid();

        /**
         * The above call checks if the actual physical connection is usable or not.
         */
        Connection connection = managedConnectionImpl.getActualConnection();

        if (validationMethod.equals("custom-validation")) {
            isValidByCustomValidation(connection, spec.getDetail(VALIDATIONCLASSNAME));
        } else if (validationMethod.equals("auto-commit")) {
            isValidByAutoCommit(connection);
        } else if (validationMethod.equals("meta-data")) {
            isValidByMetaData(connection);
        } else if (validationMethod.equals("table")) {
            isValidByTableQuery(connection, spec.getDetail(DataSourceSpec.VALIDATIONTABLENAME));
        } else {
            throw new ResourceException("The validation method is not proper");
        }
    }

    /**
     * Checks if a <code>java.sql.Connection</code> is valid or not by doing a
     * custom validation using the validation class name specified.
     *
     * @param connection <code>java.sql.Connection</code> to be validated
     * @throws ResourceException if the connection is not valid
     */
    protected void isValidByCustomValidation(Connection connection, String validationClassName) throws ResourceException {
        boolean isValid = false;
        if (connection == null) {
            throw new ResourceException("The connection is not valid as " + "the connection is null");
        }

        try {
            ConnectionValidation connectionValidation = (ConnectionValidation)
                Thread.currentThread()
                      .getContextClassLoader()
                      .loadClass(validationClassName)
                      .getDeclaredConstructor()
                      .newInstance();

            isValid = connectionValidation.isConnectionValid(connection);
        } catch (Exception e) {
            _logger.log(INFO, "jdbc.exc_custom_validation", validationClassName);
            throw new ResourceException(e);
        }

        if (!isValid) {
            _logger.log(INFO, "jdbc.exc_custom_validation", validationClassName);
            throw new ResourceException("Custom validation detected invalid connection");
        }
    }

    /**
     * Checks if a <code>java.sql.Connection</code> is valid or not by checking its
     * auto commit property.
     *
     * @param connection <code>java.sql.Connection</code> to be validated
     * @throws ResourceException if the connection is not valid
     */
    protected void isValidByAutoCommit(Connection connection) throws ResourceException {
        if (connection == 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 autoCommit = connection.getAutoCommit();
            if (autoCommit) {
                connection.setAutoCommit(false);
            } else {
                connection.rollback(); // prevents uncompleted transaction exceptions
                connection.setAutoCommit(true);
            }

            connection.setAutoCommit(autoCommit);

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

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

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

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

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

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

    /**
     * Sets the isolation level specified in the <code>ConnectionRequestInfo</code>
     * for the <code>ManagedConnection</code> passed.
     *
     * @param managedConnectionImpl <code>ManagedConnection</code>
     * @throws ResourceException if the isolation property is invalid or if the
     * isolation cannot be set over the connection
     */
    protected void setIsolation(ManagedConnectionImpl managedConnectionImpl) throws ResourceException {
        Connection connection = managedConnectionImpl.getActualConnection();
        if (connection == null) {
            return;
        }

        String tranIsolation = spec.getDetail(TRANSACTIONISOLATION);
        if (tranIsolation != null && !tranIsolation.equals("")) {
            int tranIsolationInt = getTransactionIsolationInt(tranIsolation);
            try {
                connection.setTransactionIsolation(tranIsolationInt);
                managedConnectionImpl.setLastTransactionIsolationLevel(tranIsolationInt);
            } catch (SQLException sqle) {
                _logger.log(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</code> passed. If
     * the transaction level is to be guaranteed to be the same as the one present
     * when this <code>ManagedConnection</code> was created, as specified by the
     * <code>ConnectionRequestInfo</code> passed, it sets the transaction isolation
     * level from the <code>ConnectionRequestInfo</code> passed. Else, it sets it to
     * the transaction isolation passed.
     *
     * @param managedConnectionImpl <code>ManagedConnection</code>
     * @param tranIsol int
     * @throws ResourceException if the isolation property is invalid or if the
     * isolation cannot be set over the connection
     */
    void resetIsolation(ManagedConnectionImpl managedConnectionImpl, int tranIsol) throws ResourceException {
        Connection connection = managedConnectionImpl.getActualConnection();
        if (connection == null) {
            return;
        }

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

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

                if (guarantee) {
                    int tranIsolationInt = getTransactionIsolationInt(transactionIsolation);
                    try {
                        if (tranIsolationInt != connection.getTransactionIsolation()) {
                            connection.setTransactionIsolation(tranIsolationInt);
                        }
                    } catch (SQLException sqle) {
                        _logger.log(SEVERE, "jdbc.exc_tx_iso", sqle);
                        throw new ResourceException("The isolation level could not be set: " + sqle.getMessage());
                    }
                } else {
                    try {
                        if (tranIsol != connection.getTransactionIsolation()) {
                            connection.setTransactionIsolation(tranIsol);
                        }
                    } catch (SQLException sqle) {
                        _logger.log(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(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.length == 0) {
                                        listener = (SQLTraceListener) constructor.newInstance(initargs);
                                    }
                                }
                            } catch (InstantiationException ex) {
                                _logger.log(SEVERE, "jdbc.sql_trace_listener_exception", ex.getMessage());
                            } catch (IllegalAccessException ex) {
                                _logger.log(SEVERE, "jdbc.sql_trace_listener_exception", ex.getMessage());
                            } catch (IllegalArgumentException ex) {
                                _logger.log(SEVERE, "jdbc.sql_trace_listener_exception", ex.getMessage());
                            } catch (InvocationTargetException ex) {
                                _logger.log(SEVERE, "jdbc.sql_trace_listener_exception", ex.getMessage());
                            } catch (SecurityException ex) {
                                _logger.log(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</code> constant for
     * the string specifying the isolation.
     */
    private int getTransactionIsolationInt(String tranIsolation) throws ResourceException {
        if (tranIsolation.equalsIgnoreCase("read-uncommitted")) {
            return Connection.TRANSACTION_READ_UNCOMMITTED;
        }

        if (tranIsolation.equalsIgnoreCase("read-committed")) {
            return Connection.TRANSACTION_READ_COMMITTED;
        }

        if (tranIsolation.equalsIgnoreCase("repeatable-read")) {
            return Connection.TRANSACTION_REPEATABLE_READ;
        }

        if (tranIsolation.equalsIgnoreCase("serializable")) {
            return Connection.TRANSACTION_SERIALIZABLE;
        }

        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(ManagedConnectionImpl managedConnectionImpl) throws ResourceException {
        try {
            isValid(managedConnectionImpl);
            setIsolation(managedConnectionImpl);
        } catch (ResourceException e) {
            if (managedConnectionImpl != null) {
                try {
                    managedConnectionImpl.destroy();
                } catch (ResourceException e1) {
                    _logger.log(Level.WARNING, "jdbc.exc_destroy", e1);
                }
            }

            throw new ResourceAllocationException(localStrings.getString("jdbc.exc_destroy", e.getMessage()), e);
        }
    }

    private void detectStatementCachingSupport() {
        String cacheSize = getStatementCacheSize();
        if (cacheSize != null) {
            try {
                statementCacheSize = Integer.parseInt(cacheSize);
                // TODO-SC FINE log-level with Pool Name (if possible)
                if (_logger.isLoggable(FINE)) {
                    _logger.log(FINE, "StatementCaching Size : " + statementCacheSize);
                }
            } catch (NumberFormatException nfe) {
                if (_logger.isLoggable(FINE)) {
                    _logger.fine("Exception while setting StatementCacheSize : " + nfe.getMessage());
                }
                // ignore
            }
        }
    }

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

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

    /**
     * Sets the user name
     *
     * @param user <code>String</code>
     */
    @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</code>
     */
    @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</code>
     */
    @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</code>
     */
    @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</code>
     */
    @ConfigProperty(type = String.class, defaultValue = "")
    public void setValidationMethod(String validationMethod) {
        spec.setDetail(VALIDATIONMETHOD, validationMethod);
    }

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

    /**
     * Sets the table checked for during validation
     *
     * @param table <code>String</code>
     */
    @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 className <code>String</code>
     */
    public void setValidationClassName(String className) {
        try {
            Class validationClass = Thread.currentThread().getContextClassLoader().loadClass(className);
            boolean isAssignable = ConnectionValidation.class.isAssignableFrom(validationClass);
            if (isAssignable) {
                spec.setDetail(VALIDATIONCLASSNAME, className);
            } else {
                // Validation Failed
                _logger.log(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(SEVERE, "jdbc.set_custom_validation_class_name_failure", ex.getMessage());
        } catch (ClassNotFoundException ex) {
            _logger.log(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(VALIDATIONCLASSNAME);
    }

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

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

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

    /**
     * Returns the transaction isolation level
     *
     * @return isolation level guarantee
     */
    public String getGuaranteeIsolationLevel() {
        return spec.getDetail(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</code>
     * @see <code>getServerName</code>
     */
    @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</code>
     */
    public String getServerName() {
        return spec.getDetail(DataSourceSpec.SERVERNAME);
    }

    /**
     * Sets the port number.
     *
     * @param portNumber <code>String</code>
     * @see <code>getPortNumber</code>
     */
    @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</code>
     */
    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</code>
     * @see <code>getDatabaseName</code>
     */
    @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</code>
     */
    public String getDatabaseName() {
        return spec.getDetail(DataSourceSpec.DATABASENAME);
    }

    /**
     * Sets the data source name.
     *
     * @param dsn <code>String</code>
     * @see <code>getDataSourceName</code>
     */
    @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</code>
     */
    public String getDataSourceName() {
        return spec.getDetail(DataSourceSpec.DATASOURCENAME);
    }

    /**
     * Set Statement Wrapping value
     *
     * @param wrapping <code>String</code>
     * @see <code> getStatementWrapping </code>
     */
    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</code>
     */
    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);
        this.statementCacheType = getStatementCacheType();
        if (this.statementCacheType == null || this.statementCacheType.trim().equals("")) {
            if (_logger.isLoggable(FINE)) {
                _logger.fine(
                    " Default StatementCaching Type : " +
                    localStrings.getString("jdbc.statement-cache.default.datastructure"));
            }
        } else {
            if (_logger.isLoggable(FINE)) {
                _logger.fine("StatementCaching Type : " + this.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</code>
     * @see <code> getStatementTimeout </code>
     */
    public void setStatementTimeout(String timeout) {
        spec.setDetail(DataSourceSpec.STATEMENTTIMEOUT, timeout);
    }

    /**
     * Gets the StatementTimeout value
     *
     * @return String representing "true" or "false"
     * @see <code>setStatementTimeout</code>
     */
    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</code>
     * @see <code>getDescription</code>
     */
    @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</code>
     */
    public String getDescription() {
        return spec.getDetail(DataSourceSpec.DESCRIPTION);
    }

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

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

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

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

    /**
     * Sets the login timeout.
     *
     * @param loginTimeOut <code>String</code>
     * @see <code>getLoginTimeOut</code>
     */
    @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</code>
     */
    public String getLoginTimeOut() {
        return spec.getDetail(DataSourceSpec.LOGINTIMEOUT);
    }

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

    /**
     * Gets the delimiter.
     *
     * @return delim
     * @see <code>setDelimiter</code>
     */
    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</code>
     * @see <code>getDriverProperties</code>
     */
    @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</code>
     */
    public String getDriverProperties() {
        return spec.getDetail(DataSourceSpec.DRIVERPROPERTIES);
    }

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

    protected ManagedConnectionImpl constructManagedConnection(PooledConnection pc, Connection sqlCon,
            PasswordCredential passCred, ManagedConnectionFactoryImpl mcf) throws ResourceException {
        return new ManagedConnectionImpl(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 (dataSourceObjectBuilder == null) {
            dataSourceObjectBuilder = new DataSourceObjectBuilder(spec);
        }
        return dataSourceObjectBuilder.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 overridden 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) {
        _logger.log(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.
            }
        }

        _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("jdbc-connection-pool", PluginPoint.SERVER, poolMonitoringSubTreeRoot,
                    jdbcStatsProvider);

            if (jdbcStatsProvider.getSqlTraceCache() != null) {
                _logger.finest("Scheduling timer task for sql trace caching");
                Timer timer = ((ResourceAdapterImpl) resourceAdapter).getTimer();
                jdbcStatsProvider.getSqlTraceCache().scheduleTimerTask(timer);
            }

            _logger.finest("Registered JDBCRA Stats Provider");
        }
    }

    @Override
    public void mcfDestroyed() {
        _logger.finest("MCF Destroyed");

        if (jdbcStatsProvider != null) {
            if (jdbcStatsProvider.getSqlTraceCache() != null) {
                _logger.finest("Canceling timer task for sql trace caching");
                jdbcStatsProvider.getSqlTraceCache().cancelTimerTask();
            }

            StatsProviderManager.unregister(jdbcStatsProvider);
            jdbcStatsProvider = null;
            _logger.finest("Unregistered JDBCRA Stats Provider");
        }
    }

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

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        resourceAdapter = ResourceAdapterImpl.getInstance();
    }
}
