Brian's Waste of Time

Fri, 27 Feb 2004

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.

1 writebacks [/src/java/aop] permanent link