<?xml version="1.0"?>
<!--
  Copyright 2002-2004 The Apache Software Foundation or its licensors,
  as applicable.

  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 basedir="." name="plugins">
   <!-- public targets -->     
     
  <target name="available-plugins"
          depends="init-props, plugin-unavailable, fetch-plugins-descriptors"
          description="What plugins are available?">
    <for param="plugin-descriptor-file">
      <path>
        <fileset dir="${project.temp-dir}" includes="plugins-*.xml"/>
      </path>
      <sequential>
        <xslt in="@{plugin-descriptor-file}" 
          out="${project.temp-dir}/pluginlist2echobuild.xml"
          style="${forrest.core}/var/pluginlist2echo.xsl"/>  
    <ant antfile="${project.temp-dir}/pluginlist2echobuild.xml"/>
      </sequential>
    </for>
  </target>   

  <target name="plugin-unavailable">   
    <property name="plugin.unavailable" value="true"/>
  </target>  
  
  <target name="check-plugin">  
    <condition property="plugin.unavailable">
      <and>
        <not>
          <available type="dir" file="${forrest.plugins-dir}/${versioned.name}"/>
        </not>
        <not>
          <available type="file" file="${forrest.plugins-dir}/${versioned.name}.zip"/>
        </not>
      </and>
    </condition>
    <if>
      <isset property="plugin.unavailable"/>
      <then>
        <echo>${versioned.name} is not available in the build dir</echo>
      </then>
      <else>
        <echo>${versioned.name} is available in the build dir</echo>
      </else>
    </if>
  </target>  
            
  <target name="unpack-plugin"
           if="plugin.unavailable"
          depends="init-props">
     <if>
       <available file="${forrest.plugins-dir}/${versioned.name}.zip"/>
       <then>
         <antcall target="extract-plugin">
           <param name="plugin" value="${versioned.name}"/>
         </antcall>
       </then>
       <else>
         <if>
           <available file="${forrest.plugins-dir}/${plugin.name}.zip"/>
           <then>
             <antcall target="extract-plugin">
               <param name="plugin" value="${plugin.name}"/>
             </antcall>
           </then>
           <else>
             <echo>
ERROR
=====
       
Unable to retrieve the ${versioned.name} plugin.
There may be more information about the reason for this in output
above. The usual cause is that Forrest has been unable to download
the plugin descriptor file that indicates where this plugin is to be
downloaded from. If you are behind a firewall then set the proxy.host 
and proxy.port values in the forrest.properties file.

