/*
 * 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
//     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
//       see <link>http://wiki.eclipse.org/EclipseLink/DesignDocs/316513</link>
package org.eclipse.persistence.platform.server.wls;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;

import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.platform.server.JMXServerPlatformBase;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.transaction.wls.WebLogicTransactionController;

/**
 * PUBLIC:
 *
 * This is the concrete subclass responsible for representing WebLogic-specific
 * server behavior.
 * <p>
 * This platform overrides:
 * <ul>
 * <li>getExternalTransactionControllerClass(): to use the WebLogic-specific
 * controller class
 * <li>getServerNameAndVersion(): to call the WebLogic library for this
 * information
 * </ul>
 */
public class WebLogicPlatform extends JMXServerPlatformBase {

    /**
     * Cached WLS connection class used to reflectively check connections and
     * unwrap them.
     */
    protected Class weblogicConnectionClass;

    /**
     * Cached WLConnection.getVendorConnection() Method used for
     * unwrapping connections.
     */
    protected Method vendorConnectionMethod;

    /**
     * Cached WLConnection.clearStatementCache() Method used for
     * clearing statement cache.
     */
    protected Method clearStatementCacheMethod;

    /**
     * Indicates whether WLConnection.clearStatementCache() should be called:
     * there is no need to call it in WebLogic Server 10.3.4 or later.
     */
    protected boolean shouldClearStatementCache;

    /**
     * INTERNAL: Default Constructor: All behavior for the default constructor
     * is inherited.
     */
    public WebLogicPlatform(DatabaseSession newDatabaseSession) {
        super(newDatabaseSession);
        this.disableRuntimeServices();
        this.shouldClearStatementCache = true;
    }

    /**
     * INTERNAL: Set the WLS version number through reflection.
     */
    @Override
    public void initializeServerNameAndVersion() {
        try {
            Class clazz = PrivilegedAccessHelper.getClassForName("weblogic.version");
            Method method = PrivilegedAccessHelper.getMethod(clazz, "getReleaseBuildVersion", null, false);
            this.serverNameAndVersion = (String) PrivilegedAccessHelper.invokeMethod(method, null, null);
            this.shouldClearStatementCache = Helper.compareVersions(this.serverNameAndVersion, "10.3.4") < 0;
        } catch (Exception exception) {
            getDatabaseSession().getSessionLog().logThrowable(SessionLog.WARNING, SessionLog.SERVER, exception);
        }
    }

    /**
     * INTERNAL: getExternalTransactionControllerClass(): Answer the class of
     * external transaction controller to use for WebLogic. This is read-only.
     *
     * @return Class externalTransactionControllerClass
     *
     * @see org.eclipse.persistence.transaction.JTATransactionController
     * @see org.eclipse.persistence.platform.server.ServerPlatformBase#isJTAEnabled()
     * @see org.eclipse.persistence.platform.server.ServerPlatformBase#disableJTA()
     * @see org.eclipse.persistence.platform.server.ServerPlatformBase#initializeExternalTransactionController()
     */
    @Override
    public Class getExternalTransactionControllerClass() {
        if (externalTransactionControllerClass == null) {
            externalTransactionControllerClass = WebLogicTransactionController.class;
        }
        return externalTransactionControllerClass;
    }

    /**
     * Return the class (interface) for the WebLogic JDBC connection wrapper.
     */
    protected Class getWebLogicConnectionClass() {
        if (this.weblogicConnectionClass == null) {
            try {
                this.weblogicConnectionClass = (Class) getDatabaseSession().getPlatform().convertObject("weblogic.jdbc.extensions.WLConnection", Class.class);
            } catch (Throwable exception) {
                getDatabaseSession().getSessionLog().logThrowable(SessionLog.WARNING, SessionLog.SERVER, exception);
                this.weblogicConnectionClass = void.class;
            }
        }
        return this.weblogicConnectionClass;
    }

    /**
     * Return the method for the WebLogic JDBC connection wrapper vendorConnection.
     */
    protected Method getVendorConnectionMethod() {
        if ((this.vendorConnectionMethod == null) && (!getWebLogicConnectionClass().equals(void.class))) {
            try {
                this.vendorConnectionMethod = PrivilegedAccessHelper.getDeclaredMethod(getWebLogicConnectionClass(), "getVendorConnection", new Class[0]);
            } catch (NoSuchMethodException exception) {
                getDatabaseSession().getSessionLog().logThrowable(SessionLog.WARNING, SessionLog.SERVER, exception);
            }
        }

        return this.vendorConnectionMethod;
    }

    /**
     * Unwraps the WebLogic JDBC connection wrapping using the WebLogic API reflectively.
     */
    @Override
    public Connection unwrapConnection(Connection connection) {
        if (getWebLogicConnectionClass().isInstance(connection) && getVendorConnectionMethod() != null) {
            try {
                return (Connection) PrivilegedAccessHelper.invokeMethod(getVendorConnectionMethod(), connection);
            } catch (IllegalAccessException exception) {
                getDatabaseSession().getSessionLog().logThrowable(SessionLog.WARNING, SessionLog.SERVER, exception);
            } catch (InvocationTargetException exception) {
                getDatabaseSession().getSessionLog().logThrowable(SessionLog.WARNING, SessionLog.SERVER, exception);
            }
        }

        return super.unwrapConnection(connection);
    }

    /**
     * Return the method for the WebLogic connection clearStatementCache method.
     */
    protected Method getClearStatementCacheMethod() {
        if ((this.clearStatementCacheMethod == null) && (!getWebLogicConnectionClass().equals(void.class))) {
            try {
                this.clearStatementCacheMethod = PrivilegedAccessHelper.getDeclaredMethod(getWebLogicConnectionClass(), "clearStatementCache", new Class[0]);
            } catch (NoSuchMethodException exception) {
                getDatabaseSession().getSessionLog().logThrowable(SessionLog.WARNING, SessionLog.SERVER, exception);
            }
        }

        return this.clearStatementCacheMethod;
    }

    /**
     * INTERNAL:
     * Clears statement cache of WebLogic connection using the WebLogic API reflectively.
     * 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(Connection connection) {
        if(this.serverNameAndVersion == null) {
            // this will initialize shouldClearStatementCache, too.
            initializeServerNameAndVersion();
        }
        if (this.shouldClearStatementCache && getWebLogicConnectionClass().isInstance(connection) && getClearStatementCacheMethod() != null) {
            try {
                PrivilegedAccessHelper.invokeMethod(getClearStatementCacheMethod(), connection);
            } catch (IllegalAccessException exception) {
                getDatabaseSession().getSessionLog().logThrowable(SessionLog.WARNING, SessionLog.SERVER, exception);
            } catch (InvocationTargetException exception) {
                getDatabaseSession().getSessionLog().logThrowable(SessionLog.WARNING, SessionLog.SERVER, exception);
            }
        }
    }

    /**
     * INTERNAL:
     * Check whether JTA 1.1 API is available.
     * WLS older than 10.0 is not JTA 1.1 compliant.
     *
     * @return always returns {@code false} for WLS older than 10.0.
     */
    @Override
    public boolean isJTA11() {
        return false;
    }

}
