<?xml version="1.0"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  The ASF licenses this file to You
  under the Apache License, Version 2.0 (the "License"); you may not
  use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.  For additional information regarding
  copyright in this work, please see the NOTICE file in the top level
  directory of this distribution.
-->
<!DOCTYPE project [
<!ENTITY custom-build      SYSTEM "custom/custom-build.xmlf">
<!ENTITY custom-dist       SYSTEM "custom/custom-dist.xmlf">
]>
<project name="Roller Planet" default="build" basedir=".">
    
    <description>Builds, tests, and runs the project Roller Planet.</description>

    <property file="build.properties" />
    
    <!-- a pointer to the root of the entire Roller workspace -->
    <property name="root"             value="${basedir}/../.." />
    
    <!-- core properties -->
    <property name="build"            value="${basedir}/build" />
    <property name="dist"             value="${basedir}/dist" />
    <property name="lib"              value="${basedir}/lib" />
    <property name="sql"              value="${basedir}/src/sql" />
    <property name="src"              value="${basedir}/src/java" />
    <property name="tools"            value="${basedir}/../../tools" />
    <property name="test"             value="${basedir}/test/java" />
    <property name="testcontext"      value="${basedir}/build/test/testcontext" />
    <property name="web"              value="${basedir}/web" />
    
    <!-- build properties -->
    <property name="build.compile"                  value="${build}/compile"/>
    <property name="build.compile.business"         value="${build.compile}/business"/>
    <property name="build.compile.web"              value="${build.compile}/web"/>
    <property name="build.compile.custom"           value="${build.compile}/custom"/>
    <property name="build.compile.test"             value="${build.compile}/test"/>
    <property name="build.lib"           value="${build}/lib"/>
    <property name="build.webapp"        value="${build}/webapp"/>
    <property name="build.dbscripts"     value="${build}/dbscripts"/>
    <property name="build.test"          value="${build}/test"/>
    <property name="build.test.reports"  value="${build.test}/reports"/>
    
    <fileset id="business.tools" dir="${tools}" >
        
        <!-- Roller Core -->
        <include name="roller-core/roller-core.jar"/>
        <include name="lib/commons-id-0.1-SNAPSHOT.jar"/>
        
        <!-- General dependencies -->
        <include name="lib/guice-1.0.jar"/>
        <include name="lib/log4j-1.2.11.jar"/>
        <include name="lib/commons-codec-1.3.jar"/>
        <include name="lib/commons-collections-3.2.jar"/>
        <include name="lib/commons-digester-1.6.jar"/>
        <include name="lib/commons-lang-2.1.jar"/>
        <include name="lib/commons-logging-1.0.4.jar"/>
        <include name="buildtime/activation.jar"/>
        <include name="buildtime/mail.jar"/>

        <!-- needed for JPA/OpenJPA -->
        <include name="openjpa-0.9.7/openjpa-0.9.7-incubating.jar"/>
        <include name="openjpa-0.9.7/geronimo-jpa_3.0_spec-1.0.jar"/>
        <include name="openjpa-0.9.7/geronimo-jta_1.0.1B_spec-1.0.1.jar"/>
        <include name="openjpa-0.9.7/serp-1.11.0.jar"/>
        <include name="openjpa-0.9.7/geronimo-j2ee-connector_1.5_spec-1.0.1.jar"/> 
<!--
        <include name="openjpa-1.0/geronimo-jpa_3.0_spec-1.0.jar"/>
        <include name="openjpa-1.0/geronimo-jta_1.1_spec-1.1.jar"/> 
        <include name="openjpa-1.0/openjpa-1.0.0.jar"/>
        <include name="openjpa-1.0/serp-1.13.1.jar"/>
