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

<project name="lw-build-macros" basedir=".">

	<description>
	    A collection of macros for other build files to use.
	</description>
    
	<property name="limewire.home"
			  location="${basedir}/../.."/>
	<property name="limewire.lib"
			  location="${limewire.home}/lib"/>
	<property name="limewire.lib.jars"
			  location="${limewire.lib}/jars"/>
	<property name="limewire.lib.native"
			  location="${limewire.lib}/native"/>
	<property name="limewire.library.path"
			  value="${limewire.lib.native}/windows${path.separator}${limewire.lib.native}/osx${path.separator}${limewire.lib.native}"/>
	<property name="limewire.components.home"
		      location="${limewire.home}/components"/>
    <property name="cloverjar"
    		  location="${ant.library.dir}/clover.jar"/>
    
	<property name="compile.debug"			value="true"/>
	<property name="compile.deprecation"	value="true"/>
	<property name="compile.optimize"		value="false"/>
	<property name="compile.source"			value="1.5"/>
	<property name="compile.target"			value="1.5"/>
    
    <macrodef name="do.setup-properties" description="Sets up common properties every macro uses.">
    	<attribute name="component"/>
        <attribute name="junit" default="${limewire.lib.jars}/tests/junit.jar"/>
        <element name="src-classpath" optional="true" description="Additional paths for building source"/>
        <element name="tests-classpath" optional="true" description="Additional paths for running tests"/>
        <element name="build-tests-classpath" optional="true" description="Additional paths for building tests"/>
        <sequential>
        	<property name="limewire.components.@{component}.home"
        		      location="${limewire.components.home}/@{component}"/>
        	<property name="limewire.components.@{component}.src.home"
        			  location="${limewire.components.@{component}.home}/src/main"/>	
        	<property name="limewire.components.@{component}.src"
            		  location="${limewire.components.@{component}.src.home}/java"/>
        	<property name="limewire.components.@{component}.src.resources"
            		  location="${limewire.components.@{component}.src.home}/resources"/>
            <property name="limewire.components.@{component}.tests.home"
        			  location="${limewire.components.@{component}.home}/src/test"/>
          	<property name="limewire.components.@{component}.tests"
              		  location="${limewire.components.@{component}.tests.home}/java"/>
          	<property name="limewire.components.@{component}.tests.resources"
              		  location="${limewire.components.@{component}.tests.home}/resources"/>
            
        	<property name="build.limewire.components.@{component}.home"
        		      location="${limewire.components.@{component}.home}/build"/>
        	<property name="build.limewire.components.@{component}.classes"
        			  location="${build.limewire.components.@{component}.home}/classes"/>	
        	<property name="build.limewire.components.@{component}.tests"
        			  location="${build.limewire.components.@{component}.home}/tests"/>
        	
        	<property name="tests.limewire.components.@{component}.home"
        		      location="${limewire.components.@{component}.home}/testData"/>
            <property name="tests.limewire.components.@{component}.xml"
            		  location="${tests.limewire.components.@{component}.home}/xml"/>
            <property name="tests.limewire.components.@{component}.html"
            		  location="${tests.limewire.components.@{component}.home}/html"/>
            
            <property name="clover.limewire.components.@{component}.home"
			          location="${limewire.components.@{component}.home}/clover"/>
            <property name="clover.limewire.components.@{component}.db"
			          location="${clover.limewire.components.@{component}.home}/clover.db"/>
            <property name="clover.limewire.components.@{component}.html"
			          location="${clover.limewire.components.@{component}.home}/html"/>
            
            <property name="dist.limewire.components.@{component}.home"
                      location="${limewire.components.@{component}.home}/dist"/>
            <property name="dist.limewire.components.@{component}.javadoc"
            		  location="${dist.limewire.components.@{component}.home}/javadoc"/>
            <property name="dist.limewire.components.@{component}.jar"
            		  location="${dist.limewire.components.@{component}.home}/lw-@{component}.jar"/>
       	
        	<path id="build.limewire.components.@{component}.classpath">
        	    <src-classpath/>
        	</path>
            
            <path id="build.limewire.components.@{component}.buildpath">
                <path refid="build.limewire.components.@{component}.classpath"/>
                <pathelement location="${build.limewire.components.@{component}.classes}"/>
            </path>
            
    	    <path id="build.limewire.components.@{component}.tests.classpath">
	        	<path refid="build.limewire.components.@{component}.buildpath"/>
    	        <path refid="build.limewire.components.test-util.buildpath"/>
    	        <pathelement location="@{junit}"/>
    	        <build-tests-classpath/>
    	    </path>
        	
        	<path id="tests.limewire.components.@{component}.classpath">
        	    <pathelement location="${cloverjar}"/>
        		<path refid="build.limewire.components.@{component}.tests.classpath"/>
        		<pathelement location="${build.limewire.components.@{component}.tests}"/>
        	    <pathelement location="${limewire.components.@{component}.src.resources}"/>
        	    <pathelement location="${limewire.components.@{component}.tests.resources}"/>
        	    <tests-classpath/>
        	</path>	
        </sequential>
    </macrodef>
    
    <macrodef name="do.clean" description="Cleans all generated directories.">
    	<attribute name="component"/>
		<sequential>
        	<do.clean-testData component="@{component}"/>
		    <do.clean-build    component="@{component}"/>
			<do.clean-dist     component="@{component}"/>
		    <do.clean-clover   component="@{component}"/>
		</sequential>
	</macrodef>
    
    <macrodef name="do.compile" description="Compiles source and test code.">
        <attribute name="component"/>
        <sequential>
            <do.compile-src   component="@{component}"/>
            <do.compile-tests component="@{component}"/>
        </sequential>
    </macrodef>
	
	<macrodef name="do.compile-src" description="Compiles only the source code.">
	    <attribute name="component"/>
	    <element name="more-src-paths" optional="true"/>
	    <attribute name="excludes" default=""/>
	    <sequential>
	        <do.build-init component="@{component}"/>
			<mkdir dir="${build.limewire.components.@{component}.classes}"/>
			<javac destdir		="${build.limewire.components.@{component}.classes}"
 				   debug	    ="${compile.debug}"
				   deprecation  ="${compile.deprecation}"
	 	           optimize     ="${compile.optimize}"
				   encoding     ="UTF-8"
		           source		="${compile.source}"
	  	           target       ="${compile.target}"
	 	           sourcepath   =""
			       excludes     ="@{excludes}" 
	 	    >
			    <compilerarg value="-Xlint:unchecked"/>
				<src>
					<pathelement location="${limewire.components.@{component}.src}"/>
				    <more-src-paths/>
			    </src>
				<classpath refid="build.limewire.components.@{component}.classpath"/>
			</javac>
	    </sequential>
	</macrodef>
    
    <macrodef name="do.clean-src" description="Cleans generated classfiles from compiling source.">
        <attribute name="component"/>
        <sequential>
			<delete dir="${build.limewire.components.@{component}.classes}" />
        </sequential>
    </macrodef>
	
	<macrodef name="do.compile-tests" description="Compiles test code and copies resources tests use.">
	    <attribute name="component"/>
		<sequential>
			<mkdir dir="${build.limewire.components.@{component}.tests}"/>
			<javac destdir		="${build.limewire.components.@{component}.tests}"
 				   debug	    ="${compile.debug}"
				   deprecation  ="${compile.deprecation}"
	   	   		   optimize     ="${compile.optimize}"
				   encoding     ="ISO-8859-1"
	    	       source		="${compile.source}"
	        	   target       ="${compile.target}"
	        	   sourcepath   =""
	   		>
				<src>
					<pathelement location="${limewire.components.@{component}.tests}"/>
			    </src>
				<classpath refid="build.limewire.components.@{component}.tests.classpath"/>
			</javac>
		</sequential>
	</macrodef>
    
	<macrodef name="do.clean-tests" description="Cleans generated classfiles and resources from compiling tests.">
	    <attribute name="component"/>
	    <sequential>
			<delete dir="${build.limewire.components.@{component}.tests}" />
	    </sequential>
	</macrodef>
    
	<macrodef name="do.clean-testData" description="Cleans any data generated by running tests.">
	    <attribute name="component"/>
	    <sequential>
			<delete dir="${tests.limewire.components.@{component}.home}" />
	    </sequential>
	</macrodef>
	
	<macrodef name="do.test" description="Runs a single test class.">
	    <attribute name="component"/>
	    <attribute name="class"/>
	    <attribute name="path" default="org/limewire"/>
	    <sequential>
	    	<do.clean-testData component="@{component}"/>
	        <do.tests-init     component="@{component}"/>
			<do.run-tests-batchunit 
			                   haltonerror="true"
						       haltonfailure="true"
						       unit="@{path}/${class}.class"
   			    			   component="@{component}"
			/>
			<do.tests2html     component="@{component}"/>
	    </sequential>
	</macrodef>
	
	<macrodef name="do.test-package" description="Runs all tests in a single package.">
	    <attribute name="component"/>
	    <attribute name="package"/>
	    <attribute name="path" default="org/limewire"/>
	    <attribute name="forkmode" default="once"/>
	    <sequential>
	        <do.clean-testData      component="@{component}"/>
	        <do.tests-init          component="@{component}"/>
			<do.run-tests-batchunit unit="@{path}/${package}/*Test.class"
									component="@{component}"
			    					forkmode="@{forkmode}"
			/>
	        <do.tests2html          component="@{component}"/>
	    </sequential>
	</macrodef>
	
	<macrodef name="do.test-all" description="Runs all tests.">
	    <attribute name="component"/>
	    <element name="testLocations"     optional="true"/>
	    <attribute name="forkmode" default="once"/>
	    <sequential>
	        <do.clean-testData      component="@{component}"/>
	        <do.tests-init          component="@{component}"/>
	        <do.run-tests-batchunit unit="**/*Test.class"
	            					component="@{component}"
	            					forkmode="@{forkmode}"
	        >
	        	<testPathLocations>
	        	   <testLocations/>
	            </testPathLocations>
	        </do.run-tests-batchunit>
	        <do.tests2html          component="@{component}"/>
	    </sequential>
	</macrodef>
    
    <macrodef name="do.jar" description="Generates a jar of the classfiles.">
    	<attribute name="component"/>
    	<element name="more-jar-elements" optional="true"/>
        <attribute name="basedir"     default="${build.limewire.components.@{component}.classes}"/>
        <attribute name="resourcedir" default="${limewire.components.@{component}.src.resources}"/>
        <attribute name="resexclude"  default=""/>
        <attribute name="compress"    default="false"/>
        <attribute name="excludes"    default=""/>
        <sequential>
            <do.dist-init component="@{component}"/>
            <delete file="${dist.limewire.components.@{component}.jar}"/>
            <jar destfile="${dist.limewire.components.@{component}.jar}"
            	 compress="@{compress}"
                 basedir="@{basedir}"
                 excludes="@{excludes}"
            >
                <fileset dir="@{resourcedir}" excludes="@{resexclude}"/>
                <more-jar-elements/>
            </jar>
        </sequential>
    </macrodef>
    
    <macrodef name="do.javadoc" description="Generates a javadoc for the source.">
    	<attribute name="component"/>
        <attribute name="windowtitle" default="LimeWire (@{component})"/>
        <element name="more-javadoc-elements" optional="true"/>
        <attribute name="classpathrefid" default="build.limewire.components.@{component}.classpath"/>
        <attribute name="sourcepath" default="${limewire.components.@{component}.src}"/>
    	<sequential>
    	    <delete dir="${dist.limewire.components.@{component}.javadoc}"/>
    	    <mkdir dir="${dist.limewire.components.@{component}.javadoc}"/>
    	    <javadoc       destdir="${dist.limewire.components.@{component}.javadoc}"
    	                   windowtitle="@{windowtitle}"
    	                   sourcepath="@{sourcepath}"
    	        		   use="true"
    	        		   author="false"
    	        		   version="false"
						   packagenames="*">
    	       <link href="http://java.sun.com/j2se/1.5.0/docs/api/"/>
    	       <classpath refid="@{classpathrefid}"/>
    	       <more-javadoc-elements/>
    	    </javadoc>
	    </sequential>
    </macrodef>
	
	<macrodef name="do.run-tests-batchunit">
		<attribute name="component"/>
	    <attribute name="unit"/>
	    <attribute name="haltOnFailure"     default="false"/>
	    <attribute name="haltOnError"	    default="false"/>
	    <attribute name="nativePathRefId"   default="limewire.library.path"/>
	    <element   name="testPathLocations" optional="true"/>
	    <attribute name="forkmode"			default="once"/>
	    <sequential>
	        <junit printsummary="withOutAndErr"
	    	       haltonfailure="@{haltOnFailure}"
	    		   haltonerror="@{haltOnError}"
	    		   failureproperty="testfailed"
	    	       showoutput="true"
	    	       fork="true"
	           	   forkmode="@{forkmode}"
	    	>
	            <sysproperty key="java.library.path"      		 value="${@{nativePathRefId}}"/>
	    		<sysproperty key="junit.test.method"      		 value="${method}"/>
	    		<sysproperty key="just.test.times"        		 value="${times}"/>
	    	    <sysproperty key="junit.test.hidetestname"		 value="${hidetestname}"/>
	            <sysproperty key="junit.test.ignoreErrorService" value="${ignoreErrorService}"/>
	            <jvmarg value="-Xmx512M"/>
	    		
	    		<classpath refid="tests.limewire.components.@{component}.classpath"/>
	    		
	    		<formatter type="xml"/>
	    		<formatter type="plain" usefile="false"/>
	    		
	    		<batchtest todir="${tests.limewire.components.@{component}.xml}">
	    			<fileset dir="${build.limewire.components.@{component}.tests}">
	    			    <include name="@{unit}"/>
	    		    </fileset>
	    		    <testPathLocations/>
	    		</batchtest>
			</junit>
		</sequential>
	</macrodef>
	
    <macrodef name="do.tests2html" description="Converts test XML output to HTML reports.">
        <attribute name="component"/>
        <element name="more-xml-locations" optional="true"/>
        <sequential>
	        <junitreport todir="${tests.limewire.components.@{component}.xml}">
	        	<fileset dir="${tests.limewire.components.@{component}.xml}">
				    <include name="TEST-*.xml"/>
				</fileset>
	            <more-xml-locations/>
	        	<report format="frames" todir="${tests.limewire.components.@{component}.html}"/>
	       </junitreport>
        </sequential>
    </macrodef>
	
	<macrodef name="do.build-init" description="Initializes directories for building the code.">
	    <attribute name="component"/>
	    <sequential>
	    	<mkdir dir="${build.limewire.components.@{component}.home}" />
	    </sequential>
	</macrodef>
    
    <macrodef name="do.dist-init" description="Initializes directories for distribution.">
    	<attribute name="component"/>
    	<sequential>
    	    <mkdir dir="${dist.limewire.components.@{component}.home}"/>
    	</sequential>
    </macrodef>
	
	<macrodef name="do.tests-init" description="Initializes directories for running tests.">
	    <attribute name="component"/>
	    <sequential>
			<mkdir dir="${tests.limewire.components.@{component}.home}" />
			<mkdir dir="${tests.limewire.components.@{component}.html}" />
			<mkdir dir="${tests.limewire.components.@{component}.xml}" />
	    </sequential>
	</macrodef>
	
	<macrodef name="do.clean-build" description="Cleans all data related to building the code.">
	    <attribute name="component"/>
		<sequential>
			<delete dir="${build.limewire.components.@{component}.home}" />
		</sequential>
	</macrodef>
        
    <macrodef name="do.clean-dist" description="Cleans all distribution files and directories.">
        <attribute name="component"/>
        <sequential>
        	<delete dir="${dist.limewire.components.@{component}.home}"/>
        </sequential>
    </macrodef>
    
    <macrodef name="do.clean-clover" description="Erases clover data.">
    	<attribute name="component"/>
        <sequential>
            <delete dir="${clover.limewire.components.@{component}.home}"/>
        </sequential>
    </macrodef>
    
    <macrodef name="do.clover-setup" description="Sets up clover.">
    	<attribute name="component"/>
        <element name="locations" optional="true"/>
        <attribute name="defaultfileset" default="${limewire.components.@{component}.src}"/>
        <sequential>
	        <antcall target="clover-guard"/>
            <taskdef resource="clovertasks"/>
            <mkdir dir="${clover.limewire.components.@{component}.home}"/>
            <clover-setup initString="${clover.limewire.components.@{component}.db}">
            	<fileset dir="@{defaultfileset}"/>
                <locations/>
            </clover-setup>
        </sequential>
    </macrodef>
    
    <!-- Checks to see if clover is installed and sets a property if so -->
    <target name="clover-check">
        <available property="clover.installed" classname="com.cenqua.clover.CloverInstr" />
    </target>
    
    <!-- Fails if clover isn't setup. -->
    <target name="clover-guard" depends="clover-check" unless="clover.installed">
        <fail message="Clover is not installed, the build cannot continue."/>
    </target>
    
    <macrodef name="do.clover2html">
        <attribute name="component"/>
        <sequential>
            <antcall target="clover-guard"/>
            <tstamp>
	            <format property="clover.time" pattern="EEE, MMM d, yyyy hh:mm a"/>
            </tstamp>
            <clover-report>
                <current outfile="${clover.limewire.components.@{component}.html}"
                		 title="LimeWire - ${clover.time}">
	                <format type="html"/>
                </current>
            </clover-report>
        </sequential>
    </macrodef>
    
    <target name="clean"/> <!-- Must write a real target for this when importing. -->
    <target name="with.clover"/> <!-- Must write a real target for this when importing -->
    <target name="initialize"/> <!-- Must write a real target for this when importing -->
    <target name="test-all"/> <!-- Must write a real target for this when importing -->
    <target name="clover2html"/> <!-- Must write a real target for this when importing -->
    
    <target name="clover-all" depends="initialize, clean, with.clover">
        <antcall target="test-all" inheritRefs="true" />
		<antcall target="clover2html" inheritRefs="true" />
    </target>
	
</project>