フィルタチェーンとフィルタリーダ

Unix のパイプを見て、とても高い柔軟性を提供しているので、 ファイル 'foo' の最初の 10 行より文字列 blee の入っている行のみをファイル 'bar' にコピーしたいとしましょう。 - すると、次のようにするでしょう。

cat foo|head -n10|grep blee > bar

Ant はそれほど柔軟性が高くはありません。 <copy>タスクで同様の事を行う方法がありません。 <copy>タスクで最初の十行のを得たい場合には、 特別な属性を作成しなければならなかったのです。

<copy file="foo" tofile="bar" head="10" contains="blee"/>

次のような明白な問題が現れます: Antタスクは、無限に続くようなデータ変形属性を適応させることはできないでしょう。 このタスクはこれらの属性が解釈される順番もわからないのです。 即ち、そのタスクは中に含まれる属性を先に実行し、 次に、先頭の属性を実行しなければならないなどということになるのでしょうか。 Ant のタスクに必要なのは、 プラグイン可能なフィルタ(データ変換機能)の連鎖を使えるようにすることです。 Ant は繰り返された要求ある幾つかのフィルタを提供します。 特別なフィルタリングを必要とするユーザは、 簡単に自分のフィルタを書き、プラグインすることができるでしょう。

その解決策はデータ変換指向のタスクがフィルタチェーンをサポートするようにリファクタリングすることです。 フィルタチェーンは順序付けられたフィルタリーダの集合です。 ユーザは自分のフィルタリーダを単に java.io.FilterReader クラスを拡張することにより定義できます。 そのようなカスタムフィルタリーダは <filterreader>要素を用いて、 ネストされた<filterchain>の要素に簡単にプラグインできます。

例:

<copy file="${src.file}" tofile="${dest.file}">
  <filterchain>
    <filterreader classname="your.extension.of.java.io.FilterReader">
      <param name="foo" value="bar"/>
    </filterreader>
    <filterreader classname="another.extension.of.java.io.FilterReader">
      <classpath>
        <pathelement path="${classpath}"/>
      </classpath>
      <param name="blah" value="blee"/>
      <param type="abra" value="cadabra"/>
    </filterreader>
  </filterchain>
</copy>
Ant には幾つかの組み込みのフィルタリーダがあります。 これらのフィルタリーダも 上述の文法と同じ文法を用いて宣言されています。 しかしながら、これは、より簡単な文法を使っても宣言することができます。

例:

<loadfile srcfile="${src.file}" property="${src.file.head}">
  <filterchain>
    <headfilter lines="15"/>
  </filterchain>
</loadfile>
は、次と等価です:
<loadfile srcfile="${src.file}" property="${src.file.head}">
  <filterchain>
    <filterreader classname="org.apache.tools.ant.filters.HeadFilter">
      <param name="lines" value="15"/>
    </filterreader>
  </filterchain>
</loadfile>
次の組み込みタスクはネストされた<filterchain>要素をサポートしています。
Concat,
Copy,
LoadFile,
LoadProperties,
Move

フィルタチェーンは、 ゼロ個以上の次のネストされた要素を定義することにより作られます。
FilterReader
ClassConstants
EscapeUnicode
ExpandProperties
HeadFilter
LineContains
LineContainsRegExp
PrefixLines
ReplaceTokens
StripJavaComments
StripLineBreaks
StripLineComments
TabsToSpaces
TailFilter
DeleteCharacters
ConcatFilter
TokenFilter

フィルタリーダ/FilterReader

filterreader 要素はフィルタを定義する一般的な方法です。 ユーザ定義されたフィルタ要素は この要素を用いてビルドファイル中で定義されます。 組み込みのフィルタリーダもまた、 この文法を用いて定義できることに注意してください。 filterreader 要素は、属性値としてクラス名を与えなければなりません。 この名前により名前解決されたクラスは、 java.io.FilterReader を拡張したものでなければなりません。 カスタムフィルタリーダがパラメーター化されている必要がある場合、 org.apache.tools.type.Parameterizableを実装しなければなりません。
属性 説明 必須
classname フィルタリーダのクラス名 Yes

