ant使用总结(四):扩展ant库

来源:互联网 发布:云端软件平台 替代 编辑:程序博客网 时间:2024/05/21 16:25

自定义Condition

编写自定义的condition,可以实现自定义的条件判断逻辑,需要实现org.apache.tools.ant.taskdefs.condition.Condition接口,只有一个必须实现的方法就是eval,用于返回条件判断结果。

比如:实现一个用于判断一个字符串是否全部大写的Condition。
步骤:
1.新建Java工程

2.引入ant库
ant相关的jar就在apache-ant-1.9.4\lib目录下。在Java工程中新建一个libs目录,把jar包都拷贝到libs下,选中所有jar,右键Build Path——Add To Build Path,就完成了ant库的引入。

3.自定义Condition条件判断类

package linchaolong.ant.condition;import org.apache.tools.ant.BuildException;import org.apache.tools.ant.taskdefs.condition.Condition;// 用于判断字符串是否全部是大写public class UppoerCondition implements Condition{    private String value;    // 定义一个setter方法,用于设置value的值     public void setValue(String value){        this.value = value;    }    //Is this condition true?,条件是否成立的判定方法    @Override    public boolean eval() throws BuildException {        // 如果未设置value属性,抛出异常        if (value == null) {            throw new BuildException("value attribute  is not set");        }        // 判断字符串是否大写        return value.toUpperCase().equals(value);    }}

4.使用自定义类

<project name="test" default="run">    <target name="run">        <!-- 自定义类型 -->        <typedef            name="isupper"            classname="linchaolong.ant.condition.UppoerCondition"            classpath="./../bin"/><!-- 我这里把工程bin目录添加到类路径 -->        <!-- 在condition中使用自定义标签 -->        <condition property="isUpper">            <isupper value="THIS IS ALL UPPER CASE"/> <!-- 如果条件成立,则定义isUpper属性,而值为true -->        </condition>        <!-- 打印属性值 -->        <echo>result : ${isUpper}</echo>        <antcall target="result" />    </target>    <target name="result" if="${isUpper}">        <echo>is all uppper</echo>    </target></project>

打印结果:
打印结果

自定义选择器

FilenameSelector

通过自定义选择器可以实现自定义的文件过滤规则。需要继承org.apache.tools.ant.types.selectors.FilenameSelector,并重写isSelected方法。

示例:

package linchaolong.ant.selector;import java.io.File;import org.apache.tools.ant.BuildException;import org.apache.tools.ant.types.selectors.FilenameSelector;// 用于过滤出所有指定后缀的文件的Selectorpublic class EndWithSelector extends FilenameSelector {    private String endWith;    // setter    public void setEndWith(String endWith) {        this.endWith = endWith;    }    @Override    public boolean isSelected(File dir, String filename, File file) {        // 如果未设置endWith属性则抛出异常         if (endWith == null) {            throw new BuildException("endWith is not set.");        }        return filename.toLowerCase().endsWith(endWith.toLowerCase().trim());    }}

使用示例:

<project name="test" default="run">    <target name="run">        <!-- 自定义类型 -->        <typedef            name="endwithSelector"            classname="linchaolong.ant.selector.EndWithSelector"            classpath="./../bin"/><!-- 我这里把工程bin目录添加到类路径 -->        <!-- 把上层目录下所有.class文件拷贝到to目录下 -->        <copy todir="to">           <fileset dir="./../">              <endwithSelector endWith=".class"/>           </fileset>        </copy>    </target></project>

BaseSelectorContainer

BaseSelectorContainer是一个选择器容器,在过滤文件的时候可能需要多个判断条件,这时就需要用到选择器容器了。
BaseSelectorContainereva中有一个vlidate方法,当调用vlidate方法时会调用verifySettings方法,主要用于检查配置是否正确。可以通过定义verifySettings方法检查配置。

示例代码

package linchaolong.ant.selector;import java.io.File;import java.util.Enumeration;import org.apache.tools.ant.BuildException;import org.apache.tools.ant.types.selectors.BaseSelectorContainer;import org.apache.tools.ant.types.selectors.FileSelector;// 用于过滤出满足指定数量条件的文件的选择器容器public class MatchCountSelectors extends BaseSelectorContainer {    private int count = -1;    private String when;    public static final String MORE = "more";    public static final String LESS = "less";    public static final String EQUAL = "equal";    // setter    public void setCount(int count) {        this.count = count;    }    // setter    public void setWhen(String when){        this.when = when;    }    // 校验配置是否正确        public void verifySettings() {        if (count < 0) {            // 如果配置不正确抛出异常           throw new BuildException("count attribute should be set");        }        if(when == null){            throw new BuildException("when attribute should be set");        }    }    // 从选择的文件中选择指定数量的文件    public boolean isSelected(File baseDir, String filename, File file) {        // 调用validate方法检查配置是否正确        validate();        // 迭代所有容器的选择器列表,计算当前文件满足的条件个数        int countSelected = 0;        for (Enumeration e = selectorElements(); e.hasMoreElements();) {            FileSelector s = (FileSelector) e.nextElement();            if (s.isSelected(baseDir, filename, file)) {                countSelected++;            }        }        // 判断是否满足指定数量的条件        if(MORE.equalsIgnoreCase(when)){            return countSelected > count;           }else if(EQUAL.equalsIgnoreCase(when)){            return countSelected == count;        }        else if(LESS.equalsIgnoreCase(when)){            return countSelected < count;        }else{            throw new BuildException("when value is not defined");        }    }}

