/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2020 IBM Corporation. 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,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
//     GYorke - non-bug update to set accessor in case of connection failure.  Thi
//              will allow the retry code to function.
package org.eclipse.persistence.internal.databaseaccess;

import java.util.*;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.sessions.Login;
import org.eclipse.persistence.queries.Call;
import org.eclipse.persistence.internal.sequencing.SequencingCallback;
import org.eclipse.persistence.internal.sequencing.SequencingCallbackFactory;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.sessions.SessionProfiler;
import org.eclipse.persistence.sessions.server.ConnectionPool;

/**
 * INTERNAL:
 * <code>DatasourceAccessor</code> is an abstract implementation
 * of the <code>Accessor</code> interface providing common functionality to the concrete database and EIS accessors.
 * It is responsible for
 * connecting,
 * transactions,
 * call execution
 *
 * @see Call
 * @see Login
 *
 * @author James
 * @since OracleAS TopLink 10<i>g</i> (10.0.3)
 *
 * 05/28/2008-1.0M8 Andrei Ilitchev.
 *   - 224964: Provide support for Proxy Authentication through JPA.
 *     Added ConnectionCustomizer, also fixed  postConnect/preDisconnect ExternalConnection calls so that they called in case of reads, too.
 */
public abstract class DatasourceAccessor implements Accessor {

    /** Store the reference to the driver level connection. */
    protected Object datasourceConnection;

    /** Store the login information that connected this accessor. */
    protected Login login;

    /**
     * Keep track of the number of concurrent active calls.
     * This is used for connection pooling for loadbalancing and for external connection pooling.
     */
    protected int callCount;

    /**
     * Keep track of the number of the storedprocedure statement that being executed.
     */
    public int storedProcedureStatementsCount;
    /**
     * Keep track of the number of the read statement that being executed.
     */
    public int readStatementsCount;

    /**
     * Keep track of the number of the write statement that being executed.
     */
    public int writeStatementsCount;

    //Stores the number of executed read SQL statements
    public static final String READ_STATEMENTS_COUNT_PROPERTY = "Read_Statements_Count_Property";

    //Stores the number of executed write SQL statements
    public static final String WRITE_STATEMENTS_COUNT_PROPERTY = "Write_Statements_Count_Property";

    //Stores the number of executed store procedure statements
    public static final String STOREDPROCEDURE_STATEMENTS_COUNT_PROPERTY = "StoredProcedure_Statements_Count_Property";


    /** Keep track if the accessor is within a transaction context */
    protected boolean isInTransaction;

    /** Keep track of whether the accessor is "connected". */
    protected boolean isConnected;

    /* PERF: Cache platform to avoid gets (small but can add up). */
    /** This is also required to ensure all accessors for a session are using the same platform. */
    protected DatasourcePlatform platform;

    /**
     *  This attribute is used to determine if the connection should be returned to the pool or
     *  removed from the pool and closed.  It will be set to false if an exception occurs during
     *  Call execution.
     */
    protected boolean isValid;

    /**
     *  During (not external) transaction, SequencingManager may set SequencingCallback on the accessor,
     *  The callback's only method is called when transaction commits,
     *  after transaction is completed the callback is discarded.
     */
    protected transient SequencingCallback sequencingCallback;

    /**
     * This attribute is used to track failures on an accessor that may be communication based.
     * If a failure is detected executing a call with a query timeout this flag is set.  If an error happens
     * twice in a row on the same accessor then that accessor will be checked for a comm error.  If there is no
     * query timeout then the flag is not set and the accessor will be checked immediately.
     */
    protected boolean possibleFailure;

    /**
     *  Used only in externalConnectionPooling case. Indicates which session is currently using connection.
     *  Allows to rise appropriate session's event when connection is already/still alive.
     *  Events will be risen when ClientSession or DatabaseSession acquires connection in the beginning
     *  and releases connection in the end of transaction (in afterCompletion in jta case).
     *  In case the session requires exclusive connection (ExclusiveIsolatedClientSession) the events
     *  will be risen every time the session acquires or releases connection -
     *  which is a rare event - the connection is kept for the duration of jta transaction,
     *  after jta transaction is completed the new connection is acquired on a first query execution
     *  and kept until the next beginTransaction call.
     *  In non-jta case the connection is acquired for session's life and release only by session's release.
     *  Note that the attribute is nullified only in one place - by closeConnection method.
     */
    protected transient AbstractSession currentSession;

