::Z::Thinking::

::Simple::
文章 - 124,收藏 - , 评论 - 49, trackbacks - 0
http://blog.csdn.net/camry_camry/archive/2004/10/21/146012.aspx

使用 ant 让你愉快编程(1)

使用 ant 让你愉快编程(1)

摘要: 目录结构划分

已经有无数的文章介绍过 ant 了, 我就不再介绍 ant 的安装,配置了.
每个使用 ant 的朋友都有一套自己的组织方式, 现在我把我的方式写出来
供大家参考, 也免得自己忘记.

1. 目录结构划分
假设你有一个工作目录为: /home/camry/work, 以下简称 work
为了适应多个项目的进行, 我配置了一套基本的配置文件放在 work/common
下. 目录结构是这样的:

work/common/
build_common.xml # 这个文件包含基本的构建操作
common.xml # 这个文件为 build_common.xml 作配置,
基本上不用改动.
build_tomcat.xml # 这个文件包含了与tomcat合作的基本操作.
tomcat.xml # 这个文件为 build_tomcat.xml 作配置,
基本上只需要配置一次.
build.xml # 这个文件是每个项目都需要的 build 配置,
但是基本上也不需要改动了.
build.properties # 这个文件为 build.xml 做配置,
与具体的项目相关.
usage.txt # 这个文件说明了构建过程中的各种操作.

lib/ # 这个目录放置一些公用的 jar 包免得重复.
checkstyle-all-3.4.jar # 用于代码检查
httpunit.jar # 用于 http 单元测试
junit.jar # 用于单元测试
servlet-api.jar # 用于编写 servlet 相关文件

template/ # 这个目录是套项目模版, 一个项目开始时
将把这个目录的数据复制到项目目录下以便
直接使用.
bin/ # 这个目录放置可执行文件
build/ # 这个目录放置构建时需要的辅助文件
checkstyle_checks.xml # 这个文件是 checkstyle 的配置文件
java.header # 这个文件也是 checkstyle 配置文件
用于说明你的 java 文件的头部构造
dist/ # 这个目录放置目标文件
classes/ # 编译后产生的 class 文件放在这
lib/ # 打包后产生的 jar 文件放这
lib/ # 这个目录放置项目相关的 jar 文件
src/ # 这个目录放置源代码
build.xml # 这个文件是用于与 cvs 配合工作的配置文件
main/ # 这个目录中放置主要的源代码
test/ # 这个目录中放置测试代码

后续的文章中会详细介绍所有的配置文件.

使用 ant 让你愉快编程(2)

使用 ant 让你愉快编程(2)

摘要: build_common.xml, common.xml 及 usage.txt

2. 介绍 build_common.xml, common.xml 及 usage.txt

. 以下为 build_common.xml 文件内容.

<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
Copyright 2004 camry.wu@gmail.com

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 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 General Public License for more details.

You should have received a copy of the GNU 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
-->
<project name="Common build file" default="all" basedir="">

<description>
这是一个通用的 ant build 文件. Version 1.0.
感谢: 这篇文档借用了很多 Johan 的想法, 他的主页在 http://dev.kanngard.net
Copyright 2004 camry.wu@gmail.com
</description>

<!-- 读入 common.xml 配置 -->
<xmlproperty file="${path.common}/common.xml"
semanticAttributes="true"
keepRoot="false"/>

<!-- 设置编译时的 classpath -->
<path id="compile.classpath">
<fileset dir="${path.common}/lib">
<include name="*.jar"/>
</fileset>
<fileset dir="${lib}">
<include name="*.jar"/>
</fileset>
<pathelement location="${dist.classes}"/>
</path>

<!-- 设置运行时的 classpath -->
<path id="run-time.classpath">
<path refid="compile.classpath"/>
</path>

<!-- 初始化过程, 会调用具体项目的初始化过程先 -->
<target name="init"
depends="project_init"
description="Initialize environment">
</target>

<!-- 显示使用说明 -->
<target name="usage">
<loadfile property="usage.message"
srcFile="${path.common}/usage.txt"/>
<echo message="${usage.message}"/>
</target>

