Aspect Oriented Programming in opentaps

From Opentaps Wiki
Revision as of 00:46, 21 July 2009 by Sichen (talk | contribs) (New page: opentaps uses [http://en.wikipedia.org/wiki/Aspect-oriented_programming aspect oriented programming] (AOP) to interact with pre-existing ofbiz code and enhance its behavior. For examp...)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

opentaps uses aspect oriented programming (AOP) to interact with pre-existing ofbiz code and enhance its behavior. For example, we have inserted an aspect "advice" to the ofbiz entity engine's delegator so that the data is stored will be indexed for opentaps search. You can also use AOP yourself to alter the behavior of opentaps code to meet your needs.

With opentaps 1.0.5 and later, including opentaps 1.4, AspectWerkz is used to support aspect oriented programming. (opentaps 1.0.0 through 1.0.4 used AspectJ, and you can find more information about it in [Understanding AspectJ]

AspectWerkz allows you to define your AOP advice in Java using annotations. For example, in IndexForDelegatorAspects class, we define the following point cut for the ofbiz delegator:

/**
 * @Expression execution(* org.ofbiz.entity.GenericDelegator.evalEcaRules(..)) && 
               args(event, currentOperation, value, eventMap, noEventMapFound, isError)
 */
void pointcut(String event, String currentOperation, GenericEntity value, Map eventMap, boolean noEventMapFound, boolean isError) {}

This basically defines a point cut for the

   protected void evalEcaRules(String event, String currentOperation, GenericEntity value, 
                               Map eventMap, boolean noEventMapFound, boolean isError) throws GenericEntityException {

method of the delegator. Then, we define this method to be executed after the pointcut:

  /**
   * @After pointcut(event, currentOperation, value, eventMap, noEventMapFound, isError)
   */
   public void createIndexForEca(String event, String currentOperation, GenericEntity value, 
                                 Map eventMap, boolean noEventMapFound, boolean isError) {

which means that createIndexForEca will be run after evalEcaRules is run.

These aspects are then configured in the file hot-deploy/opentaps-common/config/aop-ecas.xml:

 <aspectwerkz>
   <system id="aspectwerkz">
       <aspect class="org.opentaps.aspect.secas.CommonServiceAspects"/>
       <aspect class="org.opentaps.aspect.secas.IndexForDelegatorAspects"/>

During build time, the main build.xml invokes build-aspects.xml:

   <subant inheritall="false" failonerror="true">
      <filelist dir="." files="hot-deploy/opentaps-common/build-aspects.xml"/>
   </subant>

This in turn modifies the target jar file. For example:

 <java classname="org.codehaus.aspectwerkz.compiler.AspectWerkzC" fork="true">
    <jvmarg value="-Daspectwerkz.definition.file=${aopConfig}"/>
    <jvmarg value="-Daspectwerkz.transform.filter=no"/>
    <arg value="-verify"/>
    <arg value="-verbose"/>
    <classpath refid="local.class.path" />
    <classpath>
       <pathelement path="${build.dir}/classes/common"/>
    </classpath>
    <arg value="${ofbiz.dir}/framework/entity/build/lib/ofbiz-entity.jar"/>
 </java>

weaves the advice codes to ofbiz-entity.jar and add aop.xml into ofbiz-entity.jar in this line.

<jar jarfile="${ofbiz.dir}/framework/entity/build/lib/ofbiz-entity.jar" update="true" 
     basedir="${build.dir}/classes/" includes="META-INF/aop.xml" />

Other References