    /**
     * PERF: Cache connection pooling flag.
     */
    protected boolean usesExternalConnectionPooling;

    /**
     * Back-door to allow isConnect checks.
     * Since we now support fail-over and retry, removing old isConnected usage which can
     * cause major performance issues (on Sybase), and minor ones in general.
     */
    public static boolean shouldCheckConnection = false;

    /**
     * Allows session-specific connection customization.
     */
    protected ConnectionCustomizer customizer;

    protected ConnectionPool pool;

    /**
     *    Default Constructor.
     */
    protected DatasourceAccessor() {
        this.isInTransaction = false;
        this.callCount = 0;
        this.isConnected = false;
        this.isValid = true;
    }

    /**
     * Clone the accessor.
     */
    @Override
    public Object clone() {
        try {
            DatasourceAccessor accessor = (DatasourceAccessor)super.clone();
            if(accessor.customizer != null) {
                accessor.customizer.setAccessor(accessor);
            }
            return accessor;
        } catch (CloneNotSupportedException exception) {
            throw new InternalError("clone not supported");
        }
    }

    /**
     * Called from beforeCompletion external transaction synchronization listener callback
     * to close the external connection corresponding to the completing external transaction.
     * Final sql calls could be sent through the connection by this method
     * before it closes the connection.
     */
    @Override
    public void closeJTSConnection() {
        if (usesExternalTransactionController()) {
            this.isInTransaction = false;
            if (this.usesExternalConnectionPooling) {
                closeConnection();
            }
        }
    }

    /**
     * Set the transaction transaction status of the receiver.
     */
    protected void setIsInTransaction(boolean value) {
        isInTransaction = value;
    }

    /**
     * This should be set to false if a communication failure occurred during a call execution.
     * In the case of an invalid accessor the Accessor will not be returned to the pool.
     */
    @Override
    public void setIsValid(boolean isValid){
        this.isValid = isValid;
    }

    /**
     * Return the transaction status of the receiver.
     */
    @Override
    public boolean isInTransaction() {
        return isInTransaction;
    }

    /**
     * Returns true if this Accessor can continue to be used.  This will be false if a communication
     * failure occurred during a call execution.  In the case of an invalid accessor the Accessor
     * will not be returned to the pool.
     */
    @Override
    public boolean isValid(){
        return this.isValid;
    }

    public boolean isPossibleFailure() {
        return possibleFailure;
    }

    public void setPossibleFailure(boolean possibleFailure) {
        this.possibleFailure = possibleFailure;
    }

    /**
     * Return true if some external connection pool is in use.
     */
    @Override
    public boolean usesExternalConnectionPooling() {
        return usesExternalConnectionPooling;
    }

    /**
     *    Begin a transaction on the database. If not using managed transaction begin a local transaction.
     */
    @Override
    public void beginTransaction(AbstractSession session) throws DatabaseException {
        if (usesExternalTransactionController()) {
            if (session.isExclusiveConnectionRequired() && !this.isInTransaction && this.usesExternalConnectionPooling) {
                closeConnection();
            }
            this.isInTransaction = true;
            return;
        }

        session.log(SessionLog.FINER, SessionLog.TRANSACTION, "begin_transaction", null, this);

        try {
            session.startOperationProfile(SessionProfiler.Transaction);
            incrementCallCount(session);
            basicBeginTransaction(session);
            this.isInTransaction = true;
        } finally {
            decrementCallCount();
            session.endOperationProfile(SessionProfiler.Transaction);
        }
    }

    /**
     * Begin the driver level transaction.
     */
    protected abstract void basicBeginTransaction(AbstractSession session);

    /**
     * Commit the driver level transaction.
     */
    protected abstract void basicCommitTransaction(AbstractSession session);

