Difference between revisions of "Aspect Oriented Programming in opentaps"

From Opentaps Wiki
Jump to navigationJump to search
(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...)
 
 
(3 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
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 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 Feature|opentaps search]].  You can also use AOP yourself to alter the behavior  of opentaps code to meet your needs.   
 
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 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 Feature|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, [http://aspectwerkz.codehaus.org/ AspectWerkz]  is used to support aspect oriented programming.  (opentaps 1.0.0 through 1.0.4 used [http://www.eclipse.org/aspectj/ AspectJ],  and you can find more information about it in [Understanding AspectJ]
+
With opentaps 1.0.5 and later, including opentaps 1.4, [http://aspectwerkz.codehaus.org/ AspectWerkz]  is used to support aspect oriented programming.  (opentaps 1.0.0 through 1.0.4 used [http://www.eclipse.org/aspectj/ 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 <tt>IndexForDelegatorAspects</tt> class,  we define the following point cut for the ofbiz delegator:
 
AspectWerkz allows you to define your AOP advice in Java using annotations.  For example, in <tt>IndexForDelegatorAspects</tt> class,  we define the following point cut for the ofbiz delegator:
Line 52: Line 52:
 
  <jar jarfile="${ofbiz.dir}/framework/entity/build/lib/ofbiz-entity.jar" update="true"  
 
  <jar jarfile="${ofbiz.dir}/framework/entity/build/lib/ofbiz-entity.jar" update="true"  
 
       basedir="${build.dir}/classes/" includes="META-INF/aop.xml" />
 
       basedir="${build.dir}/classes/" includes="META-INF/aop.xml" />
 +
 +
If you use a Java decompiler to reconstruct the source code from your jar file, you might see something like this:
 +
 +
protected void evalEcaRules(String paramString1, String paramString2, GenericEntity paramGenericEntity,
 +
                            Map paramMap, boolean paramBoolean1, boolean paramBoolean2)
 +
    throws GenericEntityException
 +
  {
 +
    GenericDelegator_1_20389545_1395125462___AW_JoinPoint.invoke(this, paramString1, paramString2, paramGenericEntity,
 +
                                                                paramMap, paramBoolean1, paramBoolean2, this);
 +
  }
 +
 +
Note that when you need to define aspect advice for  methods, <tt>Public</tt>, <tt>Private</tt>, and <tt>Protected</tt>  need to be capitalized and. They cannot be written as public, private, or protected.  For example, for <tt>TestRunContainerProfiling.java</tt>,  the correct definition is:
 +
    /**
 +
    * Pointcut testRunContainerStart is pointcut to TestRunContainer.start.
 +
    * @Expression execution(Public boolean org.ofbiz.testtools.TestRunContainer.start(..))
 +
    */
 +
    Pointcut testRunContainerStart;
  
 
== Other References ==
 
== Other References ==
 
* [http://onjava.com/pub/a/onjava/2004/01/14/aop.html  Introduction to Aspect Oriented Programming]
 
* [http://onjava.com/pub/a/onjava/2004/01/14/aop.html  Introduction to Aspect Oriented Programming]
 
* [http://www.ibm.com/developerworks/rational/library/2782.html  A Look at Aspect Oriented Programming]
 
* [http://www.ibm.com/developerworks/rational/library/2782.html  A Look at Aspect Oriented Programming]

Latest revision as of 01:10, 21 July 2009

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" />

If you use a Java decompiler to reconstruct the source code from your jar file, you might see something like this:

protected void evalEcaRules(String paramString1, String paramString2, GenericEntity paramGenericEntity, 
                            Map paramMap, boolean paramBoolean1, boolean paramBoolean2)
   throws GenericEntityException
 {
   GenericDelegator_1_20389545_1395125462___AW_JoinPoint.invoke(this, paramString1, paramString2, paramGenericEntity, 
                                                                paramMap, paramBoolean1, paramBoolean2, this);
 }

Note that when you need to define aspect advice for methods, Public, Private, and Protected need to be capitalized and. They cannot be written as public, private, or protected. For example, for TestRunContainerProfiling.java, the correct definition is:

   /**
    * Pointcut testRunContainerStart is pointcut to TestRunContainer.start.
    * @Expression execution(Public boolean org.ofbiz.testtools.TestRunContainer.start(..))
    */
   Pointcut testRunContainerStart;

Other References