码迷,mamicode.com
首页 > 其他好文 > 详细

ant使用总结(四):自定义库

时间:2015-05-19 19:10:55      阅读:417      评论:0      收藏:0      [点我收藏+]

标签:ant   扩展   自定义库   

自定义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;

// 用于过滤出所有指定后缀的文件的Selector
public 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中通过定义addXXX方法,获取子标签。

示例代码:

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;

// 统计文件个数并把值赋给指定的property
public class TotalFile extends Task {

    private List<FileSet> files = new ArrayList<FileSet>();
    private String name;

    // setter,设置属性名
    public void setName(String name){
        this.name = name;
    }

    // 在java中通过addXXX方法获取子标签
    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文档。

ant使用总结(四):自定义库

标签:ant   扩展   自定义库   

原文地址:http://blog.csdn.net/linchaolong/article/details/45846917

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!