    /**
     * Rollback the driver level transaction.
     */
    protected abstract void basicRollbackTransaction(AbstractSession session);

    /**
     * Used for load balancing and external pooling.
     */
    @Override
    public synchronized void decrementCallCount() {
        int count = this.callCount;
        // Avoid decrementing count if already zero, (failure before increment).
        if (count <= 0) {
            return;
        }
        this.callCount--;
        if (this.usesExternalConnectionPooling && (!this.isInTransaction) && (currentSession == null || !currentSession.isExclusiveConnectionRequired()) && (count == 1)) {
            try {
                closeConnection();
            } catch (DatabaseException ignore) {
                // Don't allow for errors to be masked by disconnect.
            }
        }
    }

    /**
     * Used for load balancing and external pooling.
     */
    @Override
    public synchronized void incrementCallCount(AbstractSession session) {
        this.callCount++;

        if (this.callCount == 1) {
            // If the login is null, then this accessor has never been connected.
            if (this.login == null) {
                throw DatabaseException.databaseAccessorNotConnected();
            }

            // If the connection is no longer connected, it may have timed out.
            if (this.datasourceConnection != null) {
                if (shouldCheckConnection && !isConnected()) {
                    if (this.isInTransaction) {
                        throw DatabaseException.databaseAccessorNotConnected();
                    } else {
                        reconnect(session);
                    }
                }
            } else {
                // If ExternalConnectionPooling is used, the connection can be re-established.
                if (this.usesExternalConnectionPooling) {
                    reconnect(session);
                    session.postAcquireConnection(this);
                    currentSession = session;
                } else {
                    throw DatabaseException.databaseAccessorNotConnected();
                }
            }
        }
    }

    /**
     * Reset statement count.
     */
    @Override
    public void reset() {
        this.readStatementsCount = 0;
        this.writeStatementsCount = 0;
        this.storedProcedureStatementsCount = 0;
    }

    /**
     * Connect to the database.
     * Exceptions are caught and re-thrown as EclipseLink exceptions.
     */
    protected void connectInternal(Login login, AbstractSession session) throws DatabaseException {
        try{
            this.datasourceConnection = login.connectToDatasource(this, session);
            this.isConnected = true;
            if(this.customizer != null) {
                customizer.customize();
            }
        }catch (DatabaseException ex){
            //Set the accessor to ensure the retry code has an opportunity to retry.
            ex.setAccessor(this);
            throw ex;
        }
    }

    /**
     * Set whether the accessor has a connection to the "data store".
     */
    protected void setIsConnected(boolean isConnected) {
        this.isConnected = isConnected;
    }

    /**
     * Used for load balancing and external pooling.
     */
    protected void setCallCount(int callCount) {
        this.callCount = callCount;
    }

    /**
     * Used for load balancing and external pooling.
     */
    @Override
    public int getCallCount() {
        return callCount;
    }

    /**
     * Commit a transaction on the database. If using non-managed transaction commit the local transaction.
     */
    @Override
    public void commitTransaction(AbstractSession session) throws DatabaseException {
        if (usesExternalTransactionController()) {
            // if there is no external TX controller, then that means we are currently not synchronized
            // with a global JTS transaction.  In this case, there won't be any 'afterCompletion'
            // callbacks so we have to release the connection here.  It is possible (WLS 5.1) to choose
            // 'usesExternalTransactionController' on the login, but still acquire a uow that WON'T be
            // synchronized with a global TX.
            if (!session.isSynchronized()) {
                this.isInTransaction = false;
                if (this.usesExternalConnectionPooling) {
                    // closeConnection method uses currentSession and then sets it to null.
                    currentSession = session;
                    closeConnection();
                }
            }
            return;
        }

        session.log(SessionLog.FINER, SessionLog.TRANSACTION, "commit_transaction", null, this);

        try {
            session.startOperationProfile(SessionProfiler.Transaction);
            incrementCallCount(session);
            basicCommitTransaction(session);

            if(sequencingCallback != null) {
                sequencingCallback.afterCommit(this);
            }
            this.isInTransaction = false;
        } finally {
            sequencingCallback = null;
            decrementCallCount();
            session.endOperationProfile(SessionProfiler.Transaction);
        }
    }

