想要定義您自己的選擇器嗎?這很容易!
首先,選擇您想要定義的選擇器類型。有三種類型,以下是每種類型的範例。您可能會想要使用第一種,自訂選擇器。
這是 Apache Ant 專門為您提供的類別,用於定義您自己的選擇器。在任何您想要使用選擇器的地方,您都使用 <custom>
元素,並在其中指定選擇器的類別名稱。有關詳細資訊,請參閱選擇器頁面的 自訂選擇器 區段。<custom>
元素可以在核心選擇器可使用的任何地方使用。例如,它可以包含在 選擇器容器 中。
若要建立新的自訂選擇器,您必須建立一個實作 org.apache.tools.ant.types.selectors.ExtendFileSelector
的類別。最簡單的方法是透過方便的基底類別 org.apache.tools.ant.types.selectors.BaseExtendSelector
,它提供支援 <param>
標籤的所有方法。首先,覆寫 isSelected()
方法,以及 verifySettings()
方法(這是選用的)。如果您的自訂選擇器需要設定參數,您也可以覆寫 setParameters()
方法,並以您喜歡的方式詮釋傳入的參數。許多核心選擇器示範如何執行此操作,因為它們也可以用作自訂選擇器。
這些是 Ant 本身使用的選擇器。若要實作其中一個,您必須變更 Ant 中包含的一些類別。
首先,建立一個實作 org.apache.tools.ant.types.selectors.FileSelector
的類別。您可以選擇從頭開始自己實作所有方法,或者您可以延伸 org.apache.tools.ant.types.selectors.BaseSelector
,它是一個方便的類別,可為許多方法提供合理的預設行為。
只有一個方法是必要的。public boolean isSelected(File basedir, String filename, File file)
是整個練習的真正目的。它會傳回 true
或 false
,具體取決於是否應該從清單中選取指定的檔案。
如果您正在使用 org.apache.tools.ant.types.selectors.BaseSelector
,還有一些預先定義的行為您可以利用。當您在設定屬性或新增標籤時遇到任何問題時,您可以呼叫 setError(String errmsg)
,類別就會知道有問題。然後,在您的 isSelected()
方法的頂端呼叫 validate()
,並會擲回一個 BuildException
,其中包含錯誤訊息的內容。<validate()>
方法也會給您最後一次機會檢查您的設定是否一致,因為它會呼叫 verifySettings()
。覆寫此方法,並在其中呼叫 setError()
,如果您偵測到您的選擇器設定有任何問題。
您可能還想覆寫 toString()
。
org.apache.tools.ant.types.selectors.SelectorContainer
中為您的選擇器放置一個 add()
方法。這是一個介面,因此您還必須在實作它的類別中為方法新增一個實作,也就是 org.apache.tools.ant.types.AbstractFileSet
、org.apache.tools.ant.taskdefs.MatchingTask
和 org.apache.tools.ant.types.selectors.BaseSelectorContainer
。一旦它在那裡,它將在核心選擇器適用的任何地方都可用。有新選擇器容器的想法嗎?建立一個新的容器沒有問題
org.apache.tools.ant.types.selectors.SelectorContainer
的新類別。這將確保您的新容器可以存取任何隨附的新選擇器。同樣地,有一個可供您使用的便利類別,稱為 org.apache.tools.ant.types.selectors.BaseSelectorContainer
。public boolean isSelected(String filename, File file)
方法來執行正確的動作。您很有可能會想要反覆處理您底下的選擇器,因此請使用 selectorElements()
來取得將執行的反覆處理器。org.apache.tools.ant.types.selectors.SelectorContainer
及其實作 org.apache.tools.ant.types.AbstractFileSet
和 org.apache.tools.ant.types.selectors.BaseSelectorContainer
中為您的容器放置一個 add()
方法。對於強健的元件(而選擇器是 (Project) 元件),測試是必要的。對於測試任務,我們使用 JUnit 測試和規則,更具體地說,org.apache.tools.ant.BuildFileRule extends org.junit.rules.ExternalResource
。它的某些功能(例如透過讀取其建置檔和執行目標來設定(測試)專案)我們也需要用於選擇器測試。因此,我們使用該 BuildFileRule。但測試選擇器需要更多工作:擁有一組檔案、實例化和設定選擇器、檢查選擇工作等等。由於我們通常會延伸 BaseExtendSelector
,因此其功能也必須測試(例如 setError()
)。
這就是為什麼我們有一個測試規則來執行我們的選擇器測試:org.apache.tools.ant.types.selectors.BaseSelectorRule
。
此類別擴充了 ExternalResource,因此可以包含在 Ant 的單元測試中。它包含一個預先設定的 BuildFileRule 實例。設定是透過剖析 src/etc/testcases/types/selectors.xml 來完成的。BaseSelectorRule 接著提供我們處理多重選取的輔助方法。
由於「測試案例」或「測試環境」這兩個詞彙經常被使用,因此這個特殊的測試環境取得了一個新名稱:床。床的設定和清除都由 BaseSelectorRule 處理,因此任何測試只需要處理實際的測試情境即可
一般的測試情境為
範例測試如下
package org.apache.tools.ant.types.selectors; public class MySelectorTest { @Rule public final BaseSelectorRule selectorRule = new BaseSelectorRule(); @Test public void testCase1() { // Configure the selector MySelector s = new MySelector(); s.addParam("key1", "value1"); s.addParam("key2", "value2"); s.setXX(true); s.setYY("a value"); // do the tests assertEquals("FTTTTTTTT", selectorRule.selectionString(s)); } }
作為 JUnit 可能記錄的錯誤範例
[junit] FAILED [junit] Error for files: .;copy.filterset.filtered;tar/gz/asf-logo.gif.tar.gz [junit] expected:<FTTTFTTTF...> but was:<TTTTTTTTT...> [junit] junit.framework.ComparisonFailure: Error for files: .;copy.filterset.filtered;tar/gz/asf-logo.gif.tar.gz [junit] expected:<FTTTFTTTF...> but was:<TTTTTTTTT...> [junit] at junit.framework.Assert.assertEquals(Assert.java:81) [junit] at org.apache.tools.ant.types.selectors.BaseSelectorTest.performTest(BaseSelectorTest.java:194)
如上所述,測試類別應該提供一個 getInstance()
方法。但這裡並未使用該方法。所使用的 getSelector()
方法是在基礎類別中實作,並提供一個 Ant 專案的實例給選取器。這通常在一般的建置檔案執行期間完成,但不在這個特殊的環境中,因此這個方法讓選取器能夠使用它自己的專案物件(getProject()
),例如用於記錄。
在開發期間,甚至之後,有時您需要資訊輸出。因此需要記錄。由於選取器擴充了 BaseExtendSelector 或直接擴充了 BaseSelector,因此它是一個 Ant DataType
,也就是一個 ProjectComponent
。
這表示您可以存取專案物件及其記錄功能。 ProjectComponent
本身提供了 log()
方法,這些方法將存取專案實例。因此,記錄只需透過以下方式執行
log("message");
或
log("message", loglevel);
其中 loglevel
是下列值之一
org.apache.tools.ant.Project.MSG_ERR
org.apache.tools.ant.Project.MSG_WARN
org.apache.tools.ant.Project.MSG_INFO
(預設)org.apache.tools.ant.Project.MSG_VERBOSE
org.apache.tools.ant.Project.MSG_DEBUG