Antlib

說明

Antlib 檔案是一個 XML 檔案,其根元素為 antlib。Antlib 的元素為 Apache Ant 定義的任務,例如 Taskdef 或任何延伸 org.apache.tools.ant.taskdefs.AntlibDefinition 的 Ant 任務。

與 Ant 捆綁在一起並執行此功能的目前宣告如下

  1. Typedef
  2. Taskdef
  3. Macrodef
  4. Presetdef
  5. Scriptdef

一組任務和類型可以一起在 antlib 檔案中定義。例如,檔案 sample.xml 包含下列內容

<?xml version="1.0"?>
<antlib>
    <typedef name="if" classname="org.acme.ant.If"/>
    <typedef name="scriptpathmapper"
             classname="org.acme.ant.ScriptPathMapper"
             onerror="ignore"/>
    <macrodef name="print">
        <attribute name="file"/>
        <sequential>
            <concat taskname="print">
                <fileset dir="." includes="@{file}"/>
            </concat>
        </sequential>
    </macrodef>
</antlib>

它定義了兩個類型或任務,ifscriptpathmapper。此 antlib 檔案可以在建置指令碼中如下使用

<typedef file="sample.xml"/>

<typedef> 的其他屬性也可以使用。例如,假設 sample.xml 在 jar 檔案 sample.jar 中,其中也包含類別,下列建置片段將定義 ifscriptpathmapper 任務/類型,並將它們置於名稱空間 URI samples:/acme.org 中。

<typedef resource="org/acme/ant/sample.xml"
         uri="samples:/acme.org"/>

然後可以如下使用宣告

<sample:if valuetrue="${props}" xmlns:sample="samples:/acme.org">
    <sample:scriptpathmapper language="beanshell">
        some bean shell
    </sample:scriptpathmapper>
</sample:if>

Antlib 名稱空間

具有模式 antlib:java.package 的名稱空間 URI 會獲得特殊處理。

當 Ant 遇到具有此模式的名稱空間 URI 的元素時,它會檢查預設類別路徑中套件目錄中是否有名稱為 antlib.xml 的資源。

例如,假設檔案 antcontrib.jar 已置於目錄 ${ant.home}/lib 中,且它包含已定義所有 antcontrib 宣告的資源 net/sf/antcontrib/antlib.xml,下列建置檔案會自動在位置 HERE 載入 antcontrib 宣告

<project default="deletetest" xmlns:antcontrib="antlib:net.sf.antcontrib">
    <macrodef name="showdir">
        <attribute name="dir"/>
        <sequential>
            <antcontrib:shellscript shell="bash">  <!-- HERE -->
                ls -Rl @{dir}
            </antcontrib:shellscript>
        </sequential>
    </macrodef>

    <target name="deletetest">
        <delete dir="a" quiet="yes"/>
        <mkdir dir="a/b"/>
        <touch file="a/a.txt"/>
        <touch file="a/b/b.txt"/>
        <delete>
            <fileset dir="a"/>
        </delete>
        <showdir dir="a"/>
    </target>
</project>

在未來版本的 Ant 中可能會移除資源在預設類別路徑中的需求。

從建置檔案內部載入 antlib

如果您想要將 antlib 與您的本機 Ant 安裝分開,例如因為您想要將該 jar 保存在專案的 SCM 系統中,您必須指定一個類別路徑,以便 Ant 可以找到該 jar。最佳的解決方案是使用 <taskdef> 載入 antlib。

<project xmlns:antcontrib="antlib:net.sf.antcontrib">
    <taskdef uri="antlib:net.sf.antcontrib"
             resource="net/sf/antcontrib/antlib.xml"
             classpath="path/to/ant-contrib.jar"/>

    <target name="iterate">
        <antcontrib:for param="file">
            <fileset dir="."/>
            <sequential>
                <echo message="- @{file}"/>
            </sequential>
        </antcontrib:for>
    </target>
</project>

目前的名稱空間

在 antlib 中定義的宣告可以在 antlib 中使用。但是,宣告被置入的名稱空間會取決於使用 antlib 的 <typedef>。為了處理這個問題,宣告會在 antlib 執行期間置於名稱空間 URI ant:current 中。例如,下列 antlib 定義了任務 <if>、類型 <isallowed> 和使用任務和類型的巨集 <ifallowed>

<antlib xmlns:current="ant:current">
    <taskdef name="if" classname="org.acme.ant.If"/>
    <typedef name="isallowed" classname="org.acme.ant.Isallowed"/>
    <macrodef name="ifallowed">
        <attribute name="action"/>
        <element name="do"/>
        <sequential>
            <current:if>
                <current:isallowed test="@{action}"/>
                <current:then>
                    <do/>
                </current:then>
            </current:if>
        </sequential>
    </macrodef>
</antlib>

其他範例和註解

Antlib 可以使用其他 antlib。

由於 antlib 中定義的名稱在由呼叫的 <typedef> 或自動元素解析所指定的 URI 中,因此只要呼叫者使用名稱空間 URI,就可以重複使用核心 Ant 類型和任務的名稱。例如,下列 antlib 可以用來定義各種任務的預設值

<antlib xmlns:antcontrib="antlib:net.sf.antcontrib">
    <presetdef name="javac">
        <javac deprecation="${deprecation}"
               debug="${debug}"/>
    </presetdef>
    <presetdef name="delete">
        <delete quiet="yes"/>
    </presetdef>
    <presetdef name="shellscript">
        <antcontrib:shellscript shell="bash"/>
    </presetdef>
</antlib>

這可以用在下列

<project xmlns:local="localpresets">
    <typedef file="localpresets.xml" uri="localpresets"/>
    <local:shellscript>
        echo "hello world"
    </local:shellscript>
</project>