    /**
     * Connect to the datasource.  Through using a CCI ConnectionFactory.
     * Catch exceptions and re-throw as EclipseLink exceptions.
     */
    @Override
    public void connect(Login login, AbstractSession session) throws DatabaseException {
        session.startOperationProfile(SessionProfiler.ConnectionManagement);
        session.incrementProfile(SessionProfiler.Connects);

        try {
            if (session.shouldLog(SessionLog.FINE, SessionLog.CONNECTION)) {// Avoid printing if no logging required.
                Object[] args = { login };
                session.log(SessionLog.FINE, SessionLog.CONNECTION, "connecting", args, this);
            }
            setLogin(login);
            this.setDatasourcePlatform((DatasourcePlatform)session.getDatasourceLogin().getDatasourcePlatform());
            createCustomizer(session);
            try {
                connectInternal(login, session);
                this.isInTransaction = false;
            } catch (RuntimeException exception) {
                session.handleSevere(exception);
            }
            if (session.hasEventManager()) {
                session.getEventManager().postConnect(this);
            }
            incrementCallCount(session);
            try {
                buildConnectLog(session);
            } finally {
                decrementCallCount();
            }
        } finally {
            session.endOperationProfile(SessionProfiler.ConnectionManagement);
        }
    }

    /**
     * Close the connection to the driver level datasource.
     */
    protected abstract void closeDatasourceConnection();

    /**
     * Execute the call to driver level datasource.
     */
    protected abstract Object basicExecuteCall(Call call, AbstractRecord row, AbstractSession session);

    /**
     * Build a log string of any driver metadata that can be obtained.
     */
    protected abstract void buildConnectLog(AbstractSession session);

    /**
     * Return the login
     */
    public Login getLogin() {
        return login;
    }

    /**
     * SECURE:
     * set the login
     */
    protected void setLogin(Login login) {
        this.login = login;
        this.usesExternalConnectionPooling = login.shouldUseExternalConnectionPooling();
    }

    /**
     * Disconnect from the datasource.
     */
    @Override
    public void disconnect(AbstractSession session) throws DatabaseException {
        session.log(SessionLog.FINE, SessionLog.CONNECTION, "disconnect", null, this);

        if (this.datasourceConnection == null) {
            return;
        }
        session.incrementProfile(SessionProfiler.Disconnects);
        session.startOperationProfile(SessionProfiler.ConnectionManagement);
        try {
            releaseCustomizer();
            closeDatasourceConnection();
            this.datasourceConnection = null;
            this.isInTransaction = true;
        } finally {
            session.endOperationProfile(SessionProfiler.ConnectionManagement);
        }
    }

    /**
     * Close the accessor's connection.
     * This is used only for external connection pooling
     * when it is intended for the connection to be reconnected in the future.
     */
    @Override
    public void closeConnection() {
        try {
            if (this.datasourceConnection != null) {
                if (isDatasourceConnected()) {
                    if(currentSession != null) {
                        currentSession.preReleaseConnection(this);
                    }
                    if(customizer != null && customizer.isActive()) {
                        customizer.clear();
                    }
                    closeDatasourceConnection();
                }
                this.datasourceConnection = null;
            }
        } catch (DatabaseException exception) {
            // Ignore
            this.datasourceConnection = null;
        } finally {
            currentSession = null;
        }
    }

    /**
     * Execute the call.
     * @return depending of the type either the row count, row or vector of rows.
     */
    @Override
    public Object executeCall(Call call, AbstractRecord translationRow, AbstractSession session) throws DatabaseException {
        // If the login is null, then this accessor has never been connected.
        if (this.login == null) {
            throw DatabaseException.databaseAccessorNotConnected();
        }

        if (session.shouldLog(SessionLog.FINE, SessionLog.SQL)) {// pre-check to improve performance
            session.log(SessionLog.FINE, SessionLog.SQL, call.getLogString(this), null, this, false);
        }

        Object result = basicExecuteCall(call, translationRow, session);

        return result;
    }

