现在的位置: 首页 > 综合 > 正文

[Ant][StartWithAnt] 第六章 数据类型Data Type

2013年08月02日 ⁄ 综合 ⁄ 共 9268字 ⁄ 字号 评论关闭

点击此处下载StartWithAnt完整的pdf文档与代码:http://download.csdn.net/detail/sodino/6603769

Ant的核心功能有两个基本概念:特性和Data Type

同特性一样,Data TypeAnt中扮演任务参數的角色,可以在一個任務內部声明,也可以在任务外部定义,并为它起个名字,再把这个名字传给任务。这样就可以在多个任务中共享一个Data Type

但在构建过程中,Data Type支持比特性更加复杂的数据内容,比如一个待编译的文件列表或者一个待刪除的目录集。下面来逐一说下Ant支持的Data Type.

1.argument Data Type

用于Ant调用命令行任务时,向其传递命令参数。如applyexec、和java等任务均接受嵌套<arg>元素。在构建文件中以”<arg>”的形式为具体的任务传递参数。以下是<arg>的所有属性列表:

value:直接指定命令行参数值,允许参数中包含空格,但空格不起分隔作用,所以如果你的参数中有空格但又想将它作为单独一个值,则使用此属性。

line:用空格分隔的多个参数的列表。

file:指定一个参数的文件名。应该要注意的是此文件名相对于当前的工作目录。在Ant运行时过程中,此文件名会被转换为一个绝对路径。

path:指定参数路径,多个路径间可以使用";"分开。

pathref:引用<path>数据类型。<path>将在下面会讲解。

<arg>需要有一个且仅有一个以上的属性。

接下来示例如下:

<arg value="-l -a"/>

表示一个包含空格的参数“-l -a”。当需要传递的参数,比如某个文件名中包含空格,就需要使用到value

<arg line="-l -a"/>

表示传递了由空格分隔的两个参数”-l”和”-a”。

<arg path="/dir;/dir2:\dir3"/>

表示传递了一个单独的参数,在基于DOS的系统会自动解释为”/dir;/dir2;/dir3”;Unix系列的系统将解释成”/dir:/dir2:/dir3”。

2.environment Data Type

对于执行系统命令的applyexec任务,本地执行的.batshell批处理文件需要接收由Ant传递过去的参数。这时可以使用<env>对系统可执行文件传递参数。<env>元素接受以下属性:

key:环境变量名。

file:作为环境变量值的文件名。此文件名会被转换为一个绝对路径。

path:作为环境变量的路径,Ant会自动将它转换为一个本地约定(如文件分隔符的不同)

value:环境变量的一个直接量值。

以上属性中key是必须的,filepathvalue只能三选其一。

<target name="Env">
<path id="output_dir" location="lab\sodino"/>
<exec executable="build_06_02_arg_env.bat">
<!-- 传参到bat / shell中去 -->
<env key="jad_home" value="D:\MissionSetup\JD"/>
<env key="class_file" file="lab\sodino\AntTest.class"/>
<env key="output_dir" path="output_dir"/>
</exec>
</target>

代码6.1 环境变量传参

%jad_home%\jad  -d %output_dir% %class_file%

代码6.2 DOS环境下build_06_02_arg_env.bat文件运行代码

$jad_home\jad  -d $output_dir  $class_file

代码6.3 Unix环境下build_06_02_arg_env.sh文件运行代码

以上代码演示了Ant调用本地的批处理文件,直接并向批处理文件传递了三个参数的过程。Jad工具可以将指定的.class文件反编译并将结果AntTest.jad输出到output_dir中。在批处理文件中,要注意的是DOS环境下的变量引用是使用”%param%”方式,而Unix环境下是使用”$param”方式。

6.1 环境变量示例效果

在示例代码6.1中,指定”jad_home”的方式为以硬编码的方式直接设定了值。尽管在自己的机子上可能可以工作,但在其它的开发人员机器上则极有可能因路径的不同而导致失败。为避免出现这种问题,可以约定俗成的要求开发人员在运行之前设置一次jad_home的环境变量到系统中,情况更好。以下为做了优化后的修改:

