/*
 * Copyright (c) 1998, 2021 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
//     06/30/2010-2.1.1 Michael O'Brien
//       - 316513: Enable JMX MBean functionality for JBoss, Glassfish and WebSphere in addition to WebLogic
//       Move JMX MBean generic registration code up from specific platforms
//       add new isRuntimeServicesEnabledDefault()
//       see <link>http://wiki.eclipse.org/EclipseLink/DesignDocs/316513</link>
//     12/18/2014-2.6 Rick Curtis
//       - 455690: Move JNDIConnector lookup type to ServerPlatform.
package org.eclipse.persistence.platform.server;

import java.sql.SQLException;

import jakarta.persistence.spi.PersistenceUnitInfo;

import org.eclipse.persistence.internal.databaseaccess.Accessor;
import org.eclipse.persistence.internal.helper.JPAClassLoaderHolder;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.ExternalTransactionController;

/**
 * PUBLIC:
 *
 * This is the interface describing the behavior for ServerPlatformBase, and any other
 * class that wants to provide behavior for a server.
 *
 * This interface provides the behavior for
 *
 * - Which external transaction controller to use
 * - Whether or not to enable JTA (external transaction control)
 * - How to register/unregister for runtime services (JMX/MBean)
 * - Whether or not to enable runtime services
 * - How to launch container Threads
 *
 * Any subclasses of ServerPlatformBase created by the user must implement this interface.
 *
 * public API:
 *
 *  String getServerNameAndVersion()
 *
 * @see ServerPlatformBase
 */
public interface ServerPlatform {

    /**
     * INTERNAL: getDatabaseSession(): Answer the instance of DatabaseSession the receiver is helping.
     *
     * @return DatabaseSession
     */
    DatabaseSession getDatabaseSession();

    /**
     * PUBLIC: getServerNameAndVersion(): Talk to the relevant server class library, and get the server name
     * and version
     *
     * @return String serverNameAndVersion
     */
    String getServerNameAndVersion();

    /**
     * INTERNAL: getModuleName(): Answer the name of the module (jar name) that my session
       * is associated with.
       * Answer "unknown" if there is no module name available.
     *
     * @return String moduleName
     */
    String getModuleName();

    /**
     * INTERNAL: getExternalTransactionControllerClass(): Answer the class of external transaction controller to use
     * For this server platform. This is read-only.
     *
     * If the subclasses of the ServerPlatformBase do not provide the Class desired, then
     * a new subclass should be created to return the desired class.
     *
     * @return Class externalTransactionControllerClass
     *
     * @see org.eclipse.persistence.transaction.JTATransactionController
     * @see #isJTAEnabled()
     * @see #disableJTA()
     * @see #initializeExternalTransactionController()
     */
    Class<? extends ExternalTransactionController> getExternalTransactionControllerClass();

    /**
     * INTERNAL: setExternalTransactionControllerClass(Class newClass): Set the class of external
     * transaction controller to use in the DatabaseSession.
     * This is defined by the user via the sessions.xml.
     *
     * @see org.eclipse.persistence.transaction.JTATransactionController
     * @see #isJTAEnabled()
     * @see #disableJTA()
     * @see #initializeExternalTransactionController()
     * @param newClass
     */
    void setExternalTransactionControllerClass(Class<? extends ExternalTransactionController> newClass);

    /**
     * INTERNAL: initializeExternalTransactionController(): Populate the DatabaseSession's
     * external transaction controller with an instance of my transaction controller class.
     *
     * To change the external transaction controller class, we recommend creating a subclass of
     * ServerPlatformBase, and overriding getExternalTransactionControllerClass()
     *
     * @see ServerPlatformBase
     */
    void initializeExternalTransactionController();

    /**
     * INTERNAL: isJTAEnabled(): Answer true if the DatabaseSession's external transaction controller class will
     * be populated with my transaction controller class at runtime. If the transaction controller class is
     * overridden in the DatabaseSession, my transaction controller class will be ignored.
     *
     * @return boolean isJTAEnabled
     * @see #getExternalTransactionControllerClass()
     * @see #disableJTA()
     */
    boolean isJTAEnabled();

    /**
     * INTERNAL:
     * isRuntimeServicesEnabledDefault(): Answer true if the JMX/MBean providing runtime services for
     * the receiver's DatabaseSession will be deployed at runtime.
     * Provide the default value for {@link #isRuntimeServicesEnabled()} for a
     * ServerPlatform. By default this is <code>false</code> but some platforms
     * can choose to have MBeans deployed by default.
     */
    boolean isRuntimeServicesEnabledDefault();