    /**
     * PUBLIC:
     * Reconnect to the database.  This can be used if the connection was disconnected or timedout.
     * This ensures that the security is checked as it is public.
     * Because the messages can take a long time to build,
     * pre-check whether messages should be logged.
     */
    @Override
    public void reestablishConnection(AbstractSession session) throws DatabaseException {
        if (session.shouldLog(SessionLog.FINE, SessionLog.CONNECTION)) {// Avoid printing if no logging required.
            Object[] args = { getLogin() };
            session.log(SessionLog.FINE, SessionLog.CONNECTION, "reconnecting", args, this);
        }
        reestablishCustomizer();
        reconnect(session);
        this.isInTransaction = false;
        this.isValid = true;
        if (session.hasEventManager()) {
            session.getEventManager().postConnect(this);
        }
    }

    /**
     * Attempt to save some of the cost associated with getting a fresh connection.
     * Assume the DatabaseDriver has been cached, if appropriate.
     * Note: Connections that are participating in transactions will not be refreshed.^M
     */
    protected void reconnect(AbstractSession session) throws DatabaseException {
        session.log(SessionLog.FINEST, SessionLog.CONNECTION, "reconnecting_to_external_connection_pool", null, this);
        session.startOperationProfile(SessionProfiler.ConnectionManagement);
        try {
            connectInternal(this.login, session);
        } finally {
            session.endOperationProfile(SessionProfiler.ConnectionManagement);
        }
    }

    /**
     * Return the platform.
     */
    public DatasourcePlatform getDatasourcePlatform() {
        return platform;
    }

    /**
     * Set the platform.
     * This should be set to the session's platform, not the connections
     * which may not be configured correctly.
     */
    public void setDatasourcePlatform(DatasourcePlatform platform) {
        this.platform = platform;
    }

    /**
     * Return the driver level connection.
     */
    @Override
    public Object getDatasourceConnection() {
        return datasourceConnection;
    }

    /**
     * Helper method to return the JDBC connection for DatabaseAccessor.
     * Was going to deprecate this, but since most clients are JDBC this is useful.
     */
    @Override
    public java.sql.Connection getConnection() {
        return (java.sql.Connection)this.datasourceConnection;
    }

    /**
     * Return column information for the specified
     * database objects.
     */
    @Override
    public Vector<AbstractRecord> getColumnInfo(String catalog, String schema, String tableName, String columnName, AbstractSession session) throws DatabaseException {
        return new Vector<>();
    }

    /**
     * Return the number of read statements.
     */
    public int getReadStatementsCount() {
        return readStatementsCount;
    }

    /**
     * Return the number of write statements.
     */
    public int getWriteStatementsCount() {
        return writeStatementsCount;
    }

    /**
     * Return the number of stored procedure call.
     */
    public int getStoredProcedureStatementsCount() {
        return storedProcedureStatementsCount;
    }

    /**
     * Return table information for the specified
     * database objects.
     */
    @Override
    public Vector<AbstractRecord> getTableInfo(String catalog, String schema, String tableName, String[] types, AbstractSession session) throws DatabaseException {
        return new Vector<>();
    }

    /**
     * If client requires to manually set connection they can use the connection manager.
     */
    protected void setDatasourceConnection(Object connection) {
        this.datasourceConnection = connection;
    }

    /**
     * Rollback the transaction on the datasource. If not using managed transaction rollback the local transaction.
     */
    @Override
    public void rollbackTransaction(AbstractSession session) throws DatabaseException {
        if (usesExternalTransactionController()) {
            // if there is no external TX controller, then that means we are currently not synchronized
            // with a global JTS transaction.  In this case, there won't be any 'afterCompletion'
            // callbacks so we have to release the connection here.  It is possible (WLS 5.1) to choose
            // 'usesExternalTransactionController' on the login, but still acquire a uow that WON'T be
            // synchronized with a global TX.
            if (!session.isSynchronized()) {
                this.isInTransaction = false;
                if (this.usesExternalConnectionPooling) {
                    // closeConnection method uses currentSession and then sets it to null.
                    currentSession = session;
                    closeConnection();
                }
            }
            return;
        }

        session.log(SessionLog.FINER, SessionLog.TRANSACTION, "rollback_transaction", null, this);

        try {
            session.startOperationProfile(SessionProfiler.Transaction);
            incrementCallCount(session);
            basicRollbackTransaction(session);
        } finally {
            this.isInTransaction = false;
            sequencingCallback = null;
            decrementCallCount();
            session.endOperationProfile(SessionProfiler.Transaction);
        }
    }