<!-- 预备, 通常在项目刚建立的时候运行此任务 -->
<target name="common_prepare"
depends="init" description="Prepare build directory">
<copy todir="." preservelastmodified="true">
<fileset dir="${path.common}/template/">
<include name="**/*"/>
</fileset>
</copy>
</target>

<!-- 配置 checkstyle , 只检查 src/main 目录下的源代码 -->
<target name="checkstyle" depends="init">
<taskdef resource="checkstyletask.properties"
classpath="${path.common}/lib/checkstyle-all-3.4.jar"/>
<checkstyle config="${build}/checkstyle_checks.xml">
<fileset dir="${src.main}" includes="**/*.java"/>
<property key="checkstyle.cache.file"
file="${path.common}/lib/checkstyle.cache"/>
<classpath refid="compile.classpath"/>
</checkstyle>
</target>

<!-- 编译 src 下源文件, class 文件放到 dist/classes 下 -->
<target name="compile" depends="init" description="Compile source">
<mkdir dir="${dist}/classes"/>
<javac debug="${compile.debug}"
deprecation="${compile.deprecation}"
destdir="${dist}/classes"
target="${compile.jdk-version.target}"
source="${compile.jdk-version.source}"
optimize="${compile.optimize}"
srcdir="${src}">
<classpath refid="compile.classpath"/>
</javac>
</target>

<!-- 清除 dist 目录 -->
<target name="clean"
depends="project_clean"
description="Wipeout all generated files">
<delete dir="${dist}/classes"/>
<delete dir="${dist.lib}"/>
<mkdir dir="${dist}/classes"/>
<mkdir dir="${dist.lib}"/>
</target>

<!-- 打包 -->
<target name="jar"
depends="checkstyle, compile"
description="Create binary distribution">
<mkdir dir="${dist}/classes"/>
<mkdir dir="${dist.lib}"/>
<copy file="LICENSE" todir="${dist}/classes"/>
<delete>
<fileset dir="${dist.lib}" includes="*.jar"/>
</delete>
<jar basedir="${dist}/classes"
jarfile="${dist.lib}/${component.name}-${component.version}.jar">
<include name="**/*.class"/>
<exclude name="**/Test*.class"/>
</jar>

<delete>
<fileset dir="${dist}/classes">
<include name="LICENSE"/>
</fileset>
</delete>
</target>

<!-- 运行 dist/classes 目录下的所有以 Test 开头的测试类 -->
<target name="test" depends="compile" description="run junit tests">
<junit printsummary="on"
fork="false"
haltonfailure="false"
failureproperty="tests.failed"
showoutput="true">
<classpath refid="run-time.classpath"/>
<formatter type="brief" usefile="false"/>
<batchtest>
<fileset dir="${dist}/classes">
<include name="**/Test*.*"/>
</fileset>
</batchtest>
</junit>

<fail if="tests.failed">
*********************************************************
*********************************************************
**** One or more tests failed! Check the output... ****
*********************************************************
*********************************************************
</fail>
</target>

<!-- 发布, 会调用具体项目的发布任务 -->
<target name="deploy"
depends="project_deploy" description="Deploy application"/>

<!-- 创建文档 -->
<target name="javadoc"
depends="compile"
description="Create component Javadoc documentation">
<delete dir="${docs.api}"/>
<mkdir dir="${docs.api}"/>
<javadoc author="true"
bottom="${component.title}"
destdir="${docs.api}"
source="${compile.jdk-version.source}"
doctitle="${component.title}"
packagenames="*"
access="protected"
sourcepath="${src.main}"
version="true"
windowtitle="${component.title} (Version ${component.version})">
<classpath refid="compile.classpath"/>
</javadoc>
</target>

<!-- 根据 cvs 配置, 从 cvs 服务器上下载源代码 -->
<target name="fetch"
depends="project_fetch" description="fetch current source from cvs">
</target>

