<?xml version="1.0"?>
<!-- 
/*
 * Copyright 2001-2004 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 -->


<!--
  =============================================================================
    AspectJ plugin for Maven. It offers 2 main features:
    - Ability to automatically weave aspects defined in 
      ${pom.build.aspectSourceDirectory}. This feature has no goal and is
      triggered automatically when the jar:jar goal is invoked if the 
      ${maven.aspectj.autoweave} property is set to true.
    - Generate a reusable aspect jar, by creating a jar of the aspects found 
      in ${pom.build.aspectSourceDirectory}. This is invoked through the
      aspectj:jar goal.
      
    TODO:
    - Need to add back the ajdoc goal
    - Try to find a solution to weave at the class level instead of at the jar
      level as some other plugins (like the war one) do not go through the
      jar:jar goal (they stop at the java:compile step).    
    - Add goals/properties xdoc documentation
    - Add other iajc attributes as plugin properties
    - Add a aspectj:jar-deploy goal
  =============================================================================
-->

<project
  xmlns:j="jelly:core"
  xmlns:ant="jelly:ant"
  xmlns:util="jelly:util">

  <!--
     ========================================================================
       Default goal.
     ========================================================================
  -->
  <goal name="aspectj" prereqs="aspectj:weave"
      description="Weave aspects in project jar"/>

  <!--
     ========================================================================
       Automatic weaving on jar:jar if the ${maven.aspectj.autoweave} 
       property is set to true.
     ========================================================================
  -->
  <postGoal name="jar:jar">
    <attainGoal name="aspectj:init"/>
    <j:if test="${autoWeave == 'true'}">
      <attainGoal name="aspectj:weave-internal"/>
    </j:if>
  </postGoal>

  <!--
     ========================================================================
       Init AspectJ Ant task and global initializations.
     ========================================================================
  -->
  <goal name="aspectj:init">

    <ant:taskdef resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties">
      <ant:classpath>
        <ant:pathelement path="${plugin.getDependencyPath('aspectj:aspectjtools')}"/>
      </ant:classpath>
    </ant:taskdef>

    <ant:available property="aspectSourcesPresent"
        file="${pom.build.aspectSourceDirectory}"/>

    <!-- Decide whether there is anything to weave -->
    <j:forEach var="artifact" items="${pom.artifacts}">
      <j:set var="dep" value="${artifact.dependency}"/>
      <j:if test="${dep.type == 'aspect'}">
        <j:set var="aspectLibrariesPresent" value="true"/>
      </j:if>
    </j:forEach>
    <ant:condition property="shouldWeave">
      <ant:or>
        <ant:isset property="aspectSourcesPresent"/>
        <ant:isset property="aspectLibrariesPresent"/>
      </ant:or>
    </ant:condition>
    
    <!-- Decide whether auto weave is on -->    
    <ant:condition property="autoWeave">
      <ant:and>
        <ant:isset property="shouldWeave"/>
        <ant:istrue value="${maven.aspectj.autoweave}"/>
      </ant:and>
    </ant:condition>

  </goal>

  <!--
     ========================================================================
       Weave aspects in project jar
     ========================================================================
  -->
  <goal name="aspectj:weave" 
      prereqs="aspectj:init,jar:jar,aspectj:weave-internal"
      description="Weave aspects in project jar"/>

  <!-- Private goal used to that when the jar:jar postgoal is called we don't
       have to call aspectj:init and jar:jar twice -->
  <goal name="aspectj:weave-internal">

    <j:if test="${shouldWeave == 'true'}">

      <!-- Only weave if input jar has been modified. This is needed for
           the case when the user does a second run without changing 
           sources -->
      <ant:uptodate property="weaveNotRequired" 
          targetfile="${maven.aspectj.injar.nonweaved}">
        <ant:srcfiles dir="${pom.build.sourceDirectory}"/>
        <ant:srcfiles dir="${pom.build.aspectSourceDirectory}"/>
      </ant:uptodate>

      <j:if test="${weaveNotRequired == null}">
    
        <!-- Rename input jar file to a temporary name so that we can use the 
             same name for the outjar -->
        <move file="${maven.aspectj.outjar}" 
          tofile="${maven.aspectj.injar.nonweaved}"/>

        <!-- fork to avoid BCEL library version conflict with maven -->
        <ant:iajc fork="true" debug="${maven.aspectj.debug}"
            outjar="${maven.aspectj.outjar}"
            injars="${maven.aspectj.injar.nonweaved}"
            copyInjars="true"
            sourceRootCopyFilter="${maven.aspectj.sourceRootCopyFilters}"
            emacssym="${maven.aspectj.emacssym}">         

          <ant:forkclasspath>
            <ant:pathelement path="${plugin.getDependencyPath('aspectj:aspectjtools')}"/>
          </ant:forkclasspath>

          <ant:sourceroots>
            <ant:pathelement location="${pom.build.aspectSourceDirectory}"/>
          </ant:sourceroots>

          <ant:classpath>
            <ant:path refid="maven.dependency.classpath"/>
            <ant:pathelement path="${plugin.getDependencyPath('aspectj:aspectjrt')}"/>
          </ant:classpath>

          <!-- Look for aspect libraries to use for weaving -->
          <ant:aspectpath>
            <j:forEach var="artifact" items="${pom.artifacts}">
              <j:set var="dep" value="${artifact.dependency}"/>
              <j:if test="${dep.type == 'aspect'}">
                <ant:pathelement location="${artifact.path}"/>
              </j:if>
            </j:forEach>
          </ant:aspectpath>

        </ant:iajc>
      </j:if>
    </j:if>
        
  </goal>

  <!--
     ========================================================================
       Generate a jar of reusable aspects found in 
       ${pom.build.aspectSourceDirectory}. This jar can then be uploaded to
       the remote repository to serve as reusable aspects for other projects.
     ========================================================================
  -->
  <goal name="aspectj:jar" prereqs="aspectj:init"
      description="Generate reusable aspect jar">

    <j:if test="${shouldWeave == 'true'}">

      <!-- Only regenerate jar if aspect files have been modified. -->
      <ant:uptodate property="jarNotRequired" 
          targetfile="${maven.aspectj.library}">
        <ant:srcfiles dir="${pom.build.aspectSourceDirectory}"/>
      </ant:uptodate>

      <j:if test="${jarNotRequired == null}">
        <!-- fork to avoid BCEL library version conflict with maven -->
        <ant:iajc fork="true" debug="${maven.aspectj.debug}"
            outjar="${maven.aspectj.library}"
            sourceRootCopyFilter="${maven.aspectj.sourceRootCopyFilters}"
            emacssym="${maven.aspectj.emacssym}">
          <ant:forkclasspath>
            <ant:pathelement path="${plugin.getDependencyPath('aspectj:aspectjtools')}"/>
          </ant:forkclasspath>
          <ant:sourceroots>
            <ant:pathelement location="${pom.build.aspectSourceDirectory}"/>
          </ant:sourceroots>
          <ant:classpath>
            <ant:path refid="maven.dependency.classpath"/>
            <ant:pathelement path="${plugin.getDependencyPath('aspectj:aspectjrt')}"/>
          </ant:classpath>
        </ant:iajc>
      </j:if>
    </j:if>
  </goal>
  
  <!--
     ========================================================================
       Install the reusable aspects in the local repository.
     ========================================================================
  -->
  <goal name="aspectj:jar-install" prereqs="aspectj:jar"
      description="Install reusable aspect jar in local repository">

    <j:if test="${shouldWeave == 'true'}">
      <ant:property name="aspectdir__" value="${maven.repo.local}/${pom.artifactDirectory}/aspects"/>
      <ant:mkdir dir="${aspectdir__}"/>    
      <ant:copy file="${maven.aspectj.library}" overwrite="true"
        todir="${aspectdir__}"/>
    </j:if>
    
  </goal>
    
</project>