ネストされた要素:

<filterreader> は、 <classpath> および <param> をネストされた要素としてサポートします。 個々の<param> 要素は次の属性、name、type および value を取ります。

次に示すフィルタリーダはデフォルトの配布で提供されています。

ClassConstants

これは、Java クラスで定義された基本的な定数をフィルタリングし、 名前=値の形式に変換して行に出力します。

例:

これは、Java クラスで定義された基本的な定数を Ant のプロパティとしてロードします。
<loadproperties srcfile="foo.class">
  <filterchain>
    <filterreader classname="org.apache.tools.ant.filters.ClassConstants"/>
  </filterchain>
</loadproperties>
便利な方法は次の通りです:
<loadproperties srcfile="foo.class">
  <filterchain>
    <classconstants/>
  </filterchain>
</loadproperties>

EscapeUnicode

このフィルタは、入力されたすべてのUS-ASCII以外の文字列を同等なUNICODE(\uXXXX:バックスラッシュuと4桁の数字)に変換します。

Ant 1.6から

例:

これは、Antプロパティのように、Javsクラス内で定義された基本的な定数を読込みます。
<loadproperties srcfile="non_ascii_property.properties">
  <filterchain>
    <filterreader classname="org.apache.tools.ant.filters.EscapeUnicode"/>
  </filterchain>
</loadproperties>
便利な方法は次の通りです:
<loadproperties srcfile="non_ascii_property.properties">
  <filterchain>
    <escapeunicode/>
  </filterchain>
</loadproperties>

ExpandProperties

データが Ant の(${...}の形式をした)プロパティを表すデータを含んでいた場合、 それは、そのプロパティの実際の値に置き換えられます。

例:

これは、 プロパティ modifiedmessageの値が "All these moments will be lost in time, like teardrops in the rain" という結果になります。
<echo
  message="All these moments will be lost in time, like teardrops in the ${weather}"
  file="loadfile1.tmp"
  />
<property name="weather" value="rain" />
<loadfile property="modifiedmessage" srcFile="loadfile1.tmp">
  <filterchain>
    <filterreader classname="org.apache.tools.ant.filters.ExpandProperties"/>
  </filterchain>
</loadfile>
便利な方法は次の通りです:
<echo
  message="All these moments will be lost in time, like teardrops in the ${weather}"
  file="loadfile1.tmp"
  />
<property name="weather" value="rain" />
<loadfile property="modifiedmessage" srcFile="loadfile1.tmp">
  <filterchain>
    <expandproperties/>
  </filterchain>
</loadfile>

HeadFilter

このフィルタは与えられたデータから最初の何行かを読み込みます。
パラメータ名 パラメータ値 必須
lines 読み込まれる行数。 デフォルトは "10"
マイナス値は、すべての行がパスされることを意味する。(skipと一緒に使うと役立つ)
No
skip (開始から)何行飛ばされるか。 デフォルトは "0" No

例:

これは、プロパティ${src.file.head}で与えられたデータの最初の 15行を保存します。
<loadfile srcfile="${src.file}" property="${src.file.head}">
  <filterchain>
    <filterreader classname="org.apache.tools.ant.filters.HeadFilter">
      <param name="lines" value="15"/>
    </filterreader>
  </filterchain>
</loadfile>

便利な方法は次の通りです:
<loadfile srcfile="${src.file}" property="${src.file.head}">
  <filterchain>
    <headfilter lines="15"/>
  </filterchain>
</loadfile>

これは、プロパティ${src.file.head}で与えられたデータの最初の最初の2行を飛ばしてから、
15行を保存します。(この意味は : 3行目から17行目)
<loadfile srcfile="${src.file}" property="${src.file.head}">
  <filterchain>
    <headfilter lines="15" skip="2"/>
  </filterchain>
