/*
 * 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.
     */
    public 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 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 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;
   }
}
