<?xml version="1.0" encoding="UTF-8"?>

<!--+
    |
    |  OpenRefine Build File
    |
    +-->
    
<project name="openrefine" default="build" basedir="." xmlns:jacoco="antlib:org.jacoco.ant">

    <!-- Properties are immutable, so anything set in this file takes priority-->
    <property file="build.properties"/>
    
    <property environment="env"/>

    <property name="version" value="trunk"/>
    <property name="full_version" value="0.0.0.0"/>
    <property name="build.dir" value="build"/>
    <property name="dist.dir" value="dist"/>

    <property name="java_version" value="1.7"/>

    <property name="appengine.app_id" value="openrefine-broker"/>
    <property name="appengine.version" value="1"/>
    <property name="appengine.sdk.dir" value="/opt/appengine"/>
        
    <property name="fullname" value="openrefine-${version}" />
    
    <property name="main.dir" value="${basedir}/main" />

    <property name="webapp.dir" value="${main.dir}/webapp" />
    <property name="webapp.src.dir" value="${main.dir}/src" />
    <property name="webapp.lib.dir" value="${webapp.dir}/WEB-INF/lib" />
    <property name="webapp.classes.dir" value="${webapp.dir}/WEB-INF/classes" />

    <property name="server.dir" value="${basedir}/server" />
    <property name="server.src.dir" value="${server.dir}/src" />
    <property name="server.lib.dir" value="${server.dir}/lib" />
    <property name="server.classes.dir" value="${server.dir}/classes" />

    <property name="broker.dir" value="${basedir}/broker" />
    <property name="broker.core.dir" value="${broker.dir}/core" />
    <property name="broker.appengine.dir" value="${broker.dir}/appengine" />

    <property name="extensions.dir" value="${basedir}/extensions" />
    
    <property name="tests.dir" value="${main.dir}/tests" />
    <property name="server.tests.dir" value="${tests.dir}/server" />
    <property name="server.tests.lib.dir" value="${server.tests.dir}/lib" />
    <property name="server.tests.src.dir" value="${server.tests.dir}/src" />
    <property name="server.tests.classes.dir" value="${server.tests.dir}/classes" />
    <property name="server.tests.report.dir" value="${build.dir}/report"/>
    <property name="server.tests.report.html.dir" value="${server.tests.report.dir}/html"/>
    <property name="server.tests.report.xml.path" value="${server.tests.report.dir}/jacoco.xml"/>
    
    <property name="graphics.dir" value="${basedir}/graphics" />
    <property name="conf.dir" value="${basedir}/conf" />
    <property name="tools.dir" value="${basedir}/tools" />
    
    <property name="reports.dir" value="${build.dir}/reports" />

    <property name="built.webapp.name" value="webapp" />
    <property name="built.webapp.dir" value="${build.dir}/${built.webapp.name}" />

    <property name="built.broker.webapp.dir" value="${build.dir}/broker" />

    <property name="mac.dir" value="${build.dir}/mac" />
    <property name="release.name" value="openrefine-${version}" />
    <property name="windows.dir" value="${build.dir}/windows/${release.name}" />
    <property name="linux.dir" value="${build.dir}/linux/${release.name}" />
    
    <!-- ================================================================== -->
    
    <path id="server.class.path">
        <fileset dir="${server.lib.dir}">
            <include name="**/*.jar" />
        </fileset>
        <pathelement location="${server.classes.dir}"/>
    </path>

    <path id="webapp.class.path">
        <fileset dir="${server.lib.dir}">
            <include name="**/servlet-api*.jar" />
        </fileset>
        <fileset dir="${webapp.lib.dir}">
            <include name="**/*.jar" />
        </fileset>
        <pathelement location="${webapp.classes.dir}"/>
    </path>

    <path id="tests.class.path">
        <path refid="webapp.class.path"/>
        <path refid="server.class.path"/>
    	<pathelement location="${server.tests.classes.dir}"/>
        <pathelement location="${server.tests.lib.dir}/testng-6.8.jar"/>
    	<pathelement location="${tests.dir}/data" />
        <fileset dir="${server.tests.lib.dir}">
            <include name="**/*.jar" />
        </fileset>
    </path>

    <path id="broker.class.path">
        <fileset dir="${server.lib.dir}">
            <include name="**/servlet-api*.jar" />
        </fileset>
        <fileset dir="${webapp.lib.dir}">
            <include name="**/butterfly*.jar" />
            <include name="**/json*.jar" />
            <include name="**/http*.jar" />
            <include name="**/slf4j-api*.jar" />
        </fileset>
        <fileset dir="${broker.core.dir}/module/MOD-INF/lib">
            <include name="**/*.jar" />
        </fileset>
    </path>

    <path id="broker.appengine.class.path">
        <pathelement location="${broker.core.dir}/module/MOD-INF/classes"/>
        <path refid="broker.class.path"/>
        <fileset dir="${appengine.sdk.dir}/lib">
            <include name="shared/**/*.jar" />
            <include name="user/**/*.jar" />
        </fileset>
    </path>

    <!-- ================================================================== -->

    <target name="build_server">
        <mkdir dir="${server.classes.dir}" />
        <javac source="${java_version}" target="${java_version}" encoding="utf-8" srcdir="${server.src.dir}" destdir="${server.classes.dir}" debug="true" includeAntRuntime="no">
            <classpath refid="server.class.path" />
        </javac>
        <copy file="${server.src.dir}/log4j.properties" tofile="${server.classes.dir}/log4j.properties"/>
    </target>
            
    <target name="build_webapp">
        <mkdir dir="${webapp.classes.dir}" />
        <javac source="${java_version}" target="${java_version}" encoding="utf-8" destdir="${webapp.classes.dir}" debug="true" includeAntRuntime="no">
            <src path="${webapp.src.dir}"/>
            <classpath refid="webapp.class.path" />
        </javac>
        <copy file="${webapp.src.dir}/log4j.properties" tofile="${webapp.classes.dir}/log4j.properties"/>
    </target>

    <target name="build_tests" depends="build">
        <mkdir dir="${server.tests.classes.dir}" />
        <javac source="${java_version}" target="${java_version}" encoding="utf-8" srcdir="${server.tests.src.dir}" destdir="${server.tests.classes.dir}" debug="true" includeAntRuntime="no">
            <classpath refid="tests.class.path" />
        </javac>
        <copy file="${server.tests.src.dir}/tests.log4j.properties" tofile="${server.tests.classes.dir}/tests.log4j.properties"/>
    </target>
    
    <target name="build_extensions">
      <ant dir="extensions/" target="build" />
    </target>

    <target name="build" depends="build_server, build_webapp, build_extensions"/>

    <target name="build_broker_core">
        <mkdir dir="${broker.core.dir}/module/MOD-INF/classes" />
        <javac source="${java_version}" target="${java_version}" encoding="utf-8" destdir="${broker.core.dir}/module/MOD-INF/classes" debug="true" includeAntRuntime="no">
            <src path="${broker.core.dir}/src/"/>
            <classpath refid="broker.class.path" />
        </javac>
    </target>

    <target name="build_broker_appengine" depends="build_broker_core">
        <mkdir dir="${broker.appengine.dir}/module/MOD-INF/classes" />
        <javac source="${java_version}" target="${java_version}" encoding="utf-8" destdir="${broker.appengine.dir}/module/MOD-INF/classes" debug="true" includeAntRuntime="no">
            <src path="${broker.appengine.dir}/src/"/>
            <classpath refid="broker.appengine.class.path" />
        </javac>
    </target>

    <target name="build_broker" depends="build_broker_core, build_broker_appengine"/>

    <taskdef resource="testngtasks" classpath="${server.tests.lib.dir}/testng-6.8.jar"/>
    <taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml">
        <classpath path="${server.tests.lib.dir}/jacocoant.jar"/>
    </taskdef>

    <mkdir dir="${build.dir}/server_tests"/>
    <target name="server_test" depends="build_tests">
	<jacoco:coverage destfile="${server.tests.report.dir}/jacoco.exec">
            <testng verbose="2" haltOnFailure="true" workingdir="${build.dir}/server_tests"
                listener="org.testng.reporters.DotTestListener" excludedgroups="broken"
                classpathref="tests.class.path">
             <xmlfileset file="${server.tests.dir}/conf/tests.xml"/>
            </testng>
	</jacoco:coverage>
        <jacoco:report>
           <executiondata>
		   <file file="${server.tests.report.dir}/jacoco.exec"/>
           </executiondata>

           <structure name="OpenRefine server">
               <classfiles>
		       <fileset dir="${webapp.classes.dir}"/>
               </classfiles>
                <sourcefiles encoding="UTF-8">
	            <fileset dir="${server.src.dir}"/>
                </sourcefiles>
            </structure>
	    <html destdir="${server.tests.report.html.dir}"/>
	    <xml destfile="${server.tests.report.xml.path}"/>
        </jacoco:report>
    </target>

    <!-- ================================================================== -->

    <target name="prepare_jar">
        <mkdir dir="${build.dir}"/>
    </target>

    <target name="jar_server" depends="prepare_jar, build_server">
        <jar destfile="${build.dir}/${fullname}-server.jar" basedir="${server.classes.dir}"/>
    </target>
    
    <target name="jar_webapp" depends="prepare_jar, build_webapp">
        <jar destfile="${build.dir}/${fullname}.jar" basedir="${webapp.classes.dir}"/>
    </target>

    <target name="jar" depends="jar_server, jar_webapp"/>

    <!-- ================================================================== -->

    <target name="prepare_webapp" depends="jar_webapp, build">
        <mkdir dir="${built.webapp.dir}" />
        
        <copy todir="${built.webapp.dir}">
            <fileset dir="${webapp.dir}">
                <include name="**/*"/>
                <exclude name="WEB-INF/classes/**"/>
                <exclude name="WEB-INF/lib-src/**"/>
                <exclude name="WEB-INF/lib/icu4j*.jar"/>
            </fileset>
        </copy>
        
        <copy file="${build.dir}/${fullname}.jar" tofile="${built.webapp.dir}/WEB-INF/lib/${fullname}.jar"/>

        <copy todir="${built.webapp.dir}/extensions">
            <fileset dir="${extensions.dir}">
                <include name="**/*"/>
                <exclude name="**/build.xml"/>
                <exclude name="**/src/**"/>
                <exclude name="**/lib-src/**"/>
                <exclude name="**/libsrc/**"/>
            </fileset>
        </copy>
        
        <replace file="${built.webapp.dir}/WEB-INF/web.xml">
            <replacefilter token="$VERSION" value="${version}"/>
        </replace>

        <replace file="${built.webapp.dir}/WEB-INF/butterfly.properties">
            <replacefilter token="../../extensions" value="extensions"/>
        </replace>

    </target>
    
    <target name="mac" depends="jar, prepare_webapp">
        <mkdir dir="${mac.dir}"/>
        
	<taskdef name="bundleapp"
             classname="com.oracle.appbundler.AppBundlerTask"   
             classpath="${appbundler.dir}/appbundler-1.0.jar" />

        <bundleapp outputdirectory="${mac.dir}"
            name="OpenRefine"
            displayname="OpenRefine ${version}"
            icon="${graphics.dir}/icon/openrefine.icns"
            identifier="com.google.refine.Refine"
	    shortversion="${version}"
            mainclassname="com/google/refine/Refine">
	    <runtime dir="${env.JAVA_HOME}"/>
            <classpath dir="${build.dir}">
	      <include name="${fullname}-server.jar" />
	    </classpath>
            <classpath dir="${server.lib.dir}">
	      <include name="**/*.jar" />
	    </classpath>
	    <option value="-Xms256M"/>
	    <option value="-Xmx1024M"/>
	    <option value="-Drefine.version=${version}"/>
	    <option value="-Drefine.webapp=$APP_ROOT/Contents/Resource/${built.webapp.name}"/>
        </bundleapp>

	<copy todir="${mac.dir}/OpenRefine.app/Contents/Resource">
          <fileset dir="${build.dir}" id="librarypathset" >
            <include name="${built.webapp.name}/**/**" />
          </fileset>
	</copy>