</loadfile>
より多くの例はテストケースを参照してください。 (src\etc\testcases\filters\head-tail.xml 内の配布ソース)

LineContains

このフィルタはユーザが指定した全ての文字列を含む行のみを取り込みます。
パラメータ種類 パラメーター値 必須
contains 検索する部分文字列 Yes

例:

これは、foo および bar を含む行のみを取り込みます。
<filterreader classname="org.apache.tools.ant.filters.LineContains">
  <param type="contains" value="foo"/>
  <param type="contains" value="bar"/>
</filterreader>
便利な方法は次の通りです:
<linecontains>
  <contains value="foo">
  <contains value="bar">
</linecontains>

LineContainsRegExp

ユーザが指定した正規表現にマッチする文字列を含む行のみを取り込むフィルタです。
パラ−メータ種類 パラメータ値 必須
regexp 検索する部分文字列のパターン Yes

例:

パターンfooを含む全ての行を取ってきます。
<filterreader classname="org.apache.tools.ant.filters.LineContainsRegExp">
  <param type="regexp" value="foo*"/>
</filterreader>
便利な方法は次の通りです:
<linecontainsregexp>
  <regexp pattern="foo*">
</linecontainsregexp>

PrefixLines

全ての行に接頭辞をつけます。
パラメータ名 パラメータ値 必須
prefix 行に加えられる接頭辞 Yes

例:

接頭辞Fooを全ての行につけます。
<filterreader classname="org.apache.tools.ant.filters.PrefixLines">
  <param name="prefix" value="Foo"/>
</filterreader>
便利な方法は次の通りです:
<prefixlines prefix="Foo"/>

ReplaceTokens

このフィルタリーダはユーザにより定義された begintoken と endtoken で挟まれた全ての文字列を置換します。
パラメータ種類 パラメータ名 パラメータ値 必須
tokenchar begintoken トークンの始まりを示す文字。 デフォルトは @ No
tokenchar endtoken トークンの終わりを示す文字。 デフォルトは @ No
token ユーザ定義の文字列 ユーザ定義された検索文字列 Yes

例:

これは、データ中で文字列 @DATE@ が出現したら、 本日の日付で置換し、それをプロパティ ${src.file.replaced} に保存します。
<tstamp/>
<loadfile srcfile="${src.file}" property="${src.file.replaced}">
  <filterchain>
    <filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
      <param type="token" name="DATE" value="${TODAY}"/>
    </filterreader>
  </filterchain>
</loadfile>
便利な方法は次の通りです:
<tstamp/>
<loadfile srcfile="${src.file}" property="${src.file.replaced}">
  <filterchain>
    <replacetokens>
      <token key="DATE" value="${TODAY}"/>
    </replacetokens>
  </filterchain>
</loadfile>

StripJavaComments

このフィルタリーダは Java 文法ガイドラインを用いてデータよりコメントを取り除きます。 このフィルタは何もパラメータを取り込みません。

例:

<loadfile srcfile="${java.src.file}" property="${java.src.file.nocomments}">
  <filterchain>
    <filterreader classname="org.apache.tools.ant.filters.StripJavaComments"/>
  </filterchain>
</loadfile>

便利な方法は次の通りです:

<loadfile srcfile="${java.src.file}" property="${java.src.file.nocomments}">
  <filterchain>
    <stripjavacomments/>
  </filterchain>
</loadfile>

StripLineBreaks

このフィルタリーダは与えられたデータから特定の文字を取り除きます。
パラメータ名 パラメータ値 必須
linebreaks 取り除かれる(複数の)文字。 デフォルトは"\r\n" No

例:

これは、'\r' および '\n' の文字を取り除きます
<loadfile srcfile="${src.file}" property="${src.file.contents}">
  <filterchain>
    <filterreader classname="org.apache.tools.ant.filters.StripLineBreaks"/>
  </filterchain>
