<?xml version="1.0"?>

<!--
FORREST SITE BUILDER

 - The runtime part of Forrest
 - Contains actions Forrest can peform on any Forrest-using project.
 - This is typically called by forrest.bat or forrest
-->


<project default="site" basedir="." name="forrest">

  <property name="version" value="0.5"/>

  <description>
    *=======================================================*
    |                 Forrest Site Builder                  |
    |                         0.5.1                         |
    |             $Date: 2003/10/05 14:42:56 $              |
    *=======================================================*
  
             Call this through the 'forrest' command
  </description>
  
  <taskdef name="jing" classname="com.thaiopensource.relaxng.util.JingTask">
    <classpath>
      <fileset dir="${forrest.home}/WEB-INF/lib" includes="*.jar" />
    </classpath>
  </taskdef>


<!-- ***************************************************************** -->
<!-- ***************************************************************** -->
<!-- **                                                             ** -->
<!-- **                                                             ** -->
<!-- **                    COMMON SETTINGS                          ** -->
<!-- **                                                             ** -->
<!-- **                                                             ** -->
<!-- ***************************************************************** -->
<!-- ***************************************************************** -->

  <!-- ===============================================================
       Loads user defined settings.
       Steps back to defaults when they are not set.
       Echo's the settings if requested.
       =============================================================== -->
  <target name="init-props">
  
    <!-- setting defaults for parameters -->
    <!-- people should use -D switch, or <ant><property>s to override these   -->

    <property name="project.home" location="." />
    <property name="/" value="${file.separator}"/>
    <echo message="Loading project specific properties from ${project.home}${/}forrest.properties" />
    <property file="${project.home}/forrest.properties" />

    <!-- people should use forrest.properties to override following defaults  -->
    <property name="forrest.home"        location="." />
    <property name="project.name"        value="my-project"    />
    <property name="project.build-dir"   location="${project.home}/build"    />
    <property name="project.site-dir"    location="${project.build-dir}/site"    />
    <property name="project.war"         location="${project.build-dir}/${project.name}.war" />
    <property name="project.webapp"      location="${project.build-dir}/webapp" />

    <property name="project.temp-dir"    location="${project.build-dir}/tmp"     />
    <property name="project.work-dir"    location="${project.temp-dir}/work"      />
    <property name="project.ctxt-dir"    location="${project.temp-dir}/context"   />

    <property name="project.brokenlinkfile" location="${project.temp-dir}/brokenlinks.xml"/>
    <property name="project.debuglevel"  value="ERROR"                         />
    <property name="project.start-uri"   value="index.html"                    />
    <property name="project.configfile"   value="${project.ctxt-dir}/WEB-INF/cli.xconf" />
    <property name="project.logkitfile"   value="${project.ctxt-dir}/WEB-INF/logkit.xconf" />
    <property name="project.logger"       value="" />

    <!-- use of these property should be removed when the siteplan becomes active -->
    <property name="project.skin"        value="forrest-site" />
    <property name="project.menu-scheme" value="tab_attributes" />
    <property name="project.status"      location="${project.home}/status.xml" />
    <property name="project.bugtracking-url" value="http://nagoya.apache.org/bugzilla/show_bug.cgi?id=" />

    <!-- Files we don't want copied from build/* to src/* by the backcopy
    command. Relative to build/webapp -->
    <property name="forrest.backcopy.excludes" value="**/breadcrumbs.js,WEB-INF/**,status.xml"/>

    <!-- FIXME: rename project.content-dir to project.documentation-dir -->
    <property name="project.content-dir" location="${project.home}/src/documentation" />
    <!-- NOTE: Do not rely on this 'project.real-content-dir' property, as it
    will go away soon -->
    <property name="project.real-content-dir" location="${project.content-dir}/content" />
    <property name="project.sitemap-dir"     location="${project.content-dir}" />
    <property name="project.xdocs-dir"   location="${project.content-dir}/content/xdocs" />
    <property name="project.resources-dir"   location="${project.content-dir}/resources"/>
    <property name="project.stylesheets-dir" location="${project.resources-dir}/stylesheets" />
    <property name="project.images-dir"  location="${project.resources-dir}/images" />
    <property name="project.schema-dir"  location="${project.resources-dir}/schema" />
    <property name="project.grammars-dir" location="${project.resources-dir}/grammars" />
    <property name="project.catalog"     location="${project.schema-dir}/catalog.xcat" />
    <property name="forrest.catalog.verbosity" value="1" />
    <property name="forrest.maxmemory" value="64m" />
    <property name="forrest.jvmargs" value="" />
    <property name="project.skins-dir"   location="${project.content-dir}/skins" />
    <property name="project.skinconf"    location="${project.content-dir}/skinconf.xml" />
    <property name="project.conf-dir"    location="${project.content-dir}/conf" />
    <property name="project.lib-dir"     location="${project.content-dir}/lib" />
    <property name="project.classes-dir" location="${project.content-dir}/classes" />

    <!-- checks for presence of required classes and/or resources -->
    <property name="tools.jar"           location="${java.home}/../lib/tools.jar"/>
    <available file="${tools.jar}"       property="tools.jar.present"/>

    <!-- echo settings in -Dforrest.echo=true mode -->
    <antcall target="echo-settings" />
  </target>

  <target name="examine-proj" depends="init-props">
    <available property="conf.present" file="${project.conf-dir}" type="dir"/>
    <available property="real-content.present" file="${project.real-content-dir}" type="dir"/>
    <available property="sitemap.present" file="${project.sitemap-dir}" type="dir"/>
    <available property="xdocs.present" file="${project.xdocs-dir}" type="dir"/>
    <available property="resources.present" file="${project.resources-dir}" type="dir"/>
    <available property="images.present" file="${project.images-dir}" type="dir"/>
    <available property="grammars.present" file="${project.grammars-dir}" type="dir"/>
    <available property="schema.present" file="${project.schema-dir}" type="dir"/>
    <available property="stylesheets.present" file="${project.stylesheets-dir}" type="dir"/>
    <available property="lib.present" file="${project.lib-dir}" type="dir"/>
    <available property="classes.present" file="${project.classes-dir}" type="dir"/>
    <available property="skins.present" file="${project.skins-dir}" type="dir"/>
    <available property="skinconf.present" file="${project.skinconf}"/>
    <available property="status.present" file="${project.status}"/>
  </target>

  <target name="validation-props" depends="examine-proj">
    <!-- Validation flags -->

    <property name="forrest.validate" value="true" />
    <condition property="validate">
      <istrue value="${forrest.validate}"/>
    </condition>
    <property name="forrest.validate.failonerror" value="true" />
    <property name="forrest.validate.includes" value="**/*"/>
    <property name="forrest.validate.excludes" value=""/>

    <property name="forrest.validate.xdocs" value="${forrest.validate}"/>
    <condition property="validate.xdocs">
      <and>
        <istrue value="${forrest.validate.xdocs}"/>
        <isset property="xdocs.present"/>
      </and>
    </condition>
    <property name="forrest.validate.xdocs.includes" value="**/*.xml"/>
    <property name="forrest.validate.xdocs.excludes" value="site.xml,.*.swp"/>
    <property name="forrest.validate.xdocs.failonerror"
      value="${forrest.validate.failonerror}" />

    <property name="forrest.validate.skinconf" value="${forrest.validate}"/>
    <condition property="validate.skinconf">
      <and>
        <istrue value="${forrest.validate.skinconf}"/>
        <isset property="skinconf.present"/>
      </and>
    </condition>
    <basename file="${project.skinconf}" property="skinconf-file"/>
    <property name="forrest.validate.skinconf.includes" value="${skinconf-file}"/>
    <property name="forrest.validate.skinconf.excludes" value=""/>
    <property name="forrest.validate.skinconf.failonerror"
      value="${forrest.validate.failonerror}" />

    <property name="forrest.validate.sitemap" value="${forrest.validate}"/>
    <condition property="validate.sitemap">
      <and>
        <istrue value="${forrest.validate.sitemap}"/>
        <isset property="sitemap.present"/>
      </and>
    </condition>

    <property name="forrest.validate.sitemap.includes" value=""/>
    <property name="forrest.validate.sitemap.excludes" value=""/>
    <property name="forrest.validate.sitemap.failonerror"
      value="${forrest.validate.failonerror}" />

    <property name="forrest.validate.stylesheets" value="${forrest.validate}"/>
    <condition property="validate.stylesheets">
      <and>
        <istrue value="${forrest.validate.stylesheets}"/>
        <isset property="stylesheets.present"/>
      </and>
    </condition>
    <property name="forrest.validate.stylesheets.includes" value="**/*.xsl"/>
    <property name="forrest.validate.stylesheets.excludes" value=""/>
    <property name="forrest.validate.stylesheets.failonerror"
      value="${forrest.validate.failonerror}" />

    <property name="forrest.validate.skins" value="${forrest.validate}"/>
    <condition property="validate.skins">
      <and>
        <istrue value="${forrest.validate.skins}"/>
        <isset property="skins.present"/>
      </and>
    </condition>
    <property name="forrest.validate.skins.includes" value="**/*"/>
    <property name="forrest.validate.skins.excludes" value="**/*.xsl"/>
    <property name="forrest.validate.skins.failonerror"
      value="${forrest.validate.failonerror}" />

    <property name="forrest.validate.skins.stylesheets" value="${forrest.validate.skins}"/>
    <condition property="validate.skins.stylesheets">
      <and>
        <istrue value="${forrest.validate.skins.stylesheets}"/>
        <isset property="skins.present"/>
      </and>
    </condition>
    <property name="forrest.validate.skins.stylesheets.includes" value="**/*.xsl"/>
    <property name="forrest.validate.skins.stylesheets.excludes" value=""/>
    <property name="forrest.validate.skins.stylesheets.failonerror"
      value="${forrest.validate.skins.failonerror}" />
  </target>


  <!-- Load properties from user's skinconf.xml, if it is defined -->
  <target name="load-project-props" depends="validation-props, validate-skinconf" if="skinconf.present">
    <xmlproperty file="${project.skinconf}" collapseattributes="true"
      validate="${validate.skinconf}"/>
  </target>

  <!-- Load properties from Forrest's default skinconf.xml, unless a user's is defined -->
  <target name="load-forrest-props" unless="skinconf.present">
    <xmlproperty file="${forrest.home}/context/skinconf.xml"
      collapseattributes="true" validate="true"/>
    <!-- Forrest skinconf should have been previously validated in buld.xml -->
  </target>

  <!-- Define filters equating to elements in the skinconf.xml file. Skins can
  include tokens corresponding to skinconf.xml elements, and have them replaced
  at runtime.-->
  <target name="init-skinprops" depends="load-project-props, load-forrest-props">
    <mkdir dir="${project.temp-dir}"/>
    <property name="skinfilters" value="${project.temp-dir}/skinfilters.properties"/>
    <echoproperties prefix="skinconfig" destfile="${skinfilters}"/>
    <filter filtersfile="${skinfilters}"/>
  </target>

  <!-- Sets up properties and filters -->
  <target name="init" depends="init-props, init-skinprops"/>

  <!-- ===============================================================
       Echo's the settings if requested. [-Dforrest.echo=true]
       =============================================================== -->
  <target name="echo-settings" if="forrest.echo">
    <echo>
      ------------------------------------------------
      | Forrest template run.
      | Running from $${forrest.home} = ${forrest.home}
      | Working on   $${project.home} = ${project.home}
      ------------------------------------------------
      | //where to put the result
      | project.site-dir    = ${project.site-dir} 
      | //uri to start crawling/generation process
      | project.start-uri   = ${project.start-uri}
      | //cocoon.xconf location
      | project.configfile  = ${project.configfile}
      | //logkit.xconf location
      | project.logkitfile  = ${project.logkitfile}
      | //temp dir to throw stuff in (i.e. work and ctxt)
      | project.temp-dir    = ${project.temp-dir} 
      | //temp working directory for generation process
      | project.work-dir    = ${project.work-dir} 
      | //temp context directory for generation process
      | project.ctxt-dir    = ${project.ctxt-dir} 
      | //debuglevel for logging (DEBUG, INFO, WARN, ERROR, FATAL_ERROR)
      | project.debuglevel  = ${project.debuglevel}
      | //file for list of broken links
      | project.brokenlinkfile = ${project.brokenlinkfile}
      | //check if you have tools.jar installed
      | tools.jar.present   = ${tools.jar.present} 
      ------------------------------------------------
      | The following properties could be removed from future builds:
      | //which skin to apply
      | project.skin        = ${project.skin} 
      | //where your documentation xml is
      | project.content-dir = ${project.content-dir} 
      ------------------------------------------------
    </echo>
  </target>


  <!-- ===============================================================
       Set class-path.
       =============================================================== -->
  <target name="prepare-classpath" depends="prepare-context, -prepare-classpath"/>
  <target name="-prepare-classpath">
    <path id="forrest.cp">
      <pathelement location="${project.ctxt-dir}/WEB-INF/classes"/>
      <fileset dir="${project.ctxt-dir}/WEB-INF/lib" includes="*.jar"/>
      <pathelement location="${forrest.home}/WEB-INF/classes"/>
      <fileset dir="${forrest.home}/lib/optional" includes="servlet-2.3.jar"/>
      <fileset dir="${forrest.home}/lib/endorsed" includes="*.jar"/>
      <fileset dir="${forrest.home}/WEB-INF/lib" includes="*.jar" />
      <pathelement location="${tools.jar}"/>
    </path>
  </target>