    /**
     * Return true if some external transaction service is controlling transactions.
     */
    @Override
    public boolean usesExternalTransactionController() {
        if (this.login == null) {
            throw DatabaseException.databaseAccessorNotConnected();
        }
        return this.login.shouldUseExternalTransactionController();
    }

    /**
     * Return true if the accessor is currently connected to a data source.
     * Return false otherwise.
     */
    @Override
    public boolean isConnected() {
        if ((this.datasourceConnection == null) && (this.login == null)) {
            return false;
        }
        if (this.usesExternalConnectionPooling) {
            return true;// As can always reconnect.
        }

        if (this.datasourceConnection == null) {
            return false;
        }

        return isDatasourceConnected();
    }

    /**
     * Return if the driver level connection is connected.
     */
    protected abstract boolean isDatasourceConnected();

    /**
     * Added as a result of Bug 2804663 - satisfy the Accessor interface
     * implementation.
     */
    @Override
    public void flushSelectCalls(AbstractSession session) {
        // By default do nothing.
    }

    /**
     * This method will be called after a series of writes have been issued to
     * mark where a particular set of writes has completed.  It will be called
     * from commitTransaction and may be called from writeChanges.   Its main
     * purpose is to ensure that the batched statements have been executed
     */
    @Override
    public void writesCompleted(AbstractSession session) {
        //this is a no-op in this method as we do not batch on this accessor
    }

    /**
     * Return sequencing callback.
     */
    @Override
    public SequencingCallback getSequencingCallback(SequencingCallbackFactory sequencingCallbackFactory) {
        if(sequencingCallback == null) {
            sequencingCallback = sequencingCallbackFactory.createSequencingCallback();
        }
        return sequencingCallback;
    }

    /**
     * Attempts to create ConnectionCustomizer. If created the customizer is cached by the accessor.
     * Called by the owner of accessor (DatabaseSession, ServerSession through ConnectionPool) just once,
     * typically right after the accessor is created.
     * Also called by ClientSession when it acquires write accessor.
     * If accessor already has a customizer set by ConnectionPool then ClientSession's customizer
     * compared with the existing one and if they are not equal (don't produce identical customization)
     * then the new customizer set onto accessor, caching the old customizer so that it could be restored later.
     */
    @Override
    public void createCustomizer(AbstractSession session) {
        ConnectionCustomizer newCustomizer;
        if(customizer == null) {
            // Create a new customizer. The platform may be null if the accessor hasn't yet been connected.
            if(platform != null) {
                newCustomizer = platform.createConnectionCustomizer(this, session);
            } else {
                newCustomizer = ((DatasourcePlatform)session.getDatasourcePlatform()).createConnectionCustomizer(this, session);
            }
            if(newCustomizer == null) {
                // Neither old nor new exists - nothing to do.
            } else {
                // Old customizer doesn't exist - just set the new one.
                setCustomizer(newCustomizer);
            }
        } else {
            // the passed session has built the old customizer - no need to build the new one.
            if(customizer.getSession() == session) {
                return;
            }
            // Create a new customizer. The platform may be null if the accessor hasn't yet been connected.
            if(platform != null) {
                newCustomizer = platform.createConnectionCustomizer(this, session);
            } else {
                newCustomizer = ((DatasourcePlatform)session.getDatasourcePlatform()).createConnectionCustomizer(this, session);
            }
            if(newCustomizer == null) {
                // New customizer doesn't exist - but the old one does.
                if(customizer.isActive()) {
                    customizer.clear();
                }
                // The only reason for setting empty customizer is to preserve the previous customizer
                // until releaseCustomizer(session) is called - where session is the one set in empty customizer.
                // Happens when ServerSession defines customization but ClientSession explicitly demands no customization.
                newCustomizer = ConnectionCustomizer.createEmptyCustomizer(session);
                newCustomizer.setPrevCustomizer(customizer);
                // No need to call customize on Empty customizer - it does nothing.
                customizer = newCustomizer;
            } else {
                // Both old and new customizers exist.
                if(newCustomizer.equals(customizer)) {
                    // The equality of customizers means they customize connection in exactly the same way.
                    // Therefore clearing the old customization followed by application of the new one could be skipped:
                    // just keep the old customizer.
                    // Happens when ServerSession and ClientSession define equivalent customizers.
                } else {
                    // The old customizer substituted for the new one.
                    if(customizer.isActive()) {
                        customizer.clear();
                    }
                    // Note that the old one is cached in the new one and will be restored
                    // when releaseCustomizer(session( is called - where session is the one set in the new customizer.
                    // Happens when ClientSession customizer overrides ServerSession's customizer.
                    newCustomizer.setPrevCustomizer(customizer);
                    setCustomizer(newCustomizer);
                }
            }
        }
    }