</loadfile>
便利な方法は次の通りです:
<loadfile srcfile="${src.file}" property="${src.file.contents}">
  <filterchain>
    <striplinebreaks/>
  </filterchain>
</loadfile>
これは、'(' および ')' を改行文字として扱い、取り除きます。
<loadfile srcfile="${src.file}" property="${src.file.contents}">
  <filterchain>
    <filterreader classname="org.apache.tools.ant.filters.StripLineBreaks">
      <param name="linebreaks" value="()"/>
    </filterreader>
  </filterchain>
</loadfile>

StripLineComments

このフィルタは、 ユーザにより指定されたコメントを表す文字列ではじまる行を全て削除します。
パラメータ種類 パラメータ値 必須
comment 行の先頭に現れた場合、その行をコメントと判断する文字列 Yes

例:

#、 --、 REM、 rem および // ではじまる全ての行を削除します。
<filterreader classname="org.apache.tools.ant.filters.StripLineComments">
  <param type="comment" value="#"/>
  <param type="comment" value="--"/>
  <param type="comment" value="REM "/>
  <param type="comment" value="rem "/>
  <param type="comment" value="//"/>
</filterreader>
便利な方法は次の通りです:
<striplinecomments>
  <comment value="#"/>
  <comment value="--"/>
  <comment value="REM "/>
  <comment value="rem "/>
  <comment value="//"/>
</striplinecomments>

TabsToSpaces

このフィルタはタブを空白文字で置換します。
パラメータ名 パラメータ値 必須
lines タブの長さ。デフォルトは"8" No

例:

これは、${src.file} 中のタブを空白文字で置換します。
<loadfile srcfile="${src.file}" property="${src.file.notab}">
  <filterchain>
    <filterreader classname="org.apache.tools.ant.filters.TabsToSpaces"/>
  </filterchain>
</loadfile>
便利な方法は次の通りです:
<loadfile srcfile="${src.file}" property="${src.file.notab}">
  <filterchain>
    <tabstospaces/>
  </filterchain>
</loadfile>

TailFilter

このフィルタは与えられたデータより最後の数行を読み込みます。
パラメータ名 パラメータ値 必須
lines
読み込まれる行数。 デフォルトは "10"
マイナス値は、すべての行がパスされることを意味する。(skipと一緒に使うと役立つ)
No
skip
(最後から)何行飛ばされるか。 デフォルトは "0"
No

背景:

HeadFilterとTailFilterにより、それぞれの求めるテキストファイルの一部を抽出することができます。このグラフィックは依存関係を表します:

コンテンツ フィルタ
1 行目      
 
<filterchain>
    <headfilter lines="2"/>
</filterchain>
 
<filterchain>
    <tailfilter lines="-1" skip="2"/>
</filterchain>
 
<filterchain>
    <headfilter lines="-1" skip="2"/>
</filterchain>
 
<filterchain>
    <headfilter lines="-1" skip="2"/>
    <tailfilter lines="-1" skip="2"/>
</filterchain>
 
<filterchain>
    <tailfilter lines="2"/>
</filterchain>
2 行目
3 行目  
4 行目
5 行目  
... 何行目か
95 行目
96 行目  
97 行目
98 行目  
99 行目

例:

これはプロパティ ${src.file.tail} 中の与えられたデータの終わりの 15 行を保存します。

<loadfile srcfile="${src.file}" property="${src.file.tail}">
  <filterchain>
    <filterreader classname="org.apache.tools.ant.filters.TailFilter">
      <param name="lines" value="15"/>
    </filterreader>
  </filterchain>
</loadfile>
便利な方法は次の通りです:
<loadfile srcfile="${src.file}" property="${src.file.tail}">
  <filterchain>
    <tailfilter lines="15"/>
  </filterchain>
