Although I still would like to know the answer to my earlier post, I
have discovered how to get AspectJ to do this for me...
After some consideration, I've come to the conclusion that the
interface I'm interested in implementing in the domain objects is
really best solved by static croscutting. It took me a lot longer than
it probably should have to get AspectJ to do what I wanted to - and
the solution that I'm spelling out here is very easy to implement and
use with the existing Sculptor workflow.
I've never played with AspectJ before - I've always just used Spring's
AOP stuff, but now that I've taken the initial plunge, I think I'll
use it for some other things as well.
For background on what I'm doing - there is a project called
dpHibernate that supports lazy loading and such for Flex applications.
It requires that all of the domain objects being passed back and forth
implement a certain interface (IHibernateProxy) - either by
implementing the methods directly or by inheriting from their concrete
base class they provide. Earlier, I was looking at how to get the code
generator to generate the code with this stuff already typed into it -
but I decided it is a cleaner solution to use compile-time code-
weaving to do this dirty work.
Here's what my aspect file (located in src/main/aspect/
HibernateProxyIntroduction ) looks like:
-------------------------
import net.digitalprimates.persistence.hibernate.proxy.IHibernateProxy;
public aspect HibernateProxyIntroduction {
declare parents: ..domain.*Base* implements IHibernateProxy;
public Object IHibernateProxy.proxyKey;
public Boolean IHibernateProxy.proxyInitialized = true;
public Object IHibernateProxy.getProxyKey()
{
return proxyKey;
}
public void IHibernateProxy.setProxyKey(Object proxyKey)
{
this.proxyKey = proxyKey;
}
public Boolean IHibernateProxy.getProxyInitialized()
{
return proxyInitialized;
}
public void IHibernateProxy.setProxyInitialized(Boolean
proxyInitialized)
{
this.proxyInitialized = proxyInitialized;
}
}
----------------------
You'll notice that unlike most aspects, this one doesn't define any
pointcuts. The part of this aspect that is describing how it should be
weaved in is the declare parents: block - where I state that every
file with "Base" in it inside of my domain package should implement
the IHibernateProxy interface.
In the body, you see how I have IHibernateProxy.getProxyKey() etc as
my method signatures - this tells AspectJ that the interface has a
default implementation - so it will add the default implementation to
all of the classes as it does its weaving.
Here's how I configured maven to do the actual weaving:
In my <build><plugins> I have this plugin for the aspectJ weaving:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.1-SNAPSHOT</version>
<configuration>
<source>1.5</source>
<complianceLevel>1.5</complianceLevel>
<showWeaveInfo>true</showWeaveInfo>
<verbose>true</verbose>
<includes>
<include>**/*.aj</include>
<include>**/*.java</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.6.1</version>
</dependency>
</dependencies>
</plugin>
The reason I am explicitly defining the dependencies on the AspectJ
plugin is because by default it wants to use an older version of
AspectJ - and I was having trouble getting it to work so I decided to
try the newer version (the problem had to do with my source tree
structure - but since I already got it working with 1.6.1 I figured
I'd keep it that way)
The verbose option may be overkill for the long run, but I like being
able to see that the weaving is actually taking place.
I hope this helps anyone who faces a similar problem in the future.
Perhaps a brief section on using AspectJ in such a way as this could
be added to the developers guide on the wiki as one possible solution
to extending domain object interfaces without messing deeply with the
template files.
Ryan
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Fornax-developer mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/fornax-developer