    /**
     * Set customizer, customize the connection if it's available.
     */
    protected void setCustomizer(ConnectionCustomizer newCustomizer) {
        this.customizer = newCustomizer;
        if(getDatasourceConnection() != null) {
            customizer.customize();
        }
    }

    /**
     * Clear customizer if it's active and set it to null.
     * Called by the same object that has created customizer (DatabaseSession, ConnectionPool) when
     * the latter is no longer required, typically before releasing the accessor.
     * Ignored if there's no customizer.
     */
    @Override
    public void releaseCustomizer() {
        if(customizer != null) {
            if(customizer.isActive()) {
                customizer.clear();
            }
            customizer = null;
        }
    }

   /**
    * Clear and remove customizer if its session is the same as the passed one;
    * in case prevCustomizer exists set it as a new customizer.
    * Called when ClientSession releases write accessor:
    * if the customizer was created by the ClientSession it's removed, and
    * the previous customizer (that ConnectionPool had set) is brought back;
    * otherwise the customizer (created by ConnectionPool) is kept.
    * Ignored if there's no customizer.
    */
   @Override
public void releaseCustomizer(AbstractSession session) {
       if(customizer != null) {
           if(customizer.getSession() == session) {
               if(customizer.isActive()) {
                   customizer.clear();
               }
               if(customizer.getPrevCustomizer() == null) {
                   customizer = null;
               } else {
                   setCustomizer(customizer.getPrevCustomizer());
               }
           }
       }
   }

   /**
    * This method is called by reestablishConnection.
    * Nothing needs to be done in case customize is not active (customization hasn't been applied yet).
    * to repair existing customizer after connection became invalid.
    * However if connection has been customized then
    * if connection is still there and deemed to be valid - clear customization.
    * Otherwise (or if clear fails) remove customizer and set its prevCustomizer as a new customizer,
    * then re-create customizer using the same session as the original one.
    */
   protected void reestablishCustomizer() {
       if(customizer != null && customizer.isActive()) {
           if(isValid()) {
               // the method eats SQLException in case of a failure.
               customizer.clear();
           } else {
               // It's an invalid connection - don't bother trying to clear customization.
               AbstractSession customizerSession = (AbstractSession)customizer.getSession();
               // need this so that the new customizer has the same prevCustomizer as the old one.
               customizer = customizer.getPrevCustomizer();
               // customizer recreated - it's the same as the original one, but not active.
               createCustomizer(customizerSession);
           }
       }
   }

   /**
    * Return the associated connection pool this connection was obtained from.
    */
   @Override
public ConnectionPool getPool() {
       return pool;
   }

   /**
    * Set the associated connection pool this connection was obtained from.
    */
   @Override
public void setPool(ConnectionPool pool) {
       this.pool = pool;
   }
}
