/*
 * Copyright (c) 1998, 2021 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:
//     tware - added for EclipseLink 2.0 release
//     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>
//     05/10/2014 - 428675 - 2.5.2 - Rick Curtis - Add support for WebSphere logger.
//     04/01/2015 Will Dazey
//       - 463726: Added DatabaseSession null check
//     11/05/2015 Dalia Abo Sheasha
//       - 480787: Wrap several privileged method calls with a doPrivileged block
package org.eclipse.persistence.platform.server.was;

import java.lang.reflect.Constructor;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;

import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.platform.server.JMXEnabledPlatform;
import org.eclipse.persistence.services.websphere.MBeanWebSphereRuntimeServices;
import org.eclipse.persistence.sessions.DatabaseSession;

/**
 * PUBLIC:
 *
 * This is the concrete subclass responsible for representing WebSphere 7 -specific server behavior.
 *
 * This platform has: - No JMX MBean runtime services
 *
 */
public class WebSphere_7_Platform extends WebSphere_6_1_Platform implements JMXEnabledPlatform {
    public static final String SERVER_LOG_CLASS = "com.ibm.ws.jpa.container.eclipselink.logging.EclipseLinkLogger";
    /**
     * The following constants and attributes are used to determine the module and application name
     * to satisfy the requirements for 248746 where we provide an identifier pair for JMX sessions.
     * Each application can have several modules. 1) Application name - the persistence unit
     * associated with the session (a 1-1 relationship) 2) Module name - the ejb or war jar name
     * (there is a 1-many relationship for module:session(s))
     */
    static {
        /**
         * Override by subclass: Search String in application server ClassLoader for the
         * application:persistence_unit name
         */
        APP_SERVER_CLASSLOADER_APPLICATION_PU_SEARCH_STRING_PREFIX = "[app:";
        APP_SERVER_CLASSLOADER_APPLICATION_PU_SEARCH_STRING_POSTFIX = "]";
        /** Override by subclass: Search String in application server session for ejb modules */
        APP_SERVER_CLASSLOADER_MODULE_EJB_SEARCH_STRING_PREFIX = ".jar!/";
        /** Override by subclass: Search String in application server session for war modules */
        APP_SERVER_CLASSLOADER_MODULE_WAR_SEARCH_STRING_PREFIX = ".war!/";
        APP_SERVER_CLASSLOADER_MODULE_EJB_WAR_SEARCH_STRING_POSTFIX = "]";

        // Change the default value of property "eclipselink.security.usedoprivileged".
        PrivilegedAccessHelper.setDefaultUseDoPrivilegedValue(true);
    }

    /**
     * INTERNAL: Default Constructor: All behavior for the default constructor is inherited
     */
    public WebSphere_7_Platform(DatabaseSession newDatabaseSession) {
        super(newDatabaseSession);
        this.enableRuntimeServices();
        // Create the JMX MBean specific to this platform for later registration
        this.prepareServerSpecificServicesMBean();
    }

    @Override
    public SessionLog getServerLog() {
        return createSessionLog();
    }

    protected SessionLog createSessionLog() {
        SessionLog log = null;
        try {
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                log = AccessController.doPrivileged(new PrivilegedExceptionAction<SessionLog>() {
                    @Override
                    public SessionLog run() throws Exception {
                        Class<SessionLog> cls = PrivilegedAccessHelper.getClassForName(SERVER_LOG_CLASS);
                        Constructor<SessionLog> ctor = PrivilegedAccessHelper.getConstructorFor(cls, null, false);
                        return ctor.newInstance();
                    }
                });
            } else {
                Class<SessionLog> cls = PrivilegedAccessHelper.getClassForName(SERVER_LOG_CLASS);
                Constructor<SessionLog> ctor = PrivilegedAccessHelper.getConstructorFor(cls, null, false);
                log = ctor.newInstance();
            }

        } catch (Exception e) {
            // Blindly catch exception here as there is no recourse for any specific exception. If
            // we can't load the WAS logger just fall back to using the default SessionLog.
            log = super.getServerLog();
            log.log(SessionLog.FINEST, "Unable to create an instance of " + SERVER_LOG_CLASS
                + ". Falling back to using default logger.", e);
        }
        return log;
    }

    @Override
    public boolean isRuntimeServicesEnabledDefault() {
        return true;
    }

    /**
     * INTERNAL: prepareServerSpecificServicesMBean(): Server specific implementation of the
     * creation and deployment of the JMX MBean to provide runtime services for the databaseSession.
     *
     * Default is to do nothing. Implementing platform classes must override this function and
     * supply the server specific MBean instance for later registration by calling it in the
     * constructor.
     *
     * @see #isRuntimeServicesEnabled()
     * @see #disableRuntimeServices()
     * @see #registerMBean()
     */
    @Override
    public void prepareServerSpecificServicesMBean() {
        // No check for an existing cached MBean - we will replace it if it exists
        if (getDatabaseSession() != null && shouldRegisterRuntimeBean) {
            this.setRuntimeServicesMBean(new MBeanWebSphereRuntimeServices(getDatabaseSession()));
        }
    }

    /**
     * INTERNAL: serverSpecificRegisterMBean(): Server specific implementation of the creation and
     * deployment of the JMX MBean to provide runtime services for my databaseSession.
     *
     * @see #isRuntimeServicesEnabled()
     * @see #disableRuntimeServices()
     * @see #registerMBean()
     */
    @Override
    public void serverSpecificRegisterMBean() {
        super.serverSpecificRegisterMBean();
        // get and cache module and application name during registration
        initializeApplicationNameAndModuleName();
    }

}