</loadfile>
これはプロパティ ${src.file.mid} 中の与えられたデータの最初の 15 行のうちの、終わりの 5 行を保存します。
<loadfile srcfile="${src.file}" property="${src.file.mid}">
  <filterchain>
    <filterreader classname="org.apache.tools.ant.filters.HeadFilter">
      <param name="lines" value="15"/>
    </filterreader>
    <filterreader classname="org.apache.tools.ant.filters.TailFilter">
      <param name="lines" value="5"/>
    </filterreader>
  </filterchain>
</loadfile>
便利な方法は次の通りです:
<loadfile srcfile="${src.file}" property="${src.file.mid}">
  <filterchain>
    <headfilter lines="15"/>
    <tailfilter lines="5"/>
  </filterchain>
</loadfile>
これは、プロパティ${src.file.head}で与えられたデータの最後の2行を飛ばしてから、
10行を保存します。(この意味は : もし60行のデータが提供されているとき、49行目から58行目が抽出される)
<loadfile srcfile="${src.file}" property="${src.file.head}">
  <filterchain>
    <tailfilter lines="10" skip="2"/>
  </filterchain>
</loadfile>

DeleteCharacters

このフィルタは指定された文字列を削除します。

Ant 1.6から

このフィルタは、 都合のよい形式内でのみ有効です。

パラメータ名 パラメータ値 必須
chars 削除する文字列。この属性はバックスラッシュを有効とする。 Yes

例:

データからタブと改行を削除する。
<deletecharacters chars="\t\r"/>

ConcatFilter

このフィルタは、フィルタで指定したファイルの内容を、先頭または最後尾に追加します。

Ant 1.6から

パラメータ名 パラメータ値 必須
prepend 先頭にファイルの内容を追加する、ファイルの名前 No
append 最後尾にファイルの内容を追加する、ファイルの名前 No

例:

何もしない:
<filterchain>
    <concatfilter/>
</filterchain>
それぞれのjavaソースファイルの前にライセンステキストを追加する。
<filterchain>
    <concatfilter prepend="apache-license-java.txt"/>
</filterchain>

TokenFilter

このフィルタは文字列へ入力ストリームを分割して、これらの文字列を文字列フィルタに渡します。他のフィルタリーダと違って、これはパラメータをサポートせず、 唯一便利なメソッドは実装されています。トークナイザと文字列フィルタは、ネストされた要素によって定義されています。

Ant 1.6から

ひとつだけのトークナイザ要素だけが使われて、もし、何も指定されていなかったら、LineTokenizerはデフォルトになります。トークナイザは、トークン文字列への入力を分割し、区切り文字列に沿って追います。

ゼロ以上の文字列フィルタがあります。 文字列フィルタはトークンを加工し、文字列かnullを返します。 文字列がnullで無いならば、次のフィルタに通ります。 これはすべてのフィルタが呼ばれるまで続きます。 すべてのフィルタの後に文字列が返されたら、文字列はトークン区切り文字(もしひとつあれば)と関連した出力になります。 後に続く区切り文字は、delimOutput属性によって上書きされるかもしれません。

バックスラッシュの解釈 多くの属性(delimOutputを含む)は、バックスラッシュエスケープを解釈します。 以下の\n、\r、\f、\t、\\は理解されます。
属性 説明 必須
delimOutput 空でなければ、トークナイザによって返されたトークン区切り文字を上書きします。この属性はバックスラッシュを有効にします。 No

以下のトークナイザは、デフォルトディストリビュージョンによって提供されます。

LineTokenizer
FileTokenizer
StringTokenizer

以下の文字列フィルタは、デフォルトディストリビュージョンによって提供されます。

ReplaceString
ContainsString
ReplaceRegex
ContainsRegex
Trim
IgnoreBlank
DeleteCharacters

以下の文字列フィルタは、拡張ディストリビュージョンによって提供されます。

ScriptFilter

