<?xml version="1.0"?>

<!-- 
/*
 * Copyright 2003-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.
 */
 -->

<project
  xmlns:j="jelly:core"
  xmlns:m="jelly:maven"
  xmlns:x="jelly:xml"
  xmlns:d="doc"
  xmlns:u="jelly:util"
  xmlns:a="jelly:ant">

  <!--
     ========================================================================
       Generate a dashboard report.
     ========================================================================
  -->
  <goal name="dashboard" prereqs="dashboard:report"
    description="Generate a dashboard report"/>

  <!--
     ========================================================================
       Generate a dashboard report.
     ========================================================================
  -->
  <goal name="dashboard:report" description="Generate a dashboard report">

    <!-- Generate dashboard data for all sub-projects if it is required -->
    <j:set var="runreactor" value="${maven.dashboard.runreactor}"/>
    <j:choose>
      <j:when test="${runreactor == 'true'}">
        <m:reactor
            basedir="${maven.dashboard.basedir}"
            banner="Generating dashboard data for"
            includes="${maven.dashboard.includes}"
            excludes="${maven.dashboard.excludes}"
            postProcessing="true"
            goals="dashboard:report-single"
            ignoreFailures="${maven.dashboard.ignoreFailures}"/>
      </j:when>
      <j:otherwise>
        <!-- We need to run the reactor to gather the list of projects 
             because the reactor creates a reactorProjects jelly property
             that we need in the dashboard:aggregate goal. -->
        <m:reactor
            basedir="${maven.dashboard.basedir}"
            banner="Gathering project list for"
            includes="${maven.dashboard.includes}"
            excludes="${maven.dashboard.excludes}"
            postProcessing="true"
            collectOnly="true"
            ignoreFailures="${maven.dashboard.ignoreFailures}"/>
      </j:otherwise>
    </j:choose>      

    <!-- Aggregate all dashboard project data into a single master dashboard
         file -->
    <attainGoal name="dashboard:aggregate"/>

    <!-- Generate xdoc report -->
    <attainGoal name="dashboard:xdoc"/>
                   
  </goal>

  <!--
     ========================================================================
       Aggregate different dashboard single reports into one
     ========================================================================
  -->
  <goal name="dashboard:aggregate">

    <a:dirname property="xmlReportDir" file="${maven.dashboard.report.xml}"/>
    <a:mkdir dir="${xmlReportDir}"/>

    <j:file name="${maven.dashboard.report.xml}" prettyPrint="true" 
        xmlns="dashboard">
      <dashboard>
        <j:forEach var="reactorProject" items="${reactorProjects}">
          <u:available 
              file="${reactorProject.context.getVariable('maven.build.dir')}/dashboard-single.xml">

            <x:element name="project">
              <x:attribute name="name">${reactorProject.name}</x:attribute>          

              <!-- Extract all reports from the single dashboards -->
  
              <!-- TODO: Find a way to not hardcode the dashboard data 
                   location -->
              <u:file var="dashboardAsFile" 
                  name="${reactorProject.context.getVariable('maven.build.dir')}/dashboard-single.xml"/>
              <x:parse var="doc" xml="${dashboardAsFile}"/>           
              <x:copyOf select="$doc//aggregator"/>
            </x:element>        
          </u:available>
        </j:forEach>
      </dashboard>
    </j:file>

  </goal>

  <!--
     ========================================================================
       Generate xdoc report file
     ========================================================================
  -->
  <goal name="dashboard:xdoc">

    <a:dirname property="xdocReportDir" 
        file="${maven.dashboard.report.xdoc}.xml"/>
    <a:mkdir dir="${xdocReportDir}"/>

    <!-- Generate main report -->
    <d:jsl
        input="${maven.dashboard.report.xml}"
        output="${maven.dashboard.report.xdoc}.xml"
        stylesheet="${maven.dashboard.template}"
        outputMode="xml"
        prettyPrint="true"/>

    <!-- Generate legend report -->
    <d:jsl
        input="${maven.dashboard.report.xml}"
        output="${maven.dashboard.report.legend.xdoc}.xml"
        stylesheet="${maven.dashboard.template.legend}"
        outputMode="xml"
        prettyPrint="true"/>

  </goal>

  <!--
     ========================================================================
       Generate a dashboard report for a single project
     ========================================================================
  -->
  <goal name="dashboard:report-single">

    <a:dirname property="singleReportDir" file="${maven.dashboard.report.single}"/>
    <a:mkdir dir="${singleReportDir}"/>

    <attainGoal name="dashboard:run-goals"/>

    <!-- Generate report data file -->
    <u:tokenize var="aggregatorNames" delim=",">${maven.dashboard.aggregators}</u:tokenize>
    <j:file name="${maven.dashboard.report.single}" prettyPrint="true" 
        xmlns="dashboard">
      <dashboard-single>
        <j:forEach var="aggregatorName" items="${aggregatorNames}">
          <x:element name="aggregator">

            <!-- Add aggregator name -->
            <x:attribute name="name">${aggregatorName}</x:attribute>

            <!-- Add aggregator content -->
            <j:set var="scriptProperty" 
                value="maven.dashboard.aggregator.${aggregatorName}.script"/>
            
            <!-- Verify if the script exists... -->
            <j:if test="${context.getVariable(scriptProperty) == null}">
              <a:fail>Invalid aggregator name [${aggregatorName}]</a:fail>
            </j:if>

            <j:import file="${context.getVariable(scriptProperty)}"
                inherit="true"/>

          </x:element>      
        </j:forEach>
      </dashboard-single>
    </j:file>

  </goal>

  <!--
     ========================================================================
       Execute goals associated with aggregators so that the data sources 
       from which we extract report data are available.
     ========================================================================
  -->
  <goal name="dashboard:run-goals">
    
    <!-- For each report, call the goal associated with the report type so that
         raw data for that report type are generated. For example the checkstyle 
         report type will call checkstyle:checkstyle -->
    <j:set var="rungoals" value="${maven.dashboard.rungoals}"/>
    <j:if test="${rungoals == 'true'}">

      <!-- Make sure that the Clover plugin generates only the XML report (as 
           this is report used by the Clover aggregators to extract information 
           from). The reason we disable the other reports is to win some response
           time. -->
      <j:set var="cloverReportXml"
          value="${pom.getVariable('maven.clover.report.xml')}"/>
      <j:set var="maven.clover.report.xml" value="true" scope="parent"/>
      <j:set var="cloverReportHtml"
          value="${pom.getVariable('maven.clover.report.html')}"/>
      <j:set var="maven.clover.report.html" value="false" scope="parent"/>
      <j:set var="cloverReportSwing"
          value="${pom.getVariable('maven.clover.report.swing')}"/>
      <j:set var="maven.clover.report.swing" value="false" scope="parent"/>

      <u:tokenize var="aggregatorNames" delim=",">${maven.dashboard.aggregators}</u:tokenize>

      <!-- Property used to remember what goals have already been called -->
      <j:set var="executedGoals" value=""/>

      <j:forEach var="aggregatorName" items="${aggregatorNames}">

        <a:echo>Generating data for aggregator [${aggregatorName}]</a:echo>

        <j:set var="goalProperty" 
            value="maven.dashboard.aggregator.${aggregatorName}.goal"/>
        <j:set var="goalName" value="${context.getVariable(goalProperty)}"/>

        <!-- Only run if the artifact has not already been created by
             a previous goal run -->
        <j:if test="${executedGoals.indexOf(goalName) == '-1'}">

          <a:echo>Calling goal [${goalName}] to generate data...</a:echo>

          <!-- Make sure plugin doesn't fail if goal fails to be called -->
          <j:catch var="exception">
            <attainGoal name="${goalName}"/>
          </j:catch>
          <j:choose>
            <j:when test="${exception != null}">
              <a:echo>Error while calling goal [${goalName}]:</a:echo>
              <a:echo>${exception}</a:echo>
            </j:when>
            <j:otherwise>
              <j:set var="executedGoals" 
                  value="${goalName},${executedGoals}"/>
            </j:otherwise>
          </j:choose>

        </j:if>

      </j:forEach>

      <!-- Restore Clover plugin properties -->
      <j:set var="maven.clover.report.xml" value="${cloverReportXml}" 
          scope="parent"/>
      <j:set var="maven.clover.report.html" value="${cloverReportHtml}" 
          scope="parent"/>
      <j:set var="maven.clover.report.swing" value="${cloverReportSwing}" 
          scope="parent"/>

    </j:if>
    
  </goal>

  <!--
     ========================================================================
       Register the dashboard report.
     ========================================================================
  -->
  <goal name="maven-dashboard-plugin:register">

    <d:registerReport 
      name="Dashboard"
      pluginName="dashboard"
      description="Dashboard report aggregating different quality reports"
      link="${maven.dashboard.report.xdoc}"/>
  </goal>
  
  <!--
     ========================================================================
       Deregister the dashboard report.
     ========================================================================
  -->
  <goal name="maven-dashboard-plugin:deregister">
    <d:deregisterReport name="Dashboard"/>
  </goal>

</project>
