/*
 * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 1998, 2018 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
//     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.
//     08/29/2016 Jody Grassel
//       - 500441: Eclipselink core has System.getProperty() calls that are not potentially executed under doPriv()
package org.eclipse.persistence.platform.server;

import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.sql.SQLException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import jakarta.persistence.spi.PersistenceUnitInfo;

import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.databaseaccess.Accessor;
import org.eclipse.persistence.internal.helper.JPAClassLoaderHolder;
import org.eclipse.persistence.internal.localization.ToStringLocalization;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedNewInstanceFromClass;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.ExternalTransactionController;
import org.eclipse.persistence.sessions.JNDIConnector;
import org.eclipse.persistence.transaction.JTA11TransactionController;

/**
 * PUBLIC:
 * Implementation of org.eclipse.persistence.platform.server.ServerPlatform
 * <p>
 * This is the abstract superclass of all platforms for all servers. Each DatabaseSession
 * contains an instance of the receiver, to help the DatabaseSession determine:
 * <ul>
 * <li> Which external transaction controller to use
 * <li> Whether or not to enable JTA (external transaction control)
 * <li> How to register/unregister for runtime services (JMX/MBean)
 * <li> Whether or not to enable runtime services
 * <li> How to launch container Threads
 * </ul>
 * <p>
 * Subclasses already exist to provide configurations for Oc4J, WebLogic, JBoss, NetWeaver, GlassFish and WebSphere.
 * <p>
 * If the user wants a different external transaction controller class or
 * to provide some different behavior than the provided ServerPlatform(s), we recommend
 * subclassing org.eclipse.persistence.platform.server.ServerPlatformBase (or a subclass),
 * and overriding:
 * <ul>
 * <li>ServerPlatformBase.getExternalTransactionControllerClass()
 * <li>ServerPlatformBase.registerMBean()
 * <li>ServerPlatformBase.unregisterMBean()
 * </ul>
 * for the desired behavior.
 *
 * @see org.eclipse.persistence.platform.server.ServerPlatform
 */
public abstract class ServerPlatformBase implements ServerPlatform {

    // Secondary override properties can be set to disable MBean registration
    /** This System property "eclipselink.register.dev.mbean" when set to true will enable registration/unregistration of the DevelopmentServices MBean */
    public static final String JMX_REGISTER_DEV_MBEAN_PROPERTY = "eclipselink.register.dev.mbean";
    /** This System property "eclipselink.register.run.mbean" when set to true will enable registration/unregistration of the RuntimeServices MBean */
    public static final String JMX_REGISTER_RUN_MBEAN_PROPERTY = "eclipselink.register.run.mbean";
    /**
     * INTERNAL:
     * Answer "unknown" as a default for platforms that do not implement getModuleName()
     */
    public static final String DEFAULT_SERVER_NAME_AND_VERSION = ToStringLocalization.buildMessage("unknown");

    /**
     * INTERNAL:
     * isRuntimeServicesEnabled: Determines if the JMX Runtime Services will be deployed at runtime
     */
    private boolean isRuntimeServicesEnabled;

    // Only a "false" value will disable MBean registration for both beans
    protected boolean shouldRegisterDevelopmentBean = true;
    protected boolean shouldRegisterRuntimeBean = true;


    /**
     * externalTransactionControllerClass: This is a user-specifiable class defining the class
     * of external transaction controller to be set into the DatabaseSession
     */
    protected Class externalTransactionControllerClass;


    /**
     * INTERNAL:
     * isJTAEnabled: Determines if the external transaction controller will be populated into the DatabaseSession
     * at runtime
     */
    private boolean isJTAEnabled;

    /**
     * INTERNAL:
     * isCMP: true if the container created the server platform, because we're configured
     * for CMP.
     */
    private boolean isCMP;

    /**
     * INTERNAL:
     * databaseSession: The instance of DatabaseSession that I am helping.
     */
    private DatabaseSession databaseSession;

    /**
     * INTERNAL:
     * Server name and version.
     */
    protected String serverNameAndVersion;

    /**
     * Allow the thread pool size to be configured.
     */
    protected int threadPoolSize = 32;

    /**
     * Allow pooling of threads for asynchronous processing in RCM and other areas.
     */
    protected volatile ExecutorService threadPool;

