Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Weaving code that comes from an Annotation's value

This is pretty much what I do in Contract4J
(http://www.contract4j.org), where the @Pre annotations triggers
before advice. In this case, the value of the annotation is a java
expression and it is evaluated with Jakarta Jexl's expression
evaluator.

I'm actually talking about the newest version that I am finishing, not
the two previous releases on the website. (ETA for the new release is
~1 week).

Writing the aspect is not difficult. Evaluating the expression is
harder, depending on how "sophisticated" it needs to be.

Concerning the expression in the annotation value, does it vary with
each usage of the aspect or is it fixed? Your example suggests you
want to do tracing, but maybe that's just the example. If you have a
fixed java expression or one that varies in "simple" ways, it would be
far easier to omit it from the annotation and put it in the aspect
itself.  Consider the tracing aspect and ignoring the
thisJoinPointStaticPart.toString() method ;), you could write tracing
advice that does something like this:
   before(Object o, <other args>): mypointcut(o,<...>) {
     System.out.format ("class name = %s, stuff = %s",
o.getClass().getName(), ...);
   }
Even if the expression changes a lot, maybe it would be simpler to
write a base aspect and override it for each class/method, where the
advice for class "Foo.foo" contains the expression. I'm just trying to
save you the hassles of integrating an expression evaluator, having
gone through that pain myself, if you don't really need it.

Actually, it wouldn't be that bad if your expressions don't require
access to local context data, like Foo fields or methods. The pain
comes in setting up Jexl's context correctly.

So, with that digression, the aspect would be something like

aspect BeforeExecutor {
  pointcut execBefore (Object o, ExecuteBefore eb):
    execution(@ExecuteBefore * *.*(..)) && this(o) && @annotation(eb);

  before (Object o, ExecuteBefore eb): execBefore (o, eb) {
    evalExpression(eb.value());
  }

  void evalExpression(String expr) { ... }
}

Of course, "evalExpression" is the hard bit.

I can send you a preview of the newest C4J if you'd like to see what I
did with Jexl. In my case, I need to do some fancy footwork to setup
Jexl's "context" for evaluating the expression. It can be done!

Good luck,
dean

--
Dean Wampler
http://www.aspectprogramming.com
http://www.newaspects.com
http://www.contract4j.org


On 2/4/06, Michael Herrmann <Michael_Herrmann@xxxxxx> wrote:
> Hi,
>
> I'd like to be able to annotate my methods with code that should then always
> be called before the method itself is called. Is it, through AspectJ,
> possible to treat the value of a (String) element of an annotation as code?
>
> For example:
> public interface Foo {
>         @ExecuteBefore("System.out.println('hi');");
>         public void foo();
> }
>
> I now want System.out.println('hi') to always be called before the
> implementation of foo() is called. You might recommend using abstract
> classes in this case, but this is just an extremely oversimplified example
> to show you what I mean and using abstract classes or anything similar won't
> help me, unfortunately.
>
> Thank you very much for your time
> Michael Herrmann
>
> --
> 10 GB Mailbox, 100 FreeSMS/Monat http://www.gmx.net/de/go/topmail
> +++ GMX - die erste Adresse für Mail, Message, More +++
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>


Back to the top