Create Extensible Ant Script


When we write code, we need consider flexibility, extensibility and maintainability. These rules also applies when we write ant script or batch files.
The Task
In our solr related project, there are multiple cores, and we may add more cores in future. All cores share some common configuration files as the default core collection1. Every core has its own schema.xml and solrconfig.xml. 
So we put the default and shared core configuration files in solr.zip. The file structure looks like below:
solr.zip
solr/collection1/conf/schema.xml
solr/collection1/conf/solrconfig.xml
solr/core-app1/conf/schema.xml
solr/core-app1/conf/solrconfig.xml

As we may add more cores in future, so we want our ant build.xml stays stable: we don't have to update build.xml when we add new cores.

The Solution
In ant build.xml script, we use ant-contrib's foreach task to iterate all core folders: the folder name starts with core-, execute create-core task for each core folder.
<ac:foreach target="create-core" param="coreFolder">
  <path>
    <dirset id="cores" dir="solr/">
      <include name="core-*"/>
    </dirset>
  </path>
</ac:foreach>
The complete Ant Script
<project name="SolrProject" basedir="." default="all" xmlns:ac="antlib:net.sf.antcontrib">
  <dirname  property="project-basedir"  file="${ant.file.SolrProject}"/>
  <taskdef resource="net/sf/antcontrib/antlib.xml" uri="antlib:net.sf.antcontrib">
    <classpath>
      <pathelement location="BuildTools\apache-ant-1.8.4\lib\ant-contrib-1.0b3.jar"/>
    </classpath>
  </taskdef>
  <property name="application-name" value="SolrProject" />
  <property name="main-build-path" value="${project-basedir}/build" />
  <property name="project-build-path" value="${main-build-path}/${application-name}" />
  <property name="solr-zip" value="solr.zip" />
  <target name="clean">
    <delete dir="${main-build-path}" />
    <delete dir="${main-dist-path}" />
  </target>
  <target name="init">
    <mkdir dir="${main-build-path}" />
    <mkdir dir="${project-build-path}" />
  </target>
  <target name="build-package" depends="clean, init">
    <!-- copy configuration files to default core: collection1 -->
    <unzip src="${solr-zip}" dest="${project-build-path}/solr/collection1/conf" >
      <mapper>
        <globmapper from="collection1/conf/*" to="*"/>
      </mapper>
    </unzip>
    <!-- 
    <dirset id="cores" dir="solr/">
      <include name="core-*"/>
    </dirset>
    The pathconvert task can be used to format a dirset with arbitrary separators 
    <pathconvert dirsep="/" pathsep="," property="dirs" refid="cores"/>
    <echo message="${dirs}"/>
    -->
    <ac:foreach target="create-core" param="coreFolder">
      <path>
        <dirset id="cores" dir="solr/">
          <include name="core-*"/>
        </dirset>
      </path>
    </ac:foreach>
  </target>
  <target name="create-core">
    <basename property="basename" file="${coreFolder}"/>
    <echo message="file: ${coreFolder}, basename: ${basename}" />
    <mkdir dir="${project-build-path}/solr/${basename}/conf" />
    <unzip src="${solr-zip}" dest="${project-build-path}/solr/${basename}/conf" >
      <mapper>
        <globmapper from="collection1/conf/*" to="*"/>
      </mapper>
    </unzip>
  </target>
</project>

Labels

adsense (5) Algorithm (69) Algorithm Series (35) Android (7) ANT (6) bat (8) Big Data (7) Blogger (14) Bugs (6) Cache (5) Chrome (19) Code Example (29) Code Quality (7) Coding Skills (5) Database (7) Debug (16) Design (5) Dev Tips (63) Eclipse (32) Git (5) Google (33) Guava (7) How to (9) Http Client (8) IDE (7) Interview (88) J2EE (13) J2SE (49) Java (186) JavaScript (27) JSON (7) Learning code (9) Lesson Learned (6) Linux (26) Lucene-Solr (112) Mac (10) Maven (8) Network (9) Nutch2 (18) Performance (9) PowerShell (11) Problem Solving (11) Programmer Skills (6) regex (5) Scala (6) Security (9) Soft Skills (38) Spring (22) System Design (11) Testing (7) Text Mining (14) Tips (17) Tools (24) Troubleshooting (29) UIMA (9) Web Development (19) Windows (21) xml (5)