<!--- Options from old jarbundler code not supported by appbundler
                aboutmenuname="OpenRefine"
                workingdirectory="$APP_PACKAGE/Contents/Resources"
                antialiasedgraphics="true"
                antialiasedtext="true"
                liveresize="true"
                growboxintrudes="true"
                screenmenu="true">
-->
    </target>
    
    <target name="windows" depends="jar, prepare_webapp">
      <echo message="Full version ${full_version} and version ${version}"/>
        <mkdir dir="${windows.dir}"/>
        <taskdef 
            name="launch4j" 
            classname="net.sf.launch4j.ant.Launch4jTask" 
            classpath="${launch4j.dir}/launch4j.jar:${launch4j.dir}/lib/xstream.jar" 
        />
        <launch4j>
          <config 
               headerType="console" 
               outfile="${windows.dir}/openrefine.exe" 
               jarPath="server/lib/${fullname}-server.jar" 
               dontWrapJar="true"
               icon="${graphics.dir}/icon/openrefine.ico">
            <classPath mainClass="com.google.refine.Refine">
                <cp>server/lib/*.jar</cp>
            </classPath>
            <jre minVersion="1.6.0" jdkPreference="preferJre" initialHeapSize="256" maxHeapSize="1024">
                <opt>-Djava.library.path=server/lib/native/windows </opt>
            </jre>
            <versionInfo
                fileVersion="${full_version}"
                txtFileVersion="${version}"
                fileDescription="openrefine"
                copyright="Copyright (c) 2013 OpenRefine contributors, 2010, Google, Inc."
                productVersion="${full_version}"
                txtProductVersion="${version}"
                productName="OpenRefine"
                companyName="OpenRefine team"
                internalName="openrefine"
                originalFilename="openrefine.exe" 
            />
          </config>
        </launch4j>     
        <copy file="${build.dir}/${fullname}-server.jar" tofile="${windows.dir}/server/lib/${fullname}-server.jar"/>
        <copy todir="${windows.dir}/server/lib">
            <fileset dir="${server.lib.dir}">
                <include name="**/*.jar"/>
            </fileset>
        </copy>
        <copy todir="${windows.dir}/server/lib/native/windows">
            <fileset dir="${server.lib.dir}/native/windows">
                <include name="*.dll"/>
            </fileset>
        </copy>

        <copy todir="${windows.dir}/webapp">
            <fileset dir="${built.webapp.dir}">
                <include name="**"/>
            </fileset>
        </copy>

        <mkdir dir="${windows.dir}/licenses"/>
        <fixcrlf srcDir="${basedir}/licenses" destDir="${windows.dir}/licenses" eol="crlf"/>

        <fixcrlf srcDir="${basedir}" destDir="${windows.dir}" eol="crlf">
            <include name="refine.bat"/>
            <include name="refine.ini"/>
            <include name="README.txt"/>
            <include name="LICENSE.txt"/>
        </fixcrlf>
        <fixcrlf file="${conf.dir}/openrefine.l4j.ini" destDir="${windows.dir}" eol="crlf"/>

        <mkdir dir="${dist.dir}"/>
        <zip destfile="${dist.dir}/openrefine-win-${version}.zip" basedir="${windows.dir}/.." includes="${release.name}/**"/>
    </target>
    
    <target name="linux" depends="jar, prepare_webapp">
        <mkdir dir="${linux.dir}"/>
    
        <copy todir="${linux.dir}/server/lib">
            <fileset dir="${server.lib.dir}">
                <include name="**/*.jar"/>
            </fileset>
        </copy>

        <copy file="${build.dir}/${fullname}-server.jar" tofile="${linux.dir}/server/lib/${fullname}-server.jar"/>

        <copy todir="${linux.dir}/webapp">
            <fileset dir="${built.webapp.dir}">
                <include name="**"/>
            </fileset>
        </copy>

        <mkdir dir="${linux.dir}/licenses"/>
        <fixcrlf srcDir="${basedir}/licenses" destDir="${linux.dir}/licenses" eol="lf"/>

        <fixcrlf srcDir="${basedir}" destDir="${linux.dir}" eol="lf">
            <include name="refine"/>
            <include name="refine.ini"/>
            <include name="README.txt"/>
            <include name="LICENSE.txt"/>
        </fixcrlf>

        <mkdir dir="${dist.dir}"/>
        <tar longfile="gnu" compression="gzip" destfile="${dist.dir}/openrefine-linux-${version}.tar.gz">
           <tarfileset dir="${linux.dir}/.." filemode="755">
               <include name="${release.name}/refine"/>
           </tarfileset>        
           <tarfileset dir="${linux.dir}/..">
               <include name="${release.name}/**"/>
               <exclude name="${release.name}/refine"/>
           </tarfileset>        
        </tar>
    </target>

    <target name="kits" depends="linux,mac,windows" 
        description="Build kits for all supported platforms">
    </target>
    
    <!-- ================================================================== -->

    <target name="prepare_reports">
        <mkdir dir="${reports.dir}" />
    </target>

    <target name="findbugs" depends="build,prepare_reports">
        <taskdef 
            name="findbugs" 
            classname="edu.umd.cs.findbugs.anttask.FindBugsTask"
            classpath="${findbugs.dir}/lib/findbugs-ant.jar" 
        />
        <findbugs jvmargs="-Xmx1024m" home="${findbugs.dir}" output="html" outputFile="${reports.dir}/findbugs.html" >
          <auxClasspath refid="webapp.class.path" />
          <sourcePath path="${webapp.src.dir}" />
          <class location="${webapp.classes.dir}" />
        </findbugs>        
    </target>
    
    <target name="pmd" depends="prepare_reports">
        <path id="pmd.path">
            <fileset dir="${pmd.dir}/lib" includes="*.jar"/>
        </path>    
        <taskdef 
            name="pmd" 
            classname="net.sourceforge.pmd.ant.PMDTask"
            classpathref="pmd.path" 
        />
        <pmd rulesetfiles="${conf.dir}/pmd.rules.xml" targetjdk="1.6" encoding="UTF-8">
            <formatter type="html" toFile="${reports.dir}/pmd.html" toConsole="true"/>
            <fileset dir="${server.src.dir}">
                <include name="**/*.java"/>
            </fileset>
            <fileset dir="${webapp.src.dir}">
                <include name="**/*.java"/>
            </fileset>
            <fileset dir="${server.tests.src.dir}">
                <include name="**/*.java"/>
            </fileset>
        </pmd>
    </target>    

    <target name="cpd" depends="prepare_reports">
        <path id="pmd.path">
            <fileset dir="${pmd.dir}/lib" includes="*.jar"/>
        </path>    
        <taskdef 
            name="cpd" 
            classname="net.sourceforge.pmd.cpd.CPDTask"
            classpathref="pmd.path" 
        />
        <cpd minimumTokenCount="100" outputFile="${reports.dir}/cpd.txt" encoding="UTF-8">
            <fileset dir="${server.src.dir}">
                <include name="**/*.java"/>
            </fileset>
            <fileset dir="${webapp.src.dir}">
                <include name="**/*.java"/>
            </fileset>
        </cpd>
    </target>    

    <target name="jslint" depends="prepare_reports">
        <path id="jslint.path">
            <fileset dir="${jslint.dir}" includes="*.jar"/>
        </path>    
        <taskdef 
            name="jslint"
            classname="com.googlecode.jslint4java.ant.JSLintTask"
            classpathref="jslint.path" 
        />
        <jslint>
            <formatter type="plain" destfile="${reports.dir}/jslint.txt" />
            <fileset dir="${webapp.dir}/modules/core/scripts">
              <include name="**/*.js" />
            </fileset>
        </jslint>        
    </target>    

    <!-- ================================================================== -->

    <target name="prepare_broker" depends="jar_server, build_broker_core">
        <copy todir="${broker.core.dir}/WEB-INF/lib">
            <fileset dir="${webapp.lib.dir}">
                <include name="**/butterfly*.jar" />
                <include name="**/rhino*.jar" />
                <include name="**/commons-collections*.jar" />
                <include name="**/velocity*.jar" />
                <include name="**/lessen*.jar" />
                <include name="**/slf4j*.jar" />
                <include name="**/log4j*.jar" />

                <include name="**/json*.jar" />
                <include name="**/http*.jar" />
                <include name="**/jcl*.jar" />
            </fileset>
        </copy>
    </target>

    <target name="prepare_broker_appengine" depends="build_broker_appengine">
        <mkdir dir="${built.broker.webapp.dir}/appengine" />
        <mkdir dir="${built.broker.webapp.dir}/appengine/modules" />
        
        <copy todir="${built.broker.webapp.dir}/appengine">
            <fileset dir="${broker.appengine.dir}">
                <include name="WEB-INF/**"/>
                <exclude name="WEB-INF/jdo*"/>
            </fileset>
        </copy>

        <copy todir="${built.broker.webapp.dir}/appengine/WEB-INF/classes/META-INF">
            <fileset dir="${broker.appengine.dir}/WEB-INF">
                <include name="jdo*"/>
            </fileset>
        </copy>

        <copy todir="${built.broker.webapp.dir}/appengine/modules/appengine-broker">
            <fileset dir="${broker.appengine.dir}/module">
                <include name="**"/>
                <exclude name="**/lib-src/**"/>
            </fileset>
        </copy>

        <copy todir="${built.broker.webapp.dir}/appengine/modules/broker">
            <fileset dir="${broker.core.dir}/module">
                <include name="**"/>
                <exclude name="**/lib-src/**"/>
            </fileset>
        </copy>
                
        <copy todir="${built.broker.webapp.dir}/appengine/WEB-INF/lib">
            <fileset dir="${webapp.lib.dir}">
                <include name="**/butterfly*.jar" />
                <include name="**/rhino*.jar" />
                <include name="**/commons-collections*.jar" />
                <include name="**/velocity*.jar" />
                <include name="**/lessen*.jar" />

                <include name="**/slf4j-api*.jar" />
                <include name="**/jcl*.jar" />

                <include name="**/json*.jar" />
                <include name="**/http*.jar" />
            </fileset>
        </copy>
                
        <copy todir="${built.broker.webapp.dir}/appengine/WEB-INF/lib" flatten="true">
            <fileset dir="${appengine.sdk.dir}/lib/user">
                <include name="**/*.jar" />
            </fileset>
        </copy>
        
        <replace file="${built.broker.webapp.dir}/appengine/WEB-INF/appengine-web.xml">
            <replacefilter token="$APPID" value="${appengine.app_id}"/>
            <replacefilter token="$VERSION" value="${appengine.version}"/>
        </replace>
    </target>

    <!-- ================================================================== -->

    <target name="clean_extensions">
      <ant dir="extensions/" target="clean" />
    </target>

    <target name="clean" depends="clean_extensions">
        <delete file="${build.dir}/${fullname}.jar" />
        <delete file="${build.dir}/${fullname}-server.jar" />
        <delete dir="${server.classes.dir}" />
        <delete dir="${webapp.classes.dir}" />
        <delete dir="${server.tests.classes.dir}" />
        <delete dir="${broker.core.dir}/module/MOD-INF/classes" />
        <delete dir="${broker.core.dir}/WEB-INF/lib" />
        <delete dir="${broker.appengine.dir}/module/MOD-INF/classes" />
    </target>

    <target name="distclean" depends="clean">
        <delete dir="${build.dir}" />
        <delete dir="${dist.dir}" />
        <delete dir="${tools.dir}" />
    </target>

</project>