いくつかのフィルタは、直接フィルタチェーン内で使われます。 この場合、トークンフィルタは自動的に使われます。特別な属性である"byline"は、linetokenizer (byline="true")を使っても、filetokenizer(byline="false")を使っても、指定するフィルタに追加されます。デフォルトは"true"

LineTokenizer このトークナイザは行で分割します。トークナイザは、"\r"または"\n"または"\r\n"によって分割します。これはデフォルトのトークナイザです。
属性 説明 必須
includeDelims 行の最後をトークン区切りとして含む。 デフォルトは false No

例:

入力された現在の行の最後尾をUnixスタイルの行の最後尾(改行コード)に変更する。
<tokenfilter delimoutput="\n"/>
空行を削除します。
<tokenfilter>
    <ignoreblank/>
</tokenfilter>

FileTokenizer

このトークナイザはすべての入力をトークンのように扱います。ですから、大きい入力値を使わないように注意してください。

例:

最初に出現するpackageを//packageに置き換える。
<tokenfilter>
      <filetokenizer/>
      <replaceregex pattern="([\n\r]+[ \t]*|^[ \t]*)package"
                    flags="s"
                    replace="\1//package"/>
</tokenfilter>

StringTokenizer

このトークナイザは、java.util.StringTokenizerに基づいています。空白で区切られた文字列か、区切り文字列のリストで指定された文字列によって入力を分割します。 ストリームが区切り文字列から始められれば、最初のトークンは空文字になります。 (delimsaretokens属性が使われることがない限り)
属性 説明 必須
delims 区切り文字。設定されなければ空白が使われます。(このケースでは、空白はjava.lang.Character.isWhitespace()によって定義されている) No
delimsaretokens trueならば、それぞれの区切り文字はトークンとして返す。デフォルトはfalse No
suppressdelims trueならは、区切り文字は返されない。デフォルトはfalse No
includeDelims トークン内の区切り文字を含む。デフォルトはfalse
No

例:

それぞれのスペース無しトークンを"[ ]"で囲みます。
<tokenfilter>
    <stringtokenizer/>
    <replaceregex pattern="(.+)" replace="[\1]"/>
</tokenfilter>

ReplaceString

これは文字列を置換するためのシンプルなフィルタです。 このフィルタは、直接フィルタチェーン内で使うことができます。
属性 説明 必須
from 置き換えられるべき文字列 Yes
to 置き換えられる文字のための新しい値。空文字の時には省略されます。 No

例:

"sun"を"moon"に置換
<tokenfilter>
    <replacestring from="sun" to="moon"/>
</tokenfilter>

ContainsString

これは、指定された文字列を含むフィルタトークンのためのシンプルなフィルタです。
属性 説明 必須
contains トークンが含むべき文字列 Yes

例:

"foo"を含む行だけ入る;
<tokenfilter>
    <containsstring contains="foo"/>
</tokenfilter>

ReplaceRegex

このフィルタ文字列は、正規表現を置換します。正規表現上の説明である、ReplaceRegexpを参照してください。このフィルタは、直接フィルタチェーン内で使うことができます。

属性 説明 必須
pattern トークン内でマッチするための正規表現パターン。 Yes
replace 置換するための正規表現にマッチする置換パターン。省略するときは空の文字列を使う。 No
flags 正規フラグの説明のためにReplaceRegexpを参照してください。 No

例:

大文字小文字を区別せずに、出現するすべての"hello"を"world"に置換します。
<tokenfilter>
    <replaceregex pattern="hello" replace="world" flags="gi"/>
</tokenfilter>

ContainsRegex

このフィルタ文字列は、正規表現にマッチします。そのフィルタは、マッチした正規表現の状況に応じて置換することができます。正規表現上の説明である、ReplaceRegexpを参照してください。 このフィルタは、直接フィルタチェーン内で使うことができます。
属性 説明 必須
pattern トークン内でマッチするための正規表現パターン。 Yes
replace 置換するための正規表現にマッチする置換パターン。省略したときは、元のトークンが返される。 No
flags 正規フラグの説明のためにReplaceRegexpを参照してください。 No