<target name="Env">
<!--直接将系统环境变量导入到Ant运行时中-->
<property environment="env"/>
<path id="output_dir" location="lab\sodino"/>
<exec executable="build_06_02_arg_env.bat">
<!-- 传参到bat / shell中去 -->
<!-- 读取系统环境变量中jad_home的值 -->
<env key="jad_home" value="${env.jad_home}"/>
<env key="class_file" file="lab\sodino\AntTest.class"/>
<env key="output_dir" path="output_dir"/>
</exec>
</target>

代码6.4 优化后的环境变量设置

在上面的优化代码中,通过 <property environment="env"/>就将系统环境变量导入到Ant的运行时中,只要在在变量名前加上前缀”env.”,就可以引用任何环境变量了。

3.filelist Data Type

filelist是一个支持一系列具体命名的文件列表的Data Type,与第4部分将要讲的filesets相比,filelist中指定的文件可以是不存在的,指定文件时不支持通配符扩展。以下为filelist支持的属性:

dir:用于计算绝对文件名的目录。

files:一系列指定的文件名,多个文件名间可以用逗号、空格或换行符分开。

refid:利用已经定义好的filelist

在以上三个属性中,可以只指定refid,或者在不指定refid的情况下dirfiles必须同时被赋值。

filelist是与dependset任务一同使用的。dependset任务将一个或多个输入文件与另外的一个或多个目标文件加以比较。如果某些输入文件更新,或缺少某些输入文件,则所有的目标文件都将会被删除。这种功能的应用场景当目标文件需要依赖于输入文件的最新状态时,即可删除目标文件,根据目标文件的是否存在来判断是否需要重新生成目标文件。

<path id="xml_folder" location="./build_06.2_filelist_dependset"/>
<!-- dir处直接赋值为path.id名称,也可以${path.id} -->
<filelist id="xml.file01" dir="xml_folder" files="build_01.xml,build_02.xml"/>
<filelist id="xml.file02" dir="xml_folder" files="build_03.xml"/>
<target name="filelist_dependset">
<!--仅输出“filelist”,非所有的文件路径-->
<echo>${toString:xml.file01}</echo>
<dependset>
<!--在比较输入文件时,并不限制srcfilelist的个数,1个或多个皆可-->
<srcfilelist refid="xml.file01"/>
<srcfilelist refid="xml.file02"/>
<targetfilelist dir="xml_folder" files="build.xml"/>
</dependset>
</target>

代码6.5 filelist示例代码

在上面代码中,dependset任务通过<srcfilelist>指定输入文件为xml.file01xml.file02,即文件集合build_01.xmlbuild_02.xmlbuild_03.xmlAnt会去检查这三个文件是否存在,当这三个文件存在缺失或者这三个文件比目标文件build.xml的状态要新,则Ant会将目标文件build.xml进行删除。

4.fileset Data Type 与 patternset Data Type

fileset Data Type定义了一组文件,通常在构建文件中用<fileset>元素表示。不过,许多Ant任务构成了隐式的fileset,这说明它们支持所有fileset属性和嵌套元素。与filelist类型不同,由fileset表示的文件必须存在。fileset还可能指定为目标级构建文件(<project>的子元素),并由其id引用。以下为fileset常用属性列表:

dir:fileset的基目录。

casesensitive:默认值为true,表示在匹配文件时是区分文件名的大小写的。

excludes:用逗号分隔的需要排除的文件模式列表。

excludesfile:用逗号分隔开的需要排除的文件名。

includes:用逗号分隔开的需要包含的文件模式列表。

includesfile:用逗号分隔开的需要排除的文件名。

除了以上列出的属性外,fileset还支持内嵌0到多个patternset元素。

fileset是对文件的分组,而patternset是对模式的分组。它们是紧密相关的概念,因为fileset依赖于选择文件的模式。<patternset>元素可能作为目标级构建文件元素出现(即作为<project>的子元素),而且后面将通过其id被引用。patternset元素有4种,对于<include><exclude>,支持以下属性:

name:包含或排除的模式。

if:特性名。只在设置了该特性时Ant才使用此模式。

unless:特性名。只在未设置该特性时Ant才使用此模式。

对于<includesfile><excludesfile>,支持以下属性:

name:包含和排除模式的文件的文件名。

if:特性名。只在设置了该特性时Ant才使用此模式。

unless:特性名。只在未设置该特性时Ant才使用此模式。

<patternset id="exclude.xml01">
<exclude name="**/*.xml"></exclude>
</patternset>
<!-- 如果work.dir不存在,会自动创建 -->
<copy todir="${work.dir}">
<fileset dir="${src.dir}">
<patternset refid="exclude.xml01"/>
</fileset>
</copy>

