Real Dynamic Pointcuts in DynAOP
So I sat down to do real dynamic pointcuts in dynaop, as compared to the hacked interceptor control flow stuff before, and... it is dirt easy. Bob's design shines once again =)
All it entailed was extending Aspects
to add support for a Aspects#dynamicInterceptor
call which wraps the test in an interceptor:
import dynaop.*;
/**
* Aspects implementation which supports dynamic interception
*/
public class DynamicAspects extends Aspects {
public void dynamicInterceptor(ClassPointcut cp,
MethodPointcut mp,
final InvocationPointcut ip,
final Interceptor inter)
{
this.interceptor(cp, mp, new Interceptor() {
public Object intercept(Invocation invocation)
throws Throwable {
if (ip.pick(invocation)) {
return inter.intercept(invocation);
}
else {
return invocation.proceed();
}
}
});
}
}
and a InvocationPointcut
interface which tests invocations:
import dynaop.Invocation;
public interface InvocationPointcut
{
public boolean pick(Invocation invoke);
}
This lets you intercept based on invocation time properties. The unit test I wrote basically just skips the interceptor where the first arg is "foo"
DynamicAspects dynamic_aspects = new DynamicAspects();
final boolean[] called = { false };
Interceptor interp = new Interceptor() {
public Object intercept(Invocation invocation)
throws Throwable {
called[0] = true;
return invocation.proceed();
}
};
DynamicPointcut dynamic_pointcut = new InvocationPointcut() {
public boolean pick(Invocation invoke) {
Object[] args = invoke.getArguments();
// Don't select if first argument is "foo"
if ("foo".equals(args[0])) return false;
return true;
}
};
dynamic_aspects.dynamicInterceptor(Pointcuts.ALL_CLASSES,
Pointcuts.ALL_METHODS,
dynamic_pointcut,
interp);
ProxyFactory factory = new ProxyFactory(dynamic_aspects);
Map map = (Map) factory.wrap(new HashMap());
map.put("1", "2");
assertTrue(called[0]);
called[0] = false;
map.put("foo", "bar");
assertFalse(called[0]);
Meanwhile, maniax has been doing some really cool stuff with groovy and dynaop.