| <!-- |
| JSPWiki - a JSP-based WikiWiki clone. |
| |
| Copyright (C) 2001-2006 Janne Jalkanen (Janne.Jalkanen@iki.fi) |
| |
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU Lesser General Public License as published by |
| the Free Software Foundation; either version 2.1 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Lesser General Public License for more details. |
| |
| You should have received a copy of the GNU Lesser General Public License |
| along with this program; if not, write to the Free Software |
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| --> |
| |
| <!-- |
| This is the Ant build file for the JSPWiki project. |
| |
| The verbosity in this file is intentional - it is also |
| an example for those who don't know Ant yet that well |
| and would like to learn it. |
| |
| The build file assumes the following directory structure: |
| |
| JSPWiki |
| |___build.xml |
| | |
| |___etc |
| | |___[jspwiki.properties and web.xml] |
| | |
| |___src |
| | |___webdocs |
| | | |___[all .jsp files] |
| | | |
| | |___com |
| | |___[...and the rest of the source code files] |
| | |
| |___docs |
| | |
| |___lib |
| | |
| |___tests |
| |___com |
| |___[...and the rest of the test source code] |
| |
| $Id: build.xml,v 1.77.2.2 2007-02-26 19:22:49 jalkanen Exp $ |
| --> |
| |
| <!-- |
| First, we define the project. We assign it a name, |
| and the default action if no action is specified on the |
| command line. Also, all relative directory references |
| in the rest of the project file should be calculated from |
| the current directory. |
| --> |
| <project name="JSPWiki" default="compile" basedir="."> |
| |
| <!-- This tells us which build.properties file lies. By default, we |
| use the CVS version (which is tuned to my environment), but you |
| will probably want to override this from the command line. --> |
| <property name="build.properties" value="build.properties" /> |
| |
| <property file="${build.properties}" /> |
| |
| <property name="debug" value="true" /> |
| <property name="deprecation" value="false" /> |
| <property name="optimize" value="false" /> |
| |
| <!-- This denotes the directory where the source code lies. --> |
| <property name="code.src" value="src" /> |
| |
| <!-- The class files are actually put in this directory. It is |
| a good habit to keep .class -files separate from the .java -files. --> |
| <property name="code.build" value ="build" /> |
| |
| <!-- The location for the JAR file for the core JSPWiki classes --> |
| <property name="jarfile" value="${code.build}/${ant.project.name}.jar" /> |
| |
| <!-- The location of the JAR file for the test classes --> |
| <property name="testjarfile" location="${code.build}/${ant.project.name}-test.jar" /> |
| |
| <!-- The location for the keystore used to sign the JAR; will be created if it doesn't exist. --> |
| <property name="jks.keystore" value="${basedir}/etc/jspwiki.jks" /> |
| |
| <!-- Define a temporary directory, based on the system temporary directory, |
| the user name, and the project name (defined above) --> |
| <property name="tmpdir" value="${java.io.tmpdir}/${user.name}/${ant.project.name}" /> |
| |
| <!-- The following three properties define the location of the |
| test sources, the location of the test .class files and the |
| directory where the test results are written in. --> |
| |
| <property name="tests.src" value="tests" /> |
| <property name="tests.build" value="tests/build" /> |
| <property name="tests.reports" value="tests/reports" /> |
| |
| <!-- The place where the javadocs are created --> |
| |
| <property name="docs.javadoc" value="doc/javadoc" /> |
| |
| <!-- The temporary installation directory where all war-files |
| are collected, for example --> |
| <property name="install.fulldir" value="${tmpdir}/install" /> |
| |
| <!-- The directory where the CVS sources are checked out. --> |
| <property name="install.src" value="${tmpdir}/cvssrc" /> |
| |
| <!-- Define the CVS properties. These are used when building the |
| source distribution. Normally, you shouldn't have to care about these. |
| --> |
| <property name="cvs.root" value=":ext:grey.ecyrd.com:/p/cvs" /> |
| <property name="cvs.module" value="JSPWiki" /> |
| <property name="cvs.tag" value="JSPWIKI_2_4_BRANCH" /> |
| |
| <!-- And finally, the directory where the final .zip-file is put --> |
| <property name="release.dir" value="releases" /> |
| |
| <!-- PATH DEFINITIONS --> |
| |
| <!-- The base path for compilation. We include, of course, the |
| already built files in the build-directory, and then we |
| add all the jar files in the "lib" -directory. --> |
| <path id="path.base"> |
| <pathelement path="${code.build}" /> |
| <fileset dir="lib"> |
| <include name="*.jar" /> |
| </fileset> |
| </path> |
| |
| <!-- The path used for running tests. We add the tests/etc directory |
| to the base path defined above, since we put all the relevant |
| .properties-files in tests/etc. --> |
| <path id="path.tests"> |
| <pathelement location="${jarfile}" /> |
| <pathelement location="${testjarfile}" /> |
| <fileset dir="lib"> |
| <include name="*.jar" /> |
| </fileset> |
| <pathelement path="${tests.src}/etc" /> |
| </path> |
| |
| <!-- The prefix to use when reading environment variables --> |
| <property environment="env" /> |
| |
| |
| <!-- ============================================================== --> |
| |
| <!-- Initialising, cleaning, etc. --> |
| |
| <target name="init" |
| description="Initializes everything, creates directories, etc." |
| depends="mkpropertyfile"> |
| <mkdir dir="${code.build}" /> |
| <mkdir dir="${tests.build}" /> |
| <mkdir dir="${tests.reports}" /> |
| <mkdir dir="${@tests.pagedir@}" /> |
| </target> |
| |
| <target name="mkpropertyfile" |
| description="Builds the correct propertyfile from the build.properties"> |
| <copy file="etc/jspwiki.properties.tmpl" tofile="etc/jspwiki.properties" /> |
| <copy file="tests/etc/jspwiki.properties.tmpl" tofile="tests/etc/jspwiki.properties" /> |
| <copy file="tests/etc/jspwiki_rcs.properties.tmpl" tofile="tests/etc/jspwiki_rcs.properties" /> |
| <copy file="tests/etc/jspwiki_vers.properties.tmpl" tofile="tests/etc/jspwiki_vers.properties" /> |
| <replace file="etc/jspwiki.properties" |
| replacefilterfile="${build.properties}" /> |
| <replace file="tests/etc/jspwiki.properties" |
| replacefilterfile="${build.properties}" /> |
| <replace file="tests/etc/jspwiki_rcs.properties" |
| replacefilterfile="${build.properties}" /> |
| <replace file="tests/etc/jspwiki_vers.properties" |
| replacefilterfile="${build.properties}" /> |
| </target> |
| |
| <!-- Removes the build directory and the tests build directory --> |
| <target name="clean" |
| description="Cleans away all generated files."> |
| <delete dir="${tests.build}" /> |
| <delete dir="${code.build}" /> |
| <delete dir="${tests.reports}" /> |
| <delete file="etc/jspwiki.properties" /> |
| <delete file="tests/etc/jspwiki.properties" /> |
| <delete file="tests/etc/jspwiki_rcs.properties" /> |
| <delete file="tests/etc/jspwiki_vers.properties" /> |
| <delete> |
| <fileset dir="." includes="**/*~" defaultexcludes="no"/> |
| <fileset dir="." includes="**/#*#" defaultexcludes="no"/> |
| </delete> |
| </target> |
| |
| <!-- ============================================================== --> |
| |
| <!-- Compilation targets --> |
| |
| <!-- In English this means that the "init" -target must be executed |
| first. After this, the java compiler is invoked with options |
| that compile every .java file in ${code.src} into .class files |
| in directory ${code.build}. The is no debugging information |
| and the compiler is instructed to optimize the resulting code. |
| |
| For the classpath we use the previously defined path called |
| "path.base" --> |
| |
| <target name="compile" depends="init" |
| description="Builds the source code."> |
| <javac srcdir="${code.src}" |
| destdir="${code.build}" |
| debug="${debug}" |
| optimize="${optimize}" |
| deprecation="${deprecation}" |
| source="1.4" |
| target="1.4" |
| > |
| <classpath refid="path.base" /> |
| </javac> |
| </target> |
| |
| <!-- This is similar to above. We use this to compile the |
| tests. --> |
| <target name="compiletests" depends="init,compile" |
| description="Builds the test code."> |
| <javac srcdir="${tests.src}" |
| destdir="${tests.build}" |
| debug="true" |
| deprecation="${deprecation}" |
| source="1.4" |
| target="1.4" |
| > |
| <classpath refid="path.base" /> |
| </javac> |
| </target> |
| |
| <!-- Creates javadocs --> |
| <target name="javadoc" |
| description="Compiles the javadocs."> |
| |
| <delete dir="${docs.javadoc}" quiet="true"/> |
| <mkdir dir="${docs.javadoc}" /> |
| |
| <javadoc destdir="${docs.javadoc}" |
| use="yes" |
| breakiterator="true" |
| windowtitle="${ant.project.name}"> |
| <packageset dir="${code.src}"> |
| <include name="com/ecyrd/**" /> |
| </packageset> |
| <link href="http://java.sun.com/j2se/1.4.2/docs/api/"/> |
| <link href="http://java.sun.com/products/javamail/javadocs/"/> |
| <link href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/"/> |
| <link href="http://www.jdom.org/docs/apidocs/"/> |
| <classpath refid="path.base" /> |
| </javadoc> |
| |
| </target> |
| |
| <!-- ============================================================== --> |
| |
| <!-- Installation targets --> |
| |
| <!-- This target makes sure all the necessary directories exist |
| for building the installation package. --> |
| <target name="installinit"> |
| <mkdir dir="${install.fulldir}" /> |
| <delete dir="${install.src}" /> |
| <mkdir dir="${install.src}" /> |
| <delete dir="${release.dir}" /> |
| <mkdir dir="${release.dir}" /> |
| </target> |
| |
| <!-- Builds the jar of all compiled class files --> |
| |
| <target name="jar" depends="compile,sign-init"> |
| <jar jarfile="${jarfile}"> |
| <fileset dir="${code.build}" includes="**/*.class" /> |
| <fileset dir="${code.src}" includes="com/**/*.properties" /> |
| <fileset dir="etc" includes="ini/*.xml" /> |
| </jar> |
| <sign-jar jar="${jarfile}" /> |
| </target> |
| |
| <target name="jartests" depends="compiletests,sign-init"> |
| <jar jarfile="${testjarfile}" update="false"> |
| <fileset dir="${tests.build}"> |
| <include name="**/*.class"/> |
| </fileset> |
| <fileset dir="${tests.src}"> |
| <include name="com/**/*.properties"/> |
| </fileset> |
| </jar> |
| <sign-jar jar="${testjarfile}" /> |
| </target> |
| |
| <!-- Builds a Web Archive - basically a JAR file which |
| also contains all of the JSP pages and can be deployed |
| as-is. |
| |
| The archive gets put in the ${install.fulldir}. The |
| reason for this is that this is just a temporary |
| step when building the entire distribution archive. |
| |
| We include the following things: |
| |
| 1) All .jar -files in the lib-directory (except servlet.jar, since |
| it's gonna be provided by the servlet container anyway.) |
| We also omit test-related jars like JUnit. |
| 2) All .class-files from the build-directory |
| 3) Everything from the src/webdocs -directory |
| 4) Everything from the etc-directory go to the WEB-INF -directory |
| of the WAR-file. |
| --> |
| |
| <target name="war" depends="installinit,jar" |
| description="Builds the WAR file for installation."> |
| |
| <property name="warfile" value="${install.fulldir}/${ant.project.name}.war" /> |
| |
| <delete file="${warfile}" /> |
| |
| <war warfile="${warfile}" |
| webxml="etc/web.xml"> |
| <lib dir="lib" includes="*.jar" excludes="servlet.jar,junit.jar,servlet-api.jar,jsp-api.jar,hsqldb.jar,xercesImpl-*.jar,xml-apis-*.jar,jwebunit-*.jar,js-*.jar,httpunit-*.jar"/> |
| <lib file="${jarfile}" /> |
| <fileset dir="${code.src}/webdocs" includes="**" excludes="**/FCK/jsp" /> |
| <webinf dir="etc" includes="**" excludes="**.tmpl web.xml ini/** *.jks db/** lib/** classes/**/*.class" /> |
| <webinf file="${jks.keystore}"/> |
| <classes dir="etc" includes="oscache.properties" /> |
| </war> |
| |
| </target> |
| |
| |
| <target name="opened-war" depends="war" |
| description="Creates an opened JSPWiki war hierarchy into the build dir."> |
| |
| <mkdir dir="${code.build}/${ant.project.name}" /> |
| <unzip src="${warfile}" |
| dest="${code.build}/${ant.project.name}" /> |
| |
| </target> |
| |
| |
| <!-- |
| Here goes some nice Ant magic... We build the source |
| code archive by directly exporting all code from the CVS |
| repository, and then zipping it to the temporary installation |
| directory. |
| |
| Note that you must have your CVS set up so that it does |
| not ask for a password when you're checking it out. |
| |
| If you don't have CVS access, you can't build a source |
| zip with this. Sorry. |
| --> |
| <target name="srczip" depends="installinit" |
| description="Builds source zip."> |
| |
| <cvs cvsRoot="${cvs.root}" |
| dest="${install.src}" |
| package="${cvs.module}" |
| command="export" |
| tag="${cvs.tag}" /> |
| |
| <zip zipfile="${release.dir}/${ant.project.name}-src.zip"> |
| <zipfileset dir="${install.src}" /> |
| </zip> |
| |
| </target> |
| |
| <!-- Creates a zip of all the core pages. The file which determines |
| whether a page is a core page or not is found in src/wikipages/.corepages --> |
| |
| <target name="corepageszip" depends="installinit"> |
| <zip zipfile="${install.fulldir}/${ant.project.name}-corepages.zip" |
| basedir="src/wikipages" includesfile="src/wikipages/.corepages"> |
| </zip> |
| </target> |
| |
| <!-- Creates a full ZIP file of all document files --> |
| |
| <target name="documentzip" depends="installinit,javadoc" |
| description="Creates JSPWiki documentation zipfile"> |
| |
| <zip zipfile="${install.fulldir}/${ant.project.name}-doc.zip"> |
| <zipfileset dir="doc" prefix="doc" /> |
| <zipfileset dir="src/wikipages" prefix="doc/wikipages" /> |
| </zip> |
| </target> |
| |
| <!-- Builds the entire distribution set. |
| |
| We build both the WAR-file and the source zip, then |
| copy in some useful files and zip the whole thing |
| into the release directory. |
| |
| Note that if you don't have CVS access set up, you |
| probably can't run this. |
| --> |
| <target name="dist" depends="installinit,srczip,war,corepageszip,documentzip" |
| description="Builds the entire distribution archive."> |
| <copy file="README" todir="${install.fulldir}" /> |
| <copy file="ChangeLog" todir="${install.fulldir}" /> |
| <copy file="ReleaseNotes" todir="${install.fulldir}" /> |
| <copy file="doc/LICENSE" todir="${install.fulldir}" /> |
| |
| <zip zipfile="${release.dir}/${ant.project.name}-bin.zip"> |
| <zipfileset dir="${install.fulldir}" prefix="${ant.project.name}" /> |
| </zip> |
| |
| </target> |
| |
| <!-- ============================================================== --> |
| |
| <!-- Running tests --> |
| |
| <target name="tests-init"> |
| <!-- Build up the /etc directory for testing --> |
| <delete file="tests/etc/userdatabase.xml" /> |
| <delete file="tests/etc/userdatabase.xml.old" /> |
| <copy file="tests/etc/userdatabase.xml.tmpl" toFile="tests/etc/userdatabase.xml"/> |
| <delete file="tests/etc/groupdatabase.xml" /> |
| <delete file="tests/etc/groupdatabase.xml.old" /> |
| <copy file="tests/etc/groupdatabase.xml.tmpl" toFile="tests/etc/groupdatabase.xml"/> |
| <mkdir dir="tests/etc/WEB-INF" /> |
| |
| <!-- Create web.xml files for testing --> |
| <copy file="${basedir}/etc/web.xml" tofile="${tests.build}/web.xml.custom" overwrite="true" /> |
| |
| <!-- For web unit tests, turn off SSL (self-signed certs b0rk |
| the tests) and enable JDBC refs --> |
| <replace file="${tests.build}/web.xml.custom" |
| token="CONFIDENTIAL" value="NONE" /> |
| <replace file="${tests.build}/web.xml.custom" |
| token="<!-- REMOVE ME TO ENABLE JDBC DATABASE" value="" /> |
| <replace file="${tests.build}/web.xml.custom" |
| token="REMOVE ME TO ENABLE JDBC DATABASE -->" value="" /> |
| |
| <!-- For unit testing, turn on container auth --> |
| <copy file="${tests.build}/web.xml.custom" |
| tofile="${tests.build}/web.xml.container" overwrite="true" /> |
| <replace file="${tests.build}/web.xml.container" |
| token="<!-- REMOVE ME TO ENABLE CONTAINER-MANAGED AUTH" value="" /> |
| <replace file="${tests.build}/web.xml.container" |
| token="REMOVE ME TO ENABLE CONTAINER-MANAGED AUTH -->" value="" /> |
| <copy file="${tests.build}/web.xml.container" |
| tofile="tests/etc/WEB-INF/web.xml" overwrite="true" /> |
| |
| <!-- Copy the DTDs to the test WEB-INF --> |
| <mkdir dir="tests/etc/WEB-INF/dtd" /> |
| <copy toDir="tests/etc/WEB-INF/dtd"> |
| <fileset dir="${basedir}/etc/dtd/" /> |
| </copy> |
| |
| <!-- Copy the keystore to the test dir --> |
| <copy file="${jks.keystore}" toDir="tests/etc" /> |
| </target> |
| |
| <!-- This target runs the JUnit tests that are available |
| under tests/. It generates the test result files |
| into the ${tests.reports} -directory, one file per |
| each tested class. The tests are generated in |
| plain text, but you can easily get XML format results |
| as well, just by setting the formatter, below. |
| |
| Only tests that end with "*Test.java" are included. |
| This is because then you can also use a manual |
| "AllTests.java" in each directory, as per the JUnit |
| Cookbook. |
| |
| This runs the tests in text mode. If you want the |
| pretty GUI you probably want to write a new target. |
| |
| If this test fails with a "cannot find task 'junit'" |
| error, put the junit.jar in your CLASSPATH. |
| |
| More info http://ant.apache.org/faq.html#delegating-classloader |
| --> |
| <target name="tests" depends="jar,tests-init,jartests,tests-db-init" |
| description="Runs the JUnit tests."> |
| |
| <junit printsummary="yes" haltonfailure="no" fork="yes"> |
| <classpath> |
| <path refid="path.tests" /> |
| </classpath> |
| |
| <sysproperty key="java.security.auth.login.config" value="${basedir}/etc/jspwiki.jaas"/> |
| <sysproperty key="java.security.policy" value="tests/etc/jspwiki.policy"/> |
| <sysproperty key="jspwiki.tests.auth" value="true" /> |
| |
| <formatter type="plain" /> |
| <formatter type="xml" usefile="yes" /> |
| |
| <batchtest todir="${tests.reports}"> |
| <fileset dir="${tests.src}"> |
| <include name="**/*Test.java" /> |
| <exclude name="**/AllTest*java" /> |
| <include name="**/StressTestSpeed.java" if="tests.stress.enabled"/> |
| <exclude name="com/ecyrd/jspwiki/web/*.*" /> |
| <exclude name="com/ecyrd/jspwiki/TranslatorReaderTest*" /> |
| </fileset> |
| </batchtest> |
| </junit> |
| |
| <junitreport todir="${tests.src}"> |
| <fileset dir="${tests.reports}"> |
| <include name="**/TEST-*.xml" /> |
| </fileset> |
| <report format="noframes" todir="${tests.src}" /> |
| </junitreport> |
| |
| </target> |
| |
| <target name="tests-auth" depends="jar,tests-init,jartests" |
| description="Runs the AuthorizationManager tests, with JDPA"> |
| |
| <junit printsummary="yes" haltonfailure="no" fork="yes"> |
| <classpath> |
| <path refid="path.tests" /> |
| </classpath> |
| |
| <sysproperty key="java.security.auth.login.config" value="${basedir}/etc/jspwiki.jaas"/> |
| <sysproperty key="java.security.policy" value="tests/etc/jspwiki.policy"/> |
| <sysproperty key="jspwiki.tests.auth" value="true" /> |
| <jvmarg value="-Xdebug" /> |
| <jvmarg value="-Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y" /> |
| |
| <formatter type="plain" /> |
| <formatter type="xml" usefile="yes" /> |
| |
| <batchtest todir="${tests.reports}"> |
| <fileset dir="${tests.src}"> |
| <include name="**/AuthorizationManagerTest.java" /> |
| </fileset> |
| </batchtest> |
| </junit> |
| |
| <junitreport todir="${tests.src}"> |
| <fileset dir="${tests.reports}"> |
| <include name="**/TEST-*.xml" /> |
| </fileset> |
| <report format="noframes" todir="${tests.src}" /> |
| </junitreport> |
| |
| </target> |
| |
| <target name="guitests" depends="jar,tests-init,jartests" |
| description="Runs the tests in a pretty window."> |
| |
| <java classname="junit.swingui.TestRunner" fork="yes"> |
| <classpath> |
| <path refid="path.tests" /> |
| </classpath> |
| |
| <sysproperty key="java.security.auth.login.config" value="${basedir}/etc/jspwiki.jaas"/> |
| <sysproperty key="java.security.policy" value="tests/etc/jspwiki.policy"/> |
| <sysproperty key="jspwiki.tests.auth" value="true" /> |
| |
| <arg value="com.ecyrd.jspwiki.AllTests" /> |
| </java> |
| |
| </target> |
| |
| <!-- This target runs web unit tests using JWebUnit, which |
| extends JUnit. These tests assumes you have Tomcat |
| or higher installed **and** that it is running on |
| localhost:8080 when you execute this target. The Manager |
| app must be configured. Also, the Tomcat server's toncat-users.xml |
| file must contain a user named 'janne' with a password 'myP@5sw0rd' |
| and an assigned role of 'Authenticated'. |
| These tests has been verified to deploy on Tomcat 5.5; |
| other versions may not work. |
| |
| If you have previously set a custom JSPWiki security policy, you |
| MUST bounce Tomcat first. Otherwise, the previously installed policy |
| will be in effect, and may hose the web unit tests. |
| |
| Of course, you need not use Tomcat in production... but to |
| keep this build file simple, we do require it for web unit tests. |
| |
| Note: if the majority of JDBC tests fail but the non-JDBC tests do |
| not, that likely means that Tomcat cannot find your JDBC jar. You |
| should copy this file to Tomcat's common/lib directory. |
| --> |
| <target name="webtests" depends="jar,tests-init,jartests,tests-db-init,tomcat-init,war"> |
| |
| <!-- Build the custom auth WAR --> |
| <copy file="etc/jspwiki.properties" |
| toFile="${tests.build}/jspwiki.properties.custom" flatten="true" /> |
| <propertyfile file="${tests.build}/jspwiki.properties.custom"> |
| <entry key="jspwiki.userdatabase" value="com.ecyrd.jspwiki.auth.user.XMLUserDatabase" /> |
| <entry key="jspwiki.groupdatabase" value="com.ecyrd.jspwiki.auth.authorize.XMLGroupDatabase" /> |
| <entry key="jspwiki.referenceStyle" value="relative" /> |
| </propertyfile> |
| <webtest-setup context="test-custom" |
| webxml="${tests.build}/web.xml.custom" |
| props="${tests.build}/jspwiki.properties.custom" /> |
| |
| <!-- Build the custom auth WAR (absolute URLs) --> |
| <copy file="${tests.build}/jspwiki.properties.custom" |
| toFile="${tests.build}/jspwiki.properties.custom-absolute" flatten="true" /> |
| <propertyfile file="${tests.build}/jspwiki.properties.custom-absolute"> |
| <entry key="jspwiki.referenceStyle" value="absolute" /> |
| <entry key="jspwiki.baseURL" value="http://localhost:8080/test-custom-absolute/" /> |
| </propertyfile> |
| <webtest-setup context="test-custom-absolute" |
| webxml="${tests.build}/web.xml.custom" |
| props="${tests.build}/jspwiki.properties.custom-absolute" /> |
| |
| <!-- Build the container auth WAR --> |
| <webtest-setup context="test-container" |
| webxml="${tests.build}/web.xml.container" |
| props="${tests.build}/jspwiki.properties.custom" /> |
| |
| <!-- Build the custom auth WAR (JDBC database) --> |
| <copy file="etc/jspwiki.properties" |
| toFile="${tests.build}/jspwiki.properties.custom-jdbc" flatten="true" /> |
| <propertyfile file="${tests.build}/jspwiki.properties.custom-jdbc"> |
| <entry key="jspwiki.userdatabase" value="com.ecyrd.jspwiki.auth.user.JDBCUserDatabase" /> |
| <entry key="jspwiki.userdatabase.hashPrefix" value="false" /> |
| <entry key="jspwiki.groupdatabase" value="com.ecyrd.jspwiki.auth.authorize.JDBCGroupDatabase" /> |
| </propertyfile> |
| <webtest-setup context="test-custom-jdbc" |
| webxml="${tests.build}/web.xml.custom" |
| props="${tests.build}/jspwiki.properties.custom-jdbc" /> |
| |
| <!-- Build the container auth WAR (shared JDBC database) and test it --> |
| <copy file="etc/jspwiki.properties" |
| toFile="${tests.build}/jspwiki.properties.container-jdbc" flatten="true" /> |
| <propertyfile file="${tests.build}/jspwiki.properties.container-jdbc"> |
| <entry key="jspwiki.userdatabase" value="com.ecyrd.jspwiki.auth.user.JDBCUserDatabase" /> |
| <entry key="jspwiki.userdatabase.isSharedWithContainer" value="true" /> |
| <entry key="jspwiki.userdatabase.hashPrefix" value="false" /> |
| <entry key="jspwiki.groupdatabase" value="com.ecyrd.jspwiki.auth.authorize.JDBCGroupDatabase" /> |
| </propertyfile> |
| <webtest-setup context="test-container-jdbc" |
| webxml="${tests.build}/web.xml.container" |
| props="${tests.build}/jspwiki.properties.container-jdbc" /> |
| |
| <!-- Run the tests --> |
| <junit printsummary="yes" haltonfailure="no" fork="yes"> |
| <classpath> |
| <path refid="path.tests" /> |
| </classpath> |
| <formatter type="plain" /> |
| <batchtest todir="${tests.reports}"> |
| <fileset dir="${tests.src}"> |
| <include name="com/ecyrd/jspwiki/web/*Test.java" /> |
| </fileset> |
| </batchtest> |
| </junit> |
| |
| <!-- Tear down the test contexts --> |
| <webtest-teardown context="test-custom" /> |
| <webtest-teardown context="test-custom-absolute" /> |
| <webtest-teardown context="test-custom-jdbc" /> |
| <webtest-teardown context="test-container" /> |
| <webtest-teardown context="test-custom-jdbc" /> |
| </target> |
| |
| <macrodef name="webtest-setup"> |
| <attribute name="context" /> |
| <attribute name="webxml" /> |
| <attribute name="props" /> |
| <sequential> |
| <ant dir="${basedir}" antfile="tests/etc/webtests.xml" |
| target="webtest-setup" inheritRefs="true"> |
| <property name="webtest.context" value="@{context}" /> |
| <property name="webtest.webxml" value="@{webxml}" /> |
| <property name="webtest.props" value="@{props}" /> |
| </ant> |
| </sequential> |
| </macrodef> |
| |
| <macrodef name="webtest-teardown"> |
| <attribute name="context" /> |
| <sequential> |
| <ant dir="${basedir}" antfile="tests/etc/webtests.xml" |
| target="webtest-teardown" inheritRefs="true"> |
| <property name="webtest.context" value="@{context}" /> |
| </ant> |
| </sequential> |
| </macrodef> |
| |
| |
| <!-- ============================================================== --> |
| |
| <!-- Tomcat war pre-compilation --> |
| |
| <!-- This target builds a WAR file that is specially pre-compiled |
| for use with Tomcat. By generating and pre-compiling JSPs |
| ahead of time (instead of having Tomcat do it on-the-fly |
| at runtime), we provide a slight runtime speed bump. In |
| addition, in security-conscious environments this means |
| that we can eliminate the need for the Jasper JSP compiler, |
| and can run Tomcat using just a JRE instead of a full JDK. |
| |
| Pre-compilation involves three steps: |
| 1) Generating the .java files that correspond to JSPWiki's JSPs. |
| The generated classes are actually servlets. |
| 2) Compiling the .java files and creating a jar.file, |
| which is added to the WAR's WEB-INF/lib directory |
| 3) Injecting servlet mappings into the WEB-INF/web.xml |
| file so that requests for the JSPs are mapped to the |
| servlets generated in step 1. |
| |
| All of these steps are performed automatically by the |
| target "war-tomcat." |
| |
| To use Tomcat pre-compilation, you need to specify |
| where Tomcat lives on your machine. This can be done |
| two ways: |
| 1. Export the environment variable CATALINA_HOME, or: |
| 2. Set the property "tomcat.home" in build.properties to |
| Tomcat's installation directory (e.g., /usr/local/tomcat) |
| |
| NOTE: The Jasper compiler on older versions of Tomcat |
| (earlier than ~June 2004) is known to have bugs |
| that prevent the Ant "jasper2" task from running |
| successfully. So, you should probably try to use |
| a relatively recent build. |
| |
| In addition to pre-compiling the servlets, "war-tomcat" |
| executes a sub-target that generates a tarball containing |
| all of JSPWiki's static content. This is quite handy for |
| environments that use Tomcat in conjunction with a front-end |
| web server such as Apache (via mod_jk/jk2 or mod_proxy). |
| The target strips out the static content (images, css, etc) |
| and adds it to a separate tar file that can be unpacked |
| in one of Apache's content directories. |
| |
| To generate static content, set the properties |
| "static.user" and "static.group" in build.properties. |
| These should be set to the Unix runtime user and group |
| that should own the static files, for example the |
| user "apache" and "daemon" group. If the "static.user" |
| property is not supplied, war-tomcat skips the static |
| content generation step. |
| --> |
| |
| <target name="war-tomcat" depends="build-tomcat-war,staticzip" |
| description="Builds the WAR file for Tomcat (with pre-compiled JSPs)"/> |
| |
| <target name="tomcat-init" depends="init"> |
| <!-- Auto-detect whether Tomcat is available --> |
| <property name="war" value="${code.build}/${ant.project.name}" /> |
| <property name="war.tomcat" value="${ant.project.name}-tomcat.war" /> |
| <property name="tar.static" value="${ant.project.name}-static.tar.gz" /> |
| <check-property prop="env.CATALINA_HOME" /> |
| <property name="tomcat.home" value="${env.CATALINA_HOME}" /> |
| <echo message="Detected Tomcat: ${tomcat.home}" /> |
| |
| <!-- Set classpath for pre-compilation and deployment tasks --> |
| <path id="tomcat.classpath"> |
| <pathelement location="${java.home}/../lib/tools.jar" /> |
| <fileset dir="${tomcat.home}/server/lib"> |
| <include name="*.jar" /> |
| </fileset> |
| <fileset dir="${tomcat.home}/common/lib"> |
| <include name="*.jar" /> |
| </fileset> |
| <fileset dir="${tomcat.home}/bin"> |
| <include name="commons-logging-api.jar" /> |
| </fileset> |
| </path> |
| </target> |
| |
| <!-- Use Jasper to generate Java class files for the JSPs. |
| Then compile and jar 'em up. Note that Tomcat's |
| Jasper task creates a web.xml "fragment" containing |
| the JSP-to-servlet mappings. We need to copy this into |
| our existing web.xml, which we do using a file |
| copy with token substitution. --> |
| |
| <target name="compile-tomcat" depends="tomcat-init,opened-war"> |
| <mkdir dir="${code.build}/jsp-java" /> |
| <mkdir dir="${code.build}/jsp-classes"/> |
| <taskdef classname="org.apache.jasper.JspC" name="jasper2"> |
| <classpath> |
| <path refid="tomcat.classpath" /> |
| </classpath> |
| </taskdef> |
| <jasper2 |
| validateXml="false" |
| uriroot="${war}" |
| outputDir="${code.build}/jsp-java" |
| poolingEnabled="false" |
| webXmlFragment="${code.build}/web-fragment.xml" /> |
| <javac srcdir="${code.build}/jsp-java" destdir="${code.build}/jsp-classes"> |
| <classpath> |
| <path refid="tomcat.classpath" /> |
| <path id="war.classpath"> |
| <fileset dir="${war}/WEB-INF/lib"> |
| <include name="*.jar" /> |
| </fileset> |
| </path> |
| </classpath> |
| </javac> |
| <jar jarfile="${code.build}/jsp.jar"> |
| <fileset dir="${code.build}/jsp-classes" includes="**/*.class" /> |
| </jar> |
| <echo message="Adding JSP servlet mappings to web.xml" /> |
| <loadfile property="generated-web.xml" srcFile="${code.build}/web-fragment.xml"/> |
| <copy file="${war}/WEB-INF/web.xml" toFile="${code.build}/web-merged.xml" overwrite="true"> |
| <filterset begintoken="<!--" endtoken="-->"> |
| <filter token=" PLACEHOLDER FOR PRE-COMPILED JSP SERVLETS " value="${generated-web.xml}" /> |
| </filterset> |
| </copy> |
| </target> |
| |
| <!-- Create a new war file with the new JSP jar and amended web.xml --> |
| |
| <target name="build-tomcat-war" depends="compile-tomcat"> |
| <war warfile="${code.build}/${war.tomcat}" webxml="${code.build}/web-merged.xml" defaultexcludes="true"> |
| <webinf dir="${war}/WEB-INF"> |
| <exclude name="web.xml" /> |
| <exclude name="lib/*" /> |
| </webinf> |
| <lib dir="${war}/WEB-INF/lib" excludes="servlet-api.jar,j2ee.jar"/> |
| <lib dir="${code.build}" includes="jsp.jar" /> |
| <fileset dir="${war}"> |
| <exclude name="WEB-INF/**" /> |
| <exclude name="**/*.jsp" /> |
| </fileset> |
| </war> |
| </target> |
| |
| <!-- Create a tarball containing the static content. |
| User must set at least ${static.user} and preferably ${static.group}. |
| If not present, the target is skipped. |
| File permissions are owner and group read (440), |
| and for directories, owner and group read |
| and execute (550). --> |
| |
| <target name="staticzip" depends="build-tomcat-war" if="static.user"> |
| <property name="static.group" value="${static.user}" /> |
| <tar destfile="${code.build}/${tar.static}" longfile="fail" compression="gzip"> |
| <tarfileset dir="${war}" defaultexcludes="yes" |
| username="${static.user}" group="${static.group}" |
| mode="440" dirmode="550"> |
| <include name="**/*.css" /> |
| <include name="**/*.gif" /> |
| <include name="**/*.htm" /> |
| <include name="**/*.html" /> |
| <include name="**/*.jpg" /> |
| <include name="**/*.js" /> |
| <include name="**/*.png" /> |
| </tarfileset> |
| </tar> |
| </target> |
| |
| <!-- ============================================================== --> |
| |
| <!-- Targets for signing JAR files --> |
| |
| <!-- These targets collectively create a Java keystore for signing, |
| and automate the jar-signing process. |
| --> |
| <target name="sign-init" depends="installinit,jks-init,jks-create,jks-password" /> |
| |
| <target name="jks-init"> |
| <property name="jks.alias" value="jspwiki" /> |
| <available file="${jks.keystore}" property="jks.exists" /> |
| </target> |
| |
| <target name="jks-create" unless="jks.exists"> |
| <echo> |
| JSPWiki needs a digital certificate for code signing its JAR files. |
| Since you don't appear to have one, we need to generate a new certificate. |
| Once generated, it will be used to sign the JSPWiki.jar file. To create |
| the certificate, we need to ask you for your name and a few other things. |
| |
| The certificate file will be generated at: ${jks.keystore}. |
| You should copy this file to your container's configuration directory, |
| or wherever your jspwiki.policy file lives. |
| |
| If something in this process goes wrong, you can simply delete |
| ${jks.keystore} and execute this target again... no harm done. |
| To automate the JAR signing processs, you can add the property |
| 'jks.password' to your build.properties file. |
| </echo> |
| <input message="Your name (example: Simon Bar Sinister):" addproperty="jks.cn" /> |
| <input message="Your organization (example: ecyrd.com):" addproperty="jks.o" /> |
| <input message="Your country (example: US, FI, AU):" addproperty="jks.c" /> |
| <input message="Keystore password (>6 characters):" addproperty="jks.password" /> |
| <exec dir="${basedir}" executable="keytool" failonerror="true"> |
| <arg value="-genkey"/> |
| <arg value="-keysize"/> |
| <arg value="1024"/> |
| <arg value="-alias"/> |
| <arg value="${jks.alias}"/> |
| <arg value="-keystore"/> |
| <arg value="${jks.keystore}"/> |
| <arg value="-storepass"/> |
| <arg value="${jks.password}"/> |
| <arg value="-dname"/> |
| <arg value="cn=${jks.cn}, ou=JSPWiki Code Signing Division, o=${jks.o}, c=${jks.c}"/> |
| </exec> |
| </target> |
| |
| <target name="jks-password" unless="jks.password"> |
| <input message="Keystore password:" addproperty="jks.password" /> |
| </target> |
| |
| <macrodef name="sign-jar"> |
| <attribute name="jar"/> |
| <sequential> |
| <echo message="Signing code with this certificate: ${jks.keystore}" /> |
| <exec dir="${basedir}" executable="keytool" failonerror="true"> |
| <arg value="-list"/> |
| <arg value="-v"/> |
| <arg value="-alias"/> |
| <arg value="${jks.alias}"/> |
| <arg value="-keystore"/> |
| <arg value="${jks.keystore}"/> |
| <arg value="-storepass"/> |
| <arg value="${jks.password}"/> |
| </exec> |
| <signjar jar="@{jar}" alias="jspwiki" keystore="${jks.keystore}" |
| storepass="${jks.password}" verbose="false"/> |
| </sequential> |
| </macrodef> |
| |
| <!-- ============================================================== --> |
| |
| <!-- JDBC Support --> |
| |
| <!-- Starting with 2.3.33, JSPWiki supports JDBC DataSources for |
| storing user profiles. The DataSource can be any database that |
| your web container supports. In practice, most containers supply |
| a generic datatbase connection pooling package that can be configured |
| to use any JDBC driver. |
| |
| RUNNING JDBC UNIT TESTS |
| ======================= |
| If you don't enable JDBC support, the JDBC-related unit test classes |
| will compile fine, but will fail when the 'tests' Ant target executes. |
| Don't worry about that. The JDBC-related test classes, by the way, |
| are these: |
| |
| com.ecyrd.jspwiki.auth.user.JDBCUserDatabaseTest |
| |
| To run JDBC-related unit tests, you need to: |
| |
| 1) Set up an external database |
| 2) Obtain a JDBC driver |
| 3) Tell JSPWiki where to find the driver, and how to |
| connect to the database, via jdbc.* properties in |
| your build.properties file. |
| 4) Provide table setup/teardown DDL scripts (executed by |
| the db-setup and db-teardown targets, below) |
| |
| Step 1 is the hardest. Luckily for you, JSPWiki has built-in Ant |
| scripts to automatically start and stop the embedded Hypersonic 100% |
| Java database. It's small and fast, and is included |
| in the JSPWiki base distribution. You can, of course, use your own |
| JDBC-compliant database such as Postgresql. |
| |
| Step 2: set up your database properties in build.properties, for example: |
| |
| jdbc.driver.id=hsql |
| jdbc.driver.jar=lib/hsqldb.jar |
| jdbc.driver.class=org.hsqldb.jdbcDriver |
| jdbc.driver.url=jdbc:hsqldb:hsql://localhost/jspwiki |
| jdbc.admin.id=SA |
| jdbc.admin.password= |
| jdbc.user.id=jspwiki |
| jdbc.user.password=password |
| |
| The 'jdbc.driver.id' property is important. Its presence tells |
| the Ant scripts to do JDBC testing. It also points to |
| he subdirectory in etc/db that contains our setup/teardown |
| scripts, which *must* contain these files at a minumum: |
| |
| userdb-setup.ddl |
| userdb-teardown.ddl |
| |
| Sample scripts for Hypersonic and Postgresql are supplied. |
| If you want to use a different database, create a subdirectory in etc/db |
| (e.g., etc/db/oracle) and create the necessary DDL script files. |
| |
| Note that the DDL scripts contain token substitution fields where |
| table and column names mappings can be plugged in. This is so you |
| can customize how JSPWiki stores its data. For example, the Hypersonic |
| teardown DDL looks like this: |
| |
| DROP TABLE @jspwiki.userdatabase.table@ IF EXISTS; |
| |
| The complete list of customizable table properties are found |
| in etc/jspwiki.properties.tmpl. If you don't customize them, |
| JSPWiki will use some sensible defaults. For unit testing purposes, |
| this script will always use the defaults from 'tests/etc/jspwiki.properties', |
| then apply any custom properties defined in your build.properties file. |
| |
| All of this may sound complicated, but it really isn't. If you use Hypersonic, |
| the JDBC tests should Just Work. And if you specify an external database, |
| they should work just fine also. |
| |
| RUNNING JSPWIKI WITH JDBC SUPPORT |
| ================================= |
| All of the preceding tells you how to test JSPWiki with JDBC support. |
| Sounds great, but how do you *run* JSPWiki with it? Simple: |
| |
| 1) Configure the Jdbc.* properties in build.properties, as described |
| above |
| 2) Configure table and column mappings in etc/jspwiki.properties.tmpl |
| 3) Configure your web container to create a JDBC DataSource |
| (by default, the JNDI name is jdbc/UserDatabase) |
| 4) Put the JDBC driver jar in a place where your web container will |
| find it, for example CATALINA_HOME/common/lib |
| 5) Build JSPWiki, and start it up! |
| |
| See the Javadoc for com.ecyrd.jspwiki.auth.user.JDBCUserDatabase |
| for details and examples. |
| --> |
| |
| <target name="tests-db-init" depends="db-properties,hsql-init,db-setup"/> |
| |
| <target name="db-properties" depends="init" if="jdbc.driver.id"> |
| <!-- Load the JDBC props we need to do table maintenance --> |
| <check-property prop="jdbc.driver.jar" /> |
| <check-property prop="jdbc.driver.class" /> |
| <check-property prop="jdbc.driver.url" /> |
| <check-property prop="jdbc.admin.id" /> |
| <check-property prop="jdbc.admin.password" /> |
| |
| <!-- Here's a neat trick: import the JDBC runtime props from jspwiki.properties --> |
| <echo message="Getting JDBC runtime properties." /> |
| <loadproperties srcFile="etc/jspwiki.properties"> |
| <filterchain> |
| <linecontainsregexp> |
| <regexp pattern="^[jspwiki.userdatabase|jspwiki.groupdatabase]"/> |
| </linecontainsregexp> |
| </filterchain> |
| </loadproperties> |
| <check-property prop="jspwiki.userdatabase.datasource" /> |
| <check-property prop="jspwiki.userdatabase.table" /> |
| <check-property prop="jspwiki.userdatabase.email" /> |
| <check-property prop="jspwiki.userdatabase.fullName" /> |
| <check-property prop="jspwiki.userdatabase.loginName" /> |
| <check-property prop="jspwiki.userdatabase.password" /> |
| <check-property prop="jspwiki.userdatabase.wikiName" /> |
| <check-property prop="jspwiki.userdatabase.created" /> |
| <check-property prop="jspwiki.userdatabase.modified" /> |
| <check-property prop="jspwiki.userdatabase.roleTable" /> |
| <check-property prop="jspwiki.userdatabase.role" /> |
| <check-property prop="jspwiki.groupdatabase.datasource" /> |
| <check-property prop="jspwiki.groupdatabase.table" /> |
| <check-property prop="jspwiki.groupdatabase.membertable" /> |
| <check-property prop="jspwiki.groupdatabase.created" /> |
| <check-property prop="jspwiki.groupdatabase.creator" /> |
| <check-property prop="jspwiki.groupdatabase.name" /> |
| <check-property prop="jspwiki.groupdatabase.member" /> |
| <check-property prop="jspwiki.groupdatabase.modified" /> |
| <check-property prop="jspwiki.groupdatabase.modifier" /> |
| |
| <!-- Check for the presence of the database driver & script dir --> |
| <check-file file="etc/db/${jdbc.driver.id}" prop="db.scripts" /> |
| <check-file file="${jdbc.driver.jar}" prop="jdbc.jar.present" /> |
| |
| <!-- Bulk-copy the table setup/teardown scripts --> |
| <property name="tests.db.scripts" value="${tests.src}/etc/db/${jdbc.driver.id}" /> |
| <mkdir dir="${tests.db.scripts}" /> |
| <copy todir="${tests.db.scripts}" overwrite="true"> |
| <fileset dir="${db.scripts}" /> |
| <filterset> |
| <filtersfile file="tests/etc/jspwiki.properties" /> |
| <filtersfile file="build.properties" /> |
| </filterset> |
| </copy> |
| |
| <!-- Check if the customized database scripts exist --> |
| <check-file file="${tests.db.scripts}/userdb-setup.ddl" prop="userdb.setup" /> |
| <check-file file="${tests.db.scripts}/userdb-teardown.ddl" prop="userdb.teardown" /> |
| |
| <!-- If it's the Hypersonic database, set a special flag --> |
| <condition property="hsql"> |
| <equals arg1="${jdbc.driver.id}" arg2="hsql" /> |
| </condition> |
| |
| <!-- Set a flag that says all of our pre-conditions are met! --> |
| <property name="db.props.exist" value="true" /> |
| |
| <!-- Dump all of the JDBC properties where our test scripts can find them --> |
| <echoproperties prefix="jdbc." destfile="${tests.src}/etc/db/jdbc.properties" /> |
| </target> |
| |
| <target name="db-setup" depends="db-properties,hsql-init" if="db.props.exist"> |
| <echo message="Setting up the database tables." /> |
| <exec-sql file="${userdb.setup}" /> |
| </target> |
| |
| <target name="db-teardown" depends="db-properties,hsql-init" if="db.props.exist"> |
| <echo message="Tearing down the database tables." /> |
| <exec-sql file="${userdb.teardown}" /> |
| </target> |
| |
| <!-- Some convenience macrodefs --> |
| <macrodef name="check-property"> |
| <attribute name="prop"/> |
| <sequential> |
| <fail unless="@{prop}" message="Property @{prop} is required." /> |
| </sequential> |
| </macrodef> |
| |
| <macrodef name="check-file"> |
| <attribute name="file" /> |
| <attribute name="prop" /> |
| <sequential> |
| <available file="@{file}" property="@{prop}" value="@{file}" /> |
| <fail unless="@{prop}" message="Couldn't find @{file}!" /> |
| </sequential> |
| </macrodef> |
| |
| <macrodef name="exec-sql"> |
| <attribute name="file" /> |
| <sequential> |
| <sql driver="${jdbc.driver.class}" |
| classpath="${jdbc.driver.jar}" url="${jdbc.driver.url}" |
| userid="${jdbc.admin.id}" password="${jdbc.admin.password}" |
| src="@{file}" onerror="continue" autocommit="true" /> |
| </sequential> |
| </macrodef> |
| |
| <!-- ============================================================== --> |
| |
| <!-- Hypersonic embedded database startup/shutdown (for testing JDBC) --> |
| |
| <!-- Special "init" target for Hypersonic --> |
| <target name="hsql-init" depends="hsql-check-start,hsql-start" /> |
| |
| <target name="hsql-check-start"> |
| <available file="tests/etc/db/hsql/jspwiki.lck" property="hsql.up"/> |
| </target> |
| |
| <target name="hsql-start" depends="hsql-check-start" unless="hsql.up" |
| description="Starts the Hypersonic database for testing."> |
| <echo message="Starting up Hypersonic JDBC server on localhost." /> |
| <java fork="yes" spawn="yes" classname="org.hsqldb.Server" |
| dir="tests/etc/db/hsql"> |
| <classpath> |
| <pathelement location="${jdbc.driver.jar}" /> |
| </classpath> |
| </java> |
| <sleep seconds="5" /> |
| <available file="tests/etc/db/hsql/jspwiki.lck" property="hsql.up"/> |
| <fail unless="hsql.up">Hypersonic didn't appear to start up properly. You can start it manually from the command line as follows: |
| cd tests/etc/db/hsql |
| java -cp ${jdbc.driver.jar} org.hsqldb.Server |
| </fail> |
| <echo message="Done." /> |
| </target> |
| |
| <target name="hsql-stop" depends="hsql-check-start" if="hsql.up" |
| description="Shuts down the Hypersonic database, if it's up."> |
| <echo message="Shutting down Hypersonic JDBC server on localhost." /> |
| <sql driver="${jdbc.driver.class}" |
| classpath="${jdbc.driver.jar}" url="${jdbc.driver.url}" |
| onerror="continue" autocommit="true" |
| userid="${jdbc.admin.id}" password="${jdbc.admin.password}"> |
| SHUTDOWN |
| </sql> |
| <echo message="Done." /> |
| </target> |
| |
| </project> |