<!-- ***************************************************************** -->
<!-- ***************************************************************** -->
<!-- **                                                             ** -->
<!-- **                                                             ** -->
<!-- **                  SITE BUILDING ACTIONS                      ** -->
<!-- **                                                             ** -->
<!-- **                                                             ** -->
<!-- ***************************************************************** -->
<!-- ***************************************************************** -->


  <!-- ===============================================================
       Fills the Cocoon context dir to work in 
       with the forrest-predefines.
       param: name of the skin to use ${project.skin} (now)
       param: location to make temporary context-dir ${project.ctxt-dir} 
       =============================================================== -->
       <target name="bare-context" depends="init" >
         <echo>____________________________________</echo>
         <echo>Using skin ${project.skin}</echo>
         <echo>____________________________________</echo>
    <filter token="skin"              value="${project.skin}" />
    <filter token="menu-scheme"       value="${project.menu-scheme}" />
    <filter token="bugtracking-url"   value="${project.bugtracking-url}" />
    <filter token="local-catalog"     value="${project.catalog}" />
    <filter token="catalog-verbosity" value="${forrest.catalog.verbosity}" />

    <!--
    These filters defined for backwards-compatibility with old skins.
    New skins should use the skinconfig.* filters, or actively parse the
    skinconf.xml file themselves. (JT)
    -->
    <filter token="link1"      value="${skinconfig.trail.link1.name}"/>
    <filter token="link1.href" value="${skinconfig.trail.link1.href}"/>
    <filter token="link2"      value="${skinconfig.trail.link2.name}"/>
    <filter token="link2.href" value="${skinconfig.trail.link2.href}"/>
    <filter token="link3"      value="${skinconfig.trail.link3.name}"/>
    <filter token="link3.href" value="${skinconfig.trail.link3.href}"/>
    <filter token="year"       value="${skinconfig.year}"/>
    <filter token="vendor"     value="${skinconfig.vendor}"/>
    <filter token="group-logo.src"  value="${skinconfig.group-logo}"/>
    <filter token="group-logo.href" value="${skinconfig.group-url}"/>
    <filter token="group-logo.alt"  value="${skinconfig.group-name} logo"/>
    <filter token="project-logo.src"  value="${skinconfig.project-logo}"/>
    <filter token="project-logo.href" value="${skinconfig.project-url}"/>
    <filter token="project-logo.alt"  value="${skinconfig.project-name} logo"/>

    <copy todir="${project.ctxt-dir}/" filtering="off">
      <fileset dir="${forrest.home}/context" >
        <exclude name="*.xmap" />
        <exclude name="skins/**" />
      </fileset>
      <fileset dir="${forrest.home}/context" >
        <include name="skins/${project.skin}/images/**" />
        <include name="skins/common/images/**" />
      </fileset>
    </copy>

    <copy todir="${project.ctxt-dir}/" filtering="on" overwrite="true">
    <!-- everything in the skins, except the images , and the sitemap -->
      <fileset dir="${forrest.home}/context" >
        <include name="*.xmap" />
        <include name="skins/${project.skin}/**" />
        <include name="skins/common/**" />
        <exclude name="skins/**/images/**" />
      </fileset>
    </copy>

    <mkdir dir="${project.ctxt-dir}/WEB-INF"/>

    <!-- Force-copy these files as they have @tokens@ that will need replacing -->
    <copy todir="${project.ctxt-dir}/WEB-INF" filtering="true" overwrite="true">
      <fileset dir="${forrest.home}/WEB-INF">
        <include name="*.xconf" />
      </fileset>
    </copy>

    <!--Hack to stop the classpath definition breaking. If the project has any
    custom jars or classes, they will be added to these dirs -->
    <mkdir dir="${project.ctxt-dir}/WEB-INF/lib"/>
    <mkdir dir="${project.ctxt-dir}/WEB-INF/classes"/>
  </target>


  <!-- ===============================================================
       Fills the Cocoon context dir to work in 
       with the project-content-parts 
         (now: copy stuff from param ${project.content-dir}
          with siteplan: based on that plan; should allow more different parts)
       param: location to find the content ${project.content-dir}(now)
       param: location to find project descriptors == ${project.home} 
       param: location to make temporary context-dir ${project.ctxt-dir} 
       =============================================================== -->
  <target name="project-context-bot" depends="init, examine-proj, copy-conf, copy-sitemap,
    copy-xdocs, copy-stylesheets, copy-images, copy-grammars, copy-content, copy-lib, 
    copy-classes, copy-skins, copy-skinconf, copy-status"/>

  <target name="project-context" depends="examine-proj, ensure-content,
    validate, init, bare-context, copy-sitemap, copy-conf,
    copy-xdocs, copy-stylesheets, copy-images, copy-grammars, copy-resources, copy-content, copy-lib, 
    copy-classes, copy-skins, copy-skinconf, copy-status"/>

  <target name="copy-conf" if="conf.present">
    <copy toDir="${project.ctxt-dir}/WEB-INF" filtering="true"
      overwrite="true" failonerror="false">
      <fileset dir="${project.conf-dir}">
        <exclude name="*-${version}.xconf"/>
      </fileset>
    </copy>
    <copy toDir="${project.ctxt-dir}/WEB-INF" filtering="true" overwrite="true"
      failonerror="false">
      <fileset dir="${project.conf-dir}">
        <include name="*-${version}.*"/>
      </fileset>
      <mapper type="glob" from="*-${version}.xconf" to="*.xconf"/>
    </copy>
   </target>

  <target name="copy-sitemap" if="sitemap.present">
    <copy toDir="${project.ctxt-dir}" filtering="true" overwrite="true" failonerror="false">
      <fileset dir="${project.sitemap-dir}">
        <exclude name="*-${version}.xmap"/>
        <include name="*.xmap"/>
        <include name="jtidy.properties"/>
      </fileset>
    </copy>
    <copy toDir="${project.ctxt-dir}" filtering="true" overwrite="true">
      <fileset dir="${project.sitemap-dir}">
        <include name="*-${version}.xmap"/>
      </fileset>
      <mapper type="glob" from="*-${version}.xmap" to="*.xmap"/>
    </copy>
  </target>

  <target name="copy-xdocs" if="xdocs.present">
    <sync toDir="${project.ctxt-dir}/content/xdocs">
      <fileset dir="${project.xdocs-dir}"/>
    </sync>
  </target>

  <target name="copy-resources" if="resources.present">
    <copy toDir="${project.ctxt-dir}/resources" filtering="false" failonerror="false">
      <fileset dir="${project.resources-dir}">
        <exclude name="stylesheets"/>
        <exclude name="images"/>
        <exclude name="grammars"/>
      </fileset>
    </copy>
  </target>

  <target name="copy-stylesheets" if="stylesheets.present">
    <copy toDir="${project.ctxt-dir}/resources/stylesheets" filtering="false"
      overwrite="true" failonerror="false">
      <fileset dir="${project.stylesheets-dir}"/>
    </copy>
  </target>

  <target name="copy-images" if="images.present">
    <copy toDir="${project.ctxt-dir}/resources/images" filtering="false"
      overwrite="true" failonerror="false">
      <fileset dir="${project.images-dir}"/>
    </copy>
  </target>

  <target name="copy-grammars" if="grammars.present">
    <copy toDir="${project.ctxt-dir}/resources/grammars" filtering="false"
      overwrite="true" failonerror="false">
      <fileset dir="${project.grammars-dir}"/>
    </copy>
  </target>

  <!-- Copy all non-xdocs content -->
  <target name="copy-content" if="real-content.present">
    <copy toDir="${project.ctxt-dir}/content" filtering="false"
      overwrite="false" failonerror="false">
      <fileset dir="${project.real-content-dir}">
        <exclude name="xdocs/**"/>
      </fileset>
    </copy>
  </target>

  <target name="copy-lib" if="lib.present">
    <copy toDir="${project.ctxt-dir}/WEB-INF/lib" filtering="false"
      overwrite="true" failonerror="false">
      <fileset dir="${project.lib-dir}"/>
    </copy>
  </target>

  <target name="copy-classes" if="classes.present">
    <copy toDir="${project.ctxt-dir}/WEB-INF/classes" filtering="false"
      overwrite="true" failonerror="false">
      <fileset dir="${project.classes-dir}"/>
    </copy>
  </target>

  <target name="copy-skins" if="skins.present">
    <copy toDir="${project.ctxt-dir}/skins" filtering="off" overwrite="true" failonerror="false">
       <fileset dir="${project.skins-dir}" >
        <include name="**/images/**" />
      </fileset>
    </copy>
    <copy toDir="${project.ctxt-dir}/skins" filtering="on" overwrite="true" failonerror="false">
      <fileset dir="${project.skins-dir}" >
        <exclude name="**/images/**" />
      </fileset>
    </copy>
  </target>

  <target name="copy-skinconf" if="skinconf.present">
    <copy file="${project.skinconf}"
      toDir="${project.ctxt-dir}" filtering="false"
      overwrite="true" failonerror="false"/>
  </target>

  <target name="copy-status" if="status.present">
    <copy file="${project.status}" todir="${project.ctxt-dir}" filtering="false"/>
  </target>


  <!-- ===============================================================
       Makes the Cocoon context dir to work in and fills it completely.
       That is by depending on:
         bare-context     // for forrest predefines.  
         project-context  // for project's actual content
           (now: copy stuff from extra param defining the content dir
            with siteplan: based on that)
         control-context  // for derivatives from siteplan 
           (now: no need, waiting on siteplan future)
            with siteplan: e.g. sitemap and catalog)
       param: name of the skin to use ${project.skin} (now)
       param: location to find the content ${project.content-dir}(now)
       param: location to make temporary context-dir ${project.ctxt-dir} 
       =============================================================== -->
  <target name="prepare-context" depends="init, bare-context, project-context" />


  <!-- ===============================================================
       Cleans the site.  (typically before generating the new version)
       param: location to clean ${project.site-dir}
       =============================================================== -->
  <target name="clean-site" depends="init-props">
    <!-- <delete dir="${project.site-dir}"/> -->
    <mkdir dir="${project.site-dir}"/>     
    <delete includeEmptyDirs="false">
      <fileset dir="${project.site-dir}"/>
    </delete>     
  </target>
  
  <!-- ===============================================================
       Checks if the current project contains Forrest docs, and sets
       the 'project.empty' property if no docs are found.
       =============================================================== -->
  <target name="check-contentdir" depends="init-props">
    <available property="project.content.present" file="${project.content-dir}"
      type="dir"/>
  </target>

  <target name="ensure-nocontent" depends="check-contentdir"
    if="project.content.present" unless="skip.contentcheck">
    <fail>