-->
        <!-- Needed for JPA/Toplink
        <include name="toplink-essentials-9.1/toplink-essentials.jar"/> -->
        
        <!-- needed for ROME -->
        <include name="lib/rome-0.9.1-dev.jar"/>
        <include name="lib/rome-fetcher-0.9.jar"/>
        <include name="lib/jdom.jar"/>
        
        <!-- Velocity -->
        <include name="lib/velocity-1.5.jar"/>
    </fileset>
    
    <fileset id="web.tools" dir="${tools}">
        <!-- Jstl -->
        <include name="jakarta-taglibs-standard-1.1.2/lib/jstl.jar" />
        <include name="jakarta-taglibs-standard-1.1.2/lib/standard.jar" />
        <include name="jakarta-taglibs-standard-1.1.2/lib/xalan.jar" />
        <include name="jakarta-taglibs-standard-1.1.2/lib/serializer.jar" />
        
        <!-- Struts 2 -->
        <include name="struts-2.0.9/lib/*.jar"/>
        
        <!-- Struts 2 depends on Spring -->
        <include name="spring-1.2/spring.jar"/>
    </fileset>
    
    <path id="planet.business.path">
        <fileset refid="business.tools" />
    </path>
    
    <path id="planet.web.path">
        <fileset refid="web.tools" />
        
        <!-- need servlet api for build time -->
        <pathelement location="${tools}/buildtime/tomcat-5.0.28/servlet-api.jar" />
                
        <!-- planet business layer classpath -->
        <path refid="planet.business.path" />
        
        <!-- planet business layer library -->
        <pathelement location="${build.lib}/roller-planet-business.jar"/>
    </path>
    
    <path id="xdoclet.path">
        <path refid="planet.web.path"/>
        
        <fileset dir="${tools}/buildtime" includes="ejb-1.1.jar"/>
        <fileset dir="${tools}/buildtime/xdoclet-1.2.3/lib" includes="*.jar"/>
    </path>
    
    <path id="test.path">
        <!-- testing jars -->
        <fileset dir="${tools}/buildtime/mockrunner-0.35/lib">
            <include name="*.jar"/>
        </fileset>
        <pathelement location="${tools}/buildtime/junit-4.1.jar"/>
        <pathelement location="${tools}/buildtime/ant-1.7.0/ant-junit.jar"/>
        <pathelement location="${tools}/buildtime/derby.jar"/>
        <pathelement location="${tools}/buildtime/derbyclient.jar"/>
        <pathelement location="${tools}/buildtime/derbynet.jar"/>
        <pathelement location="${tools}/lib/commons-httpclient-2.0.2.jar"/>
        
        <!-- plus normal jars -->
        <path refid="planet.web.path"/>

        <!-- plus already built roller planet libraries -->
        <fileset dir="${build.lib}" includes="*.jar" />
    </path>
    
    
    <!-- ============================================== -->
    <!-- clean out any contents from last build -->
    <target name="clean" description="Clean (i.e. remove) build and dist dirs">
        <delete dir="${build}" />
        <delete dir="${dist}" />
    </target>

    
    <!-- ============================================== -->
    <!-- build all code -->
    <target name="build" depends="build-business, build-web, build-custom" >
    </target>
    
    <!-- build the business layer code and jar it up -->
    <target name="build-business" >
        
        <!-- compile planet classes -->
        <mkdir dir="${build.compile.business}"/>
        <javac destdir="${build.compile.business}"
               excludes="org/apache/roller/planet/ui/**"
               debug="${build.debug}" 
               source="${build.sourcelevel}"
               deprecation="${build.deprecation}">
            
            <src path="${src}" />
            
            <classpath>
                <path refid="planet.business.path"/>
            </classpath>
        </javac>
        
        <!-- Copy resources -->
        <copy todir="${build.compile.business}">
            <fileset dir="${src}">
                <exclude name="org/apache/roller/planet/ui/**"/>
                <exclude name="**/*.java"/>
                <exclude name="**/*.html"/>
                <exclude name="**/*.png"/>
            </fileset>
        </copy>
        
        <mkdir dir="${build.compile.business}/META-INF" />
        <copy todir="${build.compile.business}/META-INF" file="src/java/META-INF/persistence.xml" />
                
        <!-- OpenJPA bytecode enhancement   -->
        <path id="openjpac.path">
            <path refid="planet.business.path"/>
            <pathelement path="${build.compile.business}" />
            <pathelement path="${build.compile.business}/org/apache/roller/planet/pojos" />
        </path>
        <taskdef name="openjpac" classname="org.apache.openjpa.ant.PCEnhancerTask" classpathref="openjpac.path" />
        <openjpac enforcePropertyRestrictions="false">
            <config propertiesFile="src/java/META-INF/persistence.xml" />
            <!-- <fileset dir="${build.compile.business}">
                <include name="**/pojos/*.class" />
            </fileset> -->
            <classpath refid="openjpac.path" />
        </openjpac>
        
        <!-- JPA/Toplink bytecode enhancement
        <taskdef name="weave" classname="oracle.toplink.essentials.weaving.StaticWeaveAntTask" classpathref="planet.business.path"/>
        <weave  source="${build.compile.business}" target="${build.compile.business}">
            <classpath>
                <path refid="planet.business.path"/>
                <pathelement location="${build.compile.business}" />
                <pathelement location="${build.compile.business}/org/apache/roller/planet/pojos" />
            </classpath>
        </weave> -->
        
        <!-- Jar up the business layer -->
        <mkdir dir="${build.lib}"/>
        <jar basedir="${build.compile.business}"
             jarfile="${build.lib}/roller-planet-business.jar"/>
        
    </target>
    
    <!-- build the web/ui layer code and jar it up -->
    <target name="build-web" depends="build-business">
        
        <!-- compile planet web classes -->
        <mkdir dir="${build.compile.web}"/>
        <javac destdir="${build.compile.web}"
               includes="org/apache/roller/planet/ui/**"
               debug="${build.debug}" 
               source="${build.sourcelevel}"
               deprecation="${build.deprecation}">
            
            <src path="${src}" />
            <include name="" />
            
            <classpath>
                <path refid="planet.web.path"/>
            </classpath>
        </javac>
        
        <!-- Copy resources -->
        <copy todir="${build.compile.web}">
            <fileset dir="${src}">
                <include name="org/apache/roller/planet/ui/**"/>
                <exclude name="**/*.java"/>
                <exclude name="**/*.html"/>
                <exclude name="**/*.png"/>
            </fileset>
        </copy>
        
        <!-- Jar up the web layer -->
        <mkdir dir="${build.lib}"/>
        <jar basedir="${build.compile.web}"
             jarfile="${build.lib}/roller-planet-web.jar"/>
        
    </target>
    
    
    <!-- build custom code and jar it up -->
    <target name="build-custom" depends="build-web">
        
        &custom-build;
        
    </target>
    
    
    <!-- ============================================== -->
    <!-- create distributable components -->
    <target name="dist" depends="build" description="Create Roller Planet distributables">
        
        <!-- distributable libraries -->
        <mkdir dir="${dist}/lib" />
        <copy todir="${dist}/lib" >
            <fileset dir="${build.lib}" />
        </copy>
        
        <!-- assemble distributable webapp -->
        <mkdir dir="${build.webapp}/WEB-INF/lib" />
        <copy todir="${build.webapp}/WEB-INF/lib" flatten="true">
            <!-- our compiled Roller Planet libraries -->
            <fileset dir="${build.lib}" />
            
            <!-- business layer tools -->
            <fileset refid="business.tools" />
            
            <!-- web layer tools -->
            <fileset refid="web.tools" />
        </copy>         

        <copy todir="${build.webapp}">
            <fileset dir="${web}" includes="**/**" />
        </copy>         
        <chmod perm="+x" dir="${build.webapp}/WEB-INF/scripts" includes="*.sh" />
        
        <!-- allow for custom mods to webapp -->
        &custom-dist;
        
        <!-- distributable WAR file -->
        <mkdir dir="${dist}/webapp" />
        <jar destfile="${dist}/webapp/roller-planet.war"
             basedir="${build.webapp}" />
             
    </target>
    
    
    <!-- generate database scripts -->
    <target name="gen-dbscripts">
        
        <mkdir dir="${build.dbscripts}" />
        
        <!-- need a directory for each db to exist before generation can happen -->
        <mkdir dir="${build.dbscripts}/db2" />
        <mkdir dir="${build.dbscripts}/derby" />
        <mkdir dir="${build.dbscripts}/hsqldb" />
        <mkdir dir="${build.dbscripts}/mssql" />
        <mkdir dir="${build.dbscripts}/mysql" />
        <mkdir dir="${build.dbscripts}/oracle" />
        <mkdir dir="${build.dbscripts}/postgresql" />
        
        <path id="texen.path">
            <fileset refid="business.tools" />
            <pathelement location="${root}/metadata/database/" />
            <pathelement location="${sql}" />
        </path>
        <taskdef name="texen" 
                 classname="org.apache.velocity.texen.ant.TexenTask"
                 classpathref="texen.path" />
                 
        <texen
            controlTemplate="control.vm" 
            contextProperties="${sql}/dbscripts.properties"
            useClasspath="true"
            outputDirectory="${build.dbscripts}" 
            outputFile="README.txt" />
            
        <!-- just copy over the droptables script -->
        <copy todir="${build.dbscripts}" file="${sql}/droptables.sql" />
        
    </target>


    <!-- ============================================== -->
    <!-- build code used for unit testing -->
    <target name="build-tests" depends="build" description="Build unit tests">
    
        <!-- compile all test classes -->
        <mkdir dir="${build.compile.test}" />
        <javac destdir="${build.compile.test}"
            includeantruntime="false"
            debug="${build.debug}" 
            source="${build.sourcelevel}"
            deprecation="${build.deprectation}">
            
            <src path="${test}" />
            
            <classpath>
                <path refid="test.path"/>
                <pathelement location="${tools}/buildtime/ant-1.7.0/ant.jar"/>
            </classpath>
        </javac>

        <mkdir dir="${testcontext}" />
        <copy todir="${testcontext}">
            <fileset dir="${web}" excludes="**/jsps/**,**/velocity/**" />
            <fileset dir="${basedir}/testdata" />
        </copy>
        
        <!-- Copy test resources -->
        <copy todir="${build.compile.test}">
            <fileset dir="${test}" excludes="**/*.java, **/*.html, **/*.png" />
        </copy>
        
    </target>
    
    
    <target name="test" depends="build-tests" description="All tests">
        <!-- business layer tests -->
        <antcall target="test-business" />
        
        <!-- TODO: web layer tests -->
    </target>
    
    
    <!-- ===================================== -->
    <!-- test planet business layer functionality -->
    <target name="test-business" depends="build-tests, gen-dbscripts" description="Back-end tests">
        
        <mkdir dir="${build.test.reports}/business/xml"/>
        <mkdir dir="${build.test.reports}/business/html"/>
        
        <!-- allow for startup and initialization of test db -->
        <antcall target="${test.db.startTask}" />
        <antcall target="${test.db.initTask}" />
        
        <junit dir="${build.test}" fork="${junit.fork}" printsummary="on" showOutput="true">
            <classpath>
                <!-- testing jars -->
                <path refid="test.path"/>
                
                <!-- plus our compiled test classes -->
                <pathelement location="${build.compile.test}"/>
        
                <!-- testdata. the equivalent of /WEB-INF/classes in a webapp -->
                <pathelement location="${basedir}/build/test/testcontext" />
                <pathelement location="${basedir}/build/test/testcontext/WEB-INF/classes" />
                
                <!-- plus the classpath for jars needed to talk to the test db -->
                <pathelement path="${test.db.cpath}" />
            </classpath>
            
            <!-- needed to satisfy ref in log4j.properties -->
            <jvmarg value="-Dcatalina.base=${build.test}"/> 
            <jvmarg value="-Dbuild=${build}"/>
            <formatter type="xml"/>
            <batchtest toDir="${build.test.reports}/business/xml" haltonerror="${junit.haltonerror}">
                <fileset dir="${build.compile.test}">
                    <include name="org/apache/roller/planet/business/PlanetTestSuite.class"/>
                </fileset>
            </batchtest>
        </junit>
        
        <junitreport todir="${build.test.reports}/business/xml">
            <fileset dir="${build.test.reports}/business/xml">
                <include name="TEST-*.xml"/>
            </fileset>
            <report format="noframes" toDir="${build.test.reports}/business/html"/>
        </junitreport>
        
        <!-- allow for shutdown of test db -->
        <antcall target="${test.db.stopTask}" />
    
    </target>
    
    
    <!-- ********************************************************************* -->
    <!-- Test database start, init and stop targets -->
    <!-- ********************************************************************* -->
    
    <target name="init-db" description=
            "Initializes test database by running drop table and create table">
        
        <!-- start by dropping tables to reset everything -->
        <sql driver="${test.db.driver}"
             url="${test.db.url}"
             userid="${test.db.username}" 
             password="${test.db.password}"
             src="${build.dbscripts}/droptables.sql" 
             onerror="continue"
             classpath="${test.db.cpath}" />
             
        <!-- now create fresh tables -->
        <sql driver="${test.db.driver}"
             url="${test.db.url}"
             userid="${test.db.username}" 
             password="${test.db.password}"
             src="${build.dbscripts}/${test.db.name}/createdb.sql"
             onerror="continue"
             classpath="${test.db.cpath}" />
    </target>
    
    <target name="start-db" description="Starts built-in database">  
        <taskdef name="startdb" classname="org.apache.roller.ant.StartDerbyTask" 
                 classpath="${tools}/buildtime/derby.jar;${tools}/buildtime/derbynet.jar;${build.compile.test}" />
        <startdb database="${build.test}/derby-system/roller" port="3219" />
    </target>
    
    <target name="stop-db" description="Stops built-in database">   
        <taskdef name="stopdb" classname="org.apache.roller.ant.StopDerbyTask" 
                 classpath="${tools}/buildtime/derby.jar;${tools}/buildtime/derbynet.jar;${build.compile.test}" />
        <stopdb port="3219"/>
    </target>

    <target name="nothing">
        <!-- this task does nothing and is here so that 
             dynamic task definitions have a no-op choice -->
    </target>
        
    <!-- Netbeans-only: debug single class -->
    <target name="debug-selected-files" if="netbeans.home" depends="build-tests" 
            description="Debug a Single File">
        <fail unless="classname">Must set property 'classname'</fail>
        <antcall target="start-db" />
        <antcall target="init-db" />
        <nbjpdastart name="${classname}" addressproperty="jpda.address" transport="dt_socket">
            <classpath>
                <path refid="test.path"/>
                <pathelement location="${build.compile.test}"/>
                <pathelement location="${basedir}/testdata" />
                <pathelement path="${test.db.cpath}" />
            </classpath>
        </nbjpdastart>
        <java classname="${classname}" fork="true" dir="${build.test}">
            <jvmarg value="-Xdebug"/>
            <jvmarg value="-Xnoagent"/>
            <jvmarg value="-Djava.compiler=none"/>
            <jvmarg value="-Xrunjdwp:transport=dt_socket,address=${jpda.address}"/>
            <jvmarg value="-Dcatalina.base=${build.test}"/> 
            <jvmarg value="-Dbuild=${build}"/>
            <jvmarg value="-Droller.custom.config=${build.tests}/planet-custom.properties"/>
            <classpath>
                <path refid="test.path"/>
                <pathelement location="${build.compile.test}"/>
                <pathelement location="${basedir}/build/test/testcontext" />
                <pathelement location="${basedir}/build/test/testcontext/WEB-INF/classes" />
                <pathelement path="${test.db.cpath}" />
            </classpath>
        </java>
        <antcall target="stop-db" />
    </target>
    
    <!-- Netbeans-only: debug single test class -->
    <target name="test-selected-files" if="netbeans.home" depends="build-tests" 
            description="Test/debug a Single File">
        <fail unless="classname">Must set property 'classname'</fail>
        <antcall target="start-db" />
        <antcall target="init-db" />   
        <nbjpdastart name="junit.textui.TestRunner" addressproperty="jpda.address" transport="dt_socket">
            <classpath>
                <path refid="test.path"/>
                <pathelement location="${build.compile.test}"/>
                <pathelement location="${basedir}/testdata" />
                <pathelement path="${test.db.cpath}" />
            </classpath>
        </nbjpdastart>
        <java classname="junit.textui.TestRunner" fork="true" dir="${build.test}">
            <arg value="${classname}" />
            <jvmarg value="-Xdebug"/>
            <jvmarg value="-Xnoagent"/>
            <jvmarg value="-Djava.compiler=none"/>
            <jvmarg value="-Xrunjdwp:transport=dt_socket,address=${jpda.address}"/>
            <jvmarg value="-Dcatalina.base=${build.test}"/> 
            <jvmarg value="-Dbuild=${build}"/>
            <jvmarg value="-Droller.custom.config=${build.tests}/planet-custom.properties"/>
            <classpath>
                <path refid="test.path"/>
                <pathelement location="${build.compile.test}"/>
                <pathelement location="${basedir}/build/test/testcontext" />
                <pathelement location="${basedir}/build/test/testcontext/WEB-INF/classes" />
                <pathelement path="${test.db.cpath}" />
            </classpath>
        </java>
        <antcall target="stop-db" />
    </target>
    
</project>