使用示例

<project name="test" default="run">    <target name="run">        <!-- 自定义类型 -->        <typedef            name="matchCountSelectors"            classname="linchaolong.ant.selector.MatchCountSelectors"            classpath="./../bin"/><!-- 我这里把工程bin目录添加到类路径 -->        <copy todir="to">            <!-- 找出在上层目录下满足以下条件其中2个的所有文件 -->           <fileset dir="./../">               <matchCountSelectors count="2" when="more">                   <!-- 文件中包含selector的文件,忽略大小写 -->                  <contains text="selector" casesensitive="no"/>                  <!-- 小于4KB -->                  <size value="4" units="Ki" when="less"/>                  <!-- 类型为文件,dir表示目录 -->                  <type type="file"/>                  <!-- 可读 -->                  <readable />                  <!-- 在2001年1月1日12点后创建的文件 -->                   <date datetime="01/01/2001 12:00 AM" when="after"/>               </matchCountSelectors>           </fileset>        </copy>    </target></project>

>>点击查看更多选择器

自定义Task

有时ant提供的功能可能不足以满足需求时,我们可以通过继承org.apache.tools.ant.Task编写自己需要的功能,实现public void execute()方法,在execute()方法编写需要执行代码。

在java中通过定义add(Type obj )方法,获取子标签。

示例代码:

package linchaolong.ant.task;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import org.apache.tools.ant.BuildException;import org.apache.tools.ant.Task;import org.apache.tools.ant.types.FileSet;import org.apache.tools.ant.types.Resource;// 统计文件个数并把值赋给指定的propertypublic class TotalFile extends Task {    private List<FileSet> files = new ArrayList<FileSet>();    private String name;    // setter,设置属性名    public void setName(String name){        this.name = name;    }    // 在java中通过add(Type obj)方法获取子标签    public void add(FileSet fs) {        files.add(fs);    }    // 检查配置     public void validitySetting(){        if (name == null || name.isEmpty()) {            throw new BuildException("attribute name is empty");        }    }    @Override    public void execute() throws BuildException {        super.execute();        // 检查配置         validitySetting();        int total = 0;        // 统计文件个数        for (FileSet fs : files) {            Iterator<Resource> it = fs.iterator();            while(it.hasNext()){                it.next();                ++total;            }        }        // 设置属性值        getProject().setProperty(name, Integer.toString(total));    }}

使用示例:

<project name="test" default="run">    <target name="run">        <!-- 自定义类型 -->        <typedef name="totalFile" classname="linchaolong.ant.task.TotalFile"            classpath="./../bin" /><!-- 我这里把工程bin目录添加到类路径 -->        <!-- 统计文件个数 -->        <totalFile name="total" >            <fileset dir="./">                    <!-- 文件中包含selector的文件,忽略大小写 -->                    <contains text="selector" casesensitive="no" />                    <!-- 小于4KB -->                    <size value="4" units="Ki" when="less" />            </fileset>            <fileset dir="./../libs">                    <!-- 类型为文件,dir表示目录 -->                    <type type="file" />                    <!-- 可读 -->                    <readable />                    <!-- 在2001年1月1日12点后创建的文件 -->                    <date datetime="01/01/2001 12:00 AM" when="after" />            </fileset>        </totalFile>        <!-- 打印结果 -->        <echo>total = ${total}</echo>    </target></project>

运行结果:
运行结果

导出和使用自定义库

一般我们都会把所有class文件打成一个jar,供外部调用。
1.配置关联
比如这里在工程根目录新建了一个tags.cfg文件,内容如下:

#key为tag的名称,value为类的全路径名#判断字符串是否全部大写isupper = linchaolong.ant.condition.UpperCondition#过滤出满足指定条件数量的文件matchCountSelectors = linchaolong.ant.selector.MatchCountSelectors#过滤出指定后缀的文件endwithSelector = linchaolong.ant.selector.EndWithSelector#统计文件数量totalFile = linchaolong.ant.task.TotalFile

2.导出jar
选中项目,右键——export——Java——JAR file,选中src目录和配置文件tags.cfg,设置好导出路径,点击finish就ok了。
这里写图片描述

3.使用自定义库
一般在文件开头的地方先加载扩展库。

    <!-- 使用自定义库 -->    <typedef resource="tags.cfg"> <!-- 解析tags.cfg并建立关联 -->        <classpath>            <pathelement location="./linchaolong_ant.jar" /> <!-- jar文件路径 -->        </classpath>    </typedef>

项目地址:https://coding.net/u/linchaolong/p/AntCustomLibrary/git

相关文档

http://ant.apache.org/manual/Types/custom-programming.html
http://ant.apache.org/manual/develop.html#writingowntask
打开apache-ant-1.9.4/manual/index.html可以查看ant文档,点击左边的Ant API查看API文档。

0 0
原创粉丝点击