ant的功能非常强大,并且具有非常好的可扩展性,可以直接嵌入脚本(script)来自定义task,并且可以支持多种脚本语言(Javascript ,Apache BSF,Groovy ,Python,beanshell,Ruby,Judoscript等等)
注意要在ant脚本使用这些script语言,必须有相应的jar包支持,参见ant说明手册中 Library Dependencies部分
下面是我用比较熟悉的beanshell脚本实现的一个自定义task。beanshell脚本基本就是java代码,对于熟悉java的人来说非常方便。
注意:
必须将beanshell的相关jar包(如:bsh-core-2.0b4.jar),放到classpath中,我的做法是将jar包复制到$ANT_HOME/lib下
它的功能很简单,task的名字为”propertylist”,有”input”,”reverse”(默认为false),”delimiter”(默认为’,’)三个属性,实现的功能是对于给定的一个以delimiter为分隔符的String,根据reverse(是否反转)的要求,生成一个新的以delimiter的反序String,如: a,b,c 反序为c,b,a
<script language="beanshell">
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
public class PropertyList extends Task {
private java.lang.String property;
private java.lang.String input;
//分隔符默认为','
private java.lang.String delimiter = ",";
//默认不反序,返回原始input值
private boolean reverse = false;
public void execute() throws BuildException {
if(this.reverse){
java.lang.String[] sa = this.input.split(delimiter);
java.lang.StringBuilder sb=new StringBuilder();
int i=sa.length-1;
do{
sb.append(sa[i--]);
if(i>=0)sb.append(this.delimiter);
}while(i>=0);
this.input=sb.toString();
}
System.out.print(this.input);
getProject().setNewProperty(this.property,this.input);
}
public void setDelimiter(java.lang.String d) {
if (d != null) {
delimiter = d;
}
}
public void setInput(java.lang.String input) {
this.input = input;
}
public void setProperty(java.lang.String name) {
this.property = name;
}
public void setReverse(boolean reverse) {
this.reverse = reverse;
}
}
//加入名为propertylist的task定义
project.addTaskDefinition("propertylist", PropertyList.class);
</script>
下面的代码演示了这个自定义脚本的实际用法
<target name="run" depends="clean.tmp" if="database.list" description="根据action参数执行所有数据库操作,action:create,drop">
<echo>开始${action.${action}.description}数据库</echo>
<!--清除必须的共享对象,默认不清除-->
<property name="removeall" value="false"/>
<local name="worklist" />
<!--使用自定义的task,根据${action.reserse}的要求,将${database.list}反序或原值输出-->
<propertylist property="worklist" input="${database.list}" reverse="${action.reserse}" />
<echo>worklist=${worklist}</echo>
<for list="${worklist}" param="server" trim="true">
<sequential>
<echo>数据库: @{server}</echo>
<fail message="没有在${project.config.file}中找到前缀为@{server}的property" unless="@{server}.roles" />
<echo>@{server}的角色${@{server}.roles}</echo>
<antcall target="run.roles">
<param name="roles" value="${@{server}.roles}" />
<param name="server" value="@{server}" />
</antcall>
<antcall target="drop.lastremove">
<param name="server" value="@{server}" />
</antcall>
<antcall target="run.dblinks">
<param name="server" value="@{server}" />
</antcall>
</sequential>
</for>
</target>