<!-- 将源代码文件打包, 备份 -->
<target name="src-zip"
depends="checkstyle,compile"
description="Creates source distribution">
<copy file="LICENSE" todir="${src.main}"/>
<delete>
<fileset dir="${dist.lib}" includes="*-src.zip"/>
</delete>
<zip basedir="."
destfile="${dist.lib}/${component.name}-${component.version}-src.zip"
whenempty="fail">
<include name="**/*.*"/>
<include name="*"/>
<include name="**/*"/>
<exclude name="${dist}/**/*.*"/>
<exclude name="*.*~"/> <!-- vi(JEdit) backups -->
<exclude name=".nbattrs"/> <!-- Netbeans filesystem attributes -->
<exclude name="*.old"/>
</zip>
</target>

<!--
将源文件上传到服务器备份, 将目标文件上传到服务器发布.
此任务中内容由各位自行设定, 一般是运行 ftp 任务.
-->
<target name="publish"
depends="clean,jar,javadoc,src-zip" description="publish project">
</target>

<!-- 构建 -->
<target name="all"
depends="clean,fetch,test,jar,javadoc,deploy"
description="build project"/>
</project>


. 以下为 common.xml 文件内容.

<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
Copyright 2004 camry.wu@gmail.com
Common Ant build environment
-->

<root>
<!--
路径配置, 基本不用改动.
但是假如你在一个陌生的环境中使用这套 build 工具,
也许需要稍为修改一下这些路径的配置.
-->
<bin value="bin"/>
<build value="build">
<lib value="${build}/lib"/>
</build>
<dist value="dist">
<lib value="${dist}/lib"/>
<classes id="dist.classes" location="${dist}/classes"/>
</dist>
<docs value="docs">
<api value="${docs}/api"/>
</docs>
<lib value="lib"/>
<src value="src">
<main value="${src}/main"/>
<test value="${src}/test"/>
</src>

<!-- 编译选项 -->
<compile>
<debug value="true"/>
<deprecation value="true"/>
<jdk-version>
<source value="1.4"/>
<target value="1.4"/>
</jdk-version>
<optimize value="true"/>
</compile>

</root>


. 以下为 usage.txt 文件内容.

${component.name} build file
---------------------------------------------

Available targets are:

prepare --> 初始化项目环境
checkstyle --> 检查源文件编码规范
compile --> 编译
jar --> 打包
build --> 构建
test --> 测试
clean --> 清除
deploy --> 发布到 web 服务器运行
publish --> 发布产品(源码及目标文件)
fetch --> 从 cvs 上获取最新资源
docs --> 创建 api 文档
all --> 执行 clean, fetch, build, test, doc, deploy
main --> 默认的构建过程(自行修改)



使用 ant 让你愉快编程(3)

使用 ant 让你愉快编程(3)

摘要: build.xml, build.properties

2. 介绍 build.xml, build.properties

. 以下为 build.xml 文件内容.

<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
Copyright 2004 camry.wu@gmail.com

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 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 General Public License for more details.

You should have received a copy of the GNU 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
-->
<project name="App" basedir="." default="compile">
<property file="build.properties"/>

<!-- 载入 common build 内容 -->
<import file="${path.common}/build_common.xml"/>
<!--
假如项目要和 tomcat 一起配合, 那么载入 tomcat 的配置 -->
<import file="${path.common}/build_tomcat.xml"/>
-->

<!-- 项目初始化内容 -->
<target name="project_init" description="Initialize project environment">
<available property="junit.present" classname="junit.framework.TestCase"/>
<!-- 这里可以加入你自己的项目任务 -->
</target>

<!-- 项目预备内容, 一般在新建立一个项目的时候运行本任务 -->
<target name="prepare"
depends="common_prepare" description="Prepare build directory">
<!-- 这里可以加入你自己的项目任务 -->
</target>

<!-- 从 cvs 服务器上下载源程序 -->
<target name="project_fetch"
depends="init" description="fetch src from cvs or another location">
<ant dir="${src}" target="fetch"/>
</target>

<!-- 清除 -->
<target name="project_clean"
depends="init" description="Project-level prepare phase">
<!-- 这里可以加入你自己的项目任务 -->
</target>

<!-- 发布 -->
<target name="project_deploy" description="Deploy application">
<!--
假如项目要和 tomcat 一起配合, 那么调用 tomcat 的任务
<antcall target="deploy_tomcat"/>
-->
</target>