    /**
     * INTERNAL: disableJTA(): Configure the receiver such that my external transaction controller class will
     * be ignored, and will NOT be used to populate DatabaseSession's external transaction controller class
     * at runtime.
     *
     * @see #getExternalTransactionControllerClass()
     * @see #isJTAEnabled()
     */
    void disableJTA();

    /**
     * INTERNAL: isRuntimeServicesEnabled(): Answer true if the JMX/MBean providing runtime services for
     * the receiver's DatabaseSession will be deployed at runtime.
     *
     * @return boolean isRuntimeServicesEnabled
     * @see #disableRuntimeServices()
     */
    boolean isRuntimeServicesEnabled();

    /**
     * INTERNAL: disableRuntimeServices(): Configure the receiver such that no JMX/MBean will be registered
     * to provide runtime services for my DatabaseSession at runtime.
     *
     * @see #isRuntimeServicesEnabled()
     */
    void disableRuntimeServices();

    /**
     * INTERNAL: registerMBean(): Create and deploy the JMX MBean to provide runtime services for my
     * databaseSession.
     *
     * @see #isRuntimeServicesEnabled()
     * @see #disableRuntimeServices()
     * @see #unregisterMBean()
     */
    void registerMBean();

    /**
     * INTERNAL: unregisterMBean(): Unregister the JMX MBean that was providing runtime services for my
     * databaseSession.
     *
     * @see #isRuntimeServicesEnabled()
     * @see #disableRuntimeServices()
     * @see #registerMBean()
     */
    void unregisterMBean();

    /**
     * INTERNAL: perform any require shutdown tasks.
     */
    void shutdown();

    /**
     * Return the thread pool size.
     */
    int getThreadPoolSize();

    /**
     * Set the thread pool size.
     */
    void setThreadPoolSize(int threadPoolSize);

    /**
     * INTERNAL:  This method is used to unwrap the oracle connection wrapped by
     * the application server.  TopLink needs this unwrapped connection for certain
     * database vendor specific support.
     * This is added as a workaround for bug 4460996
     */
    java.sql.Connection unwrapConnection(java.sql.Connection connection);

    /**
     * INTERNAL: launchContainerRunnable(Runnable runnable): Use the container library to
     * start the provided Runnable.
     *
     * Default behavior is to use Thread(runnable).start()
     *
     * @param runnable the instance of runnable to be "started"
     */
    void launchContainerRunnable(Runnable runnable);

    /**
     * INTERNAL: getServerLog(): Return the ServerLog for this platform
     *
     * Return the default ServerLog in the base
     *
     * @return org.eclipse.persistence.logging.SessionLog
     */
    org.eclipse.persistence.logging.SessionLog getServerLog();

    /**
     * INTERNAL: shouldUseDriverManager(): Indicates whether DriverManager should be used while connecting DefaultConnector.
     *
     * @return boolean
     */
    boolean shouldUseDriverManager();

    /**
     * INTERNAL:
     * A call to this method will perform a platform based check on the connection and exception
     * error code to determine if the connection is still valid or if a communication error has occurred.
     * In the case of the server platform the connection pool itself may be tested.
     * If a communication error has occurred then the query may be retried.
     * If this platform is unable to determine if the error was communication based it will return
     * false forcing the error to be thrown to the user.
     */
    boolean wasFailureCommunicationBased(SQLException exception, Accessor connection, AbstractSession sessionForProfile);

    /**
     * INTERNAL:
     * JIRA EJBTHREE-572 requires that we use the real classLoader in place of the getNewTempClassLoader().
     * The override code should stay in place until the UCL3 loader does not throw a NPE on loadClass()
     *
     * @param puInfo - the persistence unit info
     * @return ClassLoaderHolder - a composite object containing the classLoader and the flag
     *     that is true if the classLoader returned is temporary
     *
     * @see org.eclipse.persistence.internal.helper.JPAClassLoaderHolder
     */
    JPAClassLoaderHolder getNewTempClassLoader(PersistenceUnitInfo puInfo);

    /**
     * INTERNAL:
     * Clears statement cache of the wrapper connection.
     * Required by Oracle proxy authentication: currently connection statement cache
     * becomes invalid on switching to/from proxy session.
     * This method is called by OracleJDBC_10_1_0_2ProxyConnectionCustomizer
     * before opening proxy session and before closing it.
     */
    void clearStatementCache(java.sql.Connection connection);

    /**
     * INTERNAL: Get JNDIConnector lookupType value for this platform.
     */
    int getJNDIConnectorLookupType();

    /**
     * INTERNAL: Some servers may support partitioning
     * @return true if server supports partitions, false otherwise
     */
    boolean usesPartitions();

    /**
     * INTERNAL: Get Partition ID.
     * @return partition ID
     */
    String getPartitionID();
}
