Thank you Andy,
I got it. As you stated @annotation is for dynamic matching and this has
performance issues, can you tell me how can I access the annotation on the
method in a static way? I assumed that we can access it through
thisJoinPointStaticPart but I couldn't find any method for that.
pointcut eventMethods(Object obj,Object iparam) :
within(@Observable com..*)
&& execution(@Event * *.*(..))
&& target(obj)
&& args(iparam);
Apart from that I've got another problem. I want to add a field with an
annotation on it inside all classes which are marked with @Observable. I had
a look at OvserverProtocol example and some others in Internet but they
don't meet my requirements. So I have this code:
interface ObservableInterface {};
declare parents: @Observable com..* implements ObservableInterface;
@EJB
private EventDispatcher ObservableInterface.eventDispatcher;
now in my advice how can I call dispatch(Event) method of that observable
class:
after(Object obj,Object iparam) : eventMethods(obj,iparam) {
System.out.println("thisJoinPoint:"+thisJoinPointStaticPart.toLongString());
System.out.println("thisJoinPointSig:"+thisJoinPointStaticPart.getSignature().toLongString());
System.out.println("input param: "+iparam);
System.out.println("target objet: "+obj);
com.foo.listener.Event e = new com.foo.listener.Event();
e.setName("don't know"); //1
e.setParam(iparam);
e.setSource(obj.getClass().getName());
//eventDispatcher.dispatch(e); //2
}
//1 how to access @Event to extract event name from it
//2 how to call dispatch(Event) method
thanks
On Sun, Apr 25, 2010 at 10:17 PM, Andy Clement <[email protected]>wrote:
> @annotation can match dynamically. dynamic matching throughtout
> AspectJ means we couldn't check what you asked statically (at compile
> time) so had to insert some code to check it at runtime. Static
> matching leaves no runtime overhead.
>
> > eventMethods(Event e,Object obj,Object iparam) :
> > ...
> > && @args(e)
>
> That isn't what you want. That would match where the join point takes
> an argument and that the type of that argument has the Event
> annotation. Eg. this method would match because SomeType is marked
> @Event:
>
> public void foo(SomeType obj)
>
> where:
>
> @Event
> class SomeType {}
>
> What you want is:
>
> eventMethods(Event e, Object obj, Object iparam):
> && @annotation(e)
>
> because '@annotation' is being matched against the subject of the
> joinpoint and for method execution, the subject is the method itself.
>
> Andy
>
> On 25 April 2010 10:32, Mohammad Norouzi <[email protected]> wrote:
> > Hi Andy,
> > Thanks... what does 'dynamic match' mean?
> > I finally end up with a pointcut that match my desired points but the
> thing
> > is that when I want to pass the Event annotation the pointcut doesn't
> work
> > anymore
> >
> > To pass the annotation I changed the signature to
> >
> > eventMethods(Event e,Object obj,Object iparam) :
> > ...
> > && @args(e)
> >
> > is this correct?
> >
> > On 4/25/10, Andy Clement <[email protected]> wrote:
> >>
> >> I've only looked at it quickly, but first thing I spot is you haven't
> >> used '..' in the within clause.
> >>
> >> within(@Observable com.*)
> >>
> >> will match packages com.Foo, com.Bar, it will not match
> >> com.somewhere.Foo or com.somewhere.else.Bar. I doubt that is what you
> >> want so change it to double dot.
> >>
> >> within(@Observable com..*)
> >>
> >> Also I see you using @annotation(Event) - did you really need a
> >> dynamic match on that? If you don't you could just statically match
> >> it by remove the @annotation clause and putting the annotation in the
> >> execution pointcut:
> >>
> >> execution(@Event * *.*(..))
> >>
> >>
> >> Andy
> >>
> >>
> >> On 25 April 2010 02:17, Mohammad Norouzi <[email protected]> wrote:
> >> > Hi Simone,
> >> > Can you please tell me what's wrong with this pointcut. I want all the
> >> > methods which is in a type annotated with @Observable and the method
> >> > itself
> >> > annotated with @Event
> >> >
> >> > @Observable
> >> > public class O1 {
> >> >
> >> > @Event(value = {"EVENT1","EVENT2"})
> >> > public void method1(String str) {
> >> >
> >> > }
> >> > }
> >> >
> >> > package com.foo.aspect;
> >> >
> >> > import com.foo.annotation.*;
> >> >
> >> > public aspect EventDispatcherAspect {
> >> >
> >> > pointcut eventMethods(Object obj,Object iparam) :
> >> > within(@Observable com.*)
> >> > && execution(* *.*(..))
> >> > && @annotation(Event)
> >> > && args(iparam)
> >> > && target(obj);
> >> >
> >> > after(Object obj,Object iparam) returning:
> >> > eventMethods(obj,iparam)
> >> > {
> >> >
> >> >
> >> >
> System.out.println("thisJoinPoint:"+thisJoinPointStaticPart.toLongString());
> >> >
> >> >
> >> >
> System.out.println("thisJoinPointSig:"+thisJoinPointStaticPart.getSignature().toLongString());
> >> > //System.out.println("Events: "+e.value());
> >> >
> >> > }
> >> > }
> >> >
> >> >
> >> > Regards,
> >> > Mohammad
> >> > --------------------------
> >> >
> >> > On Wed, Apr 21, 2010 at 4:51 PM, Simone Gianni <[email protected]>
> >> > wrote:
> >> >>
> >> >> Hi Mohammad,
> >> >> nope, unfortunately AspectJ is not able to declare fields
> >> >> "dynamically",
> >> >> moreover private fields injected by AspectJ have a number of
> >> >> limitations
> >> >> that are being solved (they have mangled names).
> >> >>
> >> >> What you can do however is :
> >> >> - Declare an interface WithObserverABC
> >> >> - Use an ITD to place a privare field on that interface
> >> >> - Inject that interface on all classes that have @Observable
> >> >> - Write the aspect that calls the observer method when an @Observable
> >> >> method is executed.
> >> >>
> >> >> public aspect InjectObserverABC {
> >> >> public interface WithObserverABC {}
> >> >>
> >> >> // this could be private, except for name mangling, depends on
> >> >> AspectJ
> >> >> version
> >> >> public ObserverAbc WithObserverABC.abcObserver = new
> >> >> ObserverABCImpl();
> >> >>
> >> >> // you could narrow this
> >> >> declare parents : hasmethod(@Observable *(..)) implements
> >> >> WithObserverABC;
> >> >>
> >> >> before(WithObserverABC instance) : execution(@Observable *
> >> >> WithObserverABC+.*(..)) && this(instance) {
> >> >> instance.abcObserver.
> >> >> notifyObserver();
> >> >> }
> >> >> }
> >> >>
> >> >> I'm not sure about the syntax (I wrote it here in this email, and i
> >> >> need
> >> >> compiler support when writing pointcuts :) ), but you should get the
> >> >> idea.
> >> >> Eventually you can try to play with generics/abstract aspects to make
> >> >> it
> >> >> easier to inject new observers, but I cannot think of a way of doing
> >> >> this
> >> >> completely automatically (apart from using APT to parse classes with
> >> >> @Observer and generate dynamically aop.xml to instantiate concrete
> >> >> aspects
> >> >> ... but that's another story :) )
> >> >>
> >> >> Hope this helps,
> >> >> Simone
> >> >>
> >> >> 2010/4/20 Mohammad Norouzi <[email protected]>
> >> >>>
> >> >>> Hi Simone,
> >> >>> >>if I understand correctly, when a method annotated with
> @Observable
> >> >>> >> is
> >> >>> >> executed, you want to see if there are fields in that class with
> an
> >> >>> >> instance
> >> >>> >> of an observer, and call a method on the observer.<<
> >> >>> Actually, when a method is annotated with @Observable (before
> >> >>> executing
> >> >>> and at the time of compiling codes) I want to add (not see) those
> >> >>> interfaces
> >> >>> that annotated with @Observer, as private fields in the observable
> >> >>> and I
> >> >>> want to add them because both observer and observable are EJB
> session
> >> >>> beans
> >> >>> so the application server will take the burden of instantiating
> those
> >> >>> observers using its injection technique
> >> >>>
> >> >>> What I need is something like this:
> >> >>> for(MyObserver o : observers){
> >> >>> declare a private field with a name in this instance of
> observable
> >> >>> class
> >> >>> }
> >> >>>
> >> >>>
> >> >>> On Mon, Apr 19, 2010 at 2:22 PM, Simone Gianni <[email protected]>
> >> >>> wrote:
> >> >>>>
> >> >>>> Hi Mohammad,
> >> >>>> if I understand correctly, when a method annotated with @Observable
> >> >>>> is
> >> >>>> executed, you want to see if there are fields in that class with an
> >> >>>> instance
> >> >>>> of an observer, and call a method on the observer.
> >> >>>>
> >> >>>> You can use AspectJ to execute an advice before/after/around the
> >> >>>> execution of @Obervable methods, and use thisJoinPoint or the
> this()
> >> >>>> construct to find the instance of the method.
> >> >>>>
> >> >>>> Once you are there, you must use plain java reflection, and not
> >> >>>> AspectJ,
> >> >>>> to find fields in that class that contains an observer and invoke
> >> >>>> observer
> >> >>>> methods.
> >> >>>>
> >> >>>> To add @EJB annotation to all fields of type X where X is annotated
> >> >>>> with
> >> >>>> @Observer, you can use declare @class and write a type pattern that
> >> >>>> uses
> >> >>>> @Observer annotation. If @Observer annotation is placed on methods,
> >> >>>> you can
> >> >>>> use hasmethod() to find classes that has such methods, but beware
> >> >>>> cause
> >> >>>> hasmethod is somewhat experimental.
> >> >>>>
> >> >>>> Hope this helps,
> >> >>>> Simone
> >> >>>>
> >> >>>> 2010/4/19 is_maximum <[email protected]>
> >> >>>>>
> >> >>>>> Thanks Simone, yes this is exactly what I want... but another
> >> >>>>> question
> >> >>>>> is
> >> >>>>> that this is used using 'declare' and as far as I know declare is
> >> >>>>> placed in
> >> >>>>> aspect definition. How can I place it in a for-loop.
> >> >>>>>
> >> >>>>> Let me tell you the scenario may be I am in wrong way...
> >> >>>>>
> >> >>>>> I am trying to implement an observer pattern in EJB 3.0. I saw
> many
> >> >>>>> implementation using aspectJ but mine is a little different. The
> >> >>>>> difference
> >> >>>>> is that I want to inject observer into observable...
> >> >>>>>
> >> >>>>> Because session beans are managed object and in my case both
> >> >>>>> observer
> >> >>>>> and
> >> >>>>> observable supposed to be session beans I want application server
> >> >>>>> injects
> >> >>>>> observer session beans in observable SB and then call observer
> >> >>>>> methods
> >> >>>>>
> >> >>>>> These observer and observable methods will be annotated by the
> >> >>>>> developer
> >> >>>>> with say @Observer and @Observable
> >> >>>>>
> >> >>>>> What I wanted was to look for @Observer methods and find their
> >> >>>>> interface and
> >> >>>>> put them like this:
> >> >>>>>
> >> >>>>> @EJB
> >> >>>>> private ObserverInterface1 observer1
> >> >>>>>
> >> >>>>> than each time the determined method is called I can call
> >> >>>>> observer1.notifyObserver() method
> >> >>>>>
> >> >>>>> Can you please help me on this?
> >> >>>>>
> >> >>>>>
> >> >>>>>
> >> >>>>>
> >> >>>>> Simone Gianni-2 wrote:
> >> >>>>> >
> >> >>>>> > Hi Mohammad,
> >> >>>>> > maybe you are loooking for the declare annotation statement?
> >> >>>>> >
> >> >>>>> >
> >> >>>>> >
> http://www.eclipse.org/aspectj/doc/next/adk15notebook/annotations-declare.html
> >> >>>>> >
> >> >>>>> > Simone
> >> >>>>> >
> >> >>>>> >
> >> >>>>>
> >> >>>>>
> >> >>>>> -----
> >> >>>>> --
> >> >>>>> Regards
> >> >>>>>
> >> >>>>> Mohammad Norouzi
> >> >>>>>
> >> >>>>> Help each other to reach the future faster
> >> >>>>>
> >> >>>>> http://pixelshot.wordpress.com Pixelshot Photoblog
> >> >>>>>
> >> >>>>> http://brainable.blogspot.com Brainable Blog
> >> >>>>>
> >> >>>>>
> >> >>>>> --
> >> >>>>> View this message in context:
> >> >>>>>
> >> >>>>>
> http://old.nabble.com/How-to-rewrite-a-class-with-AspectJ-tp28280867p28287273.html
> >> >>>>> Sent from the AspectJ - users mailing list archive at Nabble.com.
> >> >>>>>
> >> >>>>> _______________________________________________
> >> >>>>> aspectj-users mailing list
> >> >>>>> [email protected]
> >> >>>>> https://dev.eclipse.org/mailman/listinfo/aspectj-users
> >> >>>>
> >> >>>>
> >> >>>> _______________________________________________
> >> >>>> aspectj-users mailing list
> >> >>>> [email protected]
> >> >>>> https://dev.eclipse.org/mailman/listinfo/aspectj-users
> >> >>>>
> >> >>>
> >> >>>
> >> >>> _______________________________________________
> >> >>> aspectj-users mailing list
> >> >>> [email protected]
> >> >>> https://dev.eclipse.org/mailman/listinfo/aspectj-users
> >> >>>
> >> >>
> >> >>
> >> >> _______________________________________________
> >> >> aspectj-users mailing list
> >> >> [email protected]
> >> >> https://dev.eclipse.org/mailman/listinfo/aspectj-users
> >> >>
> >> >
> >> >
> >> > _______________________________________________
> >> > aspectj-users mailing list
> >> > [email protected]
> >> > https://dev.eclipse.org/mailman/listinfo/aspectj-users
> >> >
> >> >
> >> _______________________________________________
> >> aspectj-users mailing list
> >> [email protected]
> >> https://dev.eclipse.org/mailman/listinfo/aspectj-users
> >
> >
> >
> > --
> > Regards,
> > Mohammad
> > --------------------------
> > Sun Certified Web Developer
> > ExpertsExchange Certified, Master:
> > http://www.experts-exchange.com/M_1938796.html
> > Have a look at some pictures @ http://pixelshot.wordpress.com/
> > Do you like to read, see http://brainable.blogspot.com/
> > For the Persians see http://fekre-motefavet.blogspot.com/
> > English
> > Forum:
> http://n2.nabble.com/English-Phrase-Finder-For-Persians-f3274251.html
> >
> >
> > _______________________________________________
> > aspectj-users mailing list
> > [email protected]
> > https://dev.eclipse.org/mailman/listinfo/aspectj-users
> >
> >
> _______________________________________________
> aspectj-users mailing list
> [email protected]
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>
_______________________________________________
aspectj-users mailing list
[email protected]
https://dev.eclipse.org/mailman/listinfo/aspectj-users