Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
RE: [aspectj-users] How to provide external pcd definition?

Hi Adrian,

Thanks for your thinking on the subject ;-). A pity we didn't meet at
TSSS, we could have discussed it further. At TSSS, I've spoken to dIon
about it and he mentioned to me that the CVS HEAD of AspectJ may have
support for dynamic aspects. I haven't checked yet. Would you know
anything about it?

I like very much your JoinPointMatcher class which would solve my
problem. Would it be possible to get a current AspectJ version with it
so that I can play around with it?

Thanks a lot
-Vincent

> -----Original Message-----
> From: aspectj-users-admin@xxxxxxxxxxx [mailto:aspectj-users-
> admin@xxxxxxxxxxx] On Behalf Of Adrian Colyer
> Sent: 11 May 2004 22:50
> To: aspectj-users@xxxxxxxxxxx
> Cc: rod.johnson@xxxxxxxxxxxxxxx
> Subject: Re: [aspectj-users] How to provide external pcd definition?
> 
> This question has been vexing me for the last few days. Any
configuration
> of a pointcut would have to go through the AspectJ compiler, so what
> you're currently doing is about as good as it can get right now.
> 
> You could imagine an XML syntax that gets turned into an aspect by
some
> build step, e.g.
> 
> <aspect name="DatabaseTestAspect" extends="
AbstractDatabaseTestAspect">
>   <pointcut
name="applicationCode">within(patterntesting..*)</pointcut>
>   <pointcut name="allowedCode">within(patterntesting.db..*)</pointcut>
> </aspect>
> 
> (just for illustration, not a real syntax)
> 
> but is that really so much easier to understand than:
> 
> aspect DatabaseTestAspect extends AbstractDatabaseTestAspect {
>   pointcut applicationCode() : within(patterntesting..*);
>   pointcut allowedCode() : within(patterntesting.db..*);
> }
> 
> ? Especially when you've still got to pass the result through the
compiler
> anyway.
> 
> I've been talking a lot with the Spring folks at the TSS Symposium,
and I
> can see a case for wanting true runtime configuration of pointcut
values
> for some infrastructure (auxiliary) aspects - the kind of things that
the
> J2EE community is very used to specifying in config files rather than
in
> code. One of the exciting things that came out of those discussions is
a
> way to use Spring's IoC capabilities to configure aspects (more on
that
> soon), but this capability doesn't extend to configuring pointcuts
(just
> things like the DataSource for a persistence aspect to use etc.). I
wanted
> to enable pointcut configuration in the same way, so I've built a
private
> prototype today that shows one way it could be done. Here's how it
looks,
> and I'd be interested in feedback as to whether others would find this
> useful:
> 
> Firstly, a new utility class: JoinPointMatcher.  JoinPointMatcher is
> constructed with a string (in the expected usage this is obtained from
a
> config file, but it could be generated in the program itself at
runtime
> for extreme use cases) which contains an AspectJ pointcut expression,
> e.g.:
> 
> JoinPointMatcher jpm = new
JoinPointMatcher("within(patterntesting..*)");
> 
> At any join point, you can ask JoinPointMatcher whether or not it
matches:
>  if( jpm.matches(thisJoinPoint)) ...
> 
> Here's an aspect that allows runtime configuration using this
mechanism:
> 
> aspect DynamicPointcutConstructionExample {
> 
>   private static JoinPointMatcher jpm;
> 
>   public void setPointcutExpression(String pointcutExpr) {
>     jpm = new JoinPointMatcher(pointcutExpr);
>   }
> 
>   // this pointcut is used to narrow down as far as possible at
compile
> time the set of places
>   // at which a dynamic pointcut could match (for efficiency)
>   pointcut scope() : within(org.xyz.foo);
> 
>  before() : scope() && if(jpm.matches(thisJoinPoint)) {
>     System.out.println("I matched!!");
>  }
> 
> }
> 
> The consequence you pay for using dynamic pointcuts (I'm using the
word
> dynamic in analogy to the use of "dynamic" in DII, it may not be the
best
> term) is that the pointcut matching is (very much) less efficient
since
> the jpm.match code is driven for every join point in the scope
(whereas
> the same pointcut specified at compile time would cause the advice to
> execute exactly where it needs to with no additional overhead or
> redundancy). If a dynamic pointcut proved to be too slow, you could
always
> switch back to a traditional statically specified pc.
> 
> If you're using Spring with the above example, you can configure the
> aspect with e.g.
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
> "http://www.springframework.org/dtd/spring-beans.dtd";>
> <beans>
>     <!-- what follows is an example syntax for specifying a
factoryMethod,
> 
>          I hope we end up with something very close to this in Spring
-->
>     <bean id="dynamicPointcutConstructionExample"
>           class="DynamicPointcutConstructionExample"
>           factoryMethod="aspectOf">
>         <property name="pointcutExpression">
>            execution(* *(..)) && this(Foo)
>         </property>
>     </bean>
> </beans>
> 
> Spring will set the value of the pointcutExpression attribute when the
> aspect is constructed. Many thanks are due to Rod Johnson for the
> inspiration to look into this.
> 
> [For the AspectJ developers, here's how the prototype currently works:
> 
> JoinPointMatcher uses the PatternParser class to build a Pointcut
> (simple).
> 
> I then added a new match method in the Pointcut hierarchy that takes a
> JoinPoint instead of a shadow, and implemented match(JoinPoint) down
the
> hierarchy to do the right thing. I had to add match(Class) methods to
> TypePatterns too. All the changes were self-contained, and the logic
> mirrors the matching logic for shadows.
> 
> Restrictions in the implementation are that you can't use cflow or
> cflowbelow in a dynamic pointcut (matching is done solely on the
current
> join point), you can't use if() (don't want to go off into code), and
you
> can't provide context information (bind "this(foo)" to a parameter
"foo")
> or refer to other pointcuts.
> 
> Essentially I've written a convenience class for writing a powerful
form
> of if() pcds.
> ]
> 
> Love it? Hate it? Let me know...
> 
> Cheers, Adrian.
> 
> I know, I know, I digressed for a day - Back to 1.2rc2 and AJDT
> tomorrow....
> 
> -- Adrian
> Adrian_Colyer@xxxxxxxxxx
> 
> aspectj-users-admin@xxxxxxxxxxx wrote on 07/05/2004 09:17:35:
> 
> > Hi,
> >
> > On the Pattern Testing project (http://patterntesting.sf.net), we
have
> > aspects that enforce some design rules. For example:
> >
> > public abstract aspect AbstractDatabaseTestAspect
> > {
> >     /**
> >      * Specify what is application code that should be subject to
the
> >      * pattern test.
> >      *
> >      * Ex: <code>pointcut applicationCode():
> > within(patterntesting.*)</code>
> >      */
> >     public abstract pointcut applicationCode();
> >
> >     /**
> >      * Specify which classes are allowed to call JDBC.
> >      */
> >     public abstract pointcut allowedCode();
> >
> >     /**
> >      * Specify which JDBC calls are forbidden.
> >      */
> >     pointcut forbiddenCalls() :
> >         call(public * java.sql..*(..)) ||
> >         call(public * javax.sql..*(..));
> >
> >     /**
> >      * Raise error if violations found.
> >      */
> >     declare error: (applicationCode() && forbiddenCalls()) &&
> > !allowedCode() :
> >         "It is not allowed to use the JDBC API from here";
> > }
> >
> > Now, the question is: How can we make the applicationCode and
> > allowedCode pointcuts configurable by the end users?
> >
> > Of course one solution is to have create classes that extend the
> > abstract aspect. However that sounds complex when compared to simple
> > configuration data (the end users would need to create a project
where
> > to put the code, etc).
> >
> > Any idea?
> >
> > Note: The solution we're using so far (but which I don't like
because
> > it's tied to the build system) is to use Ant filters:
> >
> > public aspect DatabaseTestAspect extends AbstractDatabaseTestAspect
> > {
> >     public pointcut applicationCode() :
> >         @maven.patterntesting.suite.java.database.applicationCode@;
> >     public pointcut allowedCode() :
> >         @maven.patterntesting.suite.java.database.allowedCode@;
> > }
> >
> > Thanks
> > -Vincent
> >
> > _______________________________________________
> > aspectj-users mailing list
> > aspectj-users@xxxxxxxxxxx
> > http://dev.eclipse.org/mailman/listinfo/aspectj-users
> 
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> http://dev.eclipse.org/mailman/listinfo/aspectj-users



Back to the top