代码6.6 使用fileset复制文件

5.filterset Data Type

filterset Data Type 允许定义一组过滤器。这些过滤器将在文件移动或复制时完成文件中的文本替换。这称为记号过滤(token filtering)。若在输入文件中发现了某些记号则会出现此文本替换。当文本移动或复制时,这些记号被替换为匹配过滤器中所定义的文本。filterset支持内嵌<filter>元素来执行具体的文本替换任务,filter任务总是将@字符用作记号分隔符,而filterset则允许定制开始和结束记号分隔符。

filterset Data Type<filterset>元素表示,可以作为copymove任务中嵌套的内容出现,或者作为目标级构建文件元素出现(project的子元素)。以下为filterset支持的常用属性:

begintoken:标定目标替换文字的起始字符串。默认为@

endtoken:标定目标替换文字的结尾字符串。默认为@

id:对此过滤器的唯一标识符。当过滤器定义为一个目标级构建文件元素且需要在以后被引用时,则就是必要的。

refid:对构建文件中某处定义的一个过滤器的引用。

filterset可以嵌套0n<filter>元素,该元素属性有:

token:指定需要替换的记号,不包括定界符。如果此过滤器要替换@VERSION@,则将VERSION作为此属性值即可。

value:指定当遇到记号时,要替换的新的文本。

<!-- 先声明时间戳,为后面的${TODAY}生效 -->
<tstamp/>
<!-- 未声明过滤的起始、终止符,则默认为"@",效果为"@date@"替换为日期时间。 -->
<filterset id="filter_date">
<filter token="date" value="${TODAY}"/>
</filterset>
<!-- 自定义起始、终止标记。效果为"%author!"替换为"sodino" -->
<filterset id="filter_custom_token" begintoken="%" endtoken="!">
<filter token="author" value="sodino"/>
</filterset>
<target name="copy">
<copy todir="${des.dir}">
<fileset dir="${src.dir}" includes="**/*.java" casesensitive="false"/>
<filterset refid="filter_date"/>
<filterset refid="filter_custom_token"/>
</copy>
</target>

代码6.7 filterset示例

以上代码将对src.dir下所有的.java文件进行记号过滤替换。自动为.java标记上authorsodino及填写上真正的时间日期。

替换前:

 * @author %author! 

 * @date@

替换后:

 * @author sodino 

 * May 31 2013

代码6.8 filterset运行前后对比

6.path Data Type

path用于表示一个或多个文件的路径,也可以由通配符或fileset等其它的data type来表示一系列符合过滤规则的文件集合。在作为一个属性时,路径中的各项文件用分号(;)或冒号(:)字符隔开。path具有非常大的灵活性。以下为path支持的常用属性:

location:表示一个文件或目录。在运行时会自动转换成该文件或目录的绝对路径。

path:一个文件或路径名列表,并以”;”或”:”分隔。

refid:对当前构建文件中某处定义的一个path的引用。

id:对此路径的唯一标识符。

locationpath均是可选的,但不能与refid同时声明。

path Data Type还支持以下嵌套元素:
0n个嵌套的<pathelement>元素:

定义一个或多个要包含在path中的文件。每个嵌套的<pathelement>就像包含它的path DataType一样,还支持locationpath属性。

0n个嵌套的<fileset>元素

提供高级的文件过滤规则。

0n个嵌套的<path>元素

将路径递归地嵌套到其他路径中。

<path id="dir.path" path="."/>
<path id="xml.path" location="./build_001_property.xml"/>
<path id="all.xml.path">
<fileset dir=".">
<include name="**/*.xml"/>
</fileset>
</path>
<path id="project.path">
<pathelement path="dir.path"/>
<path refid="xml.path"/>
</path>
<!-- 使用${toString:path_id}输出xml.path的完整路径 -->
<target name="path_demo">
<echo message="xml.path:  ${toString:xml.path}"></echo>
<echo message="all.xml.path:  ${toString:all.xml.path}"></echo>
<echo message="project.path:  ${toString:project.path}"></echo>
</target>

代码6.9 path示例

7.mapper Data Type