You may also like to check the value of the 
forrest.plugins.descriptors property in the forrest.properties file
and ensure that the locations indicated by that value are accessible
(note there should be no spaces in this property).
             </echo>
             <fail message="Unable to install required plugins. See error messages above for more detail."/>
           </else>
         </if>
       </else>
   </if>
  </target>  
  
  <target name="extract-plugin">
   <unzip dest="${forrest.plugins-dir}/${plugin}">
     <fileset dir="${forrest.plugins-dir}/">
        <include name="${plugin}.zip"/>
      </fileset>
   </unzip>       
   <delete>
      <fileset dir="${forrest.plugins-dir}/">
        <include name="${plugin}.zip"/>
      </fileset>
   </delete>

   <!-- add to the entity catalog -->
   <copy file="${forrest.core}/var/initial_catalog.xcat"
     tofile="${forrest.plugins-dir}/catalog.xcat"
     overwrite="false"/>
   <if>
     <available file="${forrest.plugins-dir}/${plugin}/resources/schema/catalog.xcat"/>
     <then>
       <xslt in="${forrest.plugins-dir}/catalog.xcat"
           out="${forrest.plugins-dir}/catalog.xcat.new"
           style="${forrest.core}/var/catalogMountSnippet.xsl"
           force="true">
         <param name="plugin-catalog-path"
           expression="${forrest.plugins-dir}/${plugin}/resources/schema/catalog.xcat"/>
       </xslt>
       <move file="${forrest.plugins-dir}/catalog.xcat.new" 
         tofile="${forrest.plugins-dir}/catalog.xcat"/>
     </then>
   </if>
  </target>
  
  <target name="configure-plugin" 
    unless="plugin.unavailable">
    <if>
      <available file="${forrest.plugins-dir}/${versioned.name}"/>
      <then>
        <if>
          <available property="input-plugin" file="${forrest.plugins-dir}/${versioned.name}/input.xmap"/>
          <then>
            <antcall target="configure-input-plugin">
              <param name="plugin" value="${versioned.name}"/>
            </antcall>
          </then>
        </if>
        <if>
          <available property="output-plugin" file="${forrest.plugins-dir}/${versioned.name}/output.xmap"/>
          <then>
            <antcall target="configure-output-plugin">
              <param name="plugin" value="${versioned.name}"/>
            </antcall>
          </then>
        </if>
        <if>
          <available property="internal-plugin" file="${forrest.plugins-dir}/${versioned.name}/internal.xmap"/>
          <then>
            <antcall target="configure-internal-plugin">
              <param name="plugin" value="${versioned.name}"/>
            </antcall>
          </then>
        </if>
      </then>
      <else>
        <if>
          <available property="input-plugin" file="${forrest.plugins-dir}/${plugin.name}/input.xmap"/>
          <then>
            <antcall target="configure-input-plugin">
              <param name="plugin" value="${plugin.name}"/>
            </antcall>
          </then>
        </if>
        <if>
          <available property="output-plugin" file="${forrest.plugins-dir}/${plugin.name}/output.xmap"/>
          <then>
            <antcall target="configure-output-plugin">
              <param name="plugin" value="${plugin.name}"/>
            </antcall>
          </then>
        </if>
        <if>
          <available property="internal-plugin" file="${forrest.plugins-dir}/${plugin.name}/internal.xmap"/>
          <then>
            <antcall target="configure-internal-plugin">
              <param name="plugin" value="${plugin.name}"/>
            </antcall>
          </then>
        </if>
      </else>
    </if>
  </target>
  
  <target name="configure-input-plugin">
     <!-- add the snippet to plugins/input.xmap that will mount the plugin
          specific input.xmap -->
     <echo>Mounting input plugin: ${plugin}</echo>
     <xslt in="${project.temp-dir}/input.xmap"
       out="${project.temp-dir}/input.xmap.new"
       style="${forrest.core}/var/pluginMountSnippet.xsl"
       force="true">
           <param name="plugin-name" expression="${plugin}"/>  
           <param name="plugin-type" expression="input"/>  
     </xslt>
     <move file="${project.temp-dir}/input.xmap.new" 
       tofile="${project.temp-dir}/input.xmap"/>
     <xslt in="${project.temp-dir}/resources.xmap"
       out="${project.temp-dir}/resources.xmap.new"
       style="${forrest.core}/var/pluginMountSnippet.xsl"
       force="true">
           <param name="plugin-name" expression="${plugin}"/>  
           <param name="plugin-type" expression="resources"/>  
     </xslt>
     <move file="${project.temp-dir}/resources.xmap.new" 
       tofile="${project.temp-dir}/resources.xmap"/>
  </target>
  
  <target name="configure-output-plugin">
     <!-- add the snippet to plugins/output.xmap that will mount the plugin
          specific input.xmap -->
     <echo>Mounting output plugin: ${plugin}</echo>
     <xslt in="${project.temp-dir}/output.xmap"
       out="${project.temp-dir}/output.xmap.new"
       style="${forrest.core}/var/pluginMountSnippet.xsl"
       force="true">
           <param name="plugin-name" expression="${plugin}"/>  
           <param name="plugin-type" expression="output"/>  
     </xslt>
     <move file="${project.temp-dir}/output.xmap.new" 
       tofile="${project.temp-dir}/output.xmap"/>
  </target>
  
  <target name="configure-internal-plugin">
     <!-- add the snippet to plugins/internal.xmap that will mount the plugin
          specific input.xmap -->
     <echo>Mounting internal plugin: ${plugin}</echo>
     <xslt in="${project.temp-dir}/internal.xmap"
       out="${project.temp-dir}/internal.xmap.new"
       style="${forrest.core}/var/pluginMountSnippet.xsl"
       force="true">
           <param name="plugin-name" expression="${plugin}"/>  
           <param name="plugin-type" expression="internal"/>  
     </xslt>
     <move file="${project.temp-dir}/internal.xmap.new" 
       tofile="${project.temp-dir}/internal.xmap"/>
  </target>

  <target name="fetch-plugins-descriptors" if="plugin.unavailable" depends="init-proxy">
    <delete>
      <fileset dir="${project.temp-dir}" includes="plugins-*.xml"/>
    </delete>
  
    <var name="plugin-counter" value="1"/>
    <for list="${forrest.plugins.descriptors}" param="url">
      <sequential>
        <echo>Fetching plugins descriptor: @{url}</echo>
        <get src="@{url}" 
           dest="${project.temp-dir}/plugins-${plugin-counter}.xml"
           verbose="true" usetimestamp="true" ignoreerrors="true"/>
        <available property="plugin.list-${plugin-counter}.present"
                 file="${project.temp-dir}/plugins-${plugin-counter}.xml"/>
        <math result="plugin-counter" operand1="${plugin-counter}" operation="+" operand2="1" datatype="int"/>
      </sequential>
    </for>
    
    <var name="plugin-counter" value="1"/>
    <for list="${forrest.plugins.descriptors}" param="url">
      <sequential>
        <if>
          <available file="${project.temp-dir}/plugins-${plugin-counter}.xml"/>
          <then>
            <echo>Plugin list loaded from @{url}.</echo>
          </then>
          <else>
            <echo>
            WARNING
            =======
            
            Unable to load plugin list number ${plugin-counter} from @{url}. 
            Any plugins identified in this plugin list cannot be installed 
            automatially, see further errors below.</echo>
          </else>
        </if>
        <math result="plugin-counter" operand1="${plugin-counter}" operation="+" operand2="1" datatype="int"/>
      </sequential>
    </for>
  </target>  
  
  <target name="fetch-plugin" 
          if = "plugin.unavailable"
          depends="init-props, fetch-plugins-descriptors">
    <for param="plugin-descriptor-file">
      <path>
        <fileset dir="${project.temp-dir}" includes="plugins-*.xml"/>
      </path>
      <sequential>
        <xslt in="@{plugin-descriptor-file}" 
          out="${project.temp-dir}/pluginlist2fetchbuild.xml"
          style="${forrest.core}/var/pluginlist2fetch.xsl"
          force="true">
          <param name="plugin-name" expression="${plugin.name}"/>  
          <param name="plugin-version" expression="${plugin.version}"/>  
          <param name="plugin-dir" expression="${forrest.plugins-dir}/"/>      
          <param name="forrest-version" expression="${forrest.version}"/>   
       </xslt>  
       <ant antfile="${project.temp-dir}/pluginlist2fetchbuild.xml"/> 
      </sequential>
    </for>
  </target>    
  
  <target name="install-plugin" depends="check-plugin, fetch-plugin, unpack-plugin"/>
  
  <target name="init-plugins" depends="init-props"
    description="Ensure the required plugins are available locally, if any are not, download them automatically">
    
    <mkdir dir="${forrest.plugins-dir}"/>
    <mkdir dir="${project.temp-dir}"/>
    <copy file="${forrest.core}/var/initial_plugins_sitemap.xmap"
      tofile="${project.temp-dir}/input.xmap"
      overwrite="true"/>
    <copy file="${forrest.core}/var/initial_plugins_sitemap.xmap"
      tofile="${project.temp-dir}/resources.xmap"
      overwrite="true"/>
    <copy file="${forrest.core}/var/initial_plugins_sitemap.xmap"
      tofile="${project.temp-dir}/output.xmap"
      overwrite="true"/>
    <copy file="${forrest.core}/var/initial_plugins_sitemap.xmap"
      tofile="${project.temp-dir}/internal.xmap"
      overwrite="true"/>

      <for list="${project.required.plugins}" param="name">
      <sequential>
        <echo>Installing plugin: @{name}</echo>
        <propertyregex property="plugin.name"
              override="true"
              input="@{name}"
              regexp="(.*)-(.*)"
              select="\1"
              casesensitive="false" 
              defaultvalue="@{name}"/>
        <propertyregex property="plugin.version"
              override="true"
              input="@{name}"
              regexp="(.*)-(.*)"
              select="\2"
              casesensitive="false"
              defaultvalue=""/>
        <antcall target="install-plugin">
          <param name="plugin.name" value="${plugin.name}"/>
          <param name="plugin.version" value="${plugin.version}"/>
          <param name="versioned.name" value="@{name}"/>
        </antcall>
        <antcall target="configure-plugin">
          <param name="plugin.name" value="${plugin.name}"/>
          <param name="plugin.version" value="${plugin.version}"/>
          <param name="versioned.name" value="@{name}"/>
        </antcall>
      </sequential>
    </for>
  </target>
  
</project>