    /**
     * INTERNAL: Default Constructor: Initialize so that runtime services and
     * JTA are enabled. Set the DatabaseSession that I will be helping.
     *
     * @param newDatabaseSession
     *            The instance of DatabaseSession that I am helping.
     */
    public ServerPlatformBase(DatabaseSession newDatabaseSession) {
        this.isJTAEnabled = true;
        // Default JMX support to false for all sub-platforms except those that override this flag
        this.isRuntimeServicesEnabled = isRuntimeServicesEnabledDefault();
        this.databaseSession = newDatabaseSession;
        this.setIsCMP(false);
        // Enable users to disable or enable (default) MBean registration
        String shouldRegisterRuntimeBeanProperty = PrivilegedAccessHelper.getSystemProperty(JMX_REGISTER_RUN_MBEAN_PROPERTY);
        if(null != shouldRegisterRuntimeBeanProperty) {
            if(shouldRegisterRuntimeBeanProperty.toLowerCase().indexOf("false") > -1) {
                shouldRegisterRuntimeBean = false;
            }
            if(shouldRegisterRuntimeBeanProperty.toLowerCase().indexOf("true") > -1) {
                shouldRegisterRuntimeBean = true;
            }
        }
        String shouldRegisterDevelopmentBeanProperty = PrivilegedAccessHelper.getSystemProperty(JMX_REGISTER_DEV_MBEAN_PROPERTY);
        if(null != shouldRegisterDevelopmentBeanProperty) {
            if(shouldRegisterDevelopmentBeanProperty.toLowerCase().indexOf("false") > -1) {
                shouldRegisterDevelopmentBean = false;
            }
            if(shouldRegisterDevelopmentBeanProperty.toLowerCase().indexOf("true") > -1) {
                shouldRegisterDevelopmentBean = true;
            }
        }
    }

    /**
     * INTERNAL: configureProfiler(): set default performance profiler used in this server.
     */
    public void configureProfiler(org.eclipse.persistence.sessions.Session session) {
        return;
    }

    /**
     * INTERNAL: getDatabaseSession(): Answer the instance of DatabaseSession the receiver is helping.
     *
     * @return DatabaseSession databaseSession
     */
    @Override
    public DatabaseSession getDatabaseSession() {
        return this.databaseSession;
    }

    /**
     * PUBLIC: getServerNameAndVersion(): Talk to the relevant server class library, and get the server name
     * and version
     *
     * @return String serverNameAndVersion
     */
    @Override
    public String getServerNameAndVersion() {
        if(this.serverNameAndVersion == null) {
            this.initializeServerNameAndVersion();
        }
        return this.serverNameAndVersion;
    }

    /**
     * INTERNAL: initializeServerNameAndVersion(): Talk to the relevant server class library, and get the server name
     * and version
     *
     * Default is "unknown"
     */
    protected void initializeServerNameAndVersion() {
        this.serverNameAndVersion = DEFAULT_SERVER_NAME_AND_VERSION;
    }

    /**
     * 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.
       *
       * Default behavior is to return "unknown".
     *
     * @return String moduleName
     */
    @Override
    public String getModuleName() {
        return DEFAULT_SERVER_NAME_AND_VERSION;
    }