<!-- 反发布 -->
<target name="undeploy" description="Un-Deploy application">
<!--
假如项目要和 tomcat 一起配合, 那么调用 tomcat 的任务
<antcall target="undeploy_tomcat"/>
-->
</target>

<!-- 构建应用系统 -->
<target name="main" depends="test,jar,javadoc,publish" description="build">
<!-- 这里可以加入你自己的项目任务 -->
</target>
</project>


. 以下为 build.properties 文件内容
# 初始化环境

# common 文件的位置, 假如在 windows 下可能要这么写: D:\work\common
path.common=/home/camry/work/common

# 项目相关信息
component.name=App
component.package=com.vitular.app
component.title=App
component.version=0.1a

# cvs root 位置
CVSROOT=:pserver:camry@x.x.x.x:/usr/cvsroot

# ftp 设置
# ftp.server=x.x.x.x # 远程服务器位置
# ftp.user=camry # 用户名
# ftp.pass=***** # 用户密码
# remote.dir=/opt/release # 远程发布目录位置

使用 ant 让你愉快编程(4)

使用 ant 让你愉快编程(4)

摘要: checkstyle_checks.xml, java.header

现在已经有了目录结构, 有了 build_common.xml, common.xml, usage.txt,
build.xml, build.properties 等文件, 已经可以完成大部分任务了.
现在介绍如何进行辅助任务, 比如代码检查.

代码检查在 build_common.xml 中已经有这个任务了, 但是还需要两个配置
文件配合, 还需要到这里下载 checkstyle 的 jar 包并将
它放到 work/common/lib/ 目录下.

这两个配置文件是: work/common/template/build/ 目录下的
checkstyle_checks.xml 文件和 java.header 文件
checkstyle_checks.xml 文件说明了对 java 文件应该如何进行检查,
java.header 文件指出每个 java 文件的头部构造.

. checkstyle_checks.xml 文件如下, 是借用的Johan
的源文件, 作了一点儿修改. 其中每项配置的具体说明都有给出链接, 不明白的
话可以仔细看看.

<?xml version="1.0" encoding="iso-8859-1"?>
<!--
Copyright 2004 Johan K?ng?d, http://dev.kanngard.net

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 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 General Public License for more details.

You should have received a copy of the GNU 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
-->
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.2//EN"
"http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
<!--
Based on the Checkstyle configuration file sun_checks.xml with some minor
modifications..
Checkstyle is very configurable. Be sure to read the documentation at
http://checkstyle.sf.net
-->
<module name="Checker">

<!-- Checks that a package.html file exists for each package. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html#PackageHtml -->
<module name="PackageHtml"/>

<!-- Checks whether files end with a new line. -->
<!-- See http://checkstyle.sf.net/config_misc.html#NewlineAtEndOfFile -->
<module name="NewlineAtEndOfFile"/>

<!-- Checks that property files contain the same keys. -->
<!-- See http://checkstyle.sf.net/config_misc.html#Translation -->
<module name="Translation"/>

<module name="TreeWalker">
<!-- Checks for Javadoc comments. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<module name="JavadocMethod"/>
<module name="JavadocType"/>
<module name="JavadocVariable"/>
<module name="JavadocStyle"/>

<!-- Checks for Naming Conventions. -->
<!-- See http://checkstyle.sf.net/config_naming.html -->
<module name="ConstantName"/>
<module name="LocalFinalVariableName"/>
<module name="LocalVariableName"/>
<module name="MemberName">
<property name="format" value="^[_A-Z][a-zA-Z0-9]*$"/>
</module>
<module name="MethodName"/>
<module name="PackageName"/>
<module name="ParameterName"/>
<module name="StaticVariableName"/>
<module name="TypeName"/>

<!-- Checks for Headers -->
<!-- See http://checkstyle.sf.net/config_header.html -->
<module name="Header">
<!-- The follow property value demonstrates the ability -->
<!-- to have access to ANT properties. In this case it uses -->
<!-- the ${basedir} property to allow Checkstyle to be run -->
<!-- from any directory within a project. See property -->
<!-- expansion, -->
<!-- http://checkstyle.sf.net/config.html#properties -->
<property
name="headerFile"
value="${basedir}/build/java.header"/>
<property name="ignoreLines" value="3,5,8"/>
</module>

