想要定义您自己的选择器吗?这很简单!
首先,选择您要定义的选择器类型。有三种类型,每种类型都有一个配方。您很可能想要使用第一个,自定义选择器。
这是 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()
方法。对于健壮的组件(选择器是(项目)组件),测试是必要的。对于测试任务,我们使用 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 为我们提供了用于处理多个选择的方法。
由于“测试用例”或“测试环境”这两个词经常被使用,因此这个特殊的测试环境有了新的名称:bed。床的设置和清理都由 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