Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Re: hasmethod/hasfield pointcuts (was: AspectJ + Groovy?)


> On Thu, 24 Feb 2005 13:11:32 -0800, Ron Bodkin <rbodkin@xxxxxxxxxxxxxx> wrote:
> > (*) I don't think hasfield/hasmethod should be defined as pointcuts since it
> > breaks orthogonality. Instead, these ought to be type patterns, just like
> > Foo+ or annotation matching for type patterns.
>
> Hi Ron,
>
> Not sure I got what you meant from your comment, but I've implemented
> the hasfield/hasmethod poincuts in AW and I have a very clear use case
> for them.

There's an interesting discussion lurking behind these comments which I want to try and tease out a little. Firstly let me state the obvious about the join point / pointcuts / advice model. There are three components, which are separate and orthogonal concepts. Join points are events that occur during the runtime execution of the program. Pointcuts are expressions that match join points. Pointcuts support abstraction and composition making the pointcut 'language' a complete and powerful mini-language in its own right. That is to say, the various pointcut designators can be composed (&&, ||, !) in many ways to create useful pointcut definitions. Advice is associated with a pointcut _expression_, and executes at each join point matched by its associated pointcut _expression_.

So what?

So, for hasfield() to be a pointcut, we have to be able to answer in all contexts and combinations the question "what join points does the hasfield() pointcut match?" (Note, it has to be *join points*, not types for example). For each pointcut designator we have to able to complete the sentence: "The xxx pointcut designator matches any join point where...".

I'm not aware of the semantics that you gave hasfield (for example) in AW, but let's look at what it might mean in AspectJ. Suppose I write the program:

aspect X {

  before() : hasfield(foo) {
    System.out.println("There's a foo field here!");
  }
}

When does the advice run?

There are a few choices:

* at any join point where 'this' is bound, and the type of 'this' has a field named 'foo'  (runtime test)
* at any join point where 'this' is bound and the static type of 'this' has a field named 'foo'
* at any join point where 'target' is bound, and the type of 'target' has a field named 'foo' (runtime test)
* at any join point where 'target' is bound,the static type of 'target' has a field named 'foo'
* at any join point 'within' a type that has a field named 'foo'
* ... and probably some others.

The most logical choice to me seems to be the last interpretation: hasfield(NamePattern) matches any join point arising from the execution of logic defined within a type that has a field matching NamePattern.

But the within pointcut already takes a type pattern: within(TypePattern).  Ron's suggestion that hasfield() should be a type pattern should now be clearer. You really want to say something like:

within(hasfield(foo))    == within any type that has a field named foo.

This is using hasfield as a type pattern. Such a usage would also allow this type pattern to be used anywhere else a pointcut takes a type pattern too. For example:

call(* (hasfield(foo)).*(..))   == any call where the target type of the call has a field named foo.

This is the orthogonality point because by making it a type pattern it can be composed in many more interesting ways in pointcut expressions. By making it a pointcut you constrain the choices.

All this said, for your use case, it seems that you don't want a pointcut at all. Instead you are trying to say (in AspectJ syntax):

declare parents : <something here> implements MyMixin;

In the AspectJ language, <something here> is specified to be a type pattern. So if hasfield() were a type pattern, you would just write:

declare parents : hasfield(foo) implements MyMixin;

I suspect the DI case also wants the type pattern variation, e.g. :

aspect DI {

   Foo foo;

   after(Object obj) returning : execution( (hasmethod(setFoo(Foo)).new(..)) && this(obj) {
       // invoke the setFoo(Foo) method on obj via reflection...
   }

}

How do you envision this working if hasmethod() were a pointcut?

Regards, Adrian.

-- Adrian
Adrian_Colyer@xxxxxxxxxx



Michael Nascimento <misterm@xxxxxxxxx>
Sent by: aspectj-users-admin@xxxxxxxxxxx

24/02/2005 23:45

Please respond to
aspectj-users@xxxxxxxxxxx

To
aspectj-users@xxxxxxxxxxx
cc
Subject
[aspectj-users] Re: hasmethod/hasfield pointcuts (was: AspectJ + Groovy?)





On Thu, 24 Feb 2005 13:11:32 -0800, Ron Bodkin <rbodkin@xxxxxxxxxxxxxx> wrote:
> (*) I don't think hasfield/hasmethod should be defined as pointcuts since it
> breaks orthogonality. Instead, these ought to be type patterns, just like
> Foo+ or annotation matching for type patterns.

Hi Ron,

Not sure I got what you meant from your comment, but I've implemented
the hasfield/hasmethod poincuts in AW and I have a very clear use case
for them.

I wanted to introduce a mixin in any class containing a method with a
certain annotation. This is the case for genesis (
https://genesis.dev.java.net , still using AW 1.1, going to migrate to
AW 2.0 next week ) CommandResolver interface and its default
implementation. The idea is any class that had a method annotated with
@Remotable/@Transactional had this interface introduced in order to
support two core genesis features, transparent remoting and
transactional support.

Why not requiring the classes to implement a marker interface or be
annotated at the class level? Well, it feels strange. If a class has
one or more methods containing one of these annotations, there is no
point in requiring it to follow yet another pattern just for the sake
of.

Besides that, this kind of pointcut is quite useful for situations
when you want to use AOP in existing classes without changing them.
Not always these classes inherit from the same class, implement a
common interface or are in the same package, but they may share some
properties, for example. I can see these pointcuts being useful for
dependency injection as well, requiring only POJOs to work.

Regards,
Michael Nascimento Santos
https://genesis.dev.java.net/
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
http://dev.eclipse.org/mailman/listinfo/aspectj-users


Back to the top