<!-- Following interprets the header file as regular expressions. -->
<!-- <module name="RegexpHeader"/> -->

<!-- Checks for imports -->
<!-- See http://checkstyle.sf.net/config_import.html -->
<module name="AvoidStarImport"/>
<module name="IllegalImport"/> <!-- defaults to sun.* packages -->
<module name="RedundantImport"/>
<module name="UnusedImports"/>

<!-- Checks for Size Violations. -->
<!-- See http://checkstyle.sf.net/config_sizes.html -->
<module name="FileLength"/>
<module name="LineLength"/>
<module name="MethodLength"/>
<module name="ParameterNumber"/>

<!-- Checks for whitespace -->
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
<module name="EmptyForIteratorPad"/>
<module name="MethodParamPad"/>
<module name="NoWhitespaceAfter"/>
<module name="NoWhitespaceBefore"/>
<module name="OperatorWrap"/>
<module name="ParenPad"/>
<module name="TypecastParenPad"/>
<!-- <module name="TabCharacter"/>-->
<module name="WhitespaceAfter"/>
<module name="WhitespaceAround"/>

<!-- Modifier Checks -->
<!-- See http://checkstyle.sf.net/config_modifiers.html -->
<module name="ModifierOrder"/>
<module name="RedundantModifier"/>

<!-- Checks for blocks. You know, those {}'s -->
<!-- See http://checkstyle.sf.net/config_blocks.html -->
<module name="AvoidNestedBlocks"/>
<module name="EmptyBlock"/>
<module name="LeftCurly"/>
<module name="NeedBraces"/>
<module name="RightCurly"/>

<!-- Checks for common coding problems -->
<!-- See http://checkstyle.sf.net/config_coding.html -->
<module name="AvoidInlineConditionals"/>
<module name="DoubleCheckedLocking"/> <!-- MY FAVOURITE -->
<module name="EmptyStatement"/>
<module name="EqualsHashCode"/>
<module name="HiddenField">
<property name="tokens" value="VARIABLE_DEF"/>
</module>

<module name="IllegalInstantiation"/>
<module name="InnerAssignment"/>
<module name="MagicNumber"/>
<module name="MissingSwitchDefault"/>
<module name="RedundantThrows"/>
<module name="SimplifyBooleanExpression"/>
<module name="SimplifyBooleanReturn"/>

<!-- Checks for class design -->
<!-- See http://checkstyle.sf.net/config_design.html -->
<!-- <module name="DesignForExtension"/> -->
<module name="FinalClass"/>
<module name="HideUtilityClassConstructor"/>
<module name="InterfaceIsType"/>
<module name="VisibilityModifier"/>

<!-- Miscellaneous other checks. -->
<!-- See http://checkstyle.sf.net/config_misc.html -->
<module name="ArrayTypeStyle"/>
<module name="FinalParameters"/>
<module name="GenericIllegalRegexp">
<property name="format" value="\s+$"/>
<property name="message" value="Line has trailing spaces."/>
</module>
<module name="TodoComment"/>
<module name="UpperEll"/>
</module>
</module>


. 以下是我的 java 文件头部构造, 当然每个团队可以有自己的约定.
因为第3,5,8行是随文件的改变而改变的, 因此我忽略了对他们的检查,
这一点可以从上面的 checkstyle_checks.xml 文件中看出来.

/*
* -----------------------------------------------------------
* file name : _filename_
* authors : camry(camry@gmail.com)
* created : _datetime_
* copyright : (c) 2003 Vitular Inc. All Rights Reserved.
*
* modifications:
*
* -----------------------------------------------------------
*/

有的朋友可能觉得每次都在文件前写这么一个头岂不是很麻烦, 但是对于我来说,
这一点非常容易就可以让 vim 做到了. 当我用 vim 新建一个 java 文件时,
它会自动加入这个头部说明, 并用适当的文件名和时间替换 _filename_ 和
_datetime_ 这两个参数. 如何做到这一点将来会做说明.