    /**
     * INTERNAL: getExternalTransactionControllerClass(): Answer the class of external transaction controller to use
     * For this server platform. This is read-only.
     *
       * If the user wants a different external transaction controller class than the provided ServerPlatform(s),
       * we recommend subclassing org.eclipse.persistence.platform.server.ServerPlatformBase (or a subclass),
       * and overriding:
       *
       * ServerPlatformBase.getExternalTransactionControllerClass()
       *
       * for the desired behavior.
     *
     * @return Class externalTransactionControllerClass
     *
     * @see org.eclipse.persistence.transaction.JTATransactionController
     * @see #isJTAEnabled()
     * @see #disableJTA()
     */
    @Override
    public abstract Class 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()
     */
    @Override
    public void setExternalTransactionControllerClass(Class newClass) {
        this.externalTransactionControllerClass = 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().
     */
    @Override
    public void initializeExternalTransactionController() {
        this.ensureNotLoggedIn();

        //BUG 3975114: Even if JTA is disabled, override if we're in CMP
        //JTA must never be disable during CMP (WLS/Oc4j)
        if (!isJTAEnabled() && !isCMP()) {
            return;
        }
        //BUG 3975114: display a warning if JTA is disabled and we're in CMP
        if (!isJTAEnabled() && isCMP()) {
            getDatabaseSession().getSessionLog().log(SessionLog.WARNING, SessionLog.EJB, "jta_cannot_be_disabled_in_cmp", null, true);
        }

        //check if the transaction controller class is overridden by a preLogin or equivalent,
        //or if the transaction controller was already defined, in which case they should have written
        //a subclass. Show a warning
        try {
            if (getDatabaseSession().getExternalTransactionController() != null) {
                this.externalTransactionControllerNotNullWarning();
                return;
            }
            ExternalTransactionController controller = null;
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                try {
                    controller = (ExternalTransactionController)AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(this.getExternalTransactionControllerClass()));
                } catch (PrivilegedActionException exception) {
                    Exception throwableException = exception.getException();
                    if (throwableException instanceof InstantiationException) {
                        throw ValidationException.cannotCreateExternalTransactionController(getExternalTransactionControllerClass().getName());
                    } else {
                        throw ValidationException.cannotCreateExternalTransactionController(getExternalTransactionControllerClass().getName());
                    }
                }
            } else {
                controller = (ExternalTransactionController)PrivilegedAccessHelper.newInstanceFromClass(this.getExternalTransactionControllerClass());
            }
            getDatabaseSession().setExternalTransactionController(controller);
        } catch (InstantiationException instantiationException) {
            throw ValidationException.cannotCreateExternalTransactionController(getExternalTransactionControllerClass().getName());
        } catch (IllegalAccessException illegalAccessException) {
            throw ValidationException.cannotCreateExternalTransactionController(getExternalTransactionControllerClass().getName());
        }
    }

    /**
     * INTERNAL: externalTransactionControllerNotNullWarning():
     * When the external transaction controller is being initialized, we warn the developer
     * if they have already defined the external transaction controller in some way other
     * than subclassing ServerPlatformBase.
     *
     * @see #getExternalTransactionControllerClass()
     */
    protected void externalTransactionControllerNotNullWarning() {
        ((DatabaseSessionImpl)getDatabaseSession()).warning("External_transaction_controller_not_defined_by_server_platform", SessionLog.EJB);
    }

    /**
     * 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.
     *
     * Answer true if TopLink will be configured to register for callbacks for beforeCompletion and afterCompletion.
     *
     * @return boolean isJTAEnabled
     * @see #getExternalTransactionControllerClass()
     * @see #disableJTA()
     */
    @Override
    public boolean isJTAEnabled() {
        return this.isJTAEnabled;
    }

    /**
     * INTERNAL:
     * Check whether JTA 1.1 API is available.
     *
     * @return value of {@code true} when JTA 1.1 API is available or {@code false} otherwise.
     */
    public boolean isJTA11() {
        Context context = null;
        try {
            context = new InitialContext();
            if (context.lookup(JTA11TransactionController.JNDI_TRANSACTION_SYNCHRONIZATION_REGISTRY) != null) {
                return true;
            }
        } catch (NamingException ex) {
            // Ignore
        } finally {
            if (context != null) {
                try {
                    context.close();
                } catch (Exception ex) {
                    // Ignore
                }
            }
        }
        return false;
    }

    /**
     * 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.
     */
    @Override
    public boolean isRuntimeServicesEnabledDefault() {
        return false;
    }

    /**
     * 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()
     */
    @Override
    public boolean isRuntimeServicesEnabled() {
        return this.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()
     */
    @Override
    public void disableRuntimeServices() {
        this.ensureNotLoggedIn();
        this.isRuntimeServicesEnabled = false;
    }

    /**
     * INTERNAL:
     * enableRuntimeServices(): Configure the receiver such that JMX/MBeans will be registered
     * to provide runtime services for my DatabaseSession at runtime.
     *
     * @see #isRuntimeServicesEnabled()
     * @since EclipseLink 2.2.0
     */
    public void enableRuntimeServices() {
        this.ensureNotLoggedIn();
        this.isRuntimeServicesEnabled = true;
    }


    /**
     * 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.
     *
     * TopLink will NOT be configured to register for callbacks for beforeCompletion and afterCompletion.
     *
     * @see #getExternalTransactionControllerClass()
     * @see #isJTAEnabled()
     */
    @Override
    public void disableJTA() {
        this.ensureNotLoggedIn();
        this.isJTAEnabled = false;
    }

    /**
     * INTERNAL:  This method is used to unwrap the connection wrapped by
     * the application server.  TopLink needs this unwrapped connection for certain
     * database vendor specific support. (i.e. TIMESTAMPTZ,NCHAR,XMLTYPE)
     *
     * Be default we will use the connection's metadata to try to get the connection
     */
    @Override
    public java.sql.Connection unwrapConnection(java.sql.Connection connection){
        try {
            return connection.getMetaData().getConnection();
        } catch (java.sql.SQLException e){
            ((DatabaseSessionImpl)getDatabaseSession()).log(SessionLog.WARNING, SessionLog.CONNECTION, "cannot_unwrap_connection", e);
            return 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"
     */
    @Override
    public void launchContainerRunnable(Runnable runnable) {
        if (getThreadPool() == null) {
            Thread thread = new Thread(runnable);
            thread.start();
        } else {
            getThreadPool().execute(runnable);
        }
    }

    /**
     * INTERNAL: Make sure that the DatabaseSession has not logged in yet.
     * Throw a ValidationException if we have.
     *
     */
    protected void ensureNotLoggedIn() {
        //RCM: Allow for a null database session
        if (getDatabaseSession() == null) {
            return;
        }
    }

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

    /**
     * Return the thread pool size.
     */
    @Override
    public int getThreadPoolSize() {
        return threadPoolSize;
    }

    /**
     * Set the thread pool size.
     */
    @Override
    public void setThreadPoolSize(int threadPoolSize) {
        this.threadPoolSize = threadPoolSize;
    }

    /**
     * INTERNAL: Return the thread pool, initializing if required.
     */
    public ExecutorService getThreadPool() {
        if ((threadPool == null) && (this.threadPoolSize > 0)) {
            synchronized (this) {
                if (threadPool == null) {
                    threadPool = Executors.newFixedThreadPool(getThreadPoolSize());
                }
            }
        }
        return threadPool;
    }

    /**
     * INTERNAL: Set the thread pool to use.
     */
    public void setThreadPool(ExecutorService threadPool) {
        this.threadPool = threadPool;
    }

    /**
     * INTERNAL: isCMP(): Answer true if we're in the context of CMP (i.e. the container created me)
     *
     * @return boolean
     */
    public boolean isCMP() {
        return isCMP;
    }

    /**
     * INTERNAL: setIsCMP(boolean): Define whether or not we're in the context of CMP (i.e. the container created me)
     */
    public void setIsCMP(boolean isThisCMP) {
        isCMP = isThisCMP;
    }

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

    /**
     * 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.
     * 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.
     */
    @Override
    public boolean wasFailureCommunicationBased(SQLException exception, Accessor connection, AbstractSession sessionForProfile){
        return getDatabaseSession().getPlatform().wasFailureCommunicationBased(exception, connection.getConnection(), sessionForProfile);
    }

    @Override
    public JPAClassLoaderHolder getNewTempClassLoader(PersistenceUnitInfo puInfo) {
        return new JPAClassLoaderHolder(puInfo.getNewTempClassLoader(), true);
    }

    /**
     * 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.
     */
    @Override
    public void clearStatementCache(java.sql.Connection connection) {
    }

    /**
     * INTERNAL: registerMBean(): Create and deploy the JMX MBean to provide runtime services for my
     * databaseSession.
     *
     * Default is to do nothing.
     *
     * @see #isRuntimeServicesEnabled()
     * @see #disableRuntimeServices()
     * @see #unregisterMBean()
     */
    @Override
    public void registerMBean() {
        if (!this.isRuntimeServicesEnabled()) {
            return;
        }
        this.serverSpecificRegisterMBean();
    }

    /**
     * INTERNAL: unregisterMBean(): Unregister the JMX MBean that was providing runtime services for my
     * databaseSession.
     *
     * @see #isRuntimeServicesEnabled()
     * @see #disableRuntimeServices()
     * @see #registerMBean()
     */
    @Override
    public void unregisterMBean() {
        if (!this.isRuntimeServicesEnabled()) {
            return;
        }
        this.serverSpecificUnregisterMBean();
    }

    /**
     * INTERNAL: perform any require shutdown tasks.
     */
    @Override
    public void shutdown() {
        unregisterMBean();
        if (this.threadPool != null) {
            this.threadPool.shutdownNow();
            this.threadPool = null;
        }
    }


    /**
     * INTERNAL: serverSpecificUnregisterMBean(): Server specific implementation of the
     * unregistration of the JMX MBean from its server.
     *
     * Default is to do nothing. This should be subclassed if required.
     *
     * @see #isRuntimeServicesEnabled()
     * @see #disableRuntimeServices()
     */
    public void serverSpecificUnregisterMBean() { }

    /**
     * INTERNAL: serverSpecificRegisterMBean(): Server specific implementation of the
     * creation and deployment of the JMX MBean to provide runtime services for my
     * databaseSession.
     *
     * Default is to do nothing. This should be subclassed if required.
     *
     * @see #isRuntimeServicesEnabled()
     * @see #disableRuntimeServices()
     * @see #registerMBean()
     */
    public void serverSpecificRegisterMBean() { }

    /**
     * @return Return JNDIConnector.COMPOSITE_NAME_LOOKUP.
     */
    @Override
    public int getJNDIConnectorLookupType() {
        return JNDIConnector.COMPOSITE_NAME_LOOKUP;
    }

    @Override
    public String getPartitionID() {
        return "GLOBAL";
    }

    @Override
    public boolean usesPartitions() {
        return false;
    }


}
