<?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.

  TODO:
  - Need to add back the ajdoc goal
  - Add other iajc attributes as plugin properties
  =============================================================================
-->

<project
  xmlns:j="jelly:core"
  xmlns:ant="jelly:ant"
  xmlns:define="jelly:define"
  xmlns:test="test"
  xmlns:aspectj="aspectj">

  <!--
  Taglib to compile aspects
  
  Parameters:
    - sourcePathRefid
    - classpathRefid
    - destDir
  -->
  <define:taglib uri="aspectj">

    <define:tag name="compile">

      <ant:iajc
          fork="${maven.aspectj.fork}"
          incremental="${maven.aspectj.incremental}"
          destDir="${destDir}"
          sourceRootCopyFilter="${maven.aspectj.sourceRootCopyFilter}"
          debug="${maven.aspectj.debug}"
          emacssym="${maven.aspectj.emacssym}"
          verbose="${maven.aspectj.verbose}">

        <j:if test="${context.getVariable('maven.aspectj.fork') == true}">
          <j:if test="${context.getVariable('maven.aspectj.maxmem') != null}">
            <ant:setProperty name="maxmem" value="${maven.aspectj.maxmem}" />
          </j:if>
        </j:if>
        
    
        <ant:sourceroots>
          <ant:path refid="${sourcePathRefid}"/>
          <j:if test="${aspectSourcesPresent == 'true' and aspectSourceDir != ''}">
            <ant:pathelement location="${pom.build.aspectSourceDirectory}"/>
          </j:if>
        </ant:sourceroots>

        <ant:classpath>
          <ant:path refid="${classpathRefid}"/>
          <ant:pathelement path="${plugin.getDependencyPath('aspectj:aspectjrt')}"/>
          <ant:pathelement path="${maven.build.dest}"/>
        </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.getProperty('aspectj.weaveWith')=='true'}">
              <ant:echo>Weaving with: ${dep.artifactId}</ant:echo>
              <ant:pathelement location="${artifact.path}"/>
            </j:if>
          </j:forEach>
        </ant:aspectpath>

        <!-- Look for libraries for weaving into -->
        <ant:inpath>
          <j:forEach var="artifact" items="${pom.artifacts}">
            <j:set var="dep" value="${artifact.dependency}"/>
            <j:if test="${dep.getProperty('aspectj.weaveInto')=='true'}">
              <ant:echo>Weaving into: ${dep.artifactId}</ant:echo>
              <ant:pathelement location="${artifact.path}"/>
            </j:if>
          </j:forEach>
        </ant:inpath>

      </ant:iajc>
      

    </define:tag>

  </define:taglib>
  
  <!--
    ========================================================================
    Default goal.
    ========================================================================
  -->
  <goal name="aspectj" description="Weave with AspectJ"
    prereqs="aspectj:test-compile"/>

  <!--
    ========================================================================
    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>

    <j:set var="shouldWeave" value="false"/>

    <j:set var="aspectSourceDir" value="${pom.build.aspectSourceDirectory}"/>
    
    <!-- Are there aspect sources -->
    <ant:available property="aspectSourcesPresent" file="${aspectSourceDir}"/>

    <!-- If there aren't aspect sources check if there are aspect libraries -->
    <j:if test="${aspectSourcesPresent == null}">
      <j:forEach var="artifact" items="${pom.artifacts}">
        <j:set var="dep" value="${artifact.dependency}"/>
        <j:if test="${dep.getProperty('aspectj.weaveWith')=='true' and dep.type=='jar'}">
          <j:set var="aspectLibrariesPresent" value="true"/>
          <j:break/>
        </j:if>
        <j:if test="${dep.getProperty('aspectj.weaveInto')=='true' and dep.type=='jar'}">
          <j:set var="aspectLibrariesPresent" value="true"/>
          <j:break/>
        </j:if>
      </j:forEach>
    </j:if>

    <j:choose>
      <j:when test="${(aspectSourcesPresent == 'true' and aspectSourceDir != '') || (aspectLibrariesPresent == 'true')}">
        <j:set var="shouldWeave" value="true"/>
      </j:when>
      <j:otherwise>
        <echo>No Aspects to weave</echo>
      </j:otherwise>
    </j:choose>

  </goal>

  <!--
    ========================================================================
    Weave classes
    ========================================================================
  -->
  <goal name="aspectj:compile" prereqs="aspectj:init"
    description="Weave classes with AspectJ">

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

      <!-- Weave classes -->
      <aspectj:compile
        sourcePathRefid="maven.compile.src.set"
        classpathRefid="maven.dependency.classpath"
        destDir="${maven.build.dest}"/>

    </j:if>

  </goal>
  
  <!--
    ========================================================================
    Weave test classes
    ========================================================================
  -->
  <goal name="aspectj:test-compile" prereqs="aspectj:compile"
    description="Weave tests with AspectJ">

    <j:set var="testSourceDir" value="${pom.build.unitTestSourceDirectory}"/>
    <ant:available
        property="hasTestDir"
        file="${testSourceDir}"/>
 
    <j:if test="${shouldWeave == 'true' and hasTestDir != null and testSourceDir != ''}">

      <!-- By calling a goal from the test plugin we ensure that all its 
           properties are loaded and are thus accessible from this plugin -->
      <test:dependency-handle/>
      <j:set var="testPlugin" value="${pom.getPluginContext('maven-test-plugin')}"/>

      <!-- Weave test classes -->
      <ant:path id="testClasspath">
        <ant:path refid="maven.dependency.classpath"/>
        <ant:pathelement path="${plugin.getDependencyPath('junit')}"/>
      </ant:path>

      <aspectj:compile
        sourcePathRefid="maven.test.compile.src.set"
        classpathRefid="testClasspath"
        destDir="${maven.test.dest}"/>

    </j:if>

  </goal>
  
</project>
