package samples.interceptor;
import java.lang.reflect.InvocationHandler;
import alt.jiapi.InstrumentationContext;
import alt.jiapi.InstrumentationDescriptor;
import alt.jiapi.reflect.Loader;
import alt.jiapi.reflect.JiapiClass;
import alt.jiapi.util.Bootstrapper;
import alt.jiapi.util.InstrumentingClassLoader;
import alt.jiapi.interceptor.*;
/**
* Sample1 demonstrates how to intercept method invocations
* made.
* One is free to modify method call parameters / return value at will, as
* long as their type matches methods signature.
*/
public class Sample1 implements InvocationHandler {
public static void main(String args[]) throws Exception {
String className = "samples.Foo";
if (args.length > 0) {
className = args[0];
}
new Sample1(className);
}
public Sample1(String className) throws Exception {
// Configure:
InstrumentationContext ctx = new InstrumentationContext();
InstrumentationDescriptor id = new InstrumentationDescriptor();
id.addInclusionRule("samples.*");
ctx.addInstrumentationDescriptor(id);
// Associate interceptor with descriptor
// Set resolution to 'foo*', which means that interceptor applies
// its work only on invocations to methods which start with 'foo'
InvocationInterceptor ii = new InvocationInterceptor(id, "samples*",this);
// Launch samples.Foo
Bootstrapper.launch(className, null, ctx,
InstrumentingClassLoader.createClassLoader(ctx));
}
/**
* InvocationHandler interface
*
* @param o target instance. If this is null, target Method is
* static
* @param m Method, that this handler is supposed to invoke
* @param args Arguments, that are suitable to be passed to
* reflective method.
*/
public Object invoke(Object o, java.lang.reflect.Method m, Object[] args) throws Exception {
System.out.println(" Calling " + m.getName());
for (int i = 0; i < args.length; i++) {
// Modify call parameters. If call param is string, convert it
// to upper case
if (args[i] instanceof String) {
args[i] = ((String)args[i]).toUpperCase();
}
}
long l1 = System.currentTimeMillis();
// Make a call to target method through java.lang.reflect.Method
Object rv = m.invoke(o, args);
long l2 = System.currentTimeMillis();
System.out.println(" " + m.getName() + " executed in " +
(l2 - l1) + " ms");
// Remember to return value. We could change the return
// value if desired. One must make sure, that the type
// of the return value is valid.
if (rv instanceof Integer) {
int i = ((Integer)rv).intValue();
rv = new Integer(i + 1);
}
return rv;
}
}