package org.perf4j.aop;
import junit.framework.TestCase;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptors;
import javax.interceptor.InvocationContext;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
/**
* This class tests the AbstractEjbTimingAspect interceptor. We don't really use a J2EE server for this test, instead
* we create our own dynamic proxy, similar to what a J2EE server would do.
*/
public class EjbAopTest extends TestCase {
EjbProfiledObjectInterface profiledObject;
protected void setUp() throws Exception {
super.setUp();
//create the profiled object
profiledObject = wrapBean(EjbProfiledObjectInterface.class, EjbProfiledObject.class);
}
@SuppressWarnings("unchecked")
protected <T> T wrapBean(Class<T> beanInterface, final Class<? extends T> beanClass) throws Exception {
//intercept the methods on the bean class as necessary
final Map<String, Object> methodNameToInterceptorMap = new HashMap<String, Object>();
for (Method method : beanClass.getMethods()) {
Interceptors interceptorsAnnotation = method.getAnnotation(Interceptors.class);
if (interceptorsAnnotation != null) {
//for the simplicity of this test case we only get the first interceptor
Object interceptor = interceptorsAnnotation.value()[0].newInstance();
methodNameToInterceptorMap.put(method.getName(), interceptor);
}
}
//create the dynamic proxy
final Object beanInstance = beanClass.newInstance();
return (T) Proxy.newProxyInstance(
getClass().getClassLoader(),
new Class[] {beanInterface},
new InvocationHandler() {
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
Method interceptorMethod = null;
Object interceptor = methodNameToInterceptorMap.get(method.getName());
if (interceptor != null) {
//for simplicity, we only get the first around invoke method
for (Method anInterceptorMethod : interceptor.getClass().getMethods()) {
if (anInterceptorMethod.getAnnotation(AroundInvoke.class) != null) {
interceptorMethod = anInterceptorMethod;
break;
}
}
}
//find the corresponding INSTANCE method on the bean, DON'T USE THE INTERFACE METHOD
final Method instanceMethod =
beanClass.getDeclaredMethod(method.getName(), method.getParameterTypes());
if (interceptorMethod != null) {
InvocationContext ctx = new InvocationContext() {
public Object getTarget() { return beanInstance; }
public Method getMethod() { return instanceMethod; }
public Object[] getParameters() { return args; }
public void setParameters(Object[] objects) { /* not supported */ }
public Map<String, Object> getContextData() { return new HashMap<String, Object>(); }
public Object proceed() throws Exception { return method.invoke(beanInstance, args); }
};
return interceptorMethod.invoke(interceptor, ctx);
} else {
return instanceMethod.invoke(beanInstance, args);
}
}
});
}
public void testEjbAspects() throws Exception {
assertEquals(50, profiledObject.simpleTest(50));
assertTrue(EjbInMemoryTimingAspect.getLastLoggedString().contains("tag[simpleTest]"));
assertEquals(100, profiledObject.simpleTestWithProfiled(100));
assertTrue(EjbInMemoryTimingAspect.getLastLoggedString().contains("tag[usingProfiled]"));
profiledObject.simpleTestDefaultTagMessageFromProperties(5);
assertTrue("Expected tag not found in " + EjbInMemoryTimingAspect.getLastLoggedString(),
EjbInMemoryTimingAspect.getLastLoggedString().indexOf("tag[customTag]") >= 0);
assertTrue("Expected tag not found in " + EjbInMemoryTimingAspect.getLastLoggedString(),
EjbInMemoryTimingAspect.getLastLoggedString().indexOf("message[customMessage]") >= 0);
profiledObject.simpleTestDefaultTagMessageFromPropertiesJexl(5);
assertTrue("Expected tag not found in " + EjbInMemoryTimingAspect.getLastLoggedString(),
EjbInMemoryTimingAspect.getLastLoggedString().indexOf("tag[org.perf4j.aop.EjbProfiledObject#simpleTestDefaultTagMessageFromPropertiesJexl]") >= 0);
assertTrue("Expected tag not found in " + EjbInMemoryTimingAspect.getLastLoggedString(),
EjbInMemoryTimingAspect.getLastLoggedString().indexOf("message[simpleTestDefaultTagMessageFromPropertiesJexl(5)]") >= 0);
}
}