| Re: [aspectj-users] Re: Access to the aspect in 'pertypewithin' type |
| I played around with a few workarounds that give you type-specific enablement of tracing with checking of an if() conditional in the pointcut. It may not be as runtime efficient as we might like, but it shouldn't be too bad either. Start with two test classes: package ptw; public class Type1 { public void doit1() { System.out.println("in: Type1.doit1()"); } public void doit2() { System.out.println("in: Type1.doit2()"); } }
and package ptw; public class Type2 { public void doit1() { System.out.println("in: Type2.doit1()"); } public void doit2() { System.out.println("in: Type2.doit2()"); } } Here's the first aspect that uses pertypewithin and a static method to make the "enabled" field accessible. It also has a main that exercises the code: package ptw; public aspect TracerPerType pertypewithin(ptw.*) { public boolean enabled = false; static boolean isEnabledFor(Object o) { return aspectOf(o.getClass()).enabled; } // It would be great if we could just pass the type, but we only have the object. (right?) before(Object o): if (isEnabledFor(o)) && target(o) && call (* ptw.*.*(..)) { System.out.println("entering: "+thisJoinPointStaticPart); } public static void main(String[] args) { System.out.println("No tracing enabled:"); callDoits(); System.out.println("Enabling tracing for Type1:"); aspectOf(Type2.class).enabled = true; callDoits(); System.out.println("Enabling tracing for Type2:"); aspectOf(Type2.class).enabled = true; callDoits(); System.out.println("Disabling tracing for Type1:"); aspectOf(Type1.class).enabled = false; callDoits(); System.out.println("Disabling tracing for Type2:"); aspectOf(Type2.class).enabled = false; callDoits(); } private static void callDoits() { Type1 t1 = new Type1(); t1.doit1(); t1.doit2(); Type2 t2 = new Type2(); t2.doit1(); t2.doit2(); } }
Here's a second aspect that doesn't use pertypewithin and tracks which types are enabled in a Set. It also has a main: package ptw; import java.util.HashSet; public aspect Tracer { // Don't use the <?> for Java 1.4, of course. static HashSet<Class<?>> enabled = new HashSet<Class<?>>(); static void enableFor(Class<?> clazz) { enabled.add(clazz); } static void disableFor(Class<?> clazz) { enabled.remove(clazz); } before(Object o): if (enabled.contains(o.getClass())) && target(o) && call (* ptw.*.*(..)) { System.out.println("entering: "+thisJoinPointStaticPart); } public static void main(String[] args) { System.out.println("No tracing enabled:"); callDoits(); System.out.println("Enabling tracing for Type1:"); Tracer.enableFor(Type1.class); callDoits(); System.out.println("Enabling tracing for Type2:"); Tracer.enableFor(Type2.class); callDoits(); System.out.println("Disabling tracing for Type1:"); Tracer.disableFor(Type1.class); callDoits(); System.out.println("Disabling tracing for Type2:"); Tracer.disableFor(Type2.class); callDoits(); } private static void callDoits() { Type1 t1 = new Type1(); t1.doit1(); t1.doit2(); Type2 t2 = new Type2(); t2.doit1(); t2.doit2(); } } Both aspects should print out the following: No tracing enabled: in: Type1.doit1() in: Type1.doit2() in: Type2.doit1() in: Type2.doit2() Enabling tracing for Type1: entering: call(void ptw.Type1.doit1()) in: Type1.doit1() entering: call(void ptw.Type1.doit2()) in: Type1.doit2() in: Type2.doit1() in: Type2.doit2() Enabling tracing for Type2: entering: call(void ptw.Type1.doit1()) in: Type1.doit1() entering: call(void ptw.Type1.doit2()) in: Type1.doit2() entering: call(void ptw.Type2.doit1()) in: Type2.doit1() entering: call(void ptw.Type2.doit2()) in: Type2.doit2() Disabling tracing for Type1: in: Type1.doit1() in: Type1.doit2() entering: call(void ptw.Type2.doit1()) in: Type2.doit1() entering: call(void ptw.Type2.doit2()) in: Type2.doit2() Disabling tracing for Type2: in: Type1.doit1() in: Type1.doit2() in: Type2.doit1() in: Type2.doit2() Using a static Set or Map like this is a pretty common idiom. pertypewithin eliminated many cases for it. dean On Jan 31, 2008, at 11:53 AM, Andy Clement wrote: So, from the advice you can of course just use 'this' as that will be Dean Wampler, Ph.D. dean at objectmentor.com See also: http://www.aspectprogramming.com AOP advocacy site http://aquarium.rubyforge.org AOP for Ruby http://www.contract4j.org Design by Contract for Java5 |