1.Introduction XML | 2.Model XML | 3.View XML | 4.Tab XML | 5.Mapping XML | 6.Aspects XML

Chapter 6: Aspects XML (classic)

Introduction to AOP

AOP (Aspect Oriented Programming) introduces a new way for reusing code. In fact aspects complement some shortcomings in traditional Object Oriented Programming.
Which problems does AOP resolve? Sometime you have a functionality that is common to a group of classes but using inheritance is not practical (in Java we only have single inheritance) or not ethical (because there isn't a is-a relationship). Moreover the system may be already written, or maybe you need to include or not this functionality on demand. AOP is an easy way to resolve these problems.
What is an aspect? An aspect is a bunch of code that can be scattered as you wish in your application.
The Java language has a complete AOP support by means of the AspectJ project.
OpenXava adds some support for the aspects concept since version 1.2.1.The support for aspects in XML component is small, but if you use POJOs + annotations (since version 3.0) you can use AspectJ and enjoy the full strength of aspects.

Aspects definition

The aspects.xml file inside the xava folder of your project is used to define aspects.
The file syntax is:
<aspects>
    <aspect ... /> ...  <!-- 1 -->
    <apply ... /> ...   <!-- 2 -->
</aspects>
  1. aspect (several, optional): To define aspects.
  2. apply (several, optional): To apply the defined aspects to the selected models.
With aspect (1) you can define an aspect (that is a group of features) with a name, and using apply (2) you achieve that a set of models (entities or aggregates) will have these features automatically.
Let's see the aspect syntax:
<aspect
    name="name"                       <!-- 1 -->
>
    <postcreate-calculator .../> ...  <!-- 2 -->
    <postload-calculator .../> ...    <!-- 3 -->
    <postmodify-calculator .../> ...  <!-- 4 -->
    <preremove-calculator .../> ...   <!-- 5 -->
</aspect>
  1. name (required): Name for this aspect. It must be unique.
  2. postcreate-calculator (several, optional): All model with this aspect will have this postcreate-calculator implicitly.
  3. postload-calculator (several, optional): All model with this aspect will have this postload-calculator implicitly.
  4. postmodify-calculator (several, optional): All model with this aspect will have this postmodify-calculator implicitly.
  5. preremove-calculator (several, optional): All model with this aspect will have this preremove-calculator implicitly.
Furthermore, you need to assign the defined aspects to your models. The syntax to do that is:
<apply
    aspect="aspect"             <!-- 1 -->
    for-models="models"         <!-- 2 -->
    except-for-models="models"  <!-- 3 -->
/>
  1. aspect (required): The name of the aspect that you want to apply.
  2. for-models (optional): A comma separated list of models to which the aspect is applied to. It's mutually exclusive with except-for-models attribute.
  3. except-for-models (optional): A comma separated list of models to be excluded when apply this aspect. In this case the aspect applies to all models excepts the indicated ones. It's mutually exclusive with for-models attribute.
If you use neither for-models nor except-for-models, then the aspect will apply to all models in the application. Models are the names of components (for its entities) or aggregates.
A simple example may be:
<aspect name="MyAspect">
    <postcreate-calculator
        class="com.mycompany.myapplication.calculators.MyCalculator"/>
</aspect>
<apply aspect="MyAspect"/>
Whenever a new object is created (saved in database for the first time), then the logic of MyCalculator is executed. And this for all models.
At the moment only these few calculators are supported. We expect to extend the power of aspects for OpenXava in the future. Anyway the existing calculators offer interesting possibilities. Let's see an example in the next section.

AccessTracking: A practical application of aspects

The current OpenXava distribution includes the AccessTracking project. This project defines an aspect that allows you to track all access to the data in your application. Actually, this project allows your application to comply the Spanish Data Protection Law (Ley de Protección de Datos) including high level security data. Although it's generic enough to be useful in a broad variety of scenarios.

The aspect definition

You can find the aspect definition in AccessTracking/xava/aspects.xml:
<?xml version = "1.0" encoding = "ISO-8859-1"?>
 
<!DOCTYPE aspects SYSTEM "dtds/aspects.dtd">
 
<!-- AccessTracking -->
 
<aspects>
 
    <aspect name="AccessTracking">
        <postcreate-calculator
            class="org.openxava.tracking.AccessTrackingCalculator">
            <set property="accessType" value="Create"/>
        </postcreate-calculator>
        <postload-calculator
            class="org.openxava.tracking.AccessTrackingCalculator">
            <set property="accessType" value="Read"/>
        </postload-calculator>
        <postmodify-calculator
            class="org.openxava.tracking.AccessTrackingCalculator">
            <set property="accessType" value="Update"/>
        </postmodify-calculator>
        <preremove-calculator
            class="org.openxava.tracking.AccessTrackingCalculator">
            <set property="accessType" value="Delete"/>
        </preremove-calculator>
    </aspect>
 
</aspects>
When you apply this aspect to your components, then the code of AccessTrackingCalculator is executed each time a object is created, loaded, modified or removed. AccessTrackingCalculator writes a record into a database table with information about the access.
In order to apply this aspect you need to write your aspects.xml like this:
<?xml version = "1.0" encoding = "ISO-8859-1"?>
 
<!DOCTYPE aspects SYSTEM "dtds/aspects.dtd">
 
<aspects>
 
    <apply aspect="AccessTracking" for-models="Warehouse, Invoice"/>
 
</aspects>
In this way this aspect is applied to Warehouse and Invoice. All access to these entities will be record in a database table.

Setup AccessTracking

If you want to use the AccessTracking aspect in your project you have to follow the next setup steps:
  • Add AccessTracking as referenced project: Inside Eclipse click right button on your project and go to Properties > Java Build Path > Projects.
  • Create the table in your database to store the tracking of accesses. You can find the CREATE TABLEs in AccessTracking/data/access-tracking-db.script file.
  • You have to include the hibernate.dialect property in your configuration files. You can see examples of this in OpenXavaTest/jboss-hypersonic.properties and other OpenXavaTest/xxx.properties files.
  • Inside the AccessTracking project you need to select a configuration (editing build.xml) and regenerate hibernate code (using the ant target generateHibernate) for AccessTracking project.
  • Edit the file of your project build/ejb/META-INF/MANIFEST.MF to add the next jars into the classpath: ./lib/tracking.jar ./lib/ehcache.jar ./lib/antlr.jar ./lib/asm.jar ./lib/cglib.jar ./lib/hibernate3.jar ./lib/dom4j.jar ./lib/slf4j-api.jar ./lib/slf4j-jdk14.jar ./lib/javassist.jar.This step isn't needed if you use only POJOs, not EJB CMP2, new in v2.0. The slf4j-api.jar, slf4j-jdk14.jar and javassist.jar jars are only needed since v3.1.
Also you need to modify the target createEJBJars (only if you are using EJB2 CMP) and deployWar of your build.xml in this way:
<target name="createEJBJars">    <!-- 'createEJBJars' only if you use EJB2 CMP -->
    ...
    <ant antfile="../AccessTracking/build.xml" target="createEJBTracker"/>
</target>
<target name="deployWar">
    <ant antfile="../AccessTracking/build.xml" target="createTracker"/>
    ...
</target>
After these steps, you have to apply the aspect in your application. Create a file in your project xava/aspects.xml:
<?xml version = "1.0" encoding = "ISO-8859-1"?>
 
<!DOCTYPE aspects SYSTEM "dtds/aspects.dtd">
 
<aspects>
 
    <apply aspect="AccessTracking"/>
 
</aspects>
Now you only have to deploy the war for your project. (new in v2.0)
In the case that you are using EJB2 CMP you have to regenerate the code, deploying EJB and deploying war for your project.
All access are recorded in a table with the name TRACKING.ACCESS. If you want you can deploy the module web or the portlet of AccessTracking project in order to have a web application to browse the accesses.
For more details you can have a look at the OpenXavaTest project.