ant脚本中用beanshell实现简单的自定义task

时间:2022-04-19 02:22:54

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>