/*
 * Copyright (c) 1998, 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,
 * 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
//
//      05/28/2008-1.0M8 Andrei Ilitchev.
//      - 224964: Provide support for Proxy Authentication through JPA.
//          No longer throws exception in case value holder for isolated class instantiated on the closed session.
//          Instead after the session is closed it switches to a mode when it acquires write connection only for the duration of the query execution.
//          The idea is all the necessary customization will be applied to the resurrected connection again, and cleared afterwards -
//          may be expensive, but works and costs nothing unless actually used.
//          Moved setting of the accessor from getExecutionSession to executeCall because getExecutionSession is called sometimes
//          without the need for connection (like createing a row), and that used to cause an unnecessary
//          acquiring of the connection on the closed session.
//
package org.eclipse.persistence.internal.sessions;

import java.util.Collection;
import java.util.Map;

import org.eclipse.persistence.sessions.server.*;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.internal.databaseaccess.Accessor;

public class ExclusiveIsolatedClientSession extends IsolatedClientSession {
    /**
     * If true all classes are read through the exclusive connection, otherwise only the isolated ones.
     */
    protected boolean shouldAlwaysUseExclusiveConnection;

    public ExclusiveIsolatedClientSession(ServerSession parent, ConnectionPolicy connectionPolicy) {
        this(parent, connectionPolicy, null);
    }

    public ExclusiveIsolatedClientSession(ServerSession parent, ConnectionPolicy connectionPolicy, Map properties) {
        super(parent, connectionPolicy, properties);
        //the parents constructor sets an accessor, but it will be never used.
        this.accessors = null;
        this.shouldAlwaysUseExclusiveConnection = connectionPolicy.isExclusiveAlways();
    }

    /**
     * INTERNAL:
     * Always use writeConnection.
     */
    @Override
    public Collection<Accessor> getAccessors() {
        return getWriteConnections().values();
    }

    /**
     * INTERNAL:
     * Provided for consistency.
     */
    @Override
    public void setAccessor(Accessor accessor) {
        setWriteConnection(accessor);
    }

    /**
     * INTERNAL:
     * As this session type should maintain it's transaction for its entire life-
     * cycle we will wait for 'release' before releasing connection.  By making
     * this method a no-op the connection will not be released until 'release()'
     * is called on the client session.
     */
    @Override
    protected void releaseWriteConnection() {
        //do not release the connection until 'release()' is called on the client session
    }

    /**
     * INTERNAL:
     * This method rises appropriate for the session event(s)
     * right after connection is acquired.
     */
    @Override
    public void postAcquireConnection(Accessor accessor) {
        super.postAcquireConnection(accessor);
        if (this.parent.hasEventManager()) {
            this.parent.getEventManager().postAcquireExclusiveConnection(this, accessor);
        }
    }

    /**
     * INTERNAL:
     * This method rises appropriate for the session event(s)
     * right before the connection is released.
     */
    @Override
    public void preReleaseConnection(Accessor accessor) {
        super.preReleaseConnection(accessor);
        if (this.parent.hasEventManager()) {
            this.parent.getEventManager().preReleaseExclusiveConnection(this, accessor);
        }
    }

    /**
     * INTERNAL:
     * This method is called in case externalConnectionPooling is used.
     * If returns true, accessor used by the session keeps its
     * connection open until released by the session.
     */
    @Override
    public boolean isExclusiveConnectionRequired() {
        return this.isActive;
    }

    /**
     * PUBLIC:
     * Return if this session is an exclusive isolated client session.
     */
    @Override
    public boolean isExclusiveIsolatedClientSession() {
        return true;
    }

    /**
     * INTERNAL:
     * Helper method to calculate whether to execute this query locally or send
     * it to the server session.
     */
    @Override
    protected boolean shouldExecuteLocally(DatabaseQuery query) {
        if (this.shouldAlwaysUseExclusiveConnection) {
            return true;
        } else {
            return super.shouldExecuteLocally(query);
        }
    }
}