例:

大文字小文字を区別せずに、"hello"又は"world"が含まれている行をフィルタします。
<tokenfilter>
    <containsregex pattern="(hello|world)" flags="i"/>
</tokenfilter>

この例は、"SUITE(TestSuite, bits);"が含まれる行を"void register_bits();"に置換して、他の行を削除します。
<tokenfilter>
    <containsregex
        pattern="^ *SUITE\(.*,\s*(.*)\s*\).*"
        replace="void register_\1();"/>
</tokenfilter>

Trim

このフィルタは、トークンの最初と最後から空白を取り除きます。 このフィルタはフィルタチェーン内で直接使うことができます。

IgnoreBlank

このフィルタは空のトークンを削除します。このフィルタはフィルタチェーン内で直接使うことができます。

DeleteCharacters

このフィルタはトークンから指定された文字列を削除します。
属性 説明 必須
chars 削除する文字列。この属性はバックスラッシュが有効です。 Yes

例:

行からタブを削除し、行を整理し、空の行を削除する。
<tokenfilter>
    <deletecharacters chars="\t"/>
    <trim/>
    <ignoreblank/>
</tokenfilter>

ScriptFilter

これは、Apache BSFでサポートされた言語内でスクリプトを実行する拡張フィルタです。スクリプトと依存関係の説明に関してScriptタスクを参照して下さい。

このスクリプトは、 オブジェクト自身がgetToken()メソッドとsetToken(String)メソッドを用意します。
getToken()メソッドは現在のトークンを返し、setToken(String)メソッドは現在のトークンを置き換えます。

このフィルタはフィルタチェーン内で直接使うことができます。

属性 説明 必須
language スクリプトが書かれているプログラミング言語。Apache BSF言語でサポートされているに違いない。 Yes
src インラインでないなら、ファイルとしてスクリプトの場所を指し示します。 No

例:

大文字に変換:
<tokenfilter>
    <scriptfilter language="javascript">
        self.setToken(self.getToken().toUpperCase());
    </scriptfilter>
</tokenfilter>
Remove lines containing the string "bad" while copying text files:
<copy todir="dist">
  <fileset dir="src" includes="**/*.txt"/>
  <scriptfilter language="beanshell">
      if (self.getToken().indexOf("bad") != -1) {
          self.setToken(null);
      }
  </scriptfilter>
</copy>
    

カスタムのトークナイザと文字列フィルタ

カスタムの文字列フィルタとトークナイザは、org.apache.tools.ant.filters.TokenFilter.Filterインタフェースとorg.apache.tools.ant.util.Tokenizerインタフェースを拡張することによって、プラグインすることができます。これらは、<typedef/>を使ってビルドファイルにて定義されます。例えば、先頭文字を大文字にする文字列フィルタは以下のように表すことができるでしょう:
package my.customant;
import org.apache.tools.ant.filters.TokenFilter;

public class Capitalize
    implements TokenFilter.Filter
{
    public String filter(String token) {
        if (token.length() == 0)
            return token;
        return token.substring(0, 1).toUpperCase() +
                token.substring(1);
   }
}
これは以下のように使うことができます。:
  <typedef type="capitalize" classname="my.customant.Capitalize"
           classpath="my.customant.path"/>
  <copy file="input" tofile="output">
    <filterchain>
      <tokenfilter>
        <stringtokenizer/>
        <capitalize/>
      </tokenfilter>
    </filterchain>
  </copy>

Copyright © 2002-2004 The Apache Software Foundation. All rights Reserved.

[訳注:これは漆島賢二の訳を参考に、横田 聡が翻訳しました。日本語訳に対するコメントがあれば report@jajakarta.orgに送ってください]