------------------------------------------------
This project already has content in ${project.content-dir}.

Run with '-Dskip.contentcheck=yes' to ignore existing content.
------------------------------------------------
    </fail>
  </target>

  <target name="ensure-content" depends="check-contentdir"
    unless="project.content.present">
    <fail>
------------------------------------------------
This project has no content in ${project.content-dir}.
Use the 'seed' target to create a template project structure.
------------------------------------------------
    </fail>
  </target>

  <!-- ===============================================================
       Makes the site.
       param: name of the skin to use ${project.skin} (now)
       param: location to find the content ${project.content-dir}(now)
       param: location to make temporary context-dir ${project.ctxt-dir} 
       param: location to make temporary work-dir ${project.content-dir}
       param: debuglevel for logging ${project.debuglevel}
       param: location of log-file ${project.logkitfile}
       ===============================================================
   -->

   <target name="site" depends="prepare-context, -site"
     description="Generates a static HTML website for this project"/>

   <target name="-site" depends="init, -prepare-classpath"
     if="project.content.present">
    <!-- clean out the temp space, if we don't cocoon fails on this
         actually clears the cache, not yet clear why it is really needed? -->
    <delete dir="${project.work-dir}"/>
    <mkdir dir="${project.work-dir}"/>

    <parallel>
      <!--
      <java classname="org.apache.cocoon.Main"
        fork="true"
        maxmemory="${forrest.maxmemory}"
        dir="."
        failonerror="true"
        classpathref="forrest.cp">
        <jvmarg line="${forrest.jvmargs}"/>
        <jvmarg
          value="-Djava.endorsed.dirs=${forrest.home}/lib/endorsed${path.separator}${java.endorsed.dirs}"/>
        <arg value="-c${project.ctxt-dir}"/>   <!- input to the process ->
        <arg value="-d${project.site-dir}"/>   <!- output to be put ->
        <arg value="-w${project.work-dir}"/>   <!- temp dir to use for e.g. cache ->
        <arg value="-u${project.debuglevel}"/> <!- threshold for log messages ->
        <arg value="-C${project.ctxt-dir}/WEB-INF/cocoon.xconf"/>      <!- cocoon.xconf file to use ->
        <arg value="-b${project.brokenlinkfile}"/>  <!- output list of broken links ->
        <arg value="-k${project.ctxt-dir}/WEB-INF/logkit.xconf"/>  <!- output list of broken links ->
        <arg value="${project.start-uri}"/>              <!- starting page ->
        <arg value="-V" />                          <!- be verbose ->
      </java>
      -->

      <java classname="org.apache.cocoon.Main"
        fork="true"
        dir="${project.ctxt-dir}"
        failonerror="true"
        maxmemory="${forrest.maxmemory}">
        <jvmarg line="${forrest.jvmargs}"/>
        <jvmarg value="-Djava.endorsed.dirs=${forrest.home}/lib/endorsed${path.separator}${java.endorsed.dirs}"/>
        <arg value="--logLevel=${project.debuglevel}"/>
        <arg value="--Logger=${project.logger}"/>
        <arg value="--logKitconfig=${project.logkitfile}"/>
        <arg value="--destDir=${project.site-dir}"/>
        <arg value="--xconf=${project.configfile}"/>
        <arg value="${project.start-uri}"/>
        <classpath>
          <path refid="forrest.cp"/>
        </classpath>
      </java> 


      <sequential>
        <!-- 
        | Copy all non-xdocs content across, as we cannot rely on crawling to
        | discover the whole URI space.  Note: we are emulating the sitemap here;
        | please ensure they keep in synch.
        -->
        <property name="skindir" location="${project.ctxt-dir}/skins/${project.skin}"/>
        <copy toDir="${project.site-dir}" filtering="false"
          overwrite="true" failonerror="false">
          <fileset dir="${project.ctxt-dir}/content">
            <exclude name="xdocs/**"/>
          </fileset>
          <fileset dir="${project.ctxt-dir}/resources" includes="images"/>
        </copy>

        <!-- Copy skin images -->
        <mkdir dir="${project.site-dir}/skin/images"/>
        <copy toDir="${project.site-dir}/skin/images" filtering="false" overwrite="true"
          failonerror="false">
          <fileset dir="${skindir}/images"/>
        </copy>

        <!-- Copy all other non-resource files -->
        <copy toDir="${project.site-dir}/skin" filtering="false"
          overwrite="true"
          failonerror="false">
          <mapper type="flatten"/>
          <fileset dir="${skindir}">
            <exclude name="images/**"/>
            <exclude name="xslt/**"/>
          </fileset>
        </copy>

      </sequential>
    </parallel>
    <echo>