使用这个 checkstyle 时会有这么一个麻烦的地方: 它不允许在行尾有多余的
空格. 对于程序员来说, 谁在乎这么几个空格呢, 可是程序是非常严谨的:)
使用vim的朋友可以在这里发现如何轻松消除行尾空格.

使用 ant 让你愉快编程(5)

使用 ant 让你愉快编程(5)

摘要: build_tomcat.xml, tomcat.xml

现在介绍一下如何与 tomcat 一起配合工作.
java 的程序很大部分都涉及 web, 自己测试时使用 tomcat 还是很方便的,
所以有必要介绍一下.

在 work/common/ 下的 build_tomcat.xml, tomcat.xml 这两个文件是与
tomcat 配合工作的配置文件, 它的内容很简单.

. 以下为 build_tomcat.xml 文件内容:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
Copyright 2004 camry.wu@gmail.com

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc..
-->
<project name="tomcat target file" default="start" basedir="">

<description>
与tomcat相互配合的任务. Version 1.0.
Copyright 2004 camry.wu@gmail.com
</description>

<!-- 读入 tomcat 配置 -->
<xmlproperty file="${path.common}/tomcat.xml"
semanticAttributes="true" keepRoot="false"/>

<!-- 发布到 tomcat -->
<target name="deploy_tomcat"
depends="compile" description="Deploy application">
<copy todir="${path.war}/WEB-INF/classes" preservelastmodified="true">
<fileset dir="${dist}/classes">
<include name="**/*"/>
</fileset>
</copy>
<copy todir="${path.war}/WEB-INF/lib" preservelastmodified="true">
<fileset dir="${dist}/lib">
<include name="**/*"/>
</fileset>
</copy>
<copy todir="${path.deploy}/${component.name}" preservelastmodified="true">
<fileset dir="${path.war}">
<include name="**/*"/>
</fileset>
</copy>
</target>

<!-- 撤销发布 -->
<target name="undeploy_tomcat" description="Un-Deploy application">
<delete>
<fileset dir="${tomcat.home}/webapps/${component.name}">
<include name="**/*"/>
</fileset>
</delete>
</target>

<!-- 发布为 war 形式 -->
<target name="deploywar"
depends="jar" description="Deploy application as a WAR file">
<war destfile="${component.name}.war" webxml="${path.war}/WEB-INF/web.xml">
<fileset dir="${path.war}">
<include name="**/*"/>
</fileset>
</war>
<copy todir="${path.deploy}" preservelastmodified="true">
<fileset dir=".">
<include name="*.war"/>
</fileset>
</copy>
</target>

<!-- install 工程 -->
<taskdef name="install" classname="org.apache.catalina.ant.InstallTask">
<classpath>
<path location="${tomcat.home}/server/lib/catalina-ant.jar"/>
</classpath>
</taskdef>

<!-- reload 工程 -->
<taskdef name="reload" classname="org.apache.catalina.ant.ReloadTask">
<classpath>
<path location="${tomcat.home}/server/lib/catalina-ant.jar"/>
</classpath>
</taskdef>

<!-- 查看工程列表 -->
<taskdef name="list" classname="org.apache.catalina.ant.ListTask">
<classpath>
<path location="${tomcat.home}/server/lib/catalina-ant.jar"/>
</classpath>
</taskdef>

<!-- 启动 tomcat -->
<taskdef name="start" classname="org.apache.catalina.ant.StartTask">
<classpath>
<path location="${tomcat.home}/server/lib/catalina-ant.jar"/>
</classpath>
</taskdef>

<!-- 停止 tomcat -->
<taskdef name="stop" classname="org.apache.catalina.ant.StopTask">
<classpath>
<path location="${tomcat.home}/server/lib/catalina-ant.jar"/>
</classpath>
</taskdef>

<!-- install 工程 -->
<target name="install" description="Install application in Tomcat">
<install url="${tomcat.manager.url}"
username="${tomcat.manager.username}"
password="${tomcat.manager.password}"
path="/${component.name}"
war="${component.name}.war"/>
</target>

<!-- reload 工程 -->
<target name="reload" description="Reload application in Tomcat">
<reload url="${tomcat.manager.url}"
username="${tomcat.manager.username}"
password="${tomcat.manager.password}"