blob: 45548b9000b38d76059eb8ea60013e63344e809c [file] [log] [blame]
/*
* Copyright (c) 2015, 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
package org.eclipse.persistence.platform.server.wls;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.sessions.DatabaseSession;
public class WebLogic_12_Platform extends WebLogic_10_Platform {
private static final ContextHelper ctxHelper = ContextHelper.getContextHelper();
public WebLogic_12_Platform(DatabaseSession newDatabaseSession) {
super(newDatabaseSession);
}
@Override
public boolean usesPartitions() {
return ctxHelper != null;
}
@Override
public String getPartitionID() {
return ctxHelper != null ? ctxHelper.getPartitionID() : super.getPartitionID();
}
public String getPartitionName() {
return ctxHelper != null ? ctxHelper.getPartitionName() : "GLOBAL";
}
public boolean isGlobalRuntime() {
return ctxHelper == null || ctxHelper.isGlobalRuntime();
}
private static final class ContextHelper {
/**
* Instance of CIC (Component Invocation Context) or null if not
* initialized.
*/
private Object cicManagerInstance;
private Method getCurrentCicMethod;
private Method getPartitionIdMethod;
private Method getPartitionNameMethod;
private Method isGlobalRuntimeMethod;
private static final Class<?> cicManagerClass;
private static volatile ContextHelper instance;
private static final String CIC_MANAGER_RESOURCE_NAME = "META-INF/services/weblogic.invocation.ComponentInvocationContextManager";
private static final String CIC_MANAGER_CLASS_NAME = "weblogic.invocation.ComponentInvocationContextManager";
static {
if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
cicManagerClass = AccessController.doPrivileged(new PrivilegedAction<>() {
@Override
public Class<?> run() {
return getCicManagerClass(CIC_MANAGER_RESOURCE_NAME, CIC_MANAGER_CLASS_NAME);
}
});
} else {
cicManagerClass = getCicManagerClass(CIC_MANAGER_RESOURCE_NAME, CIC_MANAGER_CLASS_NAME);
}
}
private static Class<?> getCicManagerClass(String cicManagerResourceName, String cicManagerClassName) {
try {
if (WebLogic_12_Platform.class.getClassLoader().getResource(cicManagerResourceName) != null) {
return PrivilegedAccessHelper.getClassForName(cicManagerClassName);
} else {
return null;
}
} catch (ClassNotFoundException cnfe) {
return null;
}
}
private ContextHelper(final Class<?> managerClass, final String contextClassName) {
if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
initialize(managerClass, contextClassName);
return null;
}
});
} else {
initialize(managerClass, contextClassName);
}
}
private void initialize(final Class<?> managerClass, final String contextClassName) {
try {
// Get component invocation manager
final Method getInstance = PrivilegedAccessHelper.getDeclaredMethod(managerClass, "getInstance", new Class[]{});
cicManagerInstance = PrivilegedAccessHelper.invokeMethod(getInstance, managerClass);
// Get component invocation context
getCurrentCicMethod = PrivilegedAccessHelper.getMethod(managerClass, "getCurrentComponentInvocationContext", new Class[]{}, true);
final Class<?> cicClass = PrivilegedAccessHelper.getClassForName(contextClassName);
getPartitionIdMethod = PrivilegedAccessHelper.getDeclaredMethod(cicClass, "getPartitionId", new Class[]{});
getPartitionNameMethod = PrivilegedAccessHelper.getDeclaredMethod(cicClass, "getPartitionName", new Class[]{});
isGlobalRuntimeMethod = PrivilegedAccessHelper.getDeclaredMethod(cicClass, "isGlobalRuntime", new Class[]{});
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | ClassNotFoundException ex) {
AbstractSessionLog.getLog().logThrowable(SessionLog.WARNING, null, ex);
}
}
static ContextHelper getContextHelper() {
if (cicManagerClass == null) {
return null;
}
if (instance == null) {
synchronized (ContextHelper.class) {
if (instance == null) {
instance = new ContextHelper(cicManagerClass, "weblogic.invocation.ComponentInvocationContext");
}
}
}
return instance;
}
/**
* Gets partition ID. Calls cicInstance.getPartitionIdMethod().
*/
String getPartitionID() {
return getStringFromMethod(getPartitionIdMethod);
}
/**
* Gets partition name. Calls cicInstance.getPartitionNameMethod().
*/
String getPartitionName() {
return getStringFromMethod(getPartitionNameMethod);
}
/**
* Calls the method passed against cicInstance returning the result as
* String.
*
* @param methodToCall
* The cicInstance method to call
* @return the method result as String
*/
private String getStringFromMethod(final Method methodToCall) {
try {
if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
return AccessController.doPrivileged(new PrivilegedAction<>() {
@Override
public String run() {
try {
final Object cicInstance = PrivilegedAccessHelper.invokeMethod(getCurrentCicMethod, cicManagerInstance);
return PrivilegedAccessHelper.invokeMethod(methodToCall, cicInstance);
} catch (ReflectiveOperationException ex) {
AbstractSessionLog.getLog().logThrowable(SessionLog.WARNING, null, ex);
return "UNKNOWN";
}
}
});
} else {
final Object cicInstance = PrivilegedAccessHelper.invokeMethod(getCurrentCicMethod, cicManagerInstance);
return PrivilegedAccessHelper.invokeMethod(methodToCall, cicInstance);
}
} catch (ReflectiveOperationException ex) {
AbstractSessionLog.getLog().logThrowable(SessionLog.WARNING, null, ex);
return "UNKNOWN";
}
}
/**
* Returns whether code is running globally as opposed to running in
* partition. Calls cicInstance.isGlobalRuntime().
*/
boolean isGlobalRuntime() {
try {
if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
return AccessController.doPrivileged(new PrivilegedAction<>() {
@Override
public Boolean run() {
try {
final Object cicInstance = PrivilegedAccessHelper.invokeMethod(getCurrentCicMethod, cicManagerInstance);
return PrivilegedAccessHelper.invokeMethod(isGlobalRuntimeMethod, cicInstance);
} catch (ReflectiveOperationException ex) {
AbstractSessionLog.getLog().logThrowable(SessionLog.WARNING, null, ex);
return true;
}
}
});
} else {
final Object cicInstance = PrivilegedAccessHelper.invokeMethod(getCurrentCicMethod, cicManagerInstance);
return PrivilegedAccessHelper.invokeMethod(isGlobalRuntimeMethod, cicInstance);
}
} catch (ReflectiveOperationException ex) {
AbstractSessionLog.getLog().logThrowable(SessionLog.WARNING, null, ex);
return true;
}
}
}
}