------------------------------
Static site generated at:
  ${project.site-dir}

Please check the file
${project.brokenlinkfile}
for any broken links in the generated site.
------------------------------
    </echo>
  </target>



  <target name="project.webapp.defined" unless="project.webapp">
    <fail>
      ------------------------------------------------
      Error: $${project.webapp} variable has not been set. This is where the
      webapp will be assembled. Please define it in the calling script.
      ------------------------------------------------
    </fail>
  </target>

  <!-- ===============================================================
       Builds a cocoon webapp for your project.
       param: location to put generated webapp ${project.webapp}
       =============================================================== -->
  <target name="webapp" depends="init, validate, project.webapp.defined, ensure-content, prepare-context,
         load-project-props"
   description="Generates a dynamic servlet-based website (an unpackaged webapp)">
    <!-- this will need revisions in the case of the siteplan
    extra project-custom classes then will need to be warred in as well. -->
    <mkdir dir="${project.webapp}/WEB-INF"/>
    <copy file="${forrest.home}/WEB-INF/web.xml" todir="${project.webapp}/WEB-INF"/>
    <copy todir="${project.webapp}" preservelastmodified="true">
      <fileset dir="${project.ctxt-dir}" >
        <exclude name="*.xconf" /> <!-- CLI wants them there, webapp finds them in WEB-INF -->
      </fileset>
    </copy>

    <copy todir="${project.webapp}/WEB-INF">
      <!-- Note: no overwriting, so user's libs and classes get preference -->
      <fileset dir="${forrest.home}/WEB-INF">
        <include name="lib/**"/>
        <include name="classes/**"/>
      </fileset>
    </copy>

    <!-- Copy XML jars if not running JDK 1.4 (where they're built-in) -->
    <available property="jdk1.4+" classname="java.lang.CharSequence"/>
    <copy todir="${project.webapp}/WEB-INF/lib">
      <fileset dir="${forrest.home}/lib/endorsed">
        <include name="*jar" unless="jdk1.4+"/>
      </fileset>
    </copy>
    <echo>
---------------------------------
Webapp generated in ${project.webapp}

To run in Tomcat, add this to the config file (usu. server.xml):

&lt;Context path='/${skinconfig.project-name}'
            docBase='${project.webapp}'
            reloadable='true'/&gt;

If using JDK 1.4 or above, make sure to set the Java environment variable
-Djava.endorsed.dirs=${forrest.home}${/}lib${/}endorsed
Eg, in the TOMCAT_OPTS (3.3.x) or CATALINA_OPTS (4.x) env variable.
---------------------------------
    </echo>
  </target>



  <!-- ===============================================================
       Builds a cocoon .war for your project based on the siteplan.
       param: location to put generated war ${project.war}
       =============================================================== -->
 <target name="war" depends="webapp"
   description="Generates a dynamic servlet-based website (an packaged .war file)">

   <jar destfile="${project.war}" basedir="${project.webapp}"/>
   <echo>
---------------------------------
Webapp .war file generated:
${project.war}
---------------------------------
   </echo>
  </target>



<!-- ***************************************************************** -->
<!-- ***************************************************************** -->
<!-- **                                                             ** -->
<!-- **                                                             ** -->
<!-- **          PROJECT-TEMPLATE BUILDING ACTIONS                  ** -->
<!-- **                                                             ** -->
<!-- **                                                             ** -->
<!-- ***************************************************************** -->
<!-- ***************************************************************** -->



  <!-- ===============================================================
        Copies a template structure over to your project dir.
       =============================================================== -->
  <target name="seed" depends="ensure-nocontent"
    description="Seeds a directory with a template project doc structure">
    <unzip src="${forrest.home}/fresh-site.zip" 
      dest="${project.home}"
      overwrite="false"/>
    <echo>
-------------------------------
~~ Template project created! ~~

Here is an outline of the generated files:

/                        # ${basedir}
/status.xml              # List of project developers, todo list and change log
/forrest.properties      # Optional file describing your site layout
/src/documentation/      # Doc-specific files
/src/documentation/skinconf.xml    # Info about your project used by the skin
/src/documentation/content/        # Site content.
/src/documentation/content/xdocs   # XML content.
/src/documentation/content/xdocs/index.xml # Home page
/src/documentation/content/xdocs/site.xml  # Navigation file for site structure
/src/documentation/content/xdocs/tabs.xml  # Skin-specific 'tabs' file.
/src/documentation/content/*.html,pdf      # Static content files
/src/documentation/resources/images        # Project images (logos, etc)


What to do now?

- Try rendering this template to HTML by typing 'forrest'. View the generated
  HTML in a browser to make sure everything works.
- Edit status.xml and src/documentation/skinconf.xml and customize for your
  project.
- Start adding content in xdocs/, remembering to add new files to site.xml
- Provide any feedback to forrest-dev@xml.apache.org

Thanks for using Apache Forrest
-------------------------------
    </echo>
  </target>




  <target name="validate" depends="validation-props, validate-xdocs,
    validate-skinconf, validate-sitemap, validate-skins, validate-skinchoice,
    validate-stylesheets"  description="Validates XML doc files in the project"/>

  <target name="validate-site" depends="validation-props" >
    <xmlvalidate failonerror="${forrest.validate.site.failonerror}" lenient="no" warn="yes">
      <xmlcatalog>
        <catalogpath>
          <pathelement
            location="${forrest.home}/context/resources/schema/catalog.xcat"/>
          <pathelement location="${project.catalog}"/>
        </catalogpath>
      </xmlcatalog>
      <fileset dir="${project.site-dir}"
        includes="${forrest.validate.xdocs.includes}"
        excludes="${forrest.validate.xdocs.excludes}"/>
    </xmlvalidate>
    <echo message="...validated site"/>
  </target>

  <target name="validate-xdocs" depends="validation-props" if="validate.xdocs">
    <xmlvalidate failonerror="${forrest.validate.xdocs.failonerror}" lenient="no" warn="yes">
      <xmlcatalog>
        <catalogpath>
          <pathelement
            location="${forrest.home}/context/resources/schema/catalog.xcat"/>
          <pathelement location="${project.catalog}"/>
        </catalogpath>
      </xmlcatalog>
      <fileset dir="${project.xdocs-dir}"
        includes="${forrest.validate.xdocs.includes}"
        excludes="${forrest.validate.xdocs.excludes}"/>
    </xmlvalidate>
    <echo message="...validated xdocs"/>
  </target>

  <target name="validate-skinconf" depends="validation-props"
    if="validate.skinconf">
    <!--
    <jing compactSyntax="true"
      rngfile="${forrest.home}/context/resources/schema/relaxng/skinconf.rnc">
      <fileset dir="${project.content-dir}"
        includes="${forrest.validate.skinconf.includes}"
        excludes="${forrest.validate.skinconf.excludes}"/>
    </jing>
    <echo message="...validated skinconf"/>
    -->
  </target>

  <target name="validate-sitemap" depends="validation-props"
    if="validate.sitemap">
    <available property="version-specific-sitemap" file="${project.sitemap-dir}/forrest-${version}.xmap" type="file"/>
    <available property="version-specific-sitemap" file="${project.sitemap-dir}/aggregate-${version}.xmap" type="file"/>
    <available property="version-specific-sitemap" file="${project.sitemap-dir}/dtd-${version}.xmap" type="file"/>
    <available property="version-specific-sitemap" file="${project.sitemap-dir}/faq-${version}.xmap" type="file"/>
    <available property="version-specific-sitemap" file="${project.sitemap-dir}/forrest-${version}.xmap" type="file"/>
    <available property="version-specific-sitemap" file="${project.sitemap-dir}/issues-${version}.xmap" type="file"/>
    <available property="version-specific-sitemap" file="${project.sitemap-dir}/linkmap-${version}.xmap" type="file"/>
    <available property="version-specific-sitemap" file="${project.sitemap-dir}/menu-${version}.xmap" type="file"/>
    <available property="version-specific-sitemap" file="${project.sitemap-dir}/profiler-${version}.xmap" type="file"/>
    <available property="version-specific-sitemap" file="${project.sitemap-dir}/raw-${version}.xmap" type="file"/>
    <available property="version-specific-sitemap" file="${project.sitemap-dir}/resources-${version}.xmap" type="file"/>
    <available property="version-specific-sitemap" file="${project.sitemap-dir}/revisions-${version}.xmap" type="file"/>
    <available property="version-specific-sitemap" file="${project.sitemap-dir}/sitemap-${version}.xmap" type="file"/>
    <available property="version-specific-sitemap" file="${project.sitemap-dir}/status-${version}.xmap" type="file"/>

    <jing rngfile="${forrest.home}/context/resources/schema/relaxng/sitemap-v06.rng">
      <fileset dir="${project.content-dir}"
        includes="${forrest.validate.sitemap.includes}"
        excludes="${forrest.validate.sitemap.excludes}">
        <include name="*.xmap" unless="version-specific-sitemap"/>
        <include name="*-${version}.xmap" if="version-specific-sitemap"/>
      </fileset>
    </jing>
    <echo message="...validated sitemap"/>
  </target>

  <target name="validate-stylesheets" depends="validation-props"
    if="validate.stylesheets">
    <jing rngfile="${forrest.home}/context/resources/schema/relaxng/xslt.rng">
      <fileset dir="${project.stylesheets-dir}"
        includes="${forrest.validate.stylesheets.includes}"
        excludes="${forrest.validate.stylesheets.excludes}" />
    </jing>
    <echo message="...validated stylesheets"/>
  </target>

  <target name="validate-skins" depends="validate-skins-stylesheets"/>

  <target name="validate-skins-stylesheets" depends="validation-props"
    if="validate.skins.stylesheets">
    <jing rngfile="${forrest.home}/context/resources/schema/relaxng/xslt.rng">
      <fileset dir="${project.skins-dir}"
        includes="${forrest.validate.skins.stylesheets.includes}"
        excludes="${forrest.validate.skins.stylesheets.excludes}"/>
    </jing>
    <echo message="...validated skin stylesheets"/>
  </target>

  <!-- Check that ${project.skin} points to an existing skin. -->
  <target name="validate-skinchoice">
    <condition property="project.skin.present">
      <available file="${project.skin}" type="dir">
        <filepath path="${project.skins-dir}"/>
        <filepath path="${forrest.home}/context/skins"/>
      </available>
    </condition>

    <fail unless="project.skin.present">
------------------------------------------------
Error: The skin '${project.skin}' could not be found in:

${project.skins-dir}

And is not provided by Forrest in

${forrest.home}/context/skins

Please check the $${project.skins-dir} and $${project.skin} properties in
forrest.properties.
------------------------------------------------
    </fail>
    <echo message="...validated existence of skin '${project.skin}'"/>
  </target>
  
  
<!-- ***************************************************************** -->
<!-- ***************************************************************** -->
<!-- **                                                             ** -->
<!-- **                                                             ** -->
<!-- **              LOCAL SERVER RUN ACTION                        ** -->
<!-- **                                                             ** -->
<!-- **                                                             ** -->
<!-- ***************************************************************** -->
<!-- ***************************************************************** -->


  <target name="run" 
   description="Run Jetty with configuration set by the jetty.run property"
   depends="webapp">

    <java classname="org.mortbay.jetty.Server"
          dir="${project.webapp}"
          fork="yes"
          maxmemory="${forrest.maxmemory}"
          failonerror="yes">
       <classpath>
         <pathelement path="${env.CLASSPATH}" />
         <fileset dir="${forrest.home}/lib/endorsed">
           <include name="*.jar"/>
           <include name="*.JAR"/>
           <include name="*.zip"/>
           <include name="*.ZIP"/>
         </fileset>         
         <fileset dir="${forrest.home}/lib/optional">
           <include name="*.jar"/>
           <include name="*.JAR"/>
           <include name="*.zip"/>
           <include name="*.ZIP"/>
         </fileset>
       </classpath>
       <jvmarg line="${forrest.jvmargs}"/>
       <jvmarg
         value="-Djava.endorsed.dirs=${java.endorsed.dirs}${path.separator}${forrest.home}/lib/endorsed"/>
       <arg line="jettyconf.xml" />
    </java>
  </target>  


<!-- ***************************************************************** -->
<!-- ***************************************************************** -->
<!-- **                                                             ** -->
<!-- **                                                             ** -->
<!-- **              BACKCOPY                                       ** -->
<!-- **                                                             ** -->
<!-- **                                                             ** -->
<!-- ***************************************************************** -->
<!-- ***************************************************************** -->


  <!--
  If you've been editing docs, images etc in build/webapp/*, this target copies
  them back to src/documentation/*.  As 'overwrite' is false, this will not
  clobber docs legitimately edited in src/documentation/*
  -->
  <target name="backcopy" depends="init-props"
    description="If anything has been edited in build/webapps, copies them back to src/documentation">
    <!--
    Copy everything EXCEPT docs that are in the Forrest context directory and
    have been modified.
    This translates to: copy all docs that are not in the Forrest context
    directory, or that are, but are different.
    -->
    <copy toDir="${project.content-dir}" filtering="false" overwrite="false">
      <fileset dir="${project.webapp}" excludes="${forrest.backcopy.excludes}">
        <or>
          <not>
            <present targetdir="${forrest.home}/context"/>
          </not>
          <and>
            <present targetdir="${forrest.home}/context"/>
            <different targetdir="${forrest.home}/context"/>
            <type type="file"/>
          </and>
        </or>
      </fileset>
    </copy>
    <antcall target="overrides"/>
  </target>

  <target name="overrides" depends="init-props"
    description="Prints a summary of which files a project is overriding">
    <fileset dir="${project.content-dir}" id="overridden-files">
      <present targetdir="${forrest.home}/context"/>
      <different targetdir="${forrest.home}/context"/>
    </fileset>
    <fileset dir="${project.content-dir}" id="overridden-files-unmodified">
      <present targetdir="${forrest.home}/context"/>
      <not>
        <different targetdir="${forrest.home}/context"/>
      </not>
    </fileset>
    <property name="overridden" refid="overridden-files"/>
    <property name="overridden-unmodified" refid="overridden-files-unmodified"/>
    <echo>
      +----------------------------+
      | Forrest Overrides report   |
      +----------------------------+

      Overridden, modified   : ${overridden}
      Overridden, unmodified : ${overridden-unmodified}
    </echo>
  </target>
  <target name="clean" depends="init-props">
  <delete dir="${project.build-dir}" />
  </target>

</project>