mapper定义了一组源文件与一组目标文件之间的对应关系。之前所讲述的filelistfileset等只是定义了一组源文件的输入规则,而mapper不限于此,它可以在构建文件中约定文件执行copymove后的输出规则。如有选择性的对.java进行备份复制后在各个文件后追加”.bak”的后缀名;将从多个不同目录的一组文件复制到同一个目标目录中等。

这种依据输入规则而重新自定义其输出规则Ant中称之为映射处理。映射处理有以下几种方式:

1.identity mapper

恒等映射。文件的输入与输出为一一匹配原则,不作修改。最常见是在copy任务中默认使用到。

<mapper type="identity"/>

6.1 identity mapper的结果

输入文件
MapperDemo.java
lab/sodino/AntTest.java
输出文件
MapperDemo.java
lab/sodino/AntTest.java

2.flatten mapper

flatten mapper会从文件名中删除所有的路径信息。如果希望从多个不同目录中将一组文件复制到一个目录中,这就很有用。这里需要注意的是,因为取消了目录信息,如果这组文件中出现相同文件名的情况,那么就会造成覆盖,所以一般要求不要有重名。  

<mapper type="flatten"/>

6.2 identity mapper的结果 

输入文件
MapperDemo.java
lab/sodino/AntTest.java
输出文件
MapperDemo.java
AntTest.java

3.glob mapper

全局映射。基于简单的通配模式确定目标文件名。若要对已经有一致文件名(如以Test.java结尾)的一组文件重命名,这就很有用。其中<mapper>标签中的属性”to”和”from”定义了模式,其中至多有一个”*”字符。当一个源文件名与”from”模式匹配时,即生成目标文件名。”to”属性的*要替换成”from”属性的*所对应的匹配文本。  

<mapper type="glob" from="*Test.java" to="*JavaTest.java"/>

6.3 glob mapper的结果

输入文件
MapperDemo.java
lab/sodino/AntTest.java
输出文件
MapperDemo.java
lab/sodino/AntJavaTest.java

4.

再来看一下mapperfileset的影响。在下面的代码6.10中,fileset设置了copy的文件为*.java*.txt文件,但mapper中的”from”将范围限制得更小仅接受文件名以”Test.java”结尾的文件,导致在真正执行copy任务时,只有”*Test.java”文件才会被复制,而其它的java文件及txt文件都被抛弃了。

<copy todir="${output_glob}">
<fileset dir="${src_dir}" includes="**/*.java,**/*.txt"/>
<mapper type="glob" from="*Test.java" to="*JavaTest.java"/>
</copy>

代码6.10 glob mapper的使用

5.merge mapper

合并映射。该映射”from”属性则被忽略不用,只将所有源文件名与”to”属性所指定的相同目标文件相匹配。merge mapper通常与uptodate任务一起工作用于比较一组源文件和某个目标文件的时间戳。

在下面的代码中,如果指定所有.java文件中存在某个文件比javac_class.jar要新,则特性"need.to.do.javac"值为true,反之则不存在特性”need.to.do.javac”。接着代码通过条件判断来给出一个确切的结果将是否需要再重新编译java文件赋值到特性”do.javac”上。最后打印出结果。

<uptodate property="need.to.do.javac"> 
<srcfiles dir="${src_dir}" includes="**/*.java"/> 
<mapper type="merge" to="${src_dir}\..\javac_class.jar"/>
</uptodate> 
<condition property="do.javac" value="true" else="false">
<isset property="need.to.do.javac"/>
</condition>
<echo message="need to do javac:${do.javac}"/>

代码6.11 merge mapper的使用

6.package mapper

包映射。与glob mapper的功能相似,只是将属性”from”指定文件的目录信息作为新文件的文件名前缀添加到输出文件的文件名上。

<mapper type="package" from="*.java" to="*.Subfix.java"/>

6.4 package mapper的结果

输入文件
MapperDemo.java
lab/sodino/AntTest.java
输出文件
MapperDemo.Subfix.java
lab.sodino.AntTest.Subfix.java

7.unpackage mapper

解包映射。为包映射的反操作,会将文件名中的路径信息去掉并创建新的目录将输出文件存储到新目录中。

<mapper type="unpackage" from="*.java" to="*.java"/>

6.5 package mapper的结果

输入文件
MapperDemo.java
lab.sodino.AntTest.java
输出文件
MapperDemo.Subfix.java
lab/sodino/AntTest.java

  

抱歉!评论已关闭.