0 Replies Latest reply on Jul 6, 2005 8:36 PM by Bill Burke

    Refactoring Instrumentation in AOP 2.0:  Iteration 3

    Bill Burke Master

      * Write a fully optimized instrumentor that inlines before/after, within the
      OPtimized MethodInvocation, ConstructorInvocation, etc... classes. Remember
      that old generated code snippet we sent around before? I'll attach some examples.

      public class Foo
      {
       private float doit(double stuff) throws TypedException
       {
       }
      
      
       public static abstract class Joinpoint_doit implements MethodJoinpoint
       {
       protected Foo target;
       protected double arg1;
      
       protected Joinpoint_doit() {}
      
       protected Joinpoint_doit(Foo target, double arg1)
       {
       this.target = target;
       this.arg1 = arg1;
       }
      
       public Object dispatch()
       {
       return new Float(target.doit(arg1));
       }
      
       public Object[] getArguments() {...}
      
       public abstract float doit(Foo target, arg1);
       }
      }
      
      package org;
      
      public class Foo_Joinpoint_doit extends Foo.Joinpoint_doit
      {
       private Security before1;
       private TxDemarcation around1;
       private LatchedJoinpoint around2;
       private SomeAspect after1;
       private SomeAspect after2;
       Private AnotherAspect afterThrowing1;
      
       private int currentAdvice;
      
       public Foo_Joinpoint_doit(TxDemarcation around1, LatchedJoinpoint around2)
       {
       this.around1 = around1;
       this.around2 = around2;
       }
      
       public Foo_joinpoint_doit(Foo target, double arg1, TxDemarcation around1, LatchedJoinpoint around2)
       {
       super(target, arg1);
       }
      
      
       // for dynamic invoke.
       public Object invoke(Object target, MethodJoinpoint jp) throws Exception
       {
       Object[] args = jp.getArguments();
       return new Float(doit((Foo)target, ((Double)args[0]).doubleValue()));
       }
      
       public float doit(Foo target, double arg1) throws TypedException
       {
       float returnValue;
      
      
       before1.authenticate();
       try {
       Foo_Joinpoint around = new Foo_Joinpoint(target, arg1, around1, around2);
       returnValue = = (Float)(around.invokeNext()).floatValue();
       // after needs detyped args so get them from the around advice
       args = around.getArguments();
      
       returnValue = (Float)(after1.doAdvice(this, // static joinpoint
       new Float(returnValue), // return as a generic object
       args)).floatValue(); // needs generic args
      
       returnValue = after2.doAdvice(returnValue); // just typed returnValue needed.
       } catch (Throwable t) {
       t = afterThrowing1.execute(this, t, args);
       t = afterThrowing2.execute(this, t, args);
      
       if (t instanceof TypedException) throw (TypedException)t;
       else if (t instanceof RuntimeException) throw (RuntimeException)t;
       else throw new RuntimeException(t);
       }
       return returnValue;
       }
      
       public FooPolicy getAround3()
       {
       return (FooPolicy)target.getInstanceAdvisor().getPerInstanceAspect("FooPolicy");
       }
      
       public Object invokeNext() throws Throwable
       {
      
       try {
       switch (++currentAdvice) {
       case 1:
       return around1.doTransaction(this);
       case 2:
       return around2.invoke(this);
       case 3:
       InvocationStack.push(this);
       try {
       return new Float(getAround3().doit(arg1));
       } finally {
       InvocationStack.pop();
       }
       default:
       return dispatch();
       }
       } finally {
       --currentAdvice;
       }
      
       }
      }