<?xml version="1.0"?>

<!--
    $RCSfile$
    $Revision$
    $Date$

    This software is published under the terms of the GNU Public License (GPL),
    a copy of which is included in this distribution.
-->

<!--
    Build Requirements:

        * Ant 1.6 (including optional tasks)
        * JDK 1.5
        * jUnit in your Ant or Java classpath
-->

<project name="Messenger XMPP Server" default="all" basedir="..">

    <description>
        Jive Messenger build script.
    </description>

    <!-- ======================================================================================= -->
    <!-- GLOBAL TASKDEFs                                                                         -->
    <!-- ======================================================================================= -->

    <taskdef resource="net/sf/antcontrib/antcontrib.properties">
        <classpath>
            <pathelement location="${basedir}/build/lib/ant-contrib.jar"/>
        </classpath>
    </taskdef>

    <!-- ======================================================================================= -->
    <!-- GLOBAL PROPERTIES                                                                       -->
    <!-- ======================================================================================= -->

    <property file="${basedir}/build/build.properties" />

    <property name="src.dir" value="${basedir}/src" />
    <property name="src.java.dir" value="${src.dir}/java" />
    <property name="src.i18n.dir" value="${src.dir}/i18n" />
    <property name="src.test.dir" value="${src.dir}/test" />
    <property name="src.test.java.dir" value="${src.test.dir}/java" />
    <property name="docs.dir" value="${basedir}/documentation" />
    <property name="web.dir" value="${src.dir}/web" />
    <property name="lib.build.dir" value="${basedir}/build/lib" />
    <property name="lib.merge.dir" value="${lib.build.dir}/merge" />
    <property name="lib.dist.dir" value="${lib.build.dir}/dist" />
    <property name="lib.web.dir" value="${web.dir}/WEB-INF/lib" />
    <property name="target.dir" value="${basedir}/target" />
    <property name="compile.dir" value="${target.dir}/classes" />
    <property name="jar.name" value="messenger.jar" />
    <property name="jar.starter.name" value="startup.jar" />
    <property name="jar.dest.dir" value="${target.dir}/lib" />
    <property name="resources.dir" value="${src.dir}/resources" />
    <property name="javadoc.src.dir" value="${src.dir}/javadoc" />
    <property name="javadoc.dest.dir" value="${target.dir}/javadoc" />
    <property name="jspc.dest.dir" value="${target.dir}/jspc" />
    <property name="jspc.java.dest.dir" value="${target.dir}/jspc/java" />
    <property name="jspc.classes.dest.dir" value="${target.dir}/jspc/classes" />
    <property name="jspc.jar.name" value="admin-jsp.jar" />
    <property name="test.dest.dir" value="${target.dir}/test" />
    <property name="test.classes.dest.dir" value="${test.dest.dir}/classes" />
    <property name="test.results.dest.dir" value="${test.dest.dir}/results" />
    <property name="webapp.dest.dir" value="${target.dir}/webapp" />
    <property name="war.name" value="messenger.war" />
    <property name="war.dest.dir" value="${target.dir}/war" />
    <property name="release.dest.dir" value="${target.dir}/release" />
    <property name="version.major" value="2" />
    <property name="version.minor" value="0" />
    <property name="version.revision" value="0" />
    <property name="version.extra" value="beta" />
    <property name="dist.prefix" value="jive_messenger" />
    <property name="overwrite" value="false" />
    <property name="deploy.jar.dir" value="${jar.dest.dir}" />

    <!-- ======================================================================================= -->
    <!-- PATHs / PATTERNSETs / FILTERSETs                                                        -->
    <!-- ======================================================================================= -->

    <path id="javadoc.dependencies">
        <fileset dir="${lib.build.dir}" includes="*.jar" excludes="junit.jar" />
        <fileset dir="${lib.merge.dir}" includes="*.jar" />
        <fileset dir="${lib.dist.dir}" includes="servlet.jar" />
    </path>

    <path id="compile.dependencies">
        <path refid="javadoc.dependencies" />
    </path>

    <path id="jspc.dependencies">
        <path refid="compile.dependencies" />
        <fileset dir="${lib.web.dir}" includes="*.jar" />
    </path>

    <path id="test.dependencies">
        <path refid="compile.dependencies" />
        <fileset dir="${lib.build.dir}" includes="junit.jar" />
    </path>

    <patternset id="compile.sources">
        <include name="**/*.java" />
    </patternset>

    <patternset id="test.sources">
        <include name="**/*Test.java" />
    </patternset>

    <patternset id="web.sources">
        <include name="**/*.jsp" />
        <include name="**/*.jar" />
        <include name="**/*.tld" />
        <include name="**/*.jspf" />
        <include name="**/*.html" />
        <include name="**/*.css" />
        <include name="**/*.gif" />
    </patternset>

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

    <!-- all =================================================================================== -->
    <target name="all" depends="jar, javadoc" description="Calls jar and javadoc targets" />

    <!-- init ================================================================================== -->
    <target name="init">
        <!-- Check for min build requirements -->
        <condition property="ant.not.ok" value="true"><not><contains string="${ant.version}" substring="1.6" /></not></condition>
        <condition property="java.not.ok" value="true"><not><contains string="${ant.java.version}" substring="1.5" /></not></condition>
        <fail if="ant.not.ok" message="Must use Ant 1.6.x to build Jive Messenger" />
        <fail if="java.not.ok" message="Must use JDK 1.5.x to build Jive Messenger" />

        <tstamp />
        <tstamp>
            <format property="builddate" pattern="MM/dd/yyyy" />
        </tstamp>
        <tstamp>
            <format property="dailybuild.tstamp" pattern="yyyy-MM-dd" locale="en"/>
        </tstamp>

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

        <!-- Setup the versions correctly -->
        <if>
            <equals arg1="${version.extra}" arg2="" />
            <then>
                <property name="version" value="${version.major}.${version.minor}.${version.revision}" />
                <property name="version.filename" value="${version.major}_${version.minor}_${version.revision}" />
            </then>
            <else>
                <property name="version" value="${version.major}.${version.minor}.${version.revision}.${version.extra}" />
                <property name="version.filename" value="${version.major}_${version.minor}_${version.revision}_${version.extra}" />
            </else>
        </if>
    </target>

    <!-- compile =============================================================================== -->
    <target name="compile" depends="init" description="Compiles Messenger app code">
        <mkdir dir="${compile.dir}" />
        <javac
            destdir="${compile.dir}"
            includeAntRuntime="no"
            debug="on"
            source="1.5"
        >
            <src path="${src.java.dir}" />
            <patternset refid="compile.sources" />
            <classpath>
                <path refid="compile.dependencies" />
            </classpath>
        </javac>
    </target>

    <!-- jar =================================================================================== -->
    <target name="jar" depends="compile, jspc" description="Produces Messengers jars and sets up dependencies">
        <mkdir dir="${jar.dest.dir}" />
        <!-- Make main Messenger jar -->
        <jar jarfile="${jar.dest.dir}/${jar.name}">
            <fileset dir="${compile.dir}" includes="**/*.class" excludes="org/jivesoftware/messenger/starter/ServerStarter.class" />
            <fileset dir="${jspc.classes.dest.dir}" includes="**/*.class" />
            <fileset dir="${src.i18n.dir}" includes="*.properties" />
            <fileset dir="${src.dir}" includes="database/*.sql" />
            <fileset dir="${resources.dir}/jar" includes="admin-sidebar.xml" />
            <zipgroupfileset dir="${lib.merge.dir}" includes="*.jar"/>
            <manifest>
                <attribute name="Built-By" value="Jive Software (www.jivesoftware.org)"/>
            </manifest>
        </jar>
        <!-- Make startup jar -->
        <jar jarfile="${jar.dest.dir}/${jar.starter.name}">
            <fileset dir="${compile.dir}">
                <include name="org/jivesoftware/messenger/starter/ServerStarter.class" />
                <include name="org/jivesoftware/messenger/starter/JiveClassLoader*.class" />
            </fileset>
            <manifest>
                <attribute name="Main-Class" value="org.jivesoftware.messenger.starter.ServerStarter" />
                <attribute name="Built-By" value="Jive Software (www.jivesoftware.org)"/>
            </manifest>
        </jar>
        <!-- Copy application dependent jars -->
        <copy todir="${jar.dest.dir}">
            <fileset dir="${lib.dist.dir}" includes="*.jar" />
        </copy>

        <!-- Setup environment -->
        <antcall target="-prepare" />
    </target>

    <!-- deployjar ============================================================================= -->
    <target name="deployjar" depends="jar" description="Pushes JARs to specified web location.">
        <copy todir="${deploy.jar.dir}" overwrite="${overwrite}">
            <fileset dir="${jar.dest.dir}" includes="*.jar"  />
        </copy>
    </target>

    <!-- war =================================================================================== -->
    <target name="war" depends="jar" description="Creates a WAR of Messenger">
        <mkdir dir="${war.dest.dir}" />
        <mkdir dir="${war.dest.dir}/build" />
        <!-- Make a new web.xml file in the build dir -->
        <loadfile property="startup-def" srcFile="${web.dir}/WEB-INF/web.xml.startup.servlet" />
        <copy file="${web.dir}/WEB-INF/web.xml" toFile="${war.dest.dir}/build/web.xml" overwrite="${overwrite}">
            <filterset begintoken="&lt;!--@@" endtoken="@@--&gt;">
                <filter token="STARTUP-SERVLET" value="${startup-def}" />
            </filterset>
        </copy>
        <!-- Make the war -->
        <war destfile="${war.dest.dir}/${war.name}" basedir="${web.dir}"
                webxml="${war.dest.dir}/build/web.xml"
                excludes="WEB-INF/web.xml.startup.servlet">
            <patternset refid="web.sources" />
            <lib dir="${jar.dest.dir}" excludes="jasper*.jar, servlet.jar" />
        </war>
        <!-- Create a Messenger home -->
        <copy todir="${war.dest.dir}/messengerHome">
            <fileset dir="${target.dir}">
                <include name="conf/**/*.*" />
                <include name="resources/**/*.*" />
            </fileset>
        </copy>
        <!-- Force create the logs dir (will be empty) -->
        <mkdir dir="${war.dest.dir}/messengerHome/logs" />
    </target>

    <!-- javadoc =============================================================================== -->
    <target name="javadoc" depends="compile" description="Produces Messenger Javadocs">
        <mkdir dir="${javadoc.dest.dir}" />
        <antcall target="-javadoc-impl" />

        </target><target name="-javadoc-impl" unless="no.javadoc">
        <!-- Run javadoc over all source code -->
        <javadoc
            sourcepath="${src.java.dir}"
            packagenames="org.jivesoftware.*"
            destdir="${javadoc.dest.dir}"
            windowtitle="Jive Messenger ${version} Javadoc"
            overview="${src.java.dir}/overview.html"
            failonerror="yes"
        >
            <doctitle><![CDATA[<font face="arial,helvetica,sans-serif">Jive Messenger ${version} Javadoc</font>]]></doctitle>
            <header><![CDATA[<b>Jive Messenger ${version} Javadoc</b>]]></header>
            <bottom><![CDATA[<i>Copyright &copy; 1999-2004 Jive Software.</i>]]></bottom>
            <classpath>
                <path refid="javadoc.dependencies" />
            </classpath>
            <link offline="true" href="http://java.sun.com/j2se/1.5.0/docs/api/" packagelistLoc="${javadoc.src.dir}/jdk15"/>
        </javadoc>
    </target>

    <!-- jspc ================================================================================== -->
    <target name="jspc" depends="compile" description="Compiles all JSP pages in the admin console">
        <mkdir dir="${jspc.dest.dir}" />
        <mkdir dir="${jspc.java.dest.dir}" />
        <mkdir dir="${jspc.classes.dest.dir}" />
        <mkdir dir="${webapp.dest.dir}" />

        <!-- Have to use Tomcat 5's JspC task, not the default Ant one -->
        <taskdef classname="org.apache.jasper.JspC" name="jasper2" >
            <classpath id="jspc.classpath">
                <pathelement location="${java.home}/../lib/tools.jar" />
                <pathelement path="${compile.dir}" />
                <path refid="jspc.dependencies" />
            </classpath>
        </taskdef>

        <!-- JSP to JAVA -->
        <jasper2
            validateXml="false"
            uriroot="${web.dir}"
            outputDir="${jspc.java.dest.dir}"
            package="org.jivesoftware.messenger.admin"
            webXmlFragment="${jspc.dest.dir}/web.partial.xml" />

        <!-- Compile java source -->
        <javac
            destdir="${jspc.classes.dest.dir}"
            includeAntRuntime="no"
            debug="on"
            source="1.5"
            includes="org/jivesoftware/messenger/admin/**/*.java"
        >
            <src path="${jspc.java.dest.dir}" />
            <classpath>
                <pathelement path="${compile.dir}" />
                <path refid="jspc.dependencies" />
            </classpath>
        </javac>

        <!-- Update the web.xml to include the servlet and servlet mapping defs from jspc -->
        <loadfile property="servlet-xml" srcFile="${jspc.dest.dir}/web.partial.xml" />
        <copy file="${web.dir}/WEB-INF/web.xml" toFile="${webapp.dest.dir}/WEB-INF/web.xml">
            <filterset begintoken="&lt;!--@@" endtoken="@@--&gt;">
                <filter token="JSPC-SERVLETS" value="${servlet-xml}" />
            </filterset>
        </copy>

        <!-- Create a jar of compiled servlets -->
        <jar jarfile="${jspc.dest.dir}/${jspc.jar.name}">
            <fileset dir="${jspc.classes.dest.dir}" includes="**/*.class" />
        </jar>

    </target>

    <!-- test ================================================================================== -->
    <target name="test" depends="jar" description="Compiles and runs test cases">
        <!-- Compile all test code -->
        <mkdir dir="${test.classes.dest.dir}" />
        <javac
            destdir="${test.classes.dest.dir}"
            includeAntRuntime="no"
            debug="on"
            source="1.5"
        >
            <src path="${src.test.java.dir}" />
            <patternset refid="test.sources" />
            <classpath>
                <path refid="test.dependencies" />
                <pathelement path="${compile.dir}" />
            </classpath>
        </javac>

        <!-- Run jUnit -->
        <mkdir dir="${test.results.dest.dir}" />
        <junit printsummary="yes" haltonfailure="no" fork="yes" dir="${src.test.dir}">

            <!-- We must add our own classes to the classpath for testing -->
            <classpath>
                <path refid="test.dependencies" />
                <pathelement path="${compile.dir}" />
                <pathelement path="${test.classes.dest.dir}" />
            </classpath>

            <formatter type="plain" />

            <batchtest todir="${test.results.dest.dir}">
                <fileset dir="${src.test.java.dir}">
                    <patternset refid="test.sources" />
                </fileset>
            </batchtest>
        </junit>
    </target>

    <target name="-prepare">

        <property name="prepare.out.dir" value="${target.dir}" />

        <!-- Copy lib dir -->
        <copy todir="${prepare.out.dir}/lib">
            <fileset dir="${jar.dest.dir}" includes="*.*"></fileset>
        </copy>

        <!-- Copy conf dir -->
        <copy todir="${prepare.out.dir}">
            <fileset dir="${src.dir}" includes="conf/**/*.*"></fileset>
        </copy>

        <!-- Copy database scripts -->
        <copy todir="${prepare.out.dir}/resources">
            <fileset dir="${src.dir}" includes="database/**/*.*"></fileset>
        </copy>

        <!-- Copy security resources -->
        <copy todir="${prepare.out.dir}/resources">
            <fileset dir="${src.dir}">
                <include name="security/*" />
                <include name="security/*.*" />
            </fileset>
        </copy>

        <!-- Copy bin dir -->
        <copy todir="${prepare.out.dir}">
            <fileset dir="${src.dir}" includes="bin/*.*" />
        </copy>

        <!-- Create a logs dir in the binary release -->
        <mkdir dir="${prepare.out.dir}/logs" />

        <!-- Copy plugins -->
        <copy todir="${prepare.out.dir}">
            <fileset dir="${src.dir}" includes="plugins/**/*.*" />
        </copy>

        <!-- Copy admin plugin resources -->
        <copy todir="${prepare.out.dir}/plugins/admin/webapp">
            <!-- All web resources minus jsp's and jspf's - those are precompiled -->
            <fileset dir="${web.dir}">
                <patternset refid="web.sources" />
                <exclude name="**/*.jsp" />
                <exclude name="**/*.jspf" />
            </fileset>
        </copy>
        <!-- Copy other WEB-INF stuff -->
        <copy todir="${prepare.out.dir}/plugins/admin/webapp">
            <fileset dir="${webapp.dest.dir}" />
        </copy>
        <!-- Copy in tag library support -->
         <copy todir="${prepare.out.dir}/lib">
             <fileset dir="${lib.build.dir}" includes="commons-el.jar" />
         </copy>
        <!-- Copy in pre-compiled JSP jar -->
        <copy todir="${prepare.out.dir}/plugins/admin/webapp/WEB-INF/lib">
            <fileset dir="${jspc.dest.dir}" includes="${jspc.jar.name}" />
        </copy>
        <!-- Copy in jasper runtime jar -->
        <copy todir="${prepare.out.dir}/lib">
            <fileset dir="${lib.build.dir}" includes="jasper-runtime.jar" />
            <fileset dir="${lib.build.dir}" includes="jasper-compiler.jar" />
        </copy>

    </target>

    <!-- release =============================================================================== -->
    <target name="release" depends="jar,javadoc" description="Creates a distribution">
        <mkdir dir="${release.dest.dir}" />

        <!-- Create a new prop for the final release dirs then create the dirs -->

        <property name="release.out.name" value="${dist.prefix}_${version.filename}" />
        <property name="release.src.out.name" value="${dist.prefix}_src_${version.filename}" />

        <property name="release.out.dir" value="${release.dest.dir}/${release.out.name}" />
        <property name="release.src.out.dir" value="${release.dest.dir}/${release.src.out.name}" />

        <mkdir dir="${release.out.dir}" />
        <mkdir dir="${release.src.out.dir}" />

        <!-- Copy all prepare dirs to the binary dist -->
        <ant antfile="${basedir}/build/build.xml" target="-prepare">
            <property name="prepare.out.dir" value="${release.out.dir}" />
        </ant>

        <!-- Copy dist docs, use filtering  -->
        <copy todir="${release.out.dir}">
            <fileset dir="${docs.dir}/dist" includes="*.*" />
            <filterset>
                <filter token="builddate" value="${builddate}" />
                <filter token="version" value="${version}" />
            </filterset>
        </copy>
        <copy todir="${release.src.out.dir}">
            <fileset dir="${docs.dir}/dist" includes="*.*" />
            <filterset>
                <filter token="builddate" value="${builddate}" />
                <filter token="version" value="${version}" />
            </filterset>
        </copy>

        <!-- Copy docs -->
        <copy todir="${release.out.dir}/documentation">
            <fileset dir="${docs.dir}/docs" />
        </copy>
        <copy todir="${release.src.out.dir}/documentation">
            <fileset dir="${docs.dir}/docs" />
        </copy>

        <!-- Copy Javadocs -->
        <copy todir="${release.out.dir}/documentation/javadoc">
            <fileset dir="${javadoc.dest.dir}" />
        </copy>
        <copy todir="${release.src.out.dir}/documentation/javadoc">
            <fileset dir="${javadoc.dest.dir}" />
        </copy>

        <!-- Copy source -->
        <copy todir="${release.src.out.dir}/src">
            <fileset dir="${src.dir}" />
        </copy>

        <!-- Copy build -->
        <copy todir="${release.src.out.dir}/build">
            <fileset dir="${basedir}/build" />
        </copy>

        <!-- Package the release -->
        <antcall target="release-package" />

    </target>

    <!-- quickrelease ========================================================================== -->
    <target name="quickrelease" description="Makes an unpackaged release without Javadocs">
        <antcall target="release">
            <param name="no.javadoc" value="true" />
            <param name="no.package" value="true" />
        </antcall>
    </target>

    <!-- release-package ======================================================================= -->
    <target name="release-package" unless="no.package" description="Packages a release">

        <property name="package.dest.dir" value="${release.dest.dir}" />

        <!-- ZIP -->
        <zip zipfile="${package.dest.dir}/${release.out.name}.zip"
            basedir="${release.out.dir}/.."
            includes="${release.out.name}/**/*.*"
        />
        <zip zipfile="${package.dest.dir}/${release.src.out.name}.zip"
            basedir="${release.src.out.dir}/.."
            includes="${release.src.out.name}/**/*.*"
        />
        <!-- TAR.GZ -->
        <tar tarfile="${package.dest.dir}/${release.out.name}.tar.gz"
            basedir="${release.out.dir}/.."
            includes="${release.out.name}/**/*.*"
            compression="gzip"
        />
        <tar tarfile="${package.dest.dir}/${release.src.out.name}.tar.gz"
            basedir="${release.src.out.dir}/.."
            includes="${release.src.out.name}/**/*.*"
            compression="gzip"
        />

    </target>

    <!-- dailybuild ============================================================================ -->
    <target name="dailybuild" depends="init" description="Creates a daily build release">
        <property name="release.out.name" value="${dist.prefix}_${dailybuild.tstamp}" />
        <property name="release.src.out.name" value="${dist.prefix}_src_${dailybuild.tstamp}" />
        <property name="release.out.dir" value="${release.dest.dir}/dailybuild/${release.out.name}" />
        <property name="release.src.out.dir" value="${release.dest.dir}/dailybuild/${release.src.out.name}" />
        <antcall target="release">
            <param name="release.out.name" value="${release.out.name}" />
            <param name="release.src.out.name" value="${release.src.out.name}" />
            <param name="release.out.dir" value="${release.out.dir}" />
            <param name="release.src.out.dir" value="${release.src.out.dir}" />
            <param name="package.dest.dir" value="${release.dest.dir}/dailybuild" />
        </antcall>
    </target>

    <!-- clean ================================================================================= -->
    <target name="clean" description="Cleans up all build-generated output">
        <delete dir="${target.dir}" />
    </target>

    <!-- clean-jspc ============================================================================ -->
    <target name="clean-jspc" description="Cleans all JSPC output">
        <delete dir="${jspc.dest.dir}" />
    </target>

    <!-- clean-test ============================================================================ -->
    <target name="clean-test" description="Cleans all compiled test classes">
        <delete dir="${test.classes.dest.dir}" />
    </target>

</project>
