[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
RE: [aspectj-users] How to provide external pcd definition?
|
Wow. This is gold.
I had this exact discussion with someone at the symposium. They needed a way
to dynamically configure pointcuts in this manner. They even wanted to be
able to build up the pointcut expression.
So, instead of:
<property name="pointcutExpression">
execution(* *(..)) && this(Foo)
</property>
They wanted to run some logic to generate the expression.
Sure this isn't efficient.... But it would be fantastic for the cases which
need this.
Dion
> -----Original Message-----
> From: aspectj-users-admin@xxxxxxxxxxx
> [mailto:aspectj-users-admin@xxxxxxxxxxx] On Behalf Of Adrian Colyer
> Sent: Tuesday, May 11, 2004 4:50 PM
> 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
>
>