
org.openl.rules.project.instantiation.RuntimeContextInstantiationStrategyEnhancer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.openl.rules.project Show documentation
Show all versions of org.openl.rules.project Show documentation
Classes and utilities to work with OpenL Rules Project
package org.openl.rules.project.instantiation;
import org.apache.commons.lang3.ArrayUtils;
import org.openl.exception.OpenlNotCheckedException;
import org.openl.rules.context.IRulesRuntimeContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
* Auxiliary class which enhances rule service with ability to use rule service
* method with rules runtime context during method invocation. The class is used
* by engine to expose rules services as web service.
*
* Enhancer class decorates methods of original service class and exposes new
* methods signatures instead of original methods. New method signature has one
* more parameter - rules runtime context. While service method invocation
* engine do the following steps:
*
* - recognize context parameter;
* - recognize original service method to invoke using method signature;
* - set rules runtime context;
* - invoke appropriate service method.
*
*
* @author Marat Kamalov
*/
public class RuntimeContextInstantiationStrategyEnhancer extends AbstractServiceClassEnhancerInstantiationStrategy {
private final Logger log = LoggerFactory.getLogger(RuntimeContextInstantiationStrategyEnhancer.class);
/**
* Constructs new instance of instantiation strategy.
*
* @param instantiationStrategy instantiation strategy which used to
* instantiate original service
*/
public RuntimeContextInstantiationStrategyEnhancer(RulesInstantiationStrategy instantiationStrategy) {
super(instantiationStrategy);
}
@Override
protected Class> decorateServiceClass(Class> serviceClass, ClassLoader classLoader) {
try {
return RuntimeContextInstantiationStrategyEnhancerHelper.decorateClass(serviceClass, classLoader);
} catch (Exception e) {
throw new OpenlNotCheckedException("Failed to add runtime context in parameters of each method.", e);
}
}
@Override
protected Class> undecorateServiceClass(Class> serviceClass, ClassLoader classLoader) {
try {
return RuntimeContextInstantiationStrategyEnhancerHelper.undecorateClass(serviceClass, classLoader);
} catch (Exception e) {
throw new OpenlNotCheckedException("Failed to remove runtime context from parameters of each method.", e);
}
}
@Override
protected boolean validateServiceClass(Class> serviceClass) throws ValidationServiceClassException {
if (RuntimeContextInstantiationStrategyEnhancerHelper.isDecoratedClass(serviceClass)) {
return true;
} else {
throw new ValidationServiceClassException("Runtime context parameter required in each method!");
}
}
/**
* Makes invocation handler.
*
* @return {@link InvocationHandler} instance
* @throws Exception
*/
protected InvocationHandler makeInvocationHandler(Object instanceObject) throws Exception {
Map methodsMap = makeMethodMap(getServiceClass(),
getOriginalInstantiationStrategy().getInstanceClass());
return new RuntimeContextInstantiationStrategyEnhancerInvocationHandler(methodsMap, instanceObject);
}
/**
* Gets methods map where keys are interface class methods and values -
* original service class methods.
*
* @param interfaceClass class to expose as service class
* @param serviceClass original service class
* @return methods map
*/
private Map makeMethodMap(Class> interfaceClass, Class> serviceClass) {
log.debug("Creating methods map for classes: {} <-> {}", interfaceClass, serviceClass);
Map methodMap = new HashMap();
Method[] serviceMethods = serviceClass.getDeclaredMethods();
for (Method serviceMethod : serviceMethods) {
String interfaceMethodName = serviceMethod.getName();
Class>[] serviceMethodParameterTypes = serviceMethod.getParameterTypes();
Class>[] newParams = new Class>[]{IRulesRuntimeContext.class};
Class>[] extendedParamTypes = ArrayUtils.addAll(newParams, serviceMethodParameterTypes);
Method interfaceMethod;
try {
interfaceMethod = interfaceClass.getMethod(interfaceMethodName, extendedParamTypes);
methodMap.put(interfaceMethod, serviceMethod);
} catch (NoSuchMethodException e) {
// Ignore an exception. Interface class can ignore several
// methods what declared in service class.
}
}
log.debug("{}", methodMap);
return methodMap;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy