ilscipio/scipio-erp

View on GitHub
build.xml

Summary

Maintainability
Test Coverage
<?xml version="1.0" encoding="UTF-8"?>
<!--
This file is subject to the terms and conditions defined in the
files 'LICENSE' and 'NOTICE', which are part of this source
code package.
-->
<project name="Scipio Main Build" default="build" basedir="."
    xmlns:ivy="antlib:org.apache.ivy.ant"
    xmlns:sonar="antlib:org.sonar.ant:sonar"
    xmlns:if="ant:if"
    xmlns:unless="ant:unless">
    
    <!-- 
        SCIPIO MAIN BUILD
        
        NOTES:
        * macros.xml (legacy name) contains all early defs (including ofbiz.homedir), 
          defined for both main build invocations and component build subfolder ant invocations
        * Main build properties that must be passed to iterated sub-builds must be declared in:
            ofbiz.subbuild.props.pass
          otherwise the defaults from macros.xml or common.xml will be used instead (if any)
        * The framework/base/lib libraries are not automatically on the classpath; this is now (2017-02-02)
          enforced; needed libs must be specified explicitly (<taskdef>), including for the <junit/> task.
    -->

    <!-- Local build properties file, ignored by version control - local developer/user settings -->
    <property file="build.scp.local.properties"/><!-- standard filename -->
    <property file="build.local.properties"/><!-- legacy filename -->

    <!-- Default properties for your project - shared between developers/users -->
    <property file="build.properties"/>

    <!-- Contains reusable definitions to all builds and default compilation settings -->
    <import file="macros.xml"/>

    <!-- ================================================================== -->
    <!-- SCIPIO: early-inclusion, new, original properties and tasks        -->
    <!-- ================================================================== -->
    <!-- NOTE: Properties may also be defined in macros.xml (e.g. for standalone component task support) -->

    <!-- IVY BYPASS: set this to true (or pass -Dlib.update.bypass=true) to prevent 
        automatic lib update check upon build and other target invocations
        2017-02-03: Ivy now enabled by default (bypass false) -->
    <property name="lib.update.bypass" value="false"/>
    <!-- IVY AUTO MODE: set this to either "global" (runs all lib updates globally, before global build) 
        or "component" (runs per-component, before each component) -->
    <property name="lib.update.hook.mode" value="component"/>
    
    <property name="framework.dir" value="framework"/>
    <property name="applications.dir" value="applications"/>
    <property name="specialpurpose.dir" value="specialpurpose"/>
    <property name="themes.dir" value="themes"/>
    <property name="addons.dir" value="addons"/>
    <property name="hotdeploy.dir" value="hot-deploy"/>
    
    <!-- Top-level component directories, in their generally-expect build and load order 
        NOTE: 2017-01-31: build order is for now rectified to framework->themes->... in order for the build order
            to be consistent with the component load order (as defined in stock ofbiz) -->
    <property name="ofbiz.component.dirs" value="framework,themes,applications,specialpurpose,addons,hot-deploy"/>
    
    <property file="${framework.dir}/base/config/scipiometainfo.properties" />
    
    <!-- 2017-02-01: Names of properties (such as those defined above) that should always be passed 
        to sub-project builds by subant. mainly used by externalsubant and iterate in macros.xml -->
    <propertyset id="ofbiz.subbuild.props.pass">
        <propertyref name="ofbiz.home.dir"/>
        <propertyref name="ofbiz.component.dirs"/>
        <propertyref regex="scipio\.build\..*"/>
        <propertyref regex="lib\.update\..*"/>
        <propertyref regex="lib\.clean\..*"/>
        <propertyref regex="lib\.entity\..*"/><!-- FIXME?: unfortunate exception... should have been lib.scpcfg.entity... too late -->
        <propertyref regex="lib\.scpcfg\..*"/><!-- for custom lib properties for components; should be named: lib.scpcfg.[componentname].* -->
        <propertyref regex="comp.scpcfg\..*"/><!-- for component-specific config properties; should be named: comp.scpcfg.[componentname].* -->
        <propertyref regex="scpcfg\..*"/>
        <propertyref name="ivy.settings.file"/>
        <propertyref name="checkreqs.ran"/>
    </propertyset>

    <!-- Random seed, workaround for lockups on some systems -->
    <property name="scipio.exec.os.linux.randseed" value="file:///dev/./urandom"/>

    <!-- Dynamic early main build.xml additions. Allows any component or addon to include
        a file named "build-main-early.xml" in its folder, which will be imported into
        the main build, supporting plugin-like additions to root build.xml.
        NOTE: ant does not support overriding existing tasks this way, but new tasks may be added. -->
    <fileset id="framework.earlymainbuilds" dir="${framework.dir}">
        <exclude name="disabled/**"/>
        <include name="*/build-main-early.xml" />
    </fileset>
    <fileset id="applications.earlymainbuilds" dir="${applications.dir}">
        <exclude name="disabled/**"/>
        <include name="*/build-main-early.xml" />
    </fileset>
    <fileset id="specialpurpose.earlymainbuilds" dir="${specialpurpose.dir}">
        <exclude name="disabled/**"/>
        <include name="*/build-main-early.xml" />
    </fileset>
    <fileset id="addons.earlymainbuilds" dir="${addons.dir}">
        <exclude name="disabled/**"/>
        <include name="*/build-main-early.xml" />
    </fileset>
    <fileset id="hotdeploy.earlymainbuilds" dir="${hotdeploy.dir}">
        <exclude name="disabled/**"/>
        <include name="*/build-main-early.xml" />
    </fileset>
    <import optional="true">
        <fileset file="tools/misc/build-dummy.xml" /><!-- at least one import required -->
        <fileset refid="framework.earlymainbuilds" />
    </import>
    <import optional="true">
        <fileset file="tools/misc/build-dummy.xml" /><!-- at least one import required -->
        <fileset refid="applications.earlymainbuilds" />
    </import>
    <import optional="true">
        <fileset file="tools/misc/build-dummy.xml" /><!-- at least one import required -->
        <fileset refid="specialpurpose.earlymainbuilds" />
    </import>
    <import optional="true">
        <fileset file="tools/misc/build-dummy.xml" /><!-- at least one import required -->
        <fileset refid="addons.earlymainbuilds" />
    </import>
    <import optional="true">
        <fileset file="tools/misc/build-dummy.xml" /><!-- at least one import required -->
        <fileset refid="hotdeploy.earlymainbuilds" />
    </import>
    
    <!-- ================================================================== -->
    <!-- SCIPIO: original (and modified) ofbiz properties                   -->
    <!-- ================================================================== -->
    
    <property name="site.dir" value="../site"/>
    <property name="memory.initial.param" value="-Xms128M"/>
    <property name="memory.max.param" value="-Xmx3512M"/>
    
    <!-- SCIPIO: New properties -->
    
    <!-- Solr properties -->
    <property name="solr.home" value="applications/solr"/>
    <property name="solr.log.dir" value="runtime/logs/solr"/><!-- added 2017-09-08 -->
    <!-- Solr instance locking - see solrconfig.xml for details -->
    <!-- 2017-09-12: FIXME?: Ideally we should use "native", but issues have been encountered with write.lock;
        as workaround, use file-less "single" instance lock - there should no issues because running
        two ofbiz instances always fails before webapps load, due to ports-in-use. -->
    <!--<property name="solr.lock.type" value="native"/>-->
    <property name="solr.lock.type" value="single"/>
    <!-- Passing -Dscipio.solr.reindex.startup.force=true or uncommenting forces rebuildSolrIndex(Auto) on startup; 
        see also "[set|start|...]-reindex-solr" helper tasks. -->
    <!--<property name="scipio.solr.reindex.startup.force" value="true"/>-->
    <!-- Backward-compat for old property name -->
    <!-- If set to "true", prevents editing Solr config through Solr webapp's config API -->
    <property name="solr.disable.configEdit" value=""/><!-- added 2017-10-12 -->
    
    <import file="framework/build.xml" optional="false"/>
    <available file="applications/build.xml" property="applications.present"/>
    <import file="applications/build.xml" optional="true"/>
    <available file="specialpurpose/build.xml" property="specialpurpose.present"/>
    <import file="specialpurpose/build.xml" optional="true"/>

    <!-- ================================================================== -->
    <!-- Initialization of all property settings                            -->
    <!-- ================================================================== -->

    <target name="ofbiz-init" depends="dir-init,ivy-init">
        <property environment="env"/>
    </target>

    <target name="dir-init">
        <mkdir dir="runtime"/>
        <mkdir dir="runtime/output"/>
        <mkdir dir="runtime/logs"/>
        <mkdir dir="runtime/logs/test-results"/>
        <mkdir dir="runtime/logs/solr"/><!-- SCIPIO: for solr.log.dir, added 2017-09-08 -->
        <mkdir dir="runtime/data"/>
        <mkdir dir="runtime/data/derby"/>

        <condition property="isMac">
            <os family="mac"/>
        </condition>
        <antcall target="copy-derby-props" inheritall="true"/>
    </target>

    <target name="copy-derby-props" if="isMac">
        <copy file="runtime/data/derby.properties" todir="runtime/data/derby"/>
    </target>
    
    <target name="sonar-init" depends="ivy-init">
        <path id="sonar-ant-tasks.class.path">
          <fileset dir="${ofbiz.home.dir}/framework/base/lib/ant-opt/sonar-ant-task" includes="*.jar"/>
        </path>
        <taskdef uri="antlib:org.sonar.ant:sonar" resource="org/sonar/ant/antlib.xml" classpathref="sonar-ant-tasks.class.path"/>
    </target>

    <!-- SCIPIO: solr flagging -->
    <target name="set-reindex-solr">
        <property name="scipio.solr.reindex.startup.force" value="true"/>
    </target>
    <target name="set-no-reindex-solr">
        <property name="scipio.solr.reindex.startup.force" value="false"/>
    </target>
    <target name="set-bypass-crashed-reindex-solr">
        <!-- NOTE: Escape dollar sign because interpreted by ant -->
        <property name="scipio.job.crashed.ignore.filter" value="&#36;{job.serviceName=='rebuildSolrIndex'}"/>
    </target>

    <!-- ================================================================== -->
    <!-- Removes all created files and directories                          -->
    <!-- ================================================================== -->

    <target name="refresh"
          description="Clean all and rebuild">
        <antcall target="clean-all"/>
        <antcall target="build"/>
    </target>

    <target name="clean-all"
          description="Clean DB (Derby), Catalina and caches data, logs, and runtime subdirectories and all specific files like .rej, .orig (NOTE: does NOT clear external DBs: postgres/mysql/etc.)">

        <!-- SCIPIO: hooks -->
        <invokehook target="pre-clean-all" />
        
        <antcall target="clean-ivy"/>
        <if><!-- SCIPIO: NOTE: 2017-04-11: we'll now clear out the deploy folders here by default, because the clean-downloads
                call below which we just removed was already doing this, and it doesn't look like it was causing issues for anyone
            <equals arg1="${lib.clean.deployed}" arg2="true"/>-->
            <not><equals arg1="${lib.clean.deployed}" arg2="false"/></not>
            <then>
                <antcall target="lib-clean-deployed" inheritrefs="true"/>
            </then>
        </if>
        <antcall target="clean-data"/>
        <antcall target="clean-logs"/>
        <antcall target="clean-output"/>
        <antcall target="clean-xtra"/>
        <antcall target="clean-catalina"/>
        <antcall target="clean-cache"/>
        <antcall target="clean-tempfiles"/>
        <antcall target="clean-search-indexes"/>
        <!-- SCIPIO: 2017-04-11: do NOT run clean-downloads on clean-all - you must run 
            clean-downloads explicitly to remove those - and they are currently do not represent
            all supported JDBC drivers but only the legacy ofbiz download targets (TODO: clarify the legacy download targets)
        <antcall target="clean-downloads"/>-->
        <antcall target="clean-uploads"/>
        <antcall target="clean-analysis"/><!-- SCIPIO: 2018-04-24: new -->
        <antcall target="clean"/>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="post-clean-all" />
        
    </target>

    <target name="clean-downloads"
          description="Clean all downloaded files (NOTE: to avoid removing JDBC drivers, use lib-clean instead)">
        
        <!-- SCIPIO: hooks -->
        <invokehook target="pre-clean-downloads" />
        
        <delete verbose="true" deleteonexit="true">
            <fileset dir="framework/base/lib/ant-opt" includes="**/*.jar"/>
            <!-- SCIPIO: 2017-04-11: for this to be consistent we have to remove all except derby
            <fileset dir="framework/entity/lib/jdbc" includes="postgresql-*.jar"/>
            <fileset dir="framework/entity/lib/jdbc" includes="mysql-*.jar"/>-->
            <fileset dir="framework/entity/lib/jdbc" includes="*.jar" excludes="derby-*.jar"/>
        </delete>
        <antcall target="clean-ivy"/>
        <if><!-- SCIPIO: NOTE: 2017-02-03: new -->
            <not><equals arg1="${lib.clean.deployed}" arg2="false"/></not>
            <then>
                <antcall target="lib-clean-deployed" inheritrefs="true"/>
            </then>
        </if>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="post-clean-downloads" />
        
    </target>
    <target name="clean-data"
          description="Clean DB (Derby) data under runtime/data (NOTE: does NOT clear external DBs: postgres/mysql/etc.)">
        
        <!-- SCIPIO: hooks -->
        <invokehook target="pre-clean-data" />
        
        <delete verbose="on" includeemptydirs="true">
            <fileset dir="runtime/data" includes="**/*">
                <exclude name="README"/>
                <exclude name="derby.properties"/>
            </fileset>
        </delete>
        <delete file="runtime/data.zip"/>
        <delete file="runtime/test-list-build.xml"/>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="post-clean-data" />
        
    </target>

    <target name="clean-logs"
          description="Clean all logs in runtime/logs">
        
        <!-- SCIPIO: hooks -->
        <invokehook target="pre-clean-logs" />
        
        <delete verbose="on" includeemptydirs="true">
            <fileset dir="runtime/logs" includes="**/*">
                <exclude name="README"/>
            </fileset>
        </delete>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="post-clean-logs" />
        
    </target>

    <target name="clean-output"
          description="Clean runtime/output directory">
        
        <!-- SCIPIO: hooks -->
        <invokehook target="pre-clean-output" />
        
        <delete verbose="on" includeemptydirs="true">
            <fileset dir="runtime/output" includes="**/*">
                <exclude name="README"/>
            </fileset>
        </delete>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="post-clean-output" />
        
    </target>

    <target name="clean-xtra"
          description="Clean all other files like .rej, .orig, etc.">
        
        <!-- SCIPIO: hooks -->
        <invokehook target="pre-clean-xtra" />
        
        <delete verbose="on">
            <fileset dir="." includes="**/.nbattrs,**/*~,**/.#*,**/.DS_Store,**/*.rej,**/*.orig"/>
        </delete>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="post-clean-xtra" />
        
    </target>

    <target name="clean-catalina"
          description="Clean Catalina data in runtime/catalina/work">
        
        <!-- SCIPIO: hooks -->
        <invokehook target="pre-clean-catalina" />
        
        <delete dir="runtime/catalina/work"/>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="post-clean-catalina" />
        
    </target>

    <target name="clean-cache"
           description="Clean the UtilCache file if errors found with old objects in the cache (Java runtime error something like 'local class incompatible')">

        <!-- SCIPIO: hooks -->
        <invokehook target="pre-clean-cache" />
       
        <property file="framework/base/config/cache.properties"/>
        <echo message="NOTICE: deleting ${cache.file.store}.db"/>
        <delete file="${cache.file.store}.db" verbose="true"/>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="post-clean-cache" />
        
    </target>

    <target name="clean-tempfiles"
          description="Remove files located in runtime/tempfiles (captcha, etc...)">
        
        <!-- SCIPIO: hooks -->
        <invokehook target="pre-clean-tempfiles" />
        
        <delete includeemptydirs="true">
            <fileset dir="./runtime/tempfiles" includes="**/*">
                <exclude name="README"/>
            </fileset>
        </delete>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="post-clean-tempfiles" />
            
    </target>

    <target name="clean-search-indexes"
        description="Remove (Solr) search indexes/data created under runtime/indexes and anywhere else">
        
        <!-- SCIPIO: hooks -->
        <invokehook target="pre-clean-search-indexes" />
        
        <delete includeemptydirs="true">
            <fileset dir="./runtime/indexes" includes="**/*" erroronmissingdir="false" >
                <exclude name="README"/>
            </fileset>
        </delete>
        
        <!-- SCIPIO: the Solr data is now actually stored under applications/solr -->
        <externalsubant target="clean-local-solr-indexes">
            <fileset dir="${basedir}/applications/solr">
                <include name="build.xml" />
            </fileset>
        </externalsubant>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="post-clean-search-indexes" />
        
    </target>
    
    <target name="clean-uploads"
        description="Remove uploaded files">
        
        <!-- SCIPIO: hooks -->
        <invokehook target="pre-clean-uploads" />
        
        <delete includeemptydirs="true">
            <fileset dir="./runtime/uploads" includes="**/*" erroronmissingdir="false" />
        </delete>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="post-clean-uploads" />
        
    </target>
    
    <target name="clean-analysis" description="Remove code analysis results (Scipio)">
        
        <!-- SCIPIO: hooks -->
        <invokehook target="pre-clean-analysis" />
        
        <delete includeemptydirs="true">
            <fileset dir="./runtime/analysis" includes="**/*" erroronmissingdir="false" />
        </delete>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="post-clean-analysis" />
        
    </target>
    
    <target name="tests" depends="ofbiz-init">
        
        <!-- SCIPIO: hooks -->
        <invokehook target="pre-tests" />
        
        <iterate target="tests" filelist="test-builds"/>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="post-tests" />
        
    </target>

    <target name="clean" depends="ivy-init,check-build-requisites,build-scipio-build-tools">
        
        <!-- SCIPIO: hooks -->
        <invokehook target="pre-clean" />
        
        <hotdeployant target="clean"/>
        
        <!-- SCIPIO: addons dir -->
        <addonsant target="clean"/>
        
        <antcall target="clean-specialpurpose"/>
        <antcall target="clean-applications"/>
        
        <!-- SCIPIO: 2017-01-19: added clean task for themes (not invoked stock ofbiz); 2017-01-31: rectified build order -->
        <dep-subant dir="${basedir}/themes" target="clean"/>
        
        <antcall target="clean-framework"/>
        <delete file="ofbiz.jar"/>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="post-clean" />
        
        <echo message="[clean] ========== Done Cleaning =========="/>
    </target>

    <target name="clean-framework">
        <iterate target="clean" filelist="framework-builds"/>
    </target>
    <target name="clean-applications" if="${applications.present}">
        <iterate target="clean" filelist="application-builds"/>
    </target>
    <target name="clean-specialpurpose" if="${specialpurpose.present}">
        <iterate target="clean" filelist="specialpurpose-builds"/>
    </target>

    <target name="svninfo"
        description="Update the Release-revision info in the footer. Note that you need a valid Internet connection and Subversion connected to the Scipio repository for that ">
        <echo message="Creating svninfo..."/>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="pre-svninfo" />
        
        <exec executable="svn" dir="." output="runtime/svninfo_tmp.xml">
            <arg value="info"/>
            <arg value="--xml"/>
        </exec>
        <xmlproperty file="runtime/svninfo_tmp.xml"/>
        <echo message="Rev:${info.entry.commit(revision)}"/>
        <basename property="releasePath" file="${info.entry.url}"/>
        <tstamp>
            <format property="dateTime" pattern="yyyy-MM-dd HH:mm:ss"/>
        </tstamp>
        <echo message=" - Release-revision : ${releasePath}-r${info.entry.commit(revision)},  ${uiLabelMap.CommonBuiltOn} ${dateTime}" file="runtime/svninfo.ftl"/>
        <delete file="runtime/svninfo_tmp.xml"/>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="post-svninfo" />
        
        <echo message="Done!"/>
    </target>

    <target name="clean-svninfo">
        <echo message="Resetting svninfo..."/>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="pre-clean-svninfo" />
        
        <echo message=" " file="runtime/svninfo.ftl"/>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="post-clean-svninfo" />
        
        <echo message="Done!"/>
    </target>
    
    <target name="gitinfo"
        description="Update the Git Branch-revision info in the footer.">
        <echo message="Creating gitinfo..."/>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="pre-gitinfo" />
        
        <exec executable="git" outputproperty="branch">
            <arg value="rev-parse"/>
            <arg value="--abbrev-ref"/>
            <arg value="HEAD"/>
        </exec>
        <exec executable="git" outputproperty="revision">
            <arg value="rev-parse"/>
            <arg value="HEAD"/>
        </exec>
        <tstamp>
            <format property="dateTime" pattern="yyyy-MM-dd HH:mm:ss"/>
        </tstamp>
        <echo message="Found Branch-revision: ${branch}-${revision}"/>
        <echo message=" - Branch-revision: ${branch}-${revision}, ${uiLabelMap.CommonBuiltOn} ${dateTime}" file="runtime/gitinfo.ftl"/>

        <!-- SCIPIO: hooks -->
        <invokehook target="post-gitinfo" />
        
        <echo message="Done!"/>
    </target>

    <target name="clean-gitinfo">
        <echo message="Resetting gitinfo..."/>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="pre-clean-gitinfo" />
        
        <echo message=" " file="runtime/gitinfo.ftl"/>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="post-clean-gitinfo" />
        
        <echo message="Done!"/>
    </target>

    <!-- ================================================================== -->
    <!-- Apply patches where needed                                         -->
    <!-- ================================================================== -->

    <target name="build-dev"
      description="Patch sources in a dev environment if patch files are present in runtime/patches.">
        
      <!-- SCIPIO: hooks -->
      <invokehook target="pre-build-dev" />
        
      <!-- Ant patch task can't handle a fileset => create a global patch -->
      <concat destfile="${basedir}/runtime/patches/dev.patch" encoding="UTF-8" outputencoding="UTF-8">
        <fileset dir="${basedir}/runtime/patches" casesensitive="no">
          <exclude name="dev.patch"/> <!-- exclude the patch itself in case it's still there -->
          <include name="*.patch"/>
        </fileset>
      </concat>
      <if>
        <available file="${basedir}/runtime/patches/dev.patch"/>
        <then>
            <antcall target="patch">
                <param name="dir-name" value="${basedir}"/>
                <param name="diff-file" value="${basedir}/runtime/patches/dev.patch"/>
            </antcall>
            <delete file="${basedir}/runtime/patches/dev.patch"/>
        </then>
      </if>
        
      <!-- SCIPIO: hooks -->
      <invokehook target="post-build-dev" />
        
    </target>
    
    <!-- Following allow to use "svn patch" and fallback on "patch" if necessary -->
    <target name="calculate-svn-patch-available">
        <mkdir dir="build/svn-check"/>
        <exec dir="build/svn-check" output="build/svn-check/svn.output" executable="svn" failonerror="true">
            <arg value="--version" />
        </exec>
        <loadfile property="svn-output" srcFile="build/svn-check/svn.output"/>
        <condition property="svn-version-ok">
        <!-- On Linux prefer patch because "svn patch" needs "ant exec and you can't check patching errors -->
          <and>
            <os family="windows"/>
            <or>
                <!-- This might also depend on the format of the working copy -->
                <contains string="${svn-output}" substring="1.7."/>
                <contains string="${svn-output}" substring="1.8."/>
                <contains string="${svn-output}" substring="1.9."/>
                <contains string="${svn-output}" substring="1.10."/>
                <contains string="${svn-output}" substring="1.11."/>
            </or>
          </and>
        </condition>
        <delete dir="build/svn-check"/>
    </target>
    
    <target name="calculate-patch-available" depends="calculate-svn-patch-available" unless="svn-version-ok">
        <condition property="patch-ok">
            <os family="unix"/>
        </condition>
    </target>
    
    <target name="check-svn-patch-available" depends="calculate-svn-patch-available" unless="svn-version-ok">
        <echo message="You need svn version 1.7 or higher - attempting patch instead."/>
    </target>
    
    <target name="check-patch-available" depends="calculate-patch-available" unless="patch-ok"/>
    
    <target name="patch-via-svn" depends="check-svn-patch-available" if="svn-version-ok">
        <exec dir="${basedir}" executable="svn" failonerror="true">
            <arg value="patch" />
            <arg value="${diff-file}" />
            <arg value="${dir-name}" />
        </exec>
    </target>
    
    <target name="patch-via-patch" depends="check-patch-available" if="patch-ok">
        <exec dir="${basedir}" executable="patch" input="${diff-file}" failonerror="true">
            <arg value="--binary" /><!-- To prevent EOL issues which comes when using mixed development platforms (ie Unix and Win) -->
            <arg value="-p0" />
        </exec>
    </target>
    
    <target name="patch" depends="patch-via-svn,patch-via-patch"/>

    <target name="revert-dev"
      description="Revert patch files present in runtime/patches applied by build-dev.">
        
      <!-- SCIPIO: hooks -->
      <invokehook target="pre-revert-dev" />
        
      <!-- Ant patch task can't handle a fileset => create a global patch -->
      <concat destfile="${basedir}/runtime/patches/dev.patch" encoding="UTF-8" outputencoding="UTF-8">
        <fileset dir="${basedir}/runtime/patches" casesensitive="no">
          <exclude name="dev.patch"/> <!-- exclude the patch itself in case it's still there -->
          <include name="*.patch"/>
        </fileset>
      </concat>
      <if>
        <available file="${basedir}/runtime/patches/dev.patch"/>
        <then>
            <antcall target="revert-patch">
                <param name="dir-name" value="${basedir}"/>
                <param name="diff-file" value="${basedir}/runtime/patches/dev.patch"/>
            </antcall>
            <delete file="${basedir}/runtime/patches/dev.patch"/>
        </then>
      </if>
        
      <!-- SCIPIO: hooks -->
      <invokehook target="post-revert-dev" />
        
    </target>

    <target name="revert-via-svn" depends="check-svn-patch-available" if="svn-version-ok">
        <exec dir="${basedir}" executable="svn" failonerror="true">
            <arg value="patch" />
            <arg value="${diff-file}" />
            <arg value="${dir-name}" />
            <arg value="--reverse-diff" />
        </exec>
    </target>
    
    <target name="revert-via-patch" depends="check-patch-available" if="patch-ok">
        <exec dir="${basedir}" executable="patch" input="${diff-file}" failonerror="true">
            <arg value="--binary" /><!-- To prevent EOL issues which comes when using mixed development platforms (ie Unix and Win) -->
            <arg value="-p0" />
            <arg value="-R" />
        </exec>
    </target>
    
    <target name="revert-patch" depends="revert-via-svn,revert-via-patch"/>

    <target name="build-test"
        description="Patch and build all sources for use in a test environment. On Windows you need to have patch.exe in the path and patch files must all be in dos format (CR+LF)">

        <!-- SCIPIO: hooks -->
        <invokehook target="pre-build-test" />
        
        <subant inheritall="false" target="prepare-to-build-test" failonerror="true">
            <propertyset refid="ofbiz.subbuild.props.pass"/><!-- SCIPIO: new 2017-02-01 -->
            <fileset dir="${basedir}/hot-deploy" casesensitive="no">
                <exclude name="disabled/**"/>
                <include name="*/build.xml"/>
            </fileset>
        </subant>
        <!--antcall target="build"/--><!-- you can chain if you don't use build-dev  see MVP-256-->
        
        <!-- SCIPIO: hooks -->
        <invokehook target="post-build-test" />
        
    </target>
    
    <target name="build-qa"
        description="Patch and build all sources for use in a qa environment. On Windows you need to have patch.exe in the path and patch files must all be in dos format (CR+LF)">

        <!-- SCIPIO: hooks -->
        <invokehook target="pre-build-qa" />
            
        <subant inheritall="false" target="prepare-to-build-qa" failonerror="true">
            <propertyset refid="ofbiz.subbuild.props.pass"/><!-- SCIPIO: new 2017-02-01 -->
            <fileset dir="${basedir}/hot-deploy" casesensitive="no">
                <exclude name="disabled/**"/>
                <include name="*/build.xml"/>
            </fileset>
        </subant>
      <!--antcall target="build"/--><!-- you can chain if you don't use build-dev  see MVP-256-->

        <!-- SCIPIO: hooks -->
        <invokehook target="post-build-qa" />
        
    </target>

    <target name="build-production"
        description="Patch and build all sources for use in a live environment. On Windows you need to have patch.exe in the path and patch files must all be in dos format (CR+LF)">

        <!-- SCIPIO: hooks -->
        <invokehook target="pre-build-production" />
        
        <subant inheritall="false" target="prepare-to-build-production" failonerror="true">
            <propertyset refid="ofbiz.subbuild.props.pass"/><!-- SCIPIO: new 2017-02-01 -->
            <fileset dir="${basedir}/hot-deploy" casesensitive="no">
                <exclude name="disabled/**"/>
                <include name="*/build.xml"/>
            </fileset>
        </subant>
      <!--antcall target="build"/--><!-- you can chain if you don't use build-dev  see MVP-256-->
        
        <!-- SCIPIO: hooks -->
        <invokehook target="post-build-production" />
        
    </target>
    
    <!-- SCIPIO: new 2018-03-23 -->
    <target name="build-withlibsrc" description="build plus download ivy lib JAR sources (implied -Dlib.update.sources=true)">
        <property name="build.lib.update.sources" value="true"/>
        <antcall target="build"/>
    </target>
    
    <!-- ================================================================== -->
    <!-- Build Components                                                   -->
    <!-- ================================================================== -->
    
    <target name="build" depends="ofbiz-init,check-build-requisites,build-scipio-build-tools,check-lib-update">
        <!-- SCIPIO: 2018-11-14: Can bypass actual build using flag: -Dscipio.target.build=false 
            FIXME?: using big if here is ugly -->
        <if>
            <equals arg1="${scipio.target.build}" arg2="false"/>
            <then>
                <echo message="[build] (bypassed)"/>
            </then>
            <else>
                <echo message="[build] ========== Start Building (Compile) =========="/>
                
                <!-- SCIPIO: special property to only target build command with lib.update.sources -->
                <property name="lib.update.sources" value="${build.lib.update.sources}" if:set="build.lib.update.sources"/>
                
                <!-- SCIPIO: hooks -->
                <invokehook target="pre-build" />
                
                <antcall target="build-dev"/>

                <!-- SCIPIO: hooks -->
                <invokehook target="pre-build-framework" />
    
                <antcall target="build-framework"/>

                <!-- SCIPIO: hooks -->
                <invokehook target="post-build-framework" />
                
                <!-- SCIPIO: 2017-01-17: support dependency resolution for themes as well
                <externalsubant>
                    <fileset dir="${basedir}/themes">
                        <include name="*/build.xml" />
                    </fileset>
                </externalsubant>-->
                <!-- SCIPIO: 2017-01-31: rectified build order, framework->themes->..., to match component load order -->
                <dep-subant dir="${basedir}/themes"/>
    
                <antcall target="build-applications"/>
                <antcall target="build-specialpurpose"/>
                
                <!-- SCIPIO: addons dir -->
                <addonsant/>
                
                <hotdeployant/>
                <antcall target="clean-svninfo"/>
                <antcall target="clean-gitinfo"/>
    
                <!-- SCIPIO: hooks -->
                <invokehook target="post-build" />
                
                <echo message="[build] ========== Done Building (Compile) =========="/>
            </else>
        </if>
    </target>

    <target name="build-framework">
        <iterate target="jar" filelist="framework-builds"/>
    </target>

    <target name="build-applications" if="${applications.present}">
        <iterate target="jar" filelist="application-builds"/>
    </target>

    <target name="build-specialpurpose" if="${specialpurpose.present}">
        <iterate target="jar" filelist="specialpurpose-builds"/>
    </target>

    <macrodef name="hotdeployant">
      <attribute name="target" default=""/>
      <sequential>
        <!-- a check is done, if no build.xml file is present in hot-deploy dir,
            then the build.xml files - if present - in hot-deploy sub-dirs will be used.
            So the previous, simpler, behaviour is kept as long as you don't need
            to build hot-deploy components in a specific order. -->
        <if>
          <available file="hot-deploy/build.xml" property="useHotDeployBuild"/>
          <then>
            <externalsubant target="@{target}">
              <filelist dir="." files="hot-deploy/build.xml"/>
            </externalsubant>
          </then>
          <else>
            <dep-subant dir="${basedir}/hot-deploy" target="@{target}" />
          </else>
        </if>
      </sequential>
    </macrodef>
    
    <!-- ================================================================== -->
    <!-- Build JavaDocs                                                     -->
    <!-- ================================================================== -->

    <target name="docs" depends="ofbiz-init,check-build-requisites">
        <echo message="[docs] ========== Start Building (JavaDoc) =========="/>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="pre-docs" />
        
        <antcall target="docs-framework"/>
        <antcall target="docs-applications"/>
        <antcall target="docs-specialpurpose"/>
        
        <!-- SCIPIO: addons dir -->
        <addonsant target="docs"/>
        
        <hotdeployant target="docs"/>
        
        <!-- SCIPIO: hooks -->
        <invokehook target="post-docs" />
        
        <echo message="[docs] ========== Done Building (JavaDocs) =========="/>
    </target>

    <target name="docs-framework">
        <iterate target="docs" filelist="framework-builds"/>
    </target>

    <target name="docs-applications" if="${applications.present}">
        <iterate target="docs" filelist="application-builds"/>
    </target>

    <target name="docs-specialpurpose" if="${specialpurpose.present}">
        <iterate target="docs" filelist="specialpurpose-builds"/>
    </target>

    <target name="docs-all" depends="build,ofbiz-init"
            description="For committers : Build all javadoc into one tree for easier viewing by the community">

        <echo message="[docs-all] ========== Start Building (JavaDoc) =========="/>

        <!-- SCIPIO: hooks -->
        <invokehook target="pre-docs-all" />
        
        <mkdir dir="${site.dir}/javadocs"/>

        <path id="local.class.path">
          <fileset dir="${ofbiz.home.dir}/framework/base/lib" includes="*.jar"/>
          <fileset dir="${ofbiz.home.dir}/framework/catalina/lib" includes="*.jar"/>
          <fileset dir="${ofbiz.home.dir}/framework/entity/lib" includes="*.jar"/>
          <fileset dir="${ofbiz.home.dir}/framework/service/lib" includes="*.jar"/>
          <fileset dir="${ofbiz.home.dir}/framework/testtools/lib" includes="*.jar"/>
          <fileset dir="${ofbiz.home.dir}/framework/webapp/lib" includes="*.jar"/>
          <fileset dir="${ofbiz.home.dir}/framework/webapp/build/lib" includes="*.jar"/>
          <fileset dir="${ofbiz.home.dir}/specialpurpose/birt/lib" includes="*.jar"/>
          <fileset dir="${ofbiz.home.dir}/specialpurpose/ebaystore/lib" includes="*.jar"/>
          <fileset dir="${ofbiz.home.dir}/specialpurpose/googlecheckout/lib" includes="*.jar"/>
          <fileset dir="${ofbiz.home.dir}/specialpurpose/ldap/lib" includes="*.jar"/>
          <fileset dir="${ofbiz.home.dir}/specialpurpose/pos/lib" includes="*.jar"/>
          <fileset dir="${ofbiz.home.dir}/specialpurpose/jetty/lib" includes="*.jar"/>
          <fileset dir="${ofbiz.home.dir}/applications/content/lib" includes="*.jar"/>
          <fileset dir="${ofbiz.home.dir}/applications/product/lib" includes="*.jar"/>
        </path>

        <property name="desc" value="API"/>
        <property name="build.dir" value="${site.dir}"/>

        <default-javadoc/>

        <!-- SCIPIO: hooks -->
        <invokehook target="post-docs-all" />
        
        <echo message="[docs-all] ========== Done Building (JavaDocs) =========="/>
    </target>

    <!-- SCIPIO: Main FTL lib doc build. Currently requires a "build" on the main project to compile the compiler. 
        NOTE: 2016-10-27: The output of this is no longer committed to repo. -->
    <target name="docs-ftl-scipio" depends="build">
        <antcall target="docs-ftl-scipio-ftlonly"/>
    </target>
    
    <!-- SCIPIO: FIXME?: This is currently standard-Scipio-specific and quite hardcoded. May even belong in a separate project.
        Or could also integrate this better with other "docs" builds in future (delegate to component build.xml).
        NOTE: 2016-10-27: The output of this is no longer committed to repo.  -->
    <target name="docs-ftl-scipio-ftlonly">
        <echo message="[docs-ftl-scipio] ========== Start Building (FTL docs) =========="/>
        <echo message="[docs-ftl-scipio] Building Scipio template-writer-friendly FTL lib docs..."/>
        <java classname="com.ilscipio.scipio.ce.webapp.ftl.doc.FtlDocCompiler" fork="true">
            <arg value="scipio-lib"/> <!-- lib format -->
            <arg value="templating"/> <!-- doc purpose -->
            <arg value="framework/common/webcommon/includes/scipio/lib"/> <!-- base source folder -->
            <arg value="doc/scipio/templating/ftl/lib"/> <!-- base output folder -->
            <arg value=".html"/> <!-- output file extension -->
            <arg value="framework/common/webcommon/includes/scipio/doc/ftlDocTemplate.ftl"/> <!-- doc template -->
            <!-- source files to process -->
            <arg value="utilities.ftl"/>
            <arg value="standard/htmlContent.ftl"/>
            <arg value="standard/htmlForm.ftl"/>
            <arg value="standard/htmlInfo.ftl"/>
            <arg value="standard/htmlNav.ftl"/>
            <arg value="standard/htmlScript.ftl"/>
            <arg value="standard/htmlStructure.ftl"/>
            <arg value="standard/htmlTemplate.ftl"/>
            <classpath>
                <path location="framework/webapp/build/lib/ofbiz-webapp.jar"/> <!-- the compiler class currently lives in here -->
                <path location="framework/base/lib/*"/> <!-- includes Freemarker (and some others: log4j) -->
            </classpath>
        </java>
        <!-- TODO?: same as above but for docPurpose "theming"... currently I don't see the need,
            theme creators need to look at the FTL files in depth anyway, even with markup separation -->
        <echo message="[docs-ftl-scipio] ========== Done Building (FTL docs) =========="/>
    </target>
    
    <!-- SCIPIO: Website FTL lib doc build. Currently requires a "build" on the main project to compile the compiler. -->
    <target name="docs-ftl-scipio-website" depends="build">
        <antcall target="docs-ftl-scipio-website-ftlonly"/>
    </target>

    <target name="docs-ftl-scipio-website-ftlonly">
        <echo message="[docs-ftl-scipio-website] ========== Start Building (FTL docs) =========="/>
        <echo message="[docs-ftl-scipio-website] Building Scipio template-writer-friendly FTL lib docs..."/>
        <java classname="com.ilscipio.scipio.ce.webapp.ftl.doc.FtlDocCompiler" fork="true">
            <arg value="scipio-lib"/> <!-- lib format -->
            <arg value="templating"/> <!-- doc purpose -->
            <arg value="framework/common/webcommon/includes/scipio/lib"/> <!-- base source folder -->
            <arg value="doc/scipio-website/templating/ftl/lib"/> <!-- base output folder -->
            <arg value="_NONE_"/> <!-- output file extension -->
            <arg value="framework/common/webcommon/includes/scipio/doc/ftlDocTemplateWebsite.ftl"/> <!-- doc template -->
            <!-- source files to process -->
            <arg value="utilities.ftl"/>
            <arg value="standard/htmlContent.ftl"/>
            <arg value="standard/htmlForm.ftl"/>
            <arg value="standard/htmlInfo.ftl"/>
            <arg value="standard/htmlNav.ftl"/>
            <arg value="standard/htmlScript.ftl"/>
            <arg value="standard/htmlStructure.ftl"/>
            <arg value="standard/htmlTemplate.ftl"/>
            <classpath>
                <path location="framework/webapp/build/lib/ofbiz-webapp.jar"/> <!-- the compiler class currently lives in here -->
                <path location="framework/base/lib/*"/> <!-- includes Freemarker (and some others: log4j) -->
            </classpath>
        </java>
        <!-- NOTE: the following warning could be fixed in the java but it's not worth it, just deal with it -->
        <echo message="[docs-ftl-scipio-website] WARN: The output files may not be browsable locally, because the generated URLs for website may differ from the local paths (for both absolute and relative URLs)"/>
        <echo message="[docs-ftl-scipio-website] ========== Done Building (FTL docs) =========="/>
    </target>

    <!-- SCIPIO: Website FTL lib doc build. Currently requires a "build" on the main project to compile the compiler. -->
    <target name="docs-ftl-scipio-ide" depends="build">
        <antcall target="docs-ftl-scipio-ide-ftlonly"/>
    </target>

    <target name="docs-ftl-scipio-ide-ftlonly">
        <echo message="[docs-ftl-scipio-ide] ========== Start Building (FTL docs) =========="/>
        <echo message="[docs-ftl-scipio-ide] Building Scipio IDE-friendly FTL lib docs..."/>
        <java classname="com.ilscipio.scipio.ce.webapp.ftl.doc.FtlDocCompiler" fork="true">
            <arg value="scipio-lib"/> <!-- lib format -->
            <arg value="templating"/> <!-- doc purpose -->
            <arg value="framework/common/webcommon/includes/scipio/lib"/> <!-- base source folder -->
            <arg value="doc/scipio-ide/templating/ftl/lib"/> <!-- base output folder -->
            <arg value="_NONE_"/> <!-- output file extension -->
            <arg value="framework/common/webcommon/includes/scipio/doc/ftlDocTemplateIDE.ftl"/> <!-- doc template -->
            <!-- source files to process -->
            <arg value="utilities.ftl"/>
            <arg value="standard/htmlContent.ftl"/>
            <arg value="standard/htmlForm.ftl"/>
            <arg value="standard/htmlInfo.ftl"/>
            <arg value="standard/htmlNav.ftl"/>
            <arg value="standard/htmlScript.ftl"/>
            <arg value="standard/htmlStructure.ftl"/>
            <arg value="standard/htmlTemplate.ftl"/>
            <classpath>
                <path location="framework/webapp/build/lib/ofbiz-webapp.jar"/> <!-- the compiler class currently lives in here -->
                <path location="framework/base/lib/*"/> <!-- includes Freemarker (and some others: log4j) -->
            </classpath>
        </java>
        <echo message="[docs-ftl-scipio-ide] ========== Done Building (FTL docs) =========="/>
    </target>

    <!-- SCIPIO: these would have been used to deploy html files or intermediate FTLs (highly complex,
        but now we do dynamic renders which are much easier to handle
    <target name="docs-ftl-scipio-deploylocal" depends="docs-ftl-scipio">
        <antcall target="docs-ftl-scipio-deploylocalonly"/>
    </target>
    
    <target name="docs-ftl-scipio-deploylocalonly">
        <echo message="[docs-ftl-scipio] ========== Deploying Locally (FTL docs) =========="/>
        <copy todir="${basedir}/framework/webtools/webapp/webtools/docs/html/templating/ftl/lib" overwrite="true" verbose="true">
            <fileset dir="${basedir}/doc/scipio/templating/ftl/lib"/>
        </copy>
        <echo message="[docs-ftl-scipio] ========== Done Deploying (FTL docs) =========="/>
    </target>
    
    <target name="docs-ftl-scipio-ftldeploylocalonly">
        <antcall target="docs-ftl-scipio-ftlonly"/>
        <antcall target="docs-ftl-scipio-deploylocalonly"/>
    </target>-->
    
    <!-- ================================================================== -->
    <!-- Contrib Targets                                                    -->
    <!-- ================================================================== -->

    <target name="copy-contrib">
        <copy todir="${basedir}" overwrite="true" verbose="true">
            <fileset dir="${basedir}/contrib" excludes="contrib/**,**/*.class"/>
        </copy>
    </target>

    <target name="build-contrib" depends="copy-contrib,refresh"/>

    <!-- ================================================================== -->
    <!-- WebSite Targets                                                    -->
    <!-- ================================================================== -->

    <target name="build-website"
            description="For committers : Update dtds from OFBiz instance to site">
        <antcall target="copy-dtds"/>
        <!-- now deprecated since Buildbot creates and updates those automatically
        <antcall target="docs"/>
        <antcall target="copy-apis"/-->
    </target>

    <target name="copy-apis">
        <mkdir dir="${site.dir}/api"/>
        <mkdir dir="${site.dir}/api/framework"/>
        <mkdir dir="${site.dir}/api/applications"/>
        <mkdir dir="${site.dir}/api/specialpurpose"/>
        <copy todir="${site.dir}/api/framework">
            <fileset dir="${basedir}/framework" includes="*/build/javadocs/**"/>
        </copy>
        <copy todir="${site.dir}/api/applications">
            <fileset dir="${basedir}/applications" includes="*/build/javadocs/**"/>
        </copy>
        <copy todir="${site.dir}/api/specialpurpose">
            <fileset dir="${basedir}/specialpurpose" includes="*/build/javadocs/**"/>
        </copy>
    </target>

    <target name="copy-dtds"
            description="For committers : Copy all dtds from OFBiz instance to website">
        <mkdir dir="${site.dir}/dtds"/>
        <copy todir="${site.dir}/dtds" flatten="true" overwrite="true">
            <fileset dir="${basedir}" includes="**/*.dtd"/>
            <fileset dir="${basedir}" defaultexcludes="yes"> <!-- all but oagis and external in general -->
                <include name="**/*.xsd"/>
                <exclude name="**/002*.xsd"/>
                <exclude name="**/068*.xsd"/>
                <exclude name="**/161*.xsd"/>
                <exclude name="**/196*.xsd"/>
                <exclude name="**/197*.xsd"/>
            </fileset>
        </copy>
    </target>

    <!-- ================================================================== -->
    <!-- Script Targets                                                     -->
    <!-- ================================================================== -->

    <target name="scriptfix">
        <fixcrlf srcdir="${basedir}" eol="lf" eof="remove" includes="**/*.sh"/>
        <fixcrlf srcdir="${basedir}" eol="crlf" includes="**/*.bat"/>
    </target>

    <!-- ================================================================== -->
    <!-- Start and Stop OFBiz                                                        -->
    <!-- ================================================================== -->

    <!-- SCIPIO: ofbiz.jar exec macro - generic, factors out jvmargs common to ALL start tasks (added 2017-09-08, for solr) -->
    <macrodef name="exec-scipio-jar">
        <attribute name="action" default=""/>
        <attribute name="fork" default="true"/>
        <attribute name="spawn" default=""/>
        <attribute name="resultproperty" default=""/>
        <attribute name="secure" default="false"/>
        <element name="args" optional="true" implicit="true"/>
        <sequential>
            <if><!-- SCIPIO: 2018-05-08: backward compat for old scripts -->
                <isset property="scipio.solr.reindex.auto.force"/>
                <then>
                    <var name="scipio.solr.reindex.startup.force" unset="true"/>
                    <property name="scipio.solr.reindex.startup.force" value="${scipio.solr.reindex.auto.force}"/>   
                </then>
            </if>
            <!-- Ant workarounds to enable attributes to work with if:set -->
            <var name="exec-scipio-jar.action" unset="true"/>
            <if>
                <length string="@{action}" when="greater" length="0"/>
                <then><var name="exec-scipio-jar.action" value="@{action}"/></then>
            </if>
            <var name="exec-scipio-jar.component" unset="true"/>
            <if>
                <equals arg1="@{action}" arg2="load-data"/>
                <then><var name="exec-scipio-jar.component" value="${component}" if:set="component"/></then>
            </if>
            <var name="scipio.exec.os.linux.randseed.set" unset="true"/>
            <condition property="scipio.exec.os.linux.randseed.set">
                <and>
                    <os family="unix"/>
                    <not><equals arg1="${scipio.exec.os.linux.randseed}" arg2=""/></not>
                    <not><equals arg1="${scipio.exec.os.linux.randseed}" arg2="-"/></not>
                </and>
            </condition>
            <var name="scipio.exec.secure" unset="true"/>
            <condition property="scipio.exec.secure">
                <equals arg1="@{secure}" arg2="true"/>
            </condition>
            <!-- Main invocation -->
            <java jar="ofbiz.jar" fork="@{fork}" spawn="@{spawn}" resultproperty="@{resultproperty}">
                <jvmarg value="${memory.initial.param}"/>
                <jvmarg value="${memory.max.param}"/>
                <jvmarg value="-javaagent:${ofbiz.home.dir}/tools/security/notsoserial/notsoserial-1.0-SNAPSHOT.jar" if:set="scipio.exec.secure"/>
                <jvmarg value="-Dnotsoserial.whitelist=${ofbiz.home.dir}/tools/security/notsoserial/empty.txt" if:set="scipio.exec.secure"/>
                <jvmarg value="-Dnotsoserial.dryrun=${ofbiz.home.dir}/tools/security/notsoserial/is-deserialized.txt" if:set="scipio.exec.secure"/>
                <jvmarg value="-Dnotsoserial.trace=${ofbiz.home.dir}/tools/security/notsoserial/deserialize-trace.txt" if:set="scipio.exec.secure"/>
                <!-- SCIPIO: random lockup workaround -->
                <jvmarg value="-Djava.security.egd=${scipio.exec.os.linux.randseed}" if:set="scipio.exec.os.linux.randseed.set"/>
                <!-- SCIPIO: solr home -->
                <jvmarg value="-Dsolr.solr.home=${solr.home}"/>
                <jvmarg value="-Dsolr.log.dir=${solr.log.dir}"/>
                <jvmarg value="-Dsolr.lock.type=${solr.lock.type}"/>
                <jvmarg value="-Ddisable.configEdit=${solr.disable.configEdit}"/>
                <jvmarg value="-Dscipio.solr.reindex.startup.force=${scipio.solr.reindex.startup.force}"/>
                <!-- SCIPIO: Uncomment to specify a java.util.logging config for Tomcat (non-log4j)
                <jvmarg value="-Djava.util.logging.config.file=${ofbiz.home.dir}/framework/base/config/logging.properties"/>-->
                <syspropertyset>
                    <propertyref prefix="scipio."/>
                </syspropertyset>
                <arg value="@{action}" if:set="exec-scipio-jar.action"/>
                <arg value="component=${component}" if:set="exec-scipio-jar.component"/>
                <args/>
            </java>
        </sequential>
    </macrodef>
    
    <target name="start"
            description="Start Scipio ERP (use -Dportoffset=portNumber to shift all ports with the portNumber value)">
        <!-- SCIPIO: -->
        <property name="currentTarget" value="start"/>
        <condition property="spawn" else="false" >
            <isset property="scipio.start.spawn"/>
        </condition>
        <exec-scipio-jar spawn="${spawn}">
            <arg value="start"/>
            <arg value="-portoffset=${portoffset}"/>
        </exec-scipio-jar>
    </target>
    <target name="start-secure"
            description="Same than start but pre-loading the notsoserial Java agent (from tools/security/notsoserial) to protect OFBiz from the Java deserialization vulnerability">
        <exec-scipio-jar secure="true">
            <arg value="start"/>
            <arg value="-portoffset=${portoffset}"/>
        </exec-scipio-jar>
    </target>
    <target name="start-batch"
            description="Start Scipio ERP as a separate process. Use -Dportoffset=portNumber to shift all ports with the portNumber value.">
        <exec-scipio-jar spawn="true">
            <arg value="start-batch"/>
            <arg value="-portoffset=${portoffset}"/>
        </exec-scipio-jar>
    </target>
    <target name="start-batch-secure"
        description="Same than start-batch but pre-loading the notsoserial Java agent (from tools/security/notsoserial) to protect OFBiz from the Java deserialization vulnerability">
        <exec-scipio-jar spawn="true" secure="true">
            <arg value="start-batch"/>
            <arg value="-portoffset=${portoffset}"/>
        </exec-scipio-jar>
    </target>
    <target name="start-debug"
            description="Start Scipio ERP in debugging mode. It uses the 8091 port by default. Use -Dportoffset=portNumber to shift all ports with the portNumber value.">
        <exec-scipio-jar>
            <jvmarg value="-Xnoagent"/>
            <jvmarg value="-Djava.compiler=NONE"/>
            <jvmarg value="-Xdebug"/>
            <jvmarg value="-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8091"/>
            <arg value="start-debug"/>
            <arg value="-portoffset=${portoffset}"/>
        </exec-scipio-jar>
    </target>
    <target name="start-pos"
            description="Start SCIPIO ERP POS (Point of sale). Use -Dportoffset=portNumber to shift all ports with the portNumber value.">
        <exec-scipio-jar>
            <arg value="pos"/>
            <arg value="-portoffset=${portoffset}"/><!-- Not sure this makes sense and is useful at all -->
        </exec-scipio-jar>
    </target>
    <target name="start-pos-secure"
        description="Same than start-pos but pre-loading the notsoserial Java agent (from tools/security/notsoserial) to protect OFBiz from the Java deserialization vulnerability">
        <exec-scipio-jar secure="true">
            <arg value="pos"/>
            <arg value="-portoffset=${portoffset}"/><!-- Not sure this makes sense and is useful at all -->
        </exec-scipio-jar>
    </target>
    <target name="start-both"
            description="Start Scipio ERP in both Web and POS (Point of sale) modes. Use -Dportoffset=portNumber to shift all ports with the portNumber value.">
        <exec-scipio-jar>
            <arg value="both"/>
            <arg value="-portoffset=${portoffset}"/>
        </exec-scipio-jar>
    </target>
    <target name="start-both-secure"
        description="Same than start-both but pre-loading the notsoserial Java agent (from tools/security/notsoserial) to protect OFBiz from the Java deserialization vulnerability">
        <exec-scipio-jar secure="true">
            <arg value="both"/>
            <arg value="-portoffset=${portoffset}"/>
        </exec-scipio-jar>
    </target>
    <target name="stop"
            description="Stop Scipio ERP. Use -Dportoffset=portNumber to shift all ports with the portNumber value.">
        <exec-scipio-jar>
            <arg value="-shutdown"/>
            <arg value="-portoffset=${portoffset}"/>
        </exec-scipio-jar>
    </target>
    <target name="stop-wait"
            description="Stop Scipio ERP and return once it's down. Use -Dportoffset=portNumber to shift all ports with the portNumber value.">
        <exec-scipio-jar>
            <arg value="-shutdown-wait"/>
            <arg value="-portoffset=${portoffset}"/>
        </exec-scipio-jar>
    </target>
    <target name="status"
            description="Display status of Scipio ERP. Use -Dportoffset=portNumber to shift all ports with the portNumber value.">
        <exec-scipio-jar>
            <arg value="-status"/>
            <arg value="-portoffset=${portoffset}"/>
        </exec-scipio-jar>
    </target>
    
    <!-- SCIPIO: start targets with solr control -->
    <target name="start-reindex-solr" depends="set-reindex-solr,start"
                description="Start Scipio and force Solr to reindex on startup">
    </target>
    <target name="start-no-reindex-solr" depends="set-no-reindex-solr,set-bypass-crashed-reindex-solr,start"
            description="Start Scipio and prevent Solr reindex on startup">
    </target>
    <target name="start-debug-reindex-solr" depends="set-reindex-solr,start-debug"
                description="Start Scipio in debug mode and force Solr to reindex on startup">
    </target>
    <target name="start-debug-no-reindex-solr" depends="set-no-reindex-solr,set-bypass-crashed-reindex-solr,start-debug"
            description="Start Scipio in debug mode and prevent Solr reindex on startup">
    </target>

    <!-- SCIPIO: 2.1.0: Convenience stop-wait build start tasks for developers -->
    <target name="restart" depends="stop-wait,start"
            description="Convenience task alias for: stop-wait start">
    </target>
    <target name="restart-debug" depends="stop-wait,start-debug"
            description="Convenience task alias for: stop-wait start-debug">
    </target>
    <target name="build-start" depends="stop-wait,build,start"
            description="Convenience task alias for: stop-wait build start">
    </target>
    <target name="build-debug" depends="stop-wait,build,start-debug"
            description="Convenience task alias for: stop-wait build start-debug">
    </target>
    <target name="rebuild" depends="stop-wait,clean,build"
            description="Convenience task alias for: stop-wait clean build">
    </target>
    <target name="rebuild-start" depends="stop-wait,clean,build,start"
            description="Convenience task alias for: stop-wait clean build start">
    </target>
    <target name="rebuild-debug" depends="stop-wait,clean,build,start-debug"
            description="Convenience task alias for: stop-wait clean build start-debug">
    </target>

    <!-- ================================================================== -->
    <!-- Setup Scipio ERP Data                                                   -->
    <!-- ================================================================== -->

    <target name="load-demo" depends="build"
            description="Load all data; meant for generic Scipio ERP development, testing, demonstration, etc purposes">
        <property name="currentTarget" value="load"/>
        <exec-scipio-jar action="load-data"/>
    </target>
    <target name="load-demo-multitenant" depends="build"
            description="Load all data needed for the multi-tenancy demonstration. Caution: this creates three databases, with each one loaded with all demo data.">
        <exec-scipio-jar action="load-data"/>
        <exec-scipio-jar action="load-data">
            <arg value="delegator=default#DEMO1"/>
        </exec-scipio-jar>
        <exec-scipio-jar action="load-data">
            <arg value="delegator=default#DEMO2"/>
        </exec-scipio-jar>
    </target>
    <target name="load-seed" depends="build"
            description="Load ONLY the seed data (not seed-initial, demo, ext* or anything else); meant for use after an update of the code to reload the seed data as it is generally maintained along with the code and needs to be in sync for operation">
        <exec-scipio-jar action="load-data">
            <arg value="readers=seed"/>
        </exec-scipio-jar>
    </target>
    <target name="load-extseed" depends="build"
            description="Load seed, seed-initial and ext data; meant for manual/generic testing, development, or going into production with a derived system based on stock Scipio ERP where the ext data basically replaces the demo data">
        <exec-scipio-jar action="load-data">
            <arg value="readers=seed,seed-initial,ext"/>
        </exec-scipio-jar>
    </target>
    <target name="load-extseedonly" depends="build"
            description="Load seed and ext data, but not seed-initial; meant for reseeding during manual/generic testing, development, or going into production with a derived system based on stock Scipio ERP where the ext data basically replaces the demo data"><!-- SCIPIO -->
        <exec-scipio-jar action="load-data">
            <arg value="readers=seed,ext"/>
        </exec-scipio-jar>
    </target>
    <target name="load-exttest" depends="build"
            description="Load seed, seed-initial, ext and ext-test data; meant for automated testing with a derived system based on stock Scipio ERP">
        <exec-scipio-jar action="load-data">
            <arg value="readers=seed,seed-initial,ext,ext-test"/>
        </exec-scipio-jar>
    </target>
    <target name="load-readers" depends="build"
            description='Load data using the command line argument data-readers that takes a comma separated list of readers (seed, seed-initial, demo, ext, ext-test, ext-demo). On Windows XP (at least) you need top wrap the parameters in double-quotes. For instance: ant load-readers "-Ddata-readers=seed,seed-initial,ext"'>
        <exec-scipio-jar action="load-data">
            <arg value="readers=${data-readers}"/>
        </exec-scipio-jar>
    </target>
    <!-- SCIPIO: Example: ./ant load-file -Ddata-file=framework/common/data/GeoData_IN.xml,framework/common/data/CurrencyData.xml -->
    <target name="load-file" depends="build"
            description="Load data using the command line argument 'data-file' to load data from a given file or comma-separated files using the 'default' delegator or a delegator specified in the command line argument 'delegator'">
        <property name="delegator" value="default" />
        <exec-scipio-jar action="load-data">
            <arg value="delegator=${delegator}"/>
            <arg value="file=${data-file}"/>
        </exec-scipio-jar>
    </target>
    <!-- =================================
          target: load-tenant
         ================================= -->
    <target name="load-tenant" depends="build,load-tenant-all,load-tenant-reader,load-tenant-component-all,load-tenant-component-reader"
            description="Load data using tenantId, syntax eg: ant load-tenant -DtenantId=DEMO1 (needs multitenant=Y in general.properties)">
    </target>
    <target name="check-tenant-id">
        <exec-scipio-jar action="load-data">
            <arg value="readers=tenant"/>
        </exec-scipio-jar>
        <condition property="hasTenant">
            <and>
                <length string="${tenantId}" trim="true" when="greater" length="0"/>
                <not><contains string="${tenantId}" substring="tenantId"/></not>
                <or>
                    <length string="${component}" trim="true" when="equal" length="0"/>
                    <contains string="${component}" substring="component"/>
                </or>
            </and>
        </condition>
        <condition property="hasTenantComponent">
            <and>
                <length string="${tenantId}" trim="true" when="greater" length="0"/>
                <not><contains string="${tenantId}" substring="tenantId"/></not>
                <length string="${component}" trim="true" when="greater" length="0"/>
                <not><contains string="${component}" substring="component"/></not>
            </and>
        </condition>
    </target>
    <target name="check-tenant-reader" depends="check-tenant-id" if="hasTenant">
        <condition property="hasReader">
            <and>
                <length string="${data-readers}" trim="true" when="greater" length="0"/>
                <not><contains string="${data-readers}" substring="data-readers"/></not>
            </and>
        </condition>
        <condition property="noReader">
            <or>
                <length string="${data-readers}" trim="true" when="equal" length="0"/>
                <contains string="${data-readers}" substring="data-readers"/>
            </or>
        </condition>
    </target>
    <target name="load-tenant-all" depends="check-tenant-reader" if="noReader">
        <exec-scipio-jar action="load-data">
            <arg value="delegator=default#${tenantId}"/>
        </exec-scipio-jar>
    </target>
    <target name="load-tenant-reader" depends="check-tenant-reader" if="hasReader">
        <exec-scipio-jar action="load-data">
            <arg value="delegator=default#${tenantId}"/>
            <arg value="readers=${data-readers}"/>
        </exec-scipio-jar>
    </target>
    <!-- load-tenant-component -->
    <target name="load-tenant-component" if="hasTenantComponent" depends="check-tenant-id">
        <condition property="hasComponentReader">
            <and>
                <length string="${data-readers}" trim="true" when="greater" length="0"/>
                <not><contains string="${data-readers}" substring="data-readers"/></not>
            </and>
        </condition>
        <condition property="noComponentReader">
            <or>
                <length string="${data-readers}" trim="true" when="equal" length="0"/>
                <contains string="${data-readers}" substring="data-readers"/>
            </or>
        </condition>
    </target>
    <target name="load-tenant-component-all" depends="load-tenant-component" if="noComponentReader">
        <exec-scipio-jar action="load-data">
            <arg value="delegator=default#${tenantId}"/>
            <arg value="component=${component}"/>
        </exec-scipio-jar>
    </target>
    <target name="load-tenant-component-reader" depends="load-tenant-component" if="hasComponentReader">
        <exec-scipio-jar action="load-data">
            <arg value="delegator=default#${tenantId}"/>
            <arg value="readers=${data-readers}"/>
            <arg value="component=${component}"/>
        </exec-scipio-jar>
    </target>
    <!-- =================================
          target: load-all-tenants
         ================================= -->
    <target name="load-all-tenants" depends="build,load-tenants-all,load-tenants-reader"
           description="Load data for all tenants, syntax eg: ant load-all-tenants (needs multitenant=Y in general.properties)">
    </target>
    <target name="check-tenants-reader">
        <property name="delegator" value="all-tenants"/>
        <exec-scipio-jar action="load-data">
            <arg value="readers=tenant"/>
        </exec-scipio-jar>
        <condition property="hasReader">
            <and>
                <length string="${data-readers}" trim="true" when="greater" length="0"/>
                <not><contains string="${data-readers}" substring="data-readers"/></not>
            </and>
        </condition>
        <condition property="noReader">
            <or>
                <length string="${data-readers}" trim="true" when="equal" length="0"/>
                <contains string="${data-readers}" substring="data-readers"/>
            </or>
        </condition>
    </target>
    <target name="load-tenants-all" depends="check-tenants-reader" if="noReader">
        <exec-scipio-jar action="load-data">
            <arg value="delegator=${delegator}"/>
        </exec-scipio-jar>
    </target>
    <target name="load-tenants-reader" depends="check-tenants-reader" if="hasReader">
        <exec-scipio-jar action="load-data">
            <arg value="readers=${data-readers}"/>
            <arg value="delegator=${delegator}"/>
        </exec-scipio-jar>
    </target>
    <!-- =================================
          target: create-tenant
         ================================= -->
    <target name="create-tenant"
        depends="create-tenant-on-Derby,create-tenant-on-MySQL,create-tenant-on-Oracle,create-tenant-on-PostgreSQL"
        description="Create a new tenant in your environment, create the delegator, load initial data with admin-user and password (needs multitenant=Y in general.properties)">
        <tstamp/>
    </target>

    <!-- description="This creates entity Tenant and TenantDataSource in default, installs data in the delegator and creates the admin-user and password for the tenant"
        sub-target of create-tenant, can't used alone => no description, to not clutter "ant -p" -->
    <target name="get-tenant-data">
        <input addproperty="tenantId" message="Enter Id for the tenant: "/>
        <!-- SCIPIO: improved defaults and messages -->
        <input addproperty="tenantName" message="Enter name for tenant: " defaultvalue="${tenantId}"/>
        <input addproperty="domainName" message="Enter domain name for tenant (Optional): "/>
        <input addproperty="data-readers" message="Enter data to install. Choices are e.g.: seed,seed-initial,ext,demo (default: same as load-demo). Multipe datasets must be separated with a comma: "/>
        <input addproperty="db-Platform" message="Select your default database platform, D = Derby, M = MySQL, O = Oracle, P = PostgreSQL"
            validargs="D,M,O,P,d,m,o,p"/>
        <echo message="Please make sure that the driver of the platform is installed and that the databases have been created (in function of the entityengine.xml datasource-names)"/>
        <input addproperty="db-IP" message="Enter IP address of the database server (you may add a port number)"/>
        <input addproperty="db-User" message="Enter userID of database user: "/>
        <input addproperty="db-Password" message="Enter password of database user: "/>
        <condition property="isDerby">
            <equals arg1="${db-Platform}" arg2="D" casesensitive="no"/><!-- SCIPIO: accept lowercase -->
        </condition>
        <condition property="isMySQL">
            <equals arg1="${db-Platform}" arg2="M" casesensitive="no"/>
        </condition>
        <condition property="isOracle">
            <equals arg1="${db-Platform}" arg2="O" casesensitive="no"/>
        </condition>
        <condition property="isPostgreSQL">
            <equals arg1="${db-Platform}" arg2="P" casesensitive="no"/>
        </condition>
        <antcall target="tenant-data-entry"/>
    </target>
    <!-- description="Creates tenant data and instance"
        sub-target of create-tenant, can't used alone => no description, to not clutter "ant -p" -->
    <target name="create-tenant-on-Derby" depends="get-tenant-data" if="isDerby">
        <echo message="Installing on Derby"/>
        <!-- Below code will handle the case of optional domain name. It will remove the TenantDomainName entry from tmpTenantData.xml file
            if domain name is empty, so that record would not get created. -->
        <copy file="${basedir}/framework/resources/templates/AdminNewTenantData-Derby.xml" tofile="runtime/tmp/tmpTenantData.xml"/>
        <if>
          <equals arg1="${domainName}" arg2="" />
          <then>
            <replace file="runtime/tmp/tmpTenantData.xml">
               <replacetoken><![CDATA[<TenantDomainName tenantId="@tenantId@" domainName="@domainName@" />]]></replacetoken>
               <replacevalue><![CDATA[]]></replacevalue>
            </replace>
          </then>
        </if>
        <copy file="runtime/tmp/tmpTenantData.xml" tofile="runtime/tmp/tmpFilteredTenantData.xml">
            <filterset>
                <filter token="tenantId" value="${tenantId}"/>
                <filter token="tenantName" value="${tenantName}"/>
                <filter token="domainName" value="${domainName}"/>
            </filterset>
        </copy>
        <antcall target="load-file">
            <param name="data-file" value="runtime/tmp/tmpFilteredTenantData.xml"/>
        </antcall>
        <delete file="runtime/tmp/tmpTenantData.xml"/>
        <delete file="runtime/tmp/tmpFilteredTenantData.xml"/>
        <antcall target="load-tenant-data-readers"/>
        <antcall target="load-tenant-admin-user-login">
            <param name="userLoginId" value="${tenantId}-admin"/>
            <param name="delegatorId" value="default#${tenantId}"/>
        </antcall>
    </target>
    <!-- description="Creates tenant data and instance. Don't forget db driver(s) and already created DBs in function of the entityengine.xml datasource-names"
        sub-target of create-tenant, can't used alone => no description, to not clutter "ant -p" -->
    <target name="create-tenant-on-MySQL" depends="get-tenant-data" if="isMySQL">
        <echo message="Installing on MySQL"/>
        <!-- Below code will handle the case of optional domain name. It will remove the TenantDomainName entry from tmpTenantData.xml file
            if domain name is empty, so that record would not get created. -->
        <copy file="${basedir}/framework/resources/templates/AdminNewTenantData-MySQL.xml" tofile="runtime/tmp/tmpTenantData.xml"/>
        <if>
          <equals arg1="${domainName}" arg2="" />
          <then>
            <replace file="runtime/tmp/tmpTenantData.xml">
               <replacetoken><![CDATA[<TenantDomainName tenantId="@tenantId@" domainName="@domainName@" />]]></replacetoken>
               <replacevalue><![CDATA[]]></replacevalue>
            </replace>
          </then>
        </if>
        <copy file="runtime/tmp/tmpTenantData.xml" tofile="runtime/tmp/tmpFilteredTenantData.xml">
            <filterset>
                <filter token="tenantId" value="${tenantId}"/>
                <filter token="tenantName" value="${tenantName}"/>
                <filter token="domainName" value="${domainName}"/>
                <filter token="db-IP" value="${db-IP}"/>
                <filter token="db-User" value="${db-User}"/>
                <filter token="db-Password" value="${db-Password}"/>
            </filterset>
        </copy>
        <antcall target="load-file">
            <param name="data-file" value="runtime/tmp/tmpFilteredTenantData.xml"/>
        </antcall>
        <delete file="runtime/tmp/tmpTenantData.xml"/>
        <delete file="runtime/tmp/tmpFilteredTenantData.xml"/>
        <antcall target="load-tenant-data-readers"/>
        <antcall target="load-tenant-admin-user-login">
            <param name="userLoginId" value="${tenantId}-admin"/>
            <param name="delegatorId" value="default#${tenantId}"/>
        </antcall>
    </target>
    <!-- description="Creates tenant data and instance. Don't forget db driver(s) and already created DBs in function of the entityengine.xml datasource-names"
        sub-target of create-tenant, can't used alone => no description, to not clutter "ant -p" -->
    <target name="create-tenant-on-Oracle" depends="get-tenant-data" if="isOracle">
        <echo message="Installing on Oracle"/>
        <!-- Below code will handle the case of optional domain name. It will remove the TenantDomainName entry from tmpTenantData.xml file
            if domain name is empty, so that record would not get created. -->
        <copy file="${basedir}/framework/resources/templates/AdminNewTenantData-Oracle.xml" tofile="runtime/tmp/tmpTenantData.xml"/>
        <if>
          <equals arg1="${domainName}" arg2="" />
          <then>
            <replace file="runtime/tmp/tmpTenantData.xml">
               <replacetoken><![CDATA[<TenantDomainName tenantId="@tenantId@" domainName="@domainName@" />]]></replacetoken>
               <replacevalue><![CDATA[]]></replacevalue>
            </replace>
          </then>
        </if>
        <copy file="runtime/tmp/tmpTenantData.xml" tofile="runtime/tmp/tmpFilteredTenantData.xml">
            <filterset>
                <filter token="tenantId" value="${tenantId}"/>
                <filter token="tenantName" value="${tenantName}"/>
                <filter token="domainName" value="${domainName}"/>
                <filter token="db-IP" value="${db-IP}"/>
                <filter token="db-User" value="${db-User}"/>
                <filter token="db-Password" value="${db-Password}"/>
            </filterset>
        </copy>
        <antcall target="load-file">
            <param name="data-file" value="runtime/tmp/tmpFilteredTenantData.xml"/>
        </antcall>
        <delete file="runtime/tmp/tmpTenantData.xml"/>
        <delete file="runtime/tmp/tmpFilteredTenantData.xml"/>
        <antcall target="load-tenant-data-readers"/>
        <antcall target="load-tenant-admin-user-login">
            <param name="userLoginId" value="${tenantId}-admin"/>
            <param name="delegatorId" value="default#${tenantId}"/>
        </antcall>
    </target>
    <!-- description="Creates tenant data and instance. Don't forget db driver(s) and already created DBs in function of the entityengine.xml datasource-names"
        sub-target of create-tenant, can't used alone => no description, to not clutter "ant -p" -->
    <target name="create-tenant-on-PostgreSQL" depends="get-tenant-data" if="isPostgreSQL">
        <echo message="Installing on PostgreSQL"/>
        <!-- Below code will handle the case of optional domain name. It will remove the TenantDomainName entry from tmpTenantData.xml file
            if domain name is empty, so that record would not get created. -->
        <copy file="${basedir}/framework/resources/templates/AdminNewTenantData-PostgreSQL.xml" tofile="runtime/tmp/tmpTenantData.xml"/>
        <if>
          <equals arg1="${domainName}" arg2="" />
          <then>
            <replace file="runtime/tmp/tmpTenantData.xml">
               <replacetoken><![CDATA[<TenantDomainName tenantId="@tenantId@" domainName="@domainName@" />]]></replacetoken>
               <replacevalue><![CDATA[]]></replacevalue>
            </replace>
          </then>
        </if>
        <copy file="runtime/tmp/tmpTenantData.xml" tofile="runtime/tmp/tmpFilteredTenantData.xml">
            <filterset>
                <filter token="tenantId" value="${tenantId}"/>
                <filter token="tenantName" value="${tenantName}"/>
                <filter token="domainName" value="${domainName}"/>
                <filter token="db-IP" value="${db-IP}"/>
                <filter token="db-User" value="${db-User}"/>
                <filter token="db-Password" value="${db-Password}"/>
            </filterset>
        </copy>
        <antcall target="load-file">
            <param name="data-file" value="runtime/tmp/tmpFilteredTenantData.xml"/>
        </antcall>
        <delete file="runtime/tmp/tmpTenantData.xml"/>
        <delete file="runtime/tmp/tmpFilteredTenantData.xml"/>
        <antcall target="load-tenant-data-readers"/>
        <antcall target="load-tenant-admin-user-login">
            <param name="userLoginId" value="${tenantId}-admin"/>
            <param name="delegatorId" value="default#${tenantId}"/>
        </antcall>
    </target>
    <!-- description="displays tenant data"  sub-target of get-tenant-data, can't used alone => no description, to not clutter "ant -p" -->
    <target name="tenant-data-entry">
        <echo>------------------------------------</echo>
        <echo message="tenantId = ${tenantId}"/>
        <echo>tenantName = ${tenantName}</echo>
        <echo>domainName = ${domainName}</echo>
        <echo>db-Platform = ${db-Platform}</echo>
        <echo>db-IP = ${db-IP}</echo>
        <echo>db-User = ${db-User}</echo>
        <echo>db-Password = ${db-Password}</echo>
        <echo>------------------------------------</echo>
        <echo>database for tenant data will be 'ofbiz_${tenantId}'</echo>
        <echo>database for tenant olap data will be 'ofbizolap_${tenantId}</echo>
        <echo message="Please make sure that the driver of the platform is installed and that the databases have been created (Check names just above)"/>
        <echo>------------------------------------</echo>
        <input addproperty="continueYN" message="Continue Y or N" validargs="N,n,Y,y"/>
    </target>
    <target name="load-tenant-admin-user-login"
        description="Create the admin login for the tenant with admin privileges, and a temporay password equal to 'scipio'. Password must be changed on first login">
        <echo>------------------------------------</echo>
        <echo message="Installing the admin for the tenant"/>
        <echo message="Delegator = ${delegatorId}"/>
        <echo message="Tenant admin = '${userLoginId}'"/>
        <echo message="Password for tenant admin is 'scipio' must change on first login"/>
        <echo>------------------------------------</echo>
        <input addproperty="continueYN" message="Continue Y or N" validargs="N,n,Y,y"/>
        <copy file="${basedir}/framework/resources/templates/AdminUserLoginData.xml" tofile="runtime/tmp/tmpUserLogin.xml">
            <filterset>
                <filter token="userLoginId" value="${userLoginId}"/>
            </filterset>
        </copy>
        <antcall target="load-file">
            <param name="data-file" value="runtime/tmp/tmpUserLogin.xml"/>
            <param name="delegator" value="${delegatorId}"/>
        </antcall>
        <delete file="runtime/tmp/tmpUserLogin.xml"/>
    </target>
    <target name="load-tenant-data-readers"
        description="Load data of given data-readers in the tenant database. Example: ./ant load-tenant-data-readers -Ddata-readers=seed,seed-initial -DtenantId=demo">
        <echo>------------------------------------</echo>
        <echo message="Loading selected data-readers in tenant database"/>
        <echo message="Delegator = default#${tenantId}"/>
        <echo message="Data-readers = ${data-readers}"/>
        <echo>------------------------------------</echo>
        <exec-scipio-jar action="load-data">
            <arg value="readers=${data-readers}"/>
            <arg value="delegator=default#${tenantId}"/>
        </exec-scipio-jar>
    </target>
    <target name="load-admin-user-login"
            description="Create a user login with admin privileges and a temporary password equal to 'scipio'; after a successful login the user will be prompted for a new password. Example command for the userLogin 'admin': ./ant load-admin-user-login -DuserLoginId=admin">
        <fail message="userLoginId parameter is required. To add the parameter to the command for user admin: -DuserLoginId=admin">
            <condition>
                <not><isset property="userLoginId"/></not>
            </condition>
        </fail>
        <copy file="${basedir}/framework/resources/templates/AdminUserLoginData.xml" tofile="runtime/tmp/tmpUserLogin.xml">
            <filterset>
                <filter token="userLoginId" value="${userLoginId}"/>
            </filterset>
        </copy>
        <antcall target="load-file">
            <param name="data-file" value="runtime/tmp/tmpUserLogin.xml"/>
        </antcall>
        <delete file="runtime/tmp/tmpUserLogin.xml"/>
    </target>
    <target name="create-admin-user-login"
            description="Prompt for a user name, then create a user login with admin privileges and a temporary password equal to 'scipio'. After a successful login the user will be prompted for a new password. Note: this uses load-admin-user-login target">
        <input addproperty="userLoginId" message="Enter user name (default: 'admin') (log in with the temporary password 'scipio'):" defaultvalue="admin"/>
        <antcall target="load-admin-user-login"/>
    </target>

    <target name="run-tests" description="(Unreliable) Run automated integration tests [SCIPIO: run 'clean-logs' first]; you have to manually execute 'ant load-demo' before (and if needed even clear your data before) and see results in runtime/logs/test-results/html/all-tests.html.
Use -Dportoffset=portNumber to shift all ports with the portNumber value.">
        <echo>===========================================================</echo>
        <echo>= OFBiz / Scipio integration tests. Please be aware, that =</echo>
        <echo>= the tests are based on OFBiz 14 and not always reliable.=</echo>
        <echo>=                                                         =</echo>
        <echo>= NOTE: To avoid dirty results, run 'clean-logs' before   =</echo>
        <echo>= every invocation, e.g.:                                 =</echo>
        <echo>=     ./ant clean-logs run-tests                          =</echo>
        <echo>===========================================================</echo>
        <exec-scipio-jar resultproperty="test.result">
            <arg value="test"/>
            <arg value="-portoffset=${portoffset}"/>
            <env key="LC_ALL" value="C"/>
        </exec-scipio-jar>
        <mkdir dir="runtime/logs/test-results/html"/>
        <junitreport todir="runtime/logs/test-results">
            <fileset dir="runtime/logs/test-results/">
                <include name="*.xml"/>
            </fileset>
            <report format="frames" todir="runtime/logs/test-results/html"/>
        </junitreport>
        <echo></echo>
        <echo>Test results can be viewed using:</echo>
        <echo>    runtime/logs/test-results/html/all-tests.html</echo>
        <echo></echo>
        <fail message="Test run was unsuccessful">
            <condition>
                <not>
                    <equals arg1="${test.result}" arg2="0"/>
                </not>
            </condition>
        </fail>
    </target>

    <target name="run-tests-with-cobertura" depends="download-cobertura"
        description="Download Cobertura and perform code coverage (same as run-tests). You will need a valid Internet connection to download cobertura">
        <echo>=============================================================</echo>
        <echo>=                                                           =</echo>
        <echo>=     ** DEPRECATED: Please use Jacoco Tests instead. **    =</echo>
        <echo>=                                                           =</echo>
        <echo>= Scipio Cobertura integration tests. Please be aware, that =</echo>
        <echo>= the tests are based on OFBiz_14 and not always reliable.  =</echo>
        <echo>=============================================================</echo>
        <exec-scipio-jar resultproperty="test.result">
            <arg value="test"/>
            <arg value="-portoffset=${portoffset}"/>
            <env key="LC_ALL" value="C"/>
        </exec-scipio-jar>
        <antcall target="run-cobertura-analysis"/>
    </target>

    <target name="run-cobertura-analysis" depends="check-build-requisites">
        <iterate target="tests-cobertura" filelist="framework-builds"/>
        <iterate target="tests-cobertura" filelist="application-builds"/>
        <iterate target="tests-cobertura" filelist="specialpurpose-builds"/>
        <addonsant target="tests-cobertura"/>
        <hotdeployant target="tests-cobertura"/>
    </target>

    <target name="run-tests-with-jacoco" xmlns:jacoco="antlib:org.jacoco.ant"
        description="Download JaCoCo and perform code coverage (same as run-tests). You will need a valid Internet connection to download JaCoCo">
        <echo>============================================================</echo>
        <echo>= Scipio JaCoCo integration tests. Please be aware, that    =</echo>
        <echo>= the tests are based on OFBiz_14 and not always reliable.  =</echo>
        <echo>=============================================================</echo>
        <taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml">
            <classpath>
                <path refid="jacoco.class.path" />
            </classpath>
        </taskdef>
        <delete dir="runtime/logs/jacoco-report"/>
        <mkdir dir="runtime/logs/jacoco-report"/>
        <pathconvert property="jacocoAgent" refid="jacoco.agent.class.path" />

        <jacoco:agent property="agentvmparam" destfile="runtime/logs/jacoco-report/scipio-base.exec" includes="*" output="file" dumponexit="true" />
        <echo>Starting Scipio Server with Agent${agentvmparam}</echo>
        <parallel>
            <exec-scipio-jar resultproperty="test.result">
                <arg value="test"/>
                <!-- <jvmarg value="-Xnoagent"/>
                <jvmarg value="-Djava.compiler=NONE"/>
                <jvmarg value="-Xdebug"/>
                <jvmarg value="-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8091"/>-->
                <jvmarg value="${agentvmparam}" />
                <env key="LC_ALL" value="C"/>
            </exec-scipio-jar>
            <sequential>
          </sequential>
        </parallel>
        <antcall target="run-jacoco-analysis"/>
        <jacoco:merge destfile="runtime/logs/jacoco-report/jacoco.exec">
            <fileset dir="." includes="**/**/build/jacoco-result/*.exec"/>
            <fileset dir="." includes="runtime/logs/jacoco-report/scipio-base.exec"/>
        </jacoco:merge>
    </target>

    <target name="run-jacoco-analysis" depends="check-build-requisites">
        <iterate target="tests-jacoco" filelist="framework-builds"/>
        <iterate target="tests-jacoco" filelist="application-builds"/>
        <iterate target="tests-jacoco" filelist="specialpurpose-builds"/>
        <addonsant target="tests-jacoco"/>
        <hotdeployant target="tests-jacoco"/>
    </target>

    <target name="jacoco-report" xmlns:jacoco="antlib:org.jacoco.ant" depends="run-tests-with-jacoco" 
            description="Generate a HTML code coverage report with JaCoCo can be found in runtime/logs/jacoco-report">
        <taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml">
            <classpath>
                <path refid="jacoco.class.path" />
            </classpath>
        </taskdef>

        <delete dir="runtime/logs/jacoco-report/html"/>
        <mkdir dir="runtime/logs/jacoco-report/html"/>
        <delete dir="runtime/logs/jacoco-report/xml"/>
        <mkdir dir="runtime/logs/jacoco-report/xml"/>
        <delete dir="runtime/logs/jacoco-report/csv"/>
        <mkdir dir="runtime/logs/jacoco-report/csv"/>

        <jacoco:report>           
            <executiondata>
                <file file="runtime/logs/jacoco-report/jacoco.exec"/>
            </executiondata>
            <structure name="Scipio - Code Coverage">
                <classfiles>
                    <multirootfileset>
                      <basedir file="."/>
                      <include name="**/**/**/classes/**"/>
                      <exclude name="**/**/**/classes/*test*"/>
                    </multirootfileset>
                </classfiles>
                <sourcefiles encoding="UTF-8">
                    <multirootfileset>
                      <basedir file="."/>
                      <include name="**/**/src/**"/>
                      <exclude name="**/**/src/*test*"/>
                    </multirootfileset>
                </sourcefiles>
            </structure>
            <html destdir="runtime/logs/jacoco-report/html" />
            <csv destfile="runtime/logs/jacoco-report/csv/report.csv" />
            <xml destfile="runtime/logs/jacoco-report/xml/report.xml" />             
        </jacoco:report>
    </target>

    <target name="_check-separated-tests-already-setup">
        <available file="runtime/test-list-build.xml" property="_separated-tests-already-setup"/>
    </target>
    <target name="_setup-separated-test-run" depends="_check-separated-tests-already-setup" unless="_separated-tests-already-setup">
        <exec-scipio-jar>
            <arg value="testlist"/>
            <arg file="runtime/test-list-build.xml"/>
            <arg value="-ant"/>
            <env key="LC_ALL" value="C"/>
        </exec-scipio-jar>
    </target>
    <target name="run-test"
          description="Run a single test, syntax eg: ant run-test -Dtest.component=service -Dtest.case=service-soap-tests">
        <fail unless="test.component">test.component is a required parameter: -Dtest.component=componentname</fail>
        <fail unless="test.case">test.case is a required parameter: -Dtest.case=testcasename</fail>
        <exec-scipio-jar resultproperty="test.result">
            <arg value="test"/>
            <arg value="-component=${test.component}"/>
            <arg value="-case=${test.case}"/>
            <env key="LC_ALL" value="C"/>
        </exec-scipio-jar>
        <delete dir="runtime/logs/test-results/${test.component}-${test.case}"/>
        <mkdir dir="runtime/logs/test-results/${test.component}-${test.case}"/>
        <move todir="runtime/logs/test-results/${test.component}-${test.case}">
            <fileset dir="runtime/logs/test-results" includes="*.xml"/>
        </move>
        <fail message="Test run was unsuccessful">
            <condition>
                <not>
                    <equals arg1="${test.result}" arg2="0"/>
                </not>
            </condition>
        </fail>
    </target>
    <target name="run-test-debug"
            description="Run a single test in debug mode, syntax eg: ant run-test-debug -Dtest.component=service -Dtest.case=service-soap-tests">
      <fail unless="test.component">test.component is a required parameter: -Dtest.component=componentname</fail>
      <fail unless="test.case">test.case is a required parameter: -Dtest.case=testcasename</fail>
      <exec-scipio-jar resultproperty="test.result">
        <jvmarg value="-Xnoagent"/>
        <jvmarg value="-Djava.compiler=NONE"/>
        <jvmarg value="-Xdebug"/>
        <jvmarg value="-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8091"/>
        <arg value="test"/>
        <arg value="-component=${test.component}"/>
        <arg value="-case=${test.case}"/>
        <env key="LC_ALL" value="C"/>
      </exec-scipio-jar>
      <delete dir="runtime/logs/test-results/${test.component}-${test.case}"/>
      <mkdir dir="runtime/logs/test-results/${test.component}-${test.case}"/>
      <move todir="runtime/logs/test-results/${test.component}-${test.case}">
        <fileset dir="runtime/logs/test-results" includes="*.xml"/>
      </move>
      <fail message="Test run was unsuccessful">
        <condition>
          <not>
            <equals arg1="${test.result}" arg2="0"/>
          </not>
        </condition>
      </fail>
    </target>
    <target name="run-test-suite"
            description="Run a single test suite, syntax eg: ant run-test-suite -Dtest.component=mycomponent -Dtest.suiteName=mytests">
        <fail unless="test.component">test.component is a required parameter: -Dtest.component=componentname</fail>
        <fail unless="test.suiteName">test.suiteName is a required parameter: -Dtest.suiteName=testsuitename</fail>
        <exec-scipio-jar resultproperty="test.result">
            <arg value="test"/>
            <arg value="-component=${test.component}"/>
            <arg value="-suitename=${test.suiteName}"/>
            <env key="LC_ALL" value="C"/>
        </exec-scipio-jar>
        <fail message="Test run was unsuccessful">
            <condition>
                <not>
                    <equals arg1="${test.result}" arg2="0"/>
                </not>
            </condition>
        </fail>
    </target>
    <target name="run-test-list" depends="_setup-separated-test-run"
            description="Run all configured tests, stopping/starting Scipio ERP between each test">
        <delete dir="runtime/logs/test-results"/>
        <ant antfile="runtime/test-list-build.xml" target="all-tests"/>
    </target>

    <target name="cobertura-report" depends="run-tests-with-cobertura"
            description="Generate a HTML code coverage report with cobertura, can be found in runtime/logs/cobertura-report">
        <delete dir="runtime/logs/cobertura-report"/>
        <mkdir dir="runtime/logs/cobertura-report"/>
        <taskdef resource="tasks.properties" classpathref="cobertura.class.path"/>
        <cobertura-merge datafile="runtime/logs/cobertura.dat">
            <fileset dir="runtime/logs">
                <include name="cobertura-base.dat"/>
                <include name="cobertura-components.dat"/>
            </fileset>
        </cobertura-merge>
        <cobertura-report datafile="runtime/logs/cobertura.dat" destdir="runtime/logs/cobertura-report">
            <dirset dir=".">
                <include name="*/*/src"/>
            </dirset>

            <include name="**/*.java"/>
        </cobertura-report>
    </target>

    <target name="cobertura-report-xml" depends="run-tests-with-cobertura"
            description="Generate a XML file from the cobertura report, this will be used by sonar">
        <delete dir="runtime/logs/cobertura-report"/>
        <mkdir dir="runtime/logs/cobertura-report"/>
        <taskdef resource="tasks.properties" classpathref="cobertura.class.path"/>
        <cobertura-merge datafile="runtime/logs/cobertura.dat">
            <fileset dir="runtime/logs">
                <include name="cobertura-base.dat"/>
                <include name="cobertura-components.dat"/>
            </fileset>
        </cobertura-merge>
        <cobertura-report format="xml" datafile="runtime/logs/cobertura.dat" destdir="runtime/logs/cobertura-report">
            <dirset dir=".">
                <include name="*/*/src"/>
            </dirset>
            <include name="**/*.java"/>
        </cobertura-report>
    </target>

    <target name="sonar" depends="download-sonar-ant-task,sonar-init"
            description="Sonar code analysis. You need a Sonar instance running to use it. More info on http://www.sonarsource.org/
            Available Parameters: sonar.organization, sonar.host.url, sonar.login
            For external sonar server (sonarcloud), use ./ant sonar -Dsonar.host.url=https://sonarcloud.io -Dsonar.organization=... -Dsonar.login=...
            ">
        <!-- SCIPIO: now git
        <exec executable="svn" dir="." output="runtime/svninfo_tmp.xml">
            <arg value="info"/>
            <arg value="- -xml"/>
        </exec>
        <xmlproperty file="runtime/svninfo_tmp.xml"/>-->
        <exec executable="git" outputproperty="git.info.revision">
            <arg value="rev-parse"/>
            <arg value="HEAD"/>
        </exec>

        <property name="sonar.sources" value="framework/base/src,
            framework/catalina/src, framework/common/src, framework/datafile/src, framework/entity/src, framework/entityext/src,
            framework/minilang/src, framework/security/src, framework/service/src, framework/start/src,
            framework/testtools/src, framework/webapp/src, framework/webtools/src, framework/widget/src,
            applications/accounting/src, applications/content/src, applications/humanres/src,
            applications/manufacturing/src, applications/marketing/src, applications/order/src, applications/party/src,
            applications/product/src, applications/securityext/src, applications/workeffort/src, specialpurpose/assetmaint/src"
            />
        <property name="sonar.tests" value="framework/base/src/org/ofbiz/base/test, framework/entity/src/org/ofbiz/entity/test,
            framework/service/src/org/ofbiz/service/test, applications/accounting/src/org/ofbiz/accounting/test,
            applications/product/src/org/ofbiz/product/test, applications/product/src/org/ofbiz/shipment/test" />
        
        <property name="sonar.exclusions" value="**/*test*/**" />
        <property name="sonar.java.binaries" value="**/classes" />        

        <!-- list of optional Sonar properties -->
        <property name="sonar.projectName" value="SCIPIO ERP" />
        <!-- SCIPIO: this was for old sonar-ant-task
        <sonar:sonar key="org.apache:ofbiz" version="${info.entry.commit(revision)}" xmlns:sonar="antlib:org.sonar.ant:sonar"/>-->
        <property name="sonar.projectKey" value="com.ilscipio:scipio" />
        <property name="sonar.projectVersion" value="${git.info.revision}" />
        <property name="sonar.dynamicAnalysis" value="reuseReports" />
        <property name="sonar.cobertura.reportPath" value="runtime/logs/cobertura-report/coverage.xml"/>
        <property name="sonar.java.source" value="1.8" />
        <property name="sonar.java.target" value="1.8" />
        <property name="sonar.host.url" value="${sonar.host.url}" />
        
        <if>
            <isset property="sonar.login"/>
            <then>
                <echo level="verbose" message="Connecting to external sonar server"/>
                <property name="sonar.organization" value="${sonar.organization}"/>
                <property name="sonar.host.url" value="${sonar.host.url}" default="https://sonarcloud.io"/>
                <property name="sonar.login" value="${sonar.login}" />
            </then>
            <else>
                <echo level="verbose" message="Connecting to internal sonar server"/>
                <!-- default for jdbc url: jdbc:mysql://localhost:3306/sonar?useUnicode=true&amp;characterEncoding=utf8-->
                <property name="sonar.jdbc.url" value="${sonar.jdbc.url}"/>
                <property name="sonar.jdbc.driverClassName" value="com.mysql.jdbc.Driver" />
                <property name="sonar.jdbc.username" value="${sonar.jdbc.username}" />
                <property name="sonar.jdbc.password" value="${sonar.jdbc.password}" />
            </else>
        </if>
        <sonar:sonar xmlns:sonar="antlib:org.sonar.ant:sonar"/>        
    </target>

    <target name="full-sonar">
        <antcall target="clean-all"/>
        <antcall target="load-demo"/>
        <antcall target="download-cobertura"/>
        <antcall target="run-tests">
          <param name="-portoffset" value="${portoffset}"/>
        </antcall>
        <antcall target="cobertura-report-xml"/>
        <antcall target="sonar"/>
    </target>

    <!-- ================================================================== -->
    <!--    Ivy targets, more info at  http://ant.apache.org/ivy/  -->
    <!-- ================================================================== -->

    <!-- SCIPIO: 2017-01-30: New ivy download targets -->

    <target name="lib-update" depends="ivy-init,check-build-requisites,build-scipio-build-tools" description="Initial libraries and dependencies download, global">
        <stopwatch name="lib.update.stopwatch" action="start"/>
        <!--
        <tstamp>
             <format property="lib.update.start.time" pattern="yyyy-MM-dd HH:mm:ss"/>
        </tstamp>
        <antcall target="reset-lib-update-status"/>
        -->
        
        <antcall target="framework-lib-update"/>
        <antcall target="themes-lib-update"/>
        <antcall target="applications-lib-update"/>
        <antcall target="specialpurpose-lib-update"/>
        <antcall target="addons-lib-update"/>
        <antcall target="hotdeploy-lib-update"/>
        
        <!-- Removed - not really useful
        <tstamp>
             <format property="lib.update.finish.time" pattern="yyyy-MM-dd HH:mm:ss"/>
        </tstamp>
        <echo message="status=SUCCESS${line.separator}startTime=${lib.update.start.time}${line.separator}finishTime=${lib.update.finish.time}${line.separator}" file="ivy/ivy-status.txt" />
        -->
        <stopwatch name="lib.update.stopwatch" action="total"/>
    </target>
    <target name="lib-update-force" description="Initial libraries and dependencies download, global - forced (even if no change)">
        <property name="lib.update.force" value="true"/>
        <antcall target="lib-update" inheritrefs="true"/>
    </target>
    
    <target name="lib-update-withlibsrc" description="Initial libraries and dependencies AND source JARs download, global">
        <property name="lib.update.sources" value="true"/>
        <antcall target="lib-update" inheritrefs="true"/>
    </target>
    <target name="lib-update-withlibsrc-force" description="Initial libraries and dependencies AND source JARs download, global - forced (even if no change)">
        <property name="lib.update.force" value="true"/>
        <property name="lib.update.sources" value="true"/>
        <antcall target="lib-update" inheritrefs="true"/>
    </target>
    
    <target name="check-lib-update" description="Initial libraries and dependencies download, global, if enabled only">
        <!-- Removed - not really useful (see below): depends="get-lib-update-status" -->
        <if>
            <not><equals arg1="${lib.update.hook.mode}" arg2="global"/></not>
            <then>
                <echo level="verbose" message="Skipping global lib updates (not using global mode)"/>
            </then>
            <elseif>
                <equals arg1="${lib.update.bypass}" arg2="true"/>
                <then>
                    <echo message="Skipping lib updates (bypassed)"/>
                </then>
            </elseif>
            <elseif>
                <or>
                    <equals arg1="${lib.update.force}" arg2="true"/>
                    <equals arg1="${lib.update.force.deploy}" arg2="true"/>
                </or>
                <then>
                    <echo message="Lib updates check forced - starting..."/>
                    <antcall target="lib-update"/>
                </then>
            </elseif>
            <else>
                <echo message="Lib updates check starting..."/>
                <antcall target="lib-update"/>
                <!-- Removed - turns out this check is useless to deal with changes or anything after 
                    the initial download... too simplistic
                <if>
                    <equals arg1="${lib.update.last.status}" arg2="SUCCESS"/>
                    <then>
                        <if>
                            <equals arg1="${lib.update.majorlibs.present}" arg2="true"/>
                            <then>
                                <echo message="Last successful lib download: ${lib.update.last.finishTime} (SUCCESS, not re-running; use -Dlib.update.force=true to force)"/>
                            </then>
                            <else>
                                <echo level="error" message="Lib download: SANITY CHECK FAILED: missing major libraries despite last run status marked success!"/>
                                <echo message="Lib download required (sanity check failed) - starting..."/>
                                <antcall target="lib-update"/>
                            </else>
                        </if>
                    </then>
                    <else>
                        <echo message="Lib download required (last download status unknown or non-success) - starting..."/>
                        <antcall target="lib-update"/>
                    </else>
                </if>-->
            </else>
        </if>
    </target>
    
    <!-- Removed - not really useful
    <target name="reset-lib-update-status">
        <delete file="ivy/ivy-status.txt"/>
    </target>
    
    <target name="get-lib-update-status">
        <property file="ivy/ivy-status.txt" prefix="lib.update.last" />
        <if>
            <isset property="lib.update.last.status"/>
            <then>
                <echo level="verbose" message="Library download status: ${lib.update.last.status}"/>
            </then>
            <else>
                <echo level="verbose" message="Library download status: UNKNOWN (requires run)"/>
            </else>
        </if>
        <!- Sanity check: test if some of the major libraries are present ->
        <condition property="lib.update.majorlibs.present" value="true" else="false">
            <and>
                <resourcecount when="greater" count="0">
                    <fileset file="framework/base/lib/freemarker-*.jar"/>
                </resourcecount>
                <resourcecount when="greater" count="0">
                    <fileset file="framework/catalina/lib/tomcat-*.jar"/>
                </resourcecount>
            </and>
        </condition>
    </target>
    -->

    <target name="framework-lib-update">
        <iterate target="lib-update" filelist="framework-builds"/>
    </target>

    <target name="applications-lib-update" if="${applications.present}">
        <iterate target="lib-update" filelist="application-builds"/>
    </target>

    <target name="specialpurpose-lib-update" if="${specialpurpose.present}">
        <iterate target="lib-update" filelist="specialpurpose-builds"/>
    </target>
    
    <target name="addons-lib-update" depends="check-build-requisites">
        <addonsant target="lib-update"/>
    </target>
    
    <target name="hotdeploy-lib-update" depends="check-build-requisites">
        <hotdeployant target="lib-update"/>
    </target>
    
    <target name="themes-lib-update" depends="check-build-requisites">
        <dep-subant dir="${basedir}/themes" target="lib-update"/>
    </target>
    
    <target name="lib-clean" depends="ivy-init" description="Libraries and dependencies clean - by default, cleans ivy resolution cache (but not repository/download cache) and removes deployed JARs [same as clean-ivy-deployed]">
        <stopwatch name="lib.clean.stopwatch" action="start"/>

        <if>
            <not><equals arg1="${lib.clean.cache}" arg2="false"/></not>
            <then>
                <antcall target="lib-clean-cache" inheritrefs="true"/>
            </then>
        </if>
        <if>
            <not><equals arg1="${lib.clean.deployed}" arg2="false"/></not>
            <then>
                <antcall target="lib-clean-deployed" inheritrefs="true"/>
            </then>
        </if>

        <stopwatch name="lib.clean.stopwatch" action="total"/>
    </target>
    <target name="clean-ivy-deployed" depends="lib-clean" description="Libraries and dependencies clean - by default, cleans ivy resolution cache (but not repository/download cache) and removes deployed JARs [alias for lib-clean]">
    </target>
    
    <target name="clean-ivy" depends="ivy-init" description="Cleans Ivy resolution cache (but not repository/download cache, unless lib.clean.cache.repo=true) [alias for lib-clean-cache]">
        <!-- SCIPIO: NOTE: 2017-02-03: the cache is split between repository and resolution cache.
            99% of the time, emptying the repository cache is a giant waste of time, so don't do it
            by default. -->
        <if>
            <equals arg1="${lib.clean.cache.repo}" arg2="true"/>
            <then>
                <ivy:cleancache/>
            </then>
            <else><!-- lib.clean.cache.resolve -->
                <delete dir="ivy/resolutionCache"/>
            </else>
        </if>
    </target>
    <target name="lib-clean-cache" depends="clean-ivy" description="Cleans Ivy resolution cache (but not repository/download cache, unless lib.clean.cache.repo=true) [same as clean-ivy]">
    </target>
    
    <target name="clean-ivy-full" depends="ivy-init" description="Cleans Ivy resolution and repository/download caches (forces lib re-download, may affect other projects) [alias for lib-clean-cache-full]">
        <!-- SCIPIO: NOTE: because the repository cache uses the default ivy user cache, this may affect other projects -->
        <ivy:cleancache/>
    </target>
    <target name="lib-clean-cache-full" depends="clean-ivy-full" description="Cleans Ivy resolution and repository/download caches (forces lib re-download, may affect other projects) [same as clean-ivy-full]">
    </target>
    
    <target name="lib-clean-deployed" depends="check-build-requisites" description="Cleans out the library deployment folders (but not library/ivy caches)">
        <antcall target="framework-lib-clean"/>
        <antcall target="themes-lib-clean"/>
        <antcall target="applications-lib-clean"/>
        <antcall target="specialpurpose-lib-clean"/>
        <antcall target="addons-lib-clean"/>
        <antcall target="hotdeploy-lib-clean"/>
    </target>
    
    <target name="framework-lib-clean">
        <iterate target="lib-clean" filelist="framework-builds"/>
    </target>

    <target name="applications-lib-clean" if="${applications.present}">
        <iterate target="lib-clean" filelist="application-builds"/>
    </target>

    <target name="specialpurpose-lib-clean" if="${specialpurpose.present}">
        <iterate target="lib-clean" filelist="specialpurpose-builds"/>
    </target>
    
    <target name="addons-lib-clean" depends="check-build-requisites">
        <addonsant target="lib-clean"/>
    </target>
    
    <target name="hotdeploy-lib-clean" depends="check-build-requisites">
        <hotdeployant target="lib-clean"/>
    </target>
    
    <target name="themes-lib-clean" depends="check-build-requisites">
        <dep-subant dir="${basedir}/themes" target="lib-clean"/>
    </target>
    
    <target name="lib-dep-tree" depends="check-build-requisites" description="Shows library dependency trees for all components with an ivyfile">
        <iterate target="lib-dep-tree" filelist="framework-builds"/>
        <iterate target="lib-dep-tree" filelist="application-builds"/>
        <iterate target="lib-dep-tree" filelist="specialpurpose-builds"/>
        <addonsant target="lib-dep-tree"/>
        <hotdeployant target="lib-dep-tree"/>
        <dep-subant dir="${basedir}/themes" target="lib-dep-tree"/>
    </target>
    
    <target name="lib-dep-report" depends="check-build-requisites" description="Generate library dependency HTML reports">
        <iterate target="lib-dep-report" filelist="framework-builds"/>
        <iterate target="lib-dep-report" filelist="application-builds"/>
        <iterate target="lib-dep-report" filelist="specialpurpose-builds"/>
        <addonsant target="lib-dep-report"/>
        <hotdeployant target="lib-dep-report"/>
        <dep-subant dir="${basedir}/themes" target="lib-dep-report"/>
    </target>
    
    <target name="lib-clean-dep-report" description="Cleans out runtime/analysis/lib-dep-report">
        <delete includeemptydirs="true" verbose="on">
            <fileset dir="./runtime/analysis/lib-dep-report" includes="**" erroronmissingdir="false" />
        </delete>
    </target>
    
    <target name="lib-dep-checkupdates" depends="check-build-requisites" description="Check for library dependency updates">
        <iterate target="lib-dep-checkupdates" filelist="framework-builds"/>
        <iterate target="lib-dep-checkupdates" filelist="application-builds"/>
        <iterate target="lib-dep-checkupdates" filelist="specialpurpose-builds"/>
        <addonsant target="lib-dep-checkupdates"/>
        <hotdeployant target="lib-dep-checkupdates"/>
        <dep-subant dir="${basedir}/themes" target="lib-dep-checkupdates"/>
    </target>

    <target name="download-ant-ext" depends="ivy-init">
        <delete verbose="on"><fileset dir="framework/base/lib/ant-ext" includes="*.jar"/></delete>
        <ivy:retrieve file="${lib.comp.base.ivyfile}" pattern="framework/base/lib/ant-ext/[artifact]-[revision].[ext]" conf="ant-ext"/>
    </target>    
    
    <target name="download-activemq" depends="ivy-init" description="Download activemq for DCC (Distributed Cache Clearing">
        <delete verbose="on"><fileset dir="framework/base/lib/ant-opt/activemq" includes="*.jar"/></delete>
        <delete verbose="on"><fileset dir="framework/base/lib" includes="activemq-*.jar"/></delete><!-- compatibility -->
        <ivy:retrieve file="${lib.comp.base.ivyfile}" pattern="framework/base/lib/ant-opt/activemq/[artifact]-[revision].[ext]" conf="activemq"/>
        <echo> </echo>
        <echo>======================================================</echo>
        <echo>Please check that this version is appropriate for you!</echo>
    </target>

    <target name="download-cobertura" depends="ivy-init,download-ant-ext" description="Download cobertura related files">
        <delete verbose="on"><fileset dir="framework/base/lib/ant-opt/cobertura" includes="*.jar"/></delete>
        <ivy:retrieve file="${lib.comp.base.ivyfile}" pattern="framework/base/lib/ant-opt/cobertura/[artifact]-[revision].[ext]" conf="cobertura"/>
    </target>
    
    <target name="download-jacoco" depends="ivy-init,download-ant-ext" description="Download JaCoCo related files">
        <delete verbose="on"><fileset dir="framework/base/lib/ant-opt/jacoco" includes="*.jar"/></delete>
        <ivy:retrieve file="${lib.comp.base.ivyfile}" pattern="framework/base/lib/ant-opt/jacoco/[artifact]-[revision].[ext]" conf="jacoco"/>
    </target>

    <target name="download-PG-JDBC" depends="download-jdbc-postgresql" description="Download postgres jdbc driver (legacy alias for download-jdbc-postgresql)">
    </target>

    <target name="download-sonar-ant-task" depends="ivy-init" description="Download sonar related files">
        <delete verbose="on"><fileset dir="framework/base/lib/ant-opt/sonar-ant-task" includes="*.jar"/></delete>
        <ivy:retrieve file="${lib.comp.base.ivyfile}" pattern="framework/base/lib/ant-opt/sonar-ant-task/[artifact]-[revision].[ext]" conf="sonar-ant-task"/>
    </target>

    <target name="download-mySQL-JDBC" depends="download-jdbc-mysql" description="Download mySQL jdbc driver (legacy alias for download-jdbc-mysql)">
    </target>
    
    <!-- SCIPIO: new JDBC targets with consistent naming and common operation (where possible) -->
    <target name="download-jdbc-common" depends="ivy-init" description="Download postgres jdbc driver (alias for download-PG-JDBC)">
        <ivy:retrieve file="${ofbiz.home.dir}/framework/entity/ivy.xml" pattern="framework/entity/lib/jdbc/[artifact]-[revision].[ext]" conf="${lib.entity.jdbc.conf}"/>
        <echo> </echo>
        <echo>======================================================</echo>
        <echo>Please check that this version is appropriate for you!</echo>
    </target>

    <target name="download-jdbc-derby" description="Download Derby JDBC driver">
        <delete verbose="on"><fileset dir="framework/entity/lib/jdbc" includes="derby-*.jar"/></delete>
        <property name="lib.entity.jdbc.conf" value="derby"/>
        <antcall target="download-jdbc-common"/>
    </target>
    <target name="download-jdbc-jaybird" description="Download Firebird (Jaybird) JDBC driver">
        <delete verbose="on"><fileset dir="framework/entity/lib/jdbc" includes="jaybird-*.jar"/></delete>
        <property name="lib.entity.jdbc.conf" value="jaybird"/>
        <antcall target="download-jdbc-common"/>
    </target>
    <target name="download-jdbc-firebird" depends="download-jdbc-jaybird" description="Download Firebird (Jaybird) JDBC driver (alias for download-jdbc-jaybird)">
    </target>
    <target name="download-jdbc-hsqldb" description="Download hsqldb JDBC driver">
        <delete verbose="on"><fileset dir="framework/entity/lib/jdbc" includes="hsqldb-*.jar"/></delete>
        <property name="lib.entity.jdbc.conf" value="hsqldb"/>
        <antcall target="download-jdbc-common"/>
    </target>
    <target name="download-jdbc-mssql" description="Download MSSQL JDBC driver">
        <delete verbose="on"><fileset dir="framework/entity/lib/jdbc" includes="mssql-*.jar"/></delete>
        <property name="lib.entity.jdbc.conf" value="mssql"/>
        <antcall target="download-jdbc-common"/>
    </target>
    <target name="download-jdbc-mysql" description="Download mySQL JDBC driver">
        <delete verbose="on"><fileset dir="framework/entity/lib/jdbc" includes="mysql-*.jar"/></delete>
        <property name="lib.entity.jdbc.conf" value="mysql"/>
        <antcall target="download-jdbc-common"/>
    </target>
    <target name="download-jdbc-mariadb" description="Download MariaDB JDBC driver">
        <delete verbose="on"><fileset dir="framework/entity/lib/jdbc" includes="mariadb-*.jar"/></delete>
        <property name="lib.entity.jdbc.conf" value="mariadb"/>
        <antcall target="download-jdbc-common"/>
    </target>
    <target name="download-jdbc-postgresql" description="Download PostgreSQL JDBC driver">
        <delete verbose="on"><fileset dir="framework/entity/lib/jdbc" includes="postgresql-*.jar"/></delete>
        <property name="lib.entity.jdbc.conf" value="postgresql"/>
        <antcall target="download-jdbc-common"/>
    </target>

    <target name="download-util-all" description="Utility target to download all utilities (except JDBC)">
        <antcall target="download-activemq"/>
        <antcall target="download-cobertura"/>
        <antcall target="download-jacoco"/>
        <antcall target="download-sonar-ant-task"/>
    </target>

    <target name="download-jdbc-all" description="Utility target to download all JDBC drivers, for testing purposes">
        <antcall target="download-jdbc-derby"/>
        <antcall target="download-jdbc-jaybird"/>
        <antcall target="download-jdbc-hsqldb"/>
        <antcall target="download-jdbc-mysql"/>
        <antcall target="download-jdbc-mariadb"/>
        <antcall target="download-jdbc-postgresql"/>
    </target>

    <target name="clean-ant-js" description="Clean Ant Javascript engine files">
        <delete verbose="on"><fileset dir="framework/base/lib/ant-ext/js" includes="*.jar"/></delete>
    </target>

    <target name="download-ant-js" depends="ivy-init,clean-ant-js" description="Download Ant Javascript related files (JDK15+)">
        <ivy:retrieve file="${lib.comp.base.ivyfile}" pattern="framework/base/lib/ant-ext/js/[artifact]-[revision].[ext]" conf="ant-js-${lib.ant.js.engine.name}"/>
    </target>

    <target name="download-ant-js-nashorn" depends="ivy-init,clean-ant-js" description="Download Ant Javascript Nashorn related files (JDK15+)">
        <ivy:retrieve file="${lib.comp.base.ivyfile}" pattern="framework/base/lib/ant-ext/js/[artifact]-[revision].[ext]" conf="ant-js-nashorn"/>
    </target>

    <!-- ================================================================== -->
    <!-- Create New Component. This target will create basic directory structure for an Scipio ERP component in hot-deploy directory. -->
    <!-- ================================================================== -->

    <!-- SCIPIO: Added non-interactive support:
        ./ant create-component -Dcomponent-name=mycomponent -Dcomponent-resource-name=MyComponent -Dwebapp-name=mycomponent -Dbase-permission=MYCOMPONENT -Dcomponent-package=org.mycompany.myprojects -Dconfirm-component-creation=y -->
    <target name="create-component"
            description="Create the layout of a Scipio component in the hot-deploy folder.">

        <input addproperty="component-name" message="Component name (lowercase): (e.g. mycomponent) [Mandatory]" unless:set="component-name"/>
        <input addproperty="component-resource-name" message="Component resource name (CamelCase): (e.g. MyComponent) [Mandatory]" unless:set="component-resource-name"/>
        <input addproperty="webapp-name" message="Webapp name (lowercase): (e.g. mycomponent) [Mandatory]" unless:set="webapp-name"/>
        <input addproperty="base-permission" message="Base permission (UPPERCASE): (e.g. MYCOMPONENT) [Mandatory]" unless:set="base-permission"/>
        <input addproperty="component-package" message="Organization (package/group): (e.g. org.mycompany.myprojects) [default: com.ilscipio.scipio.ce.external]" defaultvalue="com.ilscipio.scipio.ce.external" unless:set="component-package"/>

        <echo>The following hot-deploy component will be created:
              Name: ${component-name}
              Resource Name: ${component-resource-name}
              Webapp Name: ${webapp-name}
              Base permission: ${base-permission}
              Folder: ${basedir}/hot-deploy/${component-name}
        </echo>
        <input addproperty="confirm-component-creation" message="Confirm: " defaultvalue="N" validargs="Y,N,y,n" unless:set="confirm-component-creation"/>
        <fail message="Component creation cancelled by the user.">
            <condition>
                <equals arg1="${confirm-component-creation}" arg2="N" casesensitive="false"/>
            </condition>
        </fail>
        <fail message="Component name is mandatory">
            <condition>
                <equals arg1="${component-name}" arg2="" casesensitive="false" trim="yes"/>
            </condition>
        </fail>
        <fail message="Resource name is mandatory">
            <condition>
                <equals arg1="${component-resource-name}" arg2="" casesensitive="false" trim="yes"/>
            </condition>
        </fail>
        <fail message="Webapp name is mandatory">
            <condition>
                <equals arg1="${webapp-name}" arg2="" casesensitive="false" trim="yes"/>
            </condition>
        </fail>
        <fail message="Base permission is mandatory">
            <condition>
                <equals arg1="${base-permission}" arg2="" casesensitive="false" trim="yes"/>
            </condition>
        </fail>
        <fail message="Organization is mandatory">
            <condition>
                <equals arg1="${component-package}" arg2="" casesensitive="false" trim="yes"/>
            </condition>
        </fail>
        <filterset id="replacePlaceholders">
            <filter token="component-name" value="${component-name}"/>
            <filter token="component-resource-name" value="${component-resource-name}"/>
            <filter token="base-permission" value="${base-permission}"/>
            <filter token="webapp-name" value="${webapp-name}"/>
            <filter token="component-package" value="${component-package}"/>
        </filterset>
        <mkdir dir="${basedir}/hot-deploy/${component-name}"/>
        <copy file="${basedir}/framework/resources/templates/.gitignore-component" tofile="${basedir}/hot-deploy/${component-name}/.gitignore"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/config"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/data"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/data/helpdata"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/dtd"/>
        <copy file="${basedir}/framework/resources/templates/.gitignore-empty" tofile="${basedir}/hot-deploy/${component-name}/dtd/.gitignore"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/documents"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/entitydef"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/lib"/>
        <copy file="${basedir}/framework/resources/templates/.gitignore-lib" tofile="${basedir}/hot-deploy/${component-name}/lib/.gitignore"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/libsrc"/>
        <copy file="${basedir}/framework/resources/templates/.gitignore-lib" tofile="${basedir}/hot-deploy/${component-name}/libsrc/.gitignore"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/patches"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/patches/test"/>
        <copy file="${basedir}/framework/resources/templates/.gitignore-empty" tofile="${basedir}/hot-deploy/${component-name}/patches/test/.gitignore"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/patches/qa"/>
        <copy file="${basedir}/framework/resources/templates/.gitignore-empty" tofile="${basedir}/hot-deploy/${component-name}/patches/qa/.gitignore"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/patches/production"/>
        <copy file="${basedir}/framework/resources/templates/.gitignore-empty" tofile="${basedir}/hot-deploy/${component-name}/patches/production/.gitignore"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/script"/>
        <copy file="${basedir}/framework/resources/templates/.gitignore-empty" tofile="${basedir}/hot-deploy/${component-name}/script/.gitignore"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/servicedef"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/src"/>
        <copy file="${basedir}/framework/resources/templates/.gitignore-empty" tofile="${basedir}/hot-deploy/${component-name}/src/.gitignore"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/testdef"/>
        <copy file="${basedir}/framework/resources/templates/.gitignore-empty" tofile="${basedir}/hot-deploy/${component-name}/testdef/.gitignore"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/webapp"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/webapp/${webapp-name}"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/webapp/${webapp-name}/error"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/webapp/${webapp-name}/WEB-INF"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/webapp/${webapp-name}/WEB-INF/actions"/>
        <copy file="${basedir}/framework/resources/templates/.gitignore-empty" tofile="${basedir}/hot-deploy/${component-name}/webapp/${webapp-name}/WEB-INF/actions/.gitignore"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/widget/"/>
        <copy file="${basedir}/framework/resources/templates/scipio-component.xml" tofile="${basedir}/hot-deploy/${component-name}/scipio-component.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/build.xml" tofile="${basedir}/hot-deploy/${component-name}/build.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/ivy.xml" tofile="${basedir}/hot-deploy/${component-name}/ivy.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/TypeData.xml" tofile="${basedir}/hot-deploy/${component-name}/data/${component-resource-name}TypeData.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/SecurityPermissionSeedData.xml" tofile="${basedir}/hot-deploy/${component-name}/data/${component-resource-name}SecurityPermissionSeedData.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/SecurityGroupDemoData.xml" tofile="${basedir}/hot-deploy/${component-name}/data/${component-resource-name}SecurityGroupDemoData.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/DemoData.xml" tofile="${basedir}/hot-deploy/${component-name}/data/${component-resource-name}DemoData.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/HELP.xml" tofile="${basedir}/hot-deploy/${component-name}/data/helpdata/HELP_${component-resource-name}.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/document.xml" tofile="${basedir}/hot-deploy/${component-name}/documents/${component-resource-name}.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/entitymodel.xml" tofile="${basedir}/hot-deploy/${component-name}/entitydef/entitymodel.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/services.xml" tofile="${basedir}/hot-deploy/${component-name}/servicedef/services.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/Tests.xml" tofile="${basedir}/hot-deploy/${component-name}/testdef/${component-resource-name}Tests.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/UiLabels.xml" tofile="${basedir}/hot-deploy/${component-name}/config/${component-resource-name}UiLabels.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/index.jsp" tofile="${basedir}/hot-deploy/${component-name}/webapp/${webapp-name}/index.jsp" encoding="iso-8859-1">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <!-- SCIPIO: gone
        <copy file="${basedir}/framework/resources/templates/error.jsp" tofile="${basedir}/hot-deploy/${component-name}/webapp/${webapp-name}/error/error.jsp" encoding="iso-8859-1">
            <filterset refid="replacePlaceholders"/>
        </copy>-->
        <copy file="${basedir}/framework/resources/templates/controller.xml" tofile="${basedir}/hot-deploy/${component-name}/webapp/${webapp-name}/WEB-INF/controller.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/web.xml" tofile="${basedir}/hot-deploy/${component-name}/webapp/${webapp-name}/WEB-INF/web.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/CommonScreens.xml" tofile="${basedir}/hot-deploy/${component-name}/widget/CommonScreens.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/Screens.xml" tofile="${basedir}/hot-deploy/${component-name}/widget/${component-resource-name}Screens.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/Menus.xml" tofile="${basedir}/hot-deploy/${component-name}/widget/${component-resource-name}Menus.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/Forms.xml" tofile="${basedir}/hot-deploy/${component-name}/widget/${component-resource-name}Forms.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <echo>Component successfully created in folder ${basedir}/hot-deploy/${component-name}.
            Restart Scipio and then visit the URL: https://localhost:8443/${webapp-name}
        </echo>
    </target>
    
    <!-- SCIPIO: new; added non-interactive support:
        ./ant create-component-shop-override -Dcomponent-name=mycomponent -Dcomponent-resource-name=MyComponent -Dwebapp-name=mycomponent -Dbase-permission=MYCOMPONENT -Dcomponent-package=org.mycompany.myprojects -Dconfirm-component-creation=Y -->
    <target name="create-component-shop-override"
            description="Create the layout of a Scipio shop webapp override component in the hot-deploy folder. (SCIPIO)">
        <input addproperty="component-name" message="Component name (lowercase): (e.g. mycomponent) [Mandatory]" unless:set="component-name"/>
        <input addproperty="component-resource-name" message="Component resource name (CamelCase): (e.g. MyComponent) [Mandatory]" unless:set="component-resource-name"/>
        <input addproperty="webapp-name" message="Webapp name (lowercase): (e.g. mycomponent) [default: ${component-name}]" defaultvalue="${component-name}" unless:set="webapp-name"/>
        <!--<input addproperty="base-permission" message="Base permission (uppercase): (e.g. MYCOMPONENT) [default: SHOP]" defaultvalue="SHOP" unless:set="base-permission"/>-->
        <property name="base-permission" value="SHOP" unless:set="base-permission"/>
        <input addproperty="component-package" message="Organization (package/group): (e.g. org.mycompany.myprojects) [default: com.ilscipio.scipio.ce.external]" defaultvalue="com.ilscipio.scipio.ce.external" unless:set="component-package"/>

        <!-- TODO? more options -->
        <echo>The following hot-deploy component will be created:
              Name: ${component-name}
              Resource Name: ${component-resource-name}
              Webapp Name: ${webapp-name}
              Base permission: ${base-permission}
              Folder: ${basedir}/hot-deploy/${component-name}
            
              The webapp will automatically override the one defined in /applications/shop/scipio-component.xml, and it will have:
              webSiteId: ScipioWebStore
              mount-point: /shop
              demo data: inherited from /applications/shop/data/
            
              NOTE: If you have modified /applications/shop directly in the filesystem, some of those changes may be carried over here.
        </echo>
        <input addproperty="confirm-component-creation" message="Confirm: " defaultvalue="N" validargs="Y,N,y,n" unless:set="confirm-component-creation"/>
        <fail message="Component creation cancelled by the user.">
            <condition>
                <equals arg1="${confirm-component-creation}" arg2="N" casesensitive="false"/>
            </condition>
        </fail>
        <fail message="Component name is mandatory">
            <condition>
                <equals arg1="${component-name}" arg2="" casesensitive="false" trim="yes"/>
            </condition>
        </fail>
        <fail message="Resource name is mandatory">
            <condition>
                <equals arg1="${component-resource-name}" arg2="" casesensitive="false" trim="yes"/>
            </condition>
        </fail>
        <fail message="Webapp name is mandatory">
            <condition>
                <equals arg1="${webapp-name}" arg2="" casesensitive="false" trim="yes"/>
            </condition>
        </fail>
        <fail message="Base permission is mandatory">
            <condition>
                <equals arg1="${base-permission}" arg2="" casesensitive="false" trim="yes"/>
            </condition>
        </fail>
        <fail message="Organization is mandatory">
            <condition>
                <equals arg1="${component-package}" arg2="" casesensitive="false" trim="yes"/>
            </condition>
        </fail>
        <filterset id="replacePlaceholders">
            <filter token="component-name" value="${component-name}"/>
            <filter token="component-resource-name" value="${component-resource-name}"/>
            <filter token="base-permission" value="${base-permission}"/>
            <filter token="webapp-name" value="${webapp-name}"/>
            <filter token="component-package" value="${component-package}"/>
        </filterset>
        <mkdir dir="${basedir}/hot-deploy/${component-name}"/>
        <copy file="${basedir}/framework/resources/templates/.gitignore-component" tofile="${basedir}/hot-deploy/${component-name}/.gitignore"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/config"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/data"/>
        <!--<mkdir dir="${basedir}/hot-deploy/${component-name}/data/helpdata"/>-->
        <!--<mkdir dir="${basedir}/hot-deploy/${component-name}/dtd"/>-->
        <!--<mkdir dir="${basedir}/hot-deploy/${component-name}/documents"/>-->
        <mkdir dir="${basedir}/hot-deploy/${component-name}/entitydef"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/lib"/>
        <copy file="${basedir}/framework/resources/templates/.gitignore-lib" tofile="${basedir}/hot-deploy/${component-name}/lib/.gitignore"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/libsrc"/>
        <copy file="${basedir}/framework/resources/templates/.gitignore-lib" tofile="${basedir}/hot-deploy/${component-name}/libsrc/.gitignore"/>
        <!--<mkdir dir="${basedir}/hot-deploy/${component-name}/patches"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/patches/test"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/patches/qa"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/patches/production"/>-->
        <mkdir dir="${basedir}/hot-deploy/${component-name}/script"/>
        <copy file="${basedir}/framework/resources/templates/.gitignore-empty" tofile="${basedir}/hot-deploy/${component-name}/script/.gitignore"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/servicedef"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/src"/>
        <copy file="${basedir}/framework/resources/templates/.gitignore-empty" tofile="${basedir}/hot-deploy/${component-name}/src/.gitignore"/>
        <!--<mkdir dir="${basedir}/hot-deploy/${component-name}/testdef"/>-->
        <mkdir dir="${basedir}/hot-deploy/${component-name}/templates"/>
        <copy file="${basedir}/framework/resources/templates/.gitignore-empty" tofile="${basedir}/hot-deploy/${component-name}/templates/.gitignore"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/webapp"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/webapp/${webapp-name}"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/webapp/${webapp-name}/error"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/webapp/${webapp-name}/images"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/webapp/${webapp-name}/WEB-INF"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/webapp/${webapp-name}/WEB-INF/actions"/>
        <mkdir dir="${basedir}/hot-deploy/${component-name}/widget/"/>
        <copy file="${basedir}/framework/resources/templates/shop-override/scipio-component.xml" tofile="${basedir}/hot-deploy/${component-name}/scipio-component.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/shop/build.xml" tofile="${basedir}/hot-deploy/${component-name}/build.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/ivy.xml" tofile="${basedir}/hot-deploy/${component-name}/ivy.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <!--<copy file="${basedir}/framework/resources/templates/TypeData.xml" tofile="${basedir}/hot-deploy/${component-name}/data/${component-resource-name}TypeData.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>-->
        <!--<copy file="${basedir}/framework/resources/templates/SecurityPermissionSeedData.xml" tofile="${basedir}/hot-deploy/${component-name}/data/${component-resource-name}SecurityPermissionSeedData.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>-->
        <!--<copy file="${basedir}/framework/resources/templates/SecurityGroupDemoData.xml" tofile="${basedir}/hot-deploy/${component-name}/data/${component-resource-name}SecurityGroupDemoData.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>-->
        <!--<copy file="${basedir}/framework/resources/templates/DemoData.xml" tofile="${basedir}/hot-deploy/${component-name}/data/${component-resource-name}DemoData.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>-->
        <!--<copy file="${basedir}/framework/resources/templates/HELP.xml" tofile="${basedir}/hot-deploy/${component-name}/data/helpdata/HELP_${component-resource-name}.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>-->
        <copy file="${basedir}/framework/resources/templates/shop-override/data/CatalogData.xml" tofile="${basedir}/hot-deploy/${component-name}/data/${component-resource-name}CatalogData.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/shop-override/data/DemoData.xml" tofile="${basedir}/hot-deploy/${component-name}/data/${component-resource-name}DemoData.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/shop-override/data/ProductData.xml" tofile="${basedir}/hot-deploy/${component-name}/data/${component-resource-name}ProductData.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/shop-override/data/SecurityGroupDemoData.xml" tofile="${basedir}/hot-deploy/${component-name}/data/${component-resource-name}SecurityGroupDemoData.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/shop-override/data/SecurityPermissionSeedData.xml" tofile="${basedir}/hot-deploy/${component-name}/data/${component-resource-name}SecurityPermissionSeedData.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/shop-override/data/ShippingData.xml" tofile="${basedir}/hot-deploy/${component-name}/data/${component-resource-name}ShippingData.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/shop-override/data/StoreData.xml" tofile="${basedir}/hot-deploy/${component-name}/data/${component-resource-name}StoreData.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/shop-override/data/TaxAuthorityData.xml" tofile="${basedir}/hot-deploy/${component-name}/data/${component-resource-name}TaxAuthorityData.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <!--<copy file="${basedir}/framework/resources/templates/document.xml" tofile="${basedir}/hot-deploy/${component-name}/documents/${component-resource-name}.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>-->
        <copy file="${basedir}/framework/resources/templates/entitymodel.xml" tofile="${basedir}/hot-deploy/${component-name}/entitydef/entitymodel.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/services.xml" tofile="${basedir}/hot-deploy/${component-name}/servicedef/services.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <!--<copy file="${basedir}/framework/resources/templates/Tests.xml" tofile="${basedir}/hot-deploy/${component-name}/testdef/${component-resource-name}Tests.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>-->
        <copy file="${basedir}/framework/resources/templates/UiLabels.xml" tofile="${basedir}/hot-deploy/${component-name}/config/${component-resource-name}UiLabels.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <!--<copy file="${basedir}/framework/resources/templates/index.jsp" tofile="${basedir}/hot-deploy/${component-name}/webapp/${webapp-name}/index.jsp" encoding="iso-8859-1">
            <filterset refid="replacePlaceholders"/>
        </copy>-->
        <!-- SCIPIO: gone
        <copy file="${basedir}/framework/resources/templates/error.jsp" tofile="${basedir}/hot-deploy/${component-name}/webapp/${webapp-name}/error/error.jsp" encoding="iso-8859-1">
            <filterset refid="replacePlaceholders"/>
        </copy>-->
        <copy file="${basedir}/framework/resources/templates/shop-override/webapp/shop/WEB-INF/controller.xml" tofile="${basedir}/hot-deploy/${component-name}/webapp/${webapp-name}/WEB-INF/controller.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/shop-override/webapp/shop/WEB-INF/web.xml" tofile="${basedir}/hot-deploy/${component-name}/webapp/${webapp-name}/WEB-INF/web.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/shop/webapp/shop/WEB-INF/urlrewrite.xml" tofile="${basedir}/hot-deploy/${component-name}/webapp/${webapp-name}/WEB-INF/urlrewrite.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/shop/webapp/shop/WEB-INF/actions/ShopSetup.groovy" tofile="${basedir}/hot-deploy/${component-name}/webapp/${webapp-name}/WEB-INF/actions/ShopSetup.groovy" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/shop-override/widget/CommonScreens.xml" tofile="${basedir}/hot-deploy/${component-name}/widget/CommonScreens.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <!--<copy file="${basedir}/framework/resources/templates/Screens.xml" tofile="${basedir}/hot-deploy/${component-name}/widget/${component-resource-name}Screens.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>-->
        <!--<copy file="${basedir}/framework/resources/templates/Menus.xml" tofile="${basedir}/hot-deploy/${component-name}/widget/${component-resource-name}Menus.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>-->
        <!--<copy file="${basedir}/framework/resources/templates/Forms.xml" tofile="${basedir}/hot-deploy/${component-name}/widget/${component-resource-name}Forms.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>-->
        <!-- /applications/shop file copies
            FIXME?: we currently are forced to duplicate the following shop files some of which is not desirable, 
                because no mechanism to extend them... -->
        <copy todir="${basedir}/hot-deploy/${component-name}/webapp/${webapp-name}/">
            <fileset dir="${basedir}/applications/shop/webapp/shop/">
                <include name="images/**"/>
                <include name="error/404.jsp"/>
                <include name="index.jsp"/>
                <include name="robots.txt"/>
            </fileset>
        </copy>
        <echo>Component successfully created in folder ${basedir}/hot-deploy/${component-name}.
            Restart Scipio and then visit the URL: https://localhost:8443/shop
        </echo>
    </target>

    <!-- SCIPIO: Added non-interactive support:
    ./ant create-theme -Dcomponent-name=my-theme -Dcomponent-resource-name=MyTheme -Dwebapp-name=mytheme -Dtheme-id=MYTHEME -Dis-backend=Y -Dconfirm-component-creation=Y -->
    <target name="create-theme"
            description="Create the layout of a Scipio theme component in the themes folder.">
        <input addproperty="component-name" message="Theme name (lowercase): (e.g. my-theme) [Mandatory]" unless:set="component-name"/>
        <input addproperty="component-resource-name" message="Theme resource name (CamelCase): (e.g. MyTheme) [Mandatory]" unless:set="component-resource-name"/>
        <input addproperty="webapp-name" message="Webapp name (lowercase): (e.g. mytheme) [Mandatory]" unless:set="webapp-name"/>
        <input addproperty="theme-id" message="Theme Id (uppercase): (e.g. MYTHEME) [Mandatory]" unless:set="theme-id"/>
        <input addproperty="is-backend" message="Is backoffice theme? (N for shop theme): [default: Y]" defaultvalue="Y" validargs="Y,N,y,n" unless:set="is-backend"/>
        <if>
            <equals arg1="${is-backend}" arg2="Y" casesensitive="false"/>
            <then>
                <property name="theme-type" value="BACKOFFICE"/>
            </then>
            <else>
                <property name="theme-type" value="ECOMMERCE"/>
            </else>
        </if>
        <echo>The following theme component will be created:
              Name: ${component-name}
              Resource Name: ${component-resource-name}
              Webapp Name: ${webapp-name}
              Folder: ${basedir}/themes/${component-name}
              ThemeId: ${theme-id}
              Theme-Type: ${theme-type} (is backoffice theme: ${is-backend})
        </echo>
        <input addproperty="confirm-component-creation" message="Confirm: " defaultvalue="N" validargs="Y,N,y,n" unless:set="confirm-component-creation"/>
        <fail message="Component creation cancelled by the user.">
            <condition>
                <equals arg1="${confirm-component-creation}" arg2="N" casesensitive="false"/>
            </condition>
        </fail>
        <fail message="Component name is mandatory">
            <condition>
                <equals arg1="${component-name}" arg2="" casesensitive="false" trim="yes"/>
            </condition>
        </fail>
        <fail message="Resource name is mandatory">
            <condition>
                <equals arg1="${component-resource-name}" arg2="" casesensitive="false" trim="yes"/>
            </condition>
        </fail>
        <fail message="Webapp name is mandatory">
            <condition>
                <equals arg1="${webapp-name}" arg2="" casesensitive="false" trim="yes"/>
            </condition>
        </fail>
        <fail message="Theme Id name is mandatory">
            <condition>
                <equals arg1="${theme-id}" arg2="" casesensitive="false" trim="yes"/>
            </condition>
        </fail>
        
        <filterset id="replacePlaceholders">
            <filter token="component-name" value="${component-name}"/>
            <filter token="component-resource-name" value="${component-resource-name}"/>
            <filter token="webapp-name" value="${webapp-name}"/>
            <filter token="theme-id" value="${theme-id}"/>
            <filter token="is-backend" value="${is-backend}"/>
            <filter token="theme-type" value="${theme-type}"/>
        </filterset>
        <mkdir dir="${basedir}/themes/${component-name}"/>
        <copy file="${basedir}/framework/resources/templates/theme/.gitignore-component" tofile="${basedir}/themes/${component-name}/.gitignore"/>
        <mkdir dir="${basedir}/themes/${component-name}/data"/>
        <mkdir dir="${basedir}/themes/${component-name}/includes"/>
        <mkdir dir="${basedir}/themes/${component-name}/webapp"/>
        <mkdir dir="${basedir}/themes/${component-name}/webapp/${webapp-name}"/>
        <mkdir dir="${basedir}/themes/${component-name}/webapp/${webapp-name}/WEB-INF"/>
        <copy file="${basedir}/framework/resources/templates/theme/.gitignore-webapp" tofile="${basedir}/themes/${component-name}/webapp/${webapp-name}/.gitignore"/>
        <copy file="${basedir}/framework/resources/templates/theme/scipio-theme.xml" tofile="${basedir}/themes/${component-name}/scipio-theme.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/theme/build.xml" tofile="${basedir}/themes/${component-name}/build.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/theme/README.md" tofile="${basedir}/themes/${component-name}/README.md" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/theme/ThemeData.xml" tofile="${basedir}/themes/${component-name}/data/${component-resource-name}ThemeData.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/theme/web.xml" tofile="${basedir}/themes/${component-name}/webapp/${webapp-name}/WEB-INF/web.xml" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/theme/appbar.ftl" tofile="${basedir}/themes/${component-name}/includes/appbar.ftl" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/theme/appbarClose.ftl" tofile="${basedir}/themes/${component-name}/includes/appbarClose.ftl" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/theme/appbarOpen.ftl" tofile="${basedir}/themes/${component-name}/includes/appbarOpen.ftl" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/theme/footer.ftl" tofile="${basedir}/themes/${component-name}/includes/footer.ftl" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/theme/header.ftl" tofile="${basedir}/themes/${component-name}/includes/header.ftl" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/theme/htmlMenuMacroLibrary.ftl" tofile="${basedir}/themes/${component-name}/includes/htmlMenuMacroLibrary.ftl" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/theme/login.ftl" tofile="${basedir}/themes/${component-name}/includes/login.ftl" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/theme/themeStyles.groovy" tofile="${basedir}/themes/${component-name}/includes/themeStyles.groovy" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>
        <copy file="${basedir}/framework/resources/templates/theme/themeTemplate.ftl" tofile="${basedir}/themes/${component-name}/includes/themeTemplate.ftl" encoding="utf-8">
            <filterset refid="replacePlaceholders"/>
        </copy>

        <echo>Theme successfully created in folder ${basedir}/themes/${component-name}.
            Restart Scipio and reseed with 'ant load-extseed'
        </echo>
    </target>

    <!-- ================================================================== -->
    <!-- kek helper                                                         -->
    <!-- ================================================================== -->

    <target name="gen-kek"
            description="Generate a new key-encrypting-key for use in entityengine.xml">
        <path id="gen-kek.class.path">
          <fileset dir="${ofbiz.home.dir}/framework/base/build/lib/" includes="ofbiz-base.jar"/>
          <fileset dir="${ofbiz.home.dir}/framework/base/lib/" includes="commons-codec-*.jar"/>
          <fileset dir="${ofbiz.home.dir}/framework/base/lib/" includes="shiro-core-*.jar"/>
          <fileset dir="${ofbiz.home.dir}/framework/base/lib/" includes="slf4j-api-*.jar"/>
        </path>
        <java classname="org.ofbiz.base.crypto.Main" fork="false" classpathref="gen-kek.class.path">
            <arg value="-kek"/>
        </java>
    </target>

    <!-- ================================================================== -->
    <!-- Old tasks.                                                         -->
    <!-- ================================================================== -->
    <target name="run">
        <echo message="The 'run' command has been renamed 'start'; please use 'ant start' to start Scipio ERP."/>
    </target>
    <target name="run-debug">
        <echo message="The 'run-debug' command has been renamed 'start-debug'; please use 'ant start-debug' to start Scipio ERP in debug mode."/>
    </target>
    <target name="run-pos">
        <echo message="The 'run-pos' command has been renamed 'start-pos'; please use 'ant start-pos' to start the Scipio ERP POS."/>
    </target>
    <target name="run-install">
        <echo message="The 'run-install' command has been renamed 'load-demo'; please use 'ant load-demo' to load seed and demo data."/>
    </target>
    <target name="run-install-multitenant">
        <echo message="The 'run-install-multitenant' command has been renamed 'load-demo-multitenant'; please use 'ant load-demo-multitenant' to load seed and demo data for multi-tenancy."/>
    </target>
    <target name="run-install-seed">
        <echo message="The 'run-install-seed' command has been renamed 'load-seed'; please use 'ant load-seed' to load seed data."/>
    </target>
    <target name="run-install-extseed">
        <echo message="The 'run-install-extseed' command has been renamed 'load-extseed'; please use 'ant load-extseed' to load seed, seed-initial and ext data."/>
    </target>
    <target name="run-install-exttest">
        <echo message="The 'run-install-exttest' command has been renamed 'load-exttest'; please use 'ant load-exttest' to load seed, seed-initial, ext and ext-test data."/>
    </target>
    <target name="run-install-readers">
        <echo message="The 'run-install-readers' command has been renamed 'load-readers'; please use 'ant load-readers' to load data using the command line argument data-readers."/>
    </target>
    <target name="run-install-file">
        <echo message="The 'run-install-file' command has been renamed 'load-file'; please use 'ant load-file' to load data from a given file."/>
    </target>
    <target name="run-install-file-in-delegator">
        <echo message="The 'run-install-file-in-delegator' command has been renamed 'load-file'; please use 'ant load-file' to load data from a given file."/>
    </target>
    
    <!-- ================================================================== -->
    <!-- SCIPIO: late-inclusion, new, original properties and tasks         -->
    <!-- ================================================================== -->

    <!-- Dynamic main build.xml additions. Allows any component or addon to include
        a file named "build-main.xml" in its folder, which will be imported into
        the main build, supporting plugin-like additions to root build.xml.
        NOTE: ant does not support overriding existing tasks this way, but new tasks may be added. -->
    <fileset id="framework.mainbuilds" dir="${framework.dir}">
        <exclude name="disabled/**"/>
        <include name="*/build-main.xml" />
    </fileset>
    <fileset id="applications.mainbuilds" dir="${applications.dir}">
        <exclude name="disabled/**"/>
        <include name="*/build-main.xml" />
    </fileset>
    <fileset id="specialpurpose.mainbuilds" dir="${specialpurpose.dir}">
        <exclude name="disabled/**"/>
        <include name="*/build-main.xml" />
    </fileset>
    <fileset id="addons.mainbuilds" dir="${addons.dir}">
        <exclude name="disabled/**"/>
        <include name="*/build-main.xml" />
    </fileset>
    <fileset id="hotdeploy.mainbuilds" dir="${hotdeploy.dir}">
        <exclude name="disabled/**"/>
        <include name="*/build-main.xml" />
    </fileset>
    <import optional="true">
        <fileset file="tools/misc/build-dummy.xml" /><!-- at least one import required -->
        <fileset refid="framework.mainbuilds" />
    </import>
    <import optional="true">
        <fileset file="tools/misc/build-dummy.xml" /><!-- at least one import required -->
        <fileset refid="applications.mainbuilds" />
    </import>
    <import optional="true">
        <fileset file="tools/misc/build-dummy.xml" /><!-- at least one import required -->
        <fileset refid="specialpurpose.mainbuilds" />
    </import>
    <import optional="true">
        <fileset file="tools/misc/build-dummy.xml" /><!-- at least one import required -->
        <fileset refid="addons.mainbuilds" />
    </import>
    <import optional="true">
        <fileset file="tools/misc/build-dummy.xml" /><!-- at least one import required -->
        <fileset refid="hotdeploy.mainbuilds" />
    </import>
    
    <!-- invokes build hooks in build-hooks.xml files.
        NOTE: unlike regular builds, hooks in build-hooks.xml files are always invoked using
            inheritall="true", to allow inspection of the main build.
        TODO: build-hooks-standalone.xml files to support inheritall="false"; but execution order is a big issue (must be consistent
            even when unpredictable until runtime) -->
    <macrodef name="invokehook">
        <attribute name="target" default=""/>
        <sequential>
            <!-- ant is already verbose enough
            <echo message="[invokehook] @{target}: Invoking..." />
            -->
            <invokehookdir target="@{target}" dir="${framework.dir}" />
            <invokehookdir target="@{target}" dir="${applications.dir}" />
            <invokehookdir target="@{target}" dir="${specialpurpose.dir}" />
            <invokehookdir target="@{target}" dir="${addons.dir}" />
            <invokehookdir target="@{target}" dir="${hotdeploy.dir}" />
            <!-- ant is already verbose enough
            <echo message="[invokehook] @{target}: Done." />
            -->
        </sequential>
    </macrodef>
    
    <macrodef name="invokehookdir">
        <attribute name="target" default=""/>
        <attribute name="dir" default=""/>
        <sequential>
            <if>
              <available file="@{dir}/build-hooks.xml" property="useBuildHooks_@{dir}"/>
              <then>
                <subant target="@{target}" inheritall="true">
                  <filelist dir="." files="@{dir}/build-hooks.xml"/>
                </subant>
              </then>
              <else>
                <fileset dir="${basedir}/@{dir}" id="hookfiles_@{dir}">
                  <exclude name="disabled/**"/>
                  <include name="*/build-hooks.xml"/>
                </fileset>
                <if>
                  <!-- Test prevents the "[subant] No sub-builds to iterate on" message. -->
                  <resourcecount when="greater" count="0">
                    <fileset refid="hookfiles_@{dir}" />
                  </resourcecount>
                  <then>
                    <subant target="@{target}" inheritall="true">
                      <fileset refid="hookfiles_@{dir}" />
                    </subant>
                  </then>
                </if>
              </else>
            </if>
        </sequential>
    </macrodef>
    
    <!-- based on hotdeployant - addons behaves more like hot-deploy than specialpurpose -->
    <macrodef name="addonsant">
      <attribute name="target" default=""/>
      <sequential>
        <!-- A check is done, if no build.xml file is present in hot-deploy dir,
            then the build.xml files - if present - in hot-deploy sub-dirs will be used.
            So the previous, simpler, behaviour is kept as long as you don't need
            to build hot-deploy components in a specific order. -->
        <if>
          <available file="addons/build.xml" property="useAddonsBuild"/>
          <then>
            <externalsubant target="@{target}">
              <filelist dir="." files="addons/build.xml"/>
            </externalsubant>
          </then>
          <else>
            <dep-subant dir="${basedir}/addons" target="@{target}" />
          </else>
        </if>
      </sequential>
    </macrodef>

    <!-- TODO?: build-scipio-build-tools should be a depends, but it currently always-builds, not just on changes -->
    <target name="check-build-requisites" description="Download build requisites (SCIPIO)" depends="check-ant-js">
    </target>

    <target name="build-scipio-build-tools" description="Builds standalone Scipio setup/build tools">
        <!-- SCIPIO: 2018-11-14: Can bypass actual build using flag: -Dscipio.target.build=false
            FIXME?: using big if here is ugly -->
        <if>
            <equals arg1="${scipio.target.build}" arg2="false"/>
            <then>
                <echo message="[build-scipio-build-tools] (bypassed)"/>
            </then>
            <else>
                <filelist id="scipio.build.tools.buildfile" dir="${ofbiz.home.dir}" files="framework/base/build-scipio-build-tools.xml"/>
                <iterate target="jar" filelist="scipio.build.tools.buildfile"/>
                <move todir="${ofbiz.home.dir}/tools/misc" file="${ofbiz.home.dir}/framework/base/build/lib/scipio-build-tools.jar" />
            </else>
        </if>
    </target>

    <target name="check-ant-js" description="Check Ant Javascript engine download required">
        <var name="javaatleast15" unset="true"/>
        <condition property="javaatleast15" value="true" else="false">
            <and>
                <not>
                    <matches pattern="^1\.[0-8]($|\..*)" string="${ant.java.version}"/><!-- string="${ant.java.version}"/> -->
                </not>
                <matches pattern="^(1[5-9]|[2-9][0-9]).*" string="${ant.java.version}"/><!-- string="${ant.java.version}"/> -->
            </and>
        </condition>
        <if>
            <equals arg1="${javaatleast15}" arg2="true"/>
            <then>
                <var name="lib.ant.js.present" unset="true"/>
                <condition property="lib.ant.js.present" value="true" else="false">
                    <resourcecount when="greater" count="0">
                        <fileset dir="${ofbiz.home.dir}/framework/base/lib/ant-ext/js" includes="*.jar" />
                    </resourcecount>
                </condition>
                <if>
                    <equals arg1="${lib.ant.js.present}" arg2="false"/>
                    <then>
                        <echo message="Java 15+ JDK detected (${ant.java.version}) - downloading Ant Javascript engine; NOTE: If build fails after this, simply re-run original task (after download-ant-js succeeds)" level="info"/>
                        <antcall target="download-ant-js"/>
                        <!-- May no longer be needed
                        <fail message="Java 15+ JDK detected (${ant.java.version}) - framework/base/lib/ant-ext/js has been updated with engine jar -
 PLEASE RE-RUN ORIGINAL TASK (this is a normal workaround); for devs: use './ant download-ant-js' separately to fix in scripts"/>-->
                    </then>
                    <else>
                        <echo message="Java 15+ JDK detected (${ant.java.version}) - Ant Javascript engine already present" level="info"/>
                    </else>
                </if>
            </then>
        </if>
    </target>

</project>