| /* |
| * Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved. |
| * Copyright (c) 2015 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: |
| // 01/05/2015 Rick Curtis |
| // - 455683: Automatically detect target server |
| // 04/24/2015 Rick Curtis |
| // - 465452: Throw ServerPlatformException rather than NPE on create null platformClass |
| package org.eclipse.persistence.platform.server; |
| |
| import java.lang.reflect.Constructor; |
| import java.lang.reflect.InvocationTargetException; |
| import java.security.AccessController; |
| import java.security.PrivilegedActionException; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.persistence.config.PersistenceUnitProperties; |
| import org.eclipse.persistence.exceptions.ServerPlatformException; |
| import org.eclipse.persistence.internal.security.PrivilegedAccessHelper; |
| import org.eclipse.persistence.internal.security.PrivilegedClassForName; |
| import org.eclipse.persistence.internal.security.PrivilegedGetConstructorFor; |
| import org.eclipse.persistence.internal.security.PrivilegedInvokeConstructor; |
| import org.eclipse.persistence.internal.sessions.AbstractSession; |
| import org.eclipse.persistence.internal.sessions.PropertiesHandler; |
| import org.eclipse.persistence.logging.AbstractSessionLog; |
| import org.eclipse.persistence.logging.SessionLog; |
| import org.eclipse.persistence.platform.server.glassfish.GlassfishPlatformDetector; |
| import org.eclipse.persistence.platform.server.was.WebSpherePlatformDetector; |
| import org.eclipse.persistence.platform.server.wls.WebLogicPlatformDetector; |
| import org.eclipse.persistence.sessions.DatabaseSession; |
| |
| /** |
| * A utility class to interact with ServerPlatforms. |
| */ |
| public final class ServerPlatformUtils { |
| private static final List<ServerPlatformDetector> PLATFORMS = new ArrayList<ServerPlatformDetector>() {{ |
| add(new NoServerPlatformDetector()); |
| add(new WebSpherePlatformDetector()); |
| add(new WebLogicPlatformDetector()); |
| add(new GlassfishPlatformDetector()); |
| }}; |
| |
| private static final String UNKNOWN_MARKER = "UNKNOWN"; |
| private static String SERVER_PLATFORM_CLS; |
| |
| private ServerPlatformUtils() { |
| // no instance please |
| } |
| |
| /** |
| * @return The target-server class string that represents platform that is |
| * currently running. Return null if unknown. |
| */ |
| public static String detectServerPlatform(AbstractSession session) { |
| if (SERVER_PLATFORM_CLS == null) { |
| for (ServerPlatformDetector server : PLATFORMS) { |
| String res = server.checkPlatform(); |
| if (res != null) { |
| // Convert property values to platform class |
| SERVER_PLATFORM_CLS = PropertiesHandler.getPropertyValue(PersistenceUnitProperties.TARGET_SERVER, res); |
| break; |
| } |
| } |
| // If we didn't detect a server, use the unknown marker so we don't |
| // continually try to detect the platform. |
| if (SERVER_PLATFORM_CLS == null) { |
| SERVER_PLATFORM_CLS = UNKNOWN_MARKER; |
| } |
| } |
| |
| if (SERVER_PLATFORM_CLS == UNKNOWN_MARKER) { |
| return null; |
| } else { |
| //https://bugs.eclipse.org/bugs/show_bug.cgi?id=476018 |
| //log message only when we know how loggers were set up |
| if (session != null) { |
| session.log(SessionLog.FINER, SessionLog.SERVER, "detect_server_platform", SERVER_PLATFORM_CLS); |
| } else { |
| AbstractSessionLog.getLog().log(SessionLog.FINER, SessionLog.SERVER, "detect_server_platform", SERVER_PLATFORM_CLS); |
| } |
| return SERVER_PLATFORM_CLS; |
| } |
| } |
| |
| /** |
| * Create an instance of {@link ServerPlatform} from parameters passed in. |
| * |
| * @param session {@link DatabaseSession} which will be passed to the constructor of {@link ServerPlatform} |
| * @param platformClass fully qualified name of the {@link ServerPlatform} implementation to initialize |
| * @param loader {@link ClassLoader} to look up given platformClass |
| * |
| * @return initialized instance of {@link ServerPlatform} |
| * @throws ServerPlatformException if supplied platformClass is not found, can not be initialized, or is null. |
| * |
| * @see ServerPlatformBase#ServerPlatformBase(DatabaseSession) |
| */ |
| public static ServerPlatform createServerPlatform(DatabaseSession session, String platformClass, ClassLoader loader) { |
| if (platformClass == null) { |
| throw ServerPlatformException.invalidServerPlatformClass(null, null); |
| } |
| Class cls = null; |
| try { |
| //try the supplied classloader |
| cls = findClass(platformClass, loader); |
| } catch (ClassNotFoundException | PrivilegedActionException ex) { |
| //fallback to EL loader |
| ClassLoader cl = ServerPlatformUtils.class.getClassLoader(); |
| if (loader != cl) { |
| try { |
| cls = findClass(platformClass, cl); |
| } catch (ClassNotFoundException | PrivilegedActionException ex1) { |
| //ignore, throw first exception |
| throw ServerPlatformException.serverPlatformClassNotFound(platformClass, ex); |
| } |
| } else { |
| throw ServerPlatformException.serverPlatformClassNotFound(platformClass, ex); |
| } |
| } |
| final Class[] paramTypes = new Class[] { DatabaseSession.class }; |
| final Object[] params = new Object[] { session }; |
| ServerPlatform platform = null; |
| if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) { |
| try { |
| Constructor constructor = AccessController.doPrivileged( |
| new PrivilegedGetConstructorFor(cls, paramTypes, false)); |
| platform = (ServerPlatform) AccessController.doPrivileged( |
| new PrivilegedInvokeConstructor(constructor, params)); |
| } catch (PrivilegedActionException ex) { |
| throw ServerPlatformException.invalidServerPlatformClass(platformClass, ex); |
| } |
| } else { |
| try { |
| Constructor constructor = PrivilegedAccessHelper.getConstructorFor(cls, paramTypes, false); |
| platform = (ServerPlatform) PrivilegedAccessHelper.invokeConstructor(constructor, params); |
| } catch (NoSuchMethodException | IllegalAccessException |
| | InvocationTargetException | InstantiationException ex) { |
| throw ServerPlatformException.invalidServerPlatformClass(platformClass, ex); |
| } |
| } |
| return platform; |
| } |
| |
| private static Class findClass(String className, ClassLoader loader) throws ClassNotFoundException, PrivilegedActionException { |
| if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) { |
| return AccessController.doPrivileged(new PrivilegedClassForName(className, false, loader)); |
| } else { |
| return PrivilegedAccessHelper.getClassForName(className, false, loader); |
| } |
| } |
| } |