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>要素をサポートしています。| 属性 | 説明 | 必須 |
| classname | フィルタリーダのクラス名 | Yes |
次に示すフィルタリーダはデフォルトの配布で提供されています。
これは、Java クラスで定義された基本的な定数をフィルタリングし、 名前=値の形式に変換して行に出力します。
<loadproperties srcfile="foo.class">
<filterchain>
<filterreader classname="org.apache.tools.ant.filters.ClassConstants"/>
</filterchain>
</loadproperties>
便利な方法は次の通りです:
<loadproperties srcfile="foo.class">
<filterchain>
<classconstants/>
</filterchain>
</loadproperties>
このフィルタは、入力されたすべてのUS-ASCII以外の文字列を同等なUNICODE(\uXXXX:バックスラッシュuと4桁の数字)に変換します。
Ant 1.6から
<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>
データが Ant の(${...}の形式をした)プロパティを表すデータを含んでいた場合、 それは、そのプロパティの実際の値に置き換えられます。
<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>
| パラメータ名 | パラメータ値 | 必須 |
| lines | 読み込まれる行数。 デフォルトは "10" マイナス値は、すべての行がパスされることを意味する。(skipと一緒に使うと役立つ) |
No |
| skip | (開始から)何行飛ばされるか。 デフォルトは "0" | No |
<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 内の配布ソース)
| パラメータ種類 | パラメーター値 | 必須 |
| 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>
| パラ−メータ種類 | パラメータ値 | 必須 |
| regexp | 検索する部分文字列のパターン | Yes |
fooを含む全ての行を取ってきます。
便利な方法は次の通りです:<filterreader classname="org.apache.tools.ant.filters.LineContainsRegExp"> <param type="regexp" value="foo*"/> </filterreader>
<linecontainsregexp> <regexp pattern="foo*"> </linecontainsregexp>
| パラメータ名 | パラメータ値 | 必須 |
| prefix | 行に加えられる接頭辞 | Yes |
Fooを全ての行につけます。
便利な方法は次の通りです:<filterreader classname="org.apache.tools.ant.filters.PrefixLines"> <param name="prefix" value="Foo"/> </filterreader>
<prefixlines prefix="Foo"/>
| パラメータ種類 | パラメータ名 | パラメータ値 | 必須 |
| tokenchar | begintoken | トークンの始まりを示す文字。 デフォルトは @ | No |
| tokenchar | endtoken | トークンの終わりを示す文字。 デフォルトは @ | No |
| token | ユーザ定義の文字列 | ユーザ定義された検索文字列 | Yes |
<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>
<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>
| パラメータ名 | パラメータ値 | 必須 |
| linebreaks | 取り除かれる(複数の)文字。 デフォルトは"\r\n" | No |
<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>
| パラメータ種類 | パラメータ値 | 必須 |
| comment | 行の先頭に現れた場合、その行をコメントと判断する文字列 | Yes |
便利な方法は次の通りです:<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>
| パラメータ名 | パラメータ値 | 必須 |
| lines | タブの長さ。デフォルトは"8" | No |
<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>
| パラメータ名 | パラメータ値 | 必須 |
| lines | 読み込まれる行数。 デフォルトは "10" マイナス値は、すべての行がパスされることを意味する。(skipと一緒に使うと役立つ) |
No |
| skip | (最後から)何行飛ばされるか。 デフォルトは "0" |
No |
HeadFilterとTailFilterにより、それぞれの求めるテキストファイルの一部を抽出することができます。このグラフィックは依存関係を表します:
| コンテンツ | フィルタ | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 行目 |
|
|||||||||||||
| 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>
このフィルタは指定された文字列を削除します。
Ant 1.6から
このフィルタは、 都合のよい形式内でのみ有効です。
| パラメータ名 | パラメータ値 | 必須 |
| chars | 削除する文字列。この属性はバックスラッシュを有効とする。 | Yes |
<deletecharacters chars="\t\r"/>
このフィルタは、フィルタで指定したファイルの内容を、先頭または最後尾に追加します。
Ant 1.6から
| パラメータ名 | パラメータ値 | 必須 |
| prepend | 先頭にファイルの内容を追加する、ファイルの名前 | No |
| append | 最後尾にファイルの内容を追加する、ファイルの名前 | No |
<filterchain>
<concatfilter/>
</filterchain>
それぞれのjavaソースファイルの前にライセンステキストを追加する。
<filterchain>
<concatfilter prepend="apache-license-java.txt"/>
</filterchain>
Ant 1.6から
ひとつだけのトークナイザ要素だけが使われて、もし、何も指定されていなかったら、LineTokenizerはデフォルトになります。トークナイザは、トークン文字列への入力を分割し、区切り文字列に沿って追います。
ゼロ以上の文字列フィルタがあります。 文字列フィルタはトークンを加工し、文字列かnullを返します。 文字列がnullで無いならば、次のフィルタに通ります。 これはすべてのフィルタが呼ばれるまで続きます。 すべてのフィルタの後に文字列が返されたら、文字列はトークン区切り文字(もしひとつあれば)と関連した出力になります。 後に続く区切り文字は、delimOutput属性によって上書きされるかもしれません。
バックスラッシュの解釈 多くの属性(delimOutputを含む)は、バックスラッシュエスケープを解釈します。 以下の\n、\r、\f、\t、\\は理解されます。
| 属性 | 説明 | 必須 |
| delimOutput | 空でなければ、トークナイザによって返されたトークン区切り文字を上書きします。この属性はバックスラッシュを有効にします。 | No |
以下のトークナイザは、デフォルトディストリビュージョンによって提供されます。
LineTokenizer
FileTokenizer
StringTokenizer
ReplaceString
ContainsString
ReplaceRegex
ContainsRegex
Trim
IgnoreBlank
DeleteCharacters
LineTokenizer
このトークナイザは行で分割します。トークナイザは、"\r"または"\n"または"\r\n"によって分割します。これはデフォルトのトークナイザです。
| 属性 | 説明 | 必須 |
| includeDelims | 行の最後をトークン区切りとして含む。 デフォルトは false | No |
空行を削除します。<tokenfilter delimoutput="\n"/>
<tokenfilter>
<ignoreblank/>
</tokenfilter>
このトークナイザはすべての入力をトークンのように扱います。ですから、大きい入力値を使わないように注意してください。
<tokenfilter>
<filetokenizer/>
<replaceregex pattern="([\n\r]+[ \t]*|^[ \t]*)package"
flags="s"
replace="\1//package"/>
</tokenfilter>
このトークナイザは、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>
これは文字列を置換するためのシンプルなフィルタです。
このフィルタは、直接フィルタチェーン内で使うことができます。
| 属性 | 説明 | 必須 |
| from | 置き換えられるべき文字列 | Yes |
| to | 置き換えられる文字のための新しい値。空文字の時には省略されます。 | No |
<tokenfilter>
<replacestring from="sun" to="moon"/>
</tokenfilter>
これは、指定された文字列を含むフィルタトークンのためのシンプルなフィルタです。
| 属性 | 説明 | 必須 |
| contains | トークンが含むべき文字列 | Yes |
<tokenfilter>
<containsstring contains="foo"/>
</tokenfilter>
このフィルタ文字列は、正規表現を置換します。正規表現上の説明である、ReplaceRegexpを参照してください。このフィルタは、直接フィルタチェーン内で使うことができます。
| 属性 | 説明 | 必須 |
| pattern | トークン内でマッチするための正規表現パターン。 | Yes |
| replace | 置換するための正規表現にマッチする置換パターン。省略するときは空の文字列を使う。 | No |
| flags | 正規フラグの説明のためにReplaceRegexpを参照してください。 | No |
<tokenfilter>
<replaceregex pattern="hello" replace="world" flags="gi"/>
</tokenfilter>
このフィルタ文字列は、正規表現にマッチします。そのフィルタは、マッチした正規表現の状況に応じて置換することができます。正規表現上の説明である、ReplaceRegexpを参照してください。
このフィルタは、直接フィルタチェーン内で使うことができます。
| 属性 | 説明 | 必須 |
| pattern | トークン内でマッチするための正規表現パターン。 | Yes |
| replace | 置換するための正規表現にマッチする置換パターン。省略したときは、元のトークンが返される。 | No |
| flags | 正規フラグの説明のためにReplaceRegexpを参照してください。 | No |
<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>
このフィルタは、トークンの最初と最後から空白を取り除きます。
このフィルタはフィルタチェーン内で直接使うことができます。
このフィルタは空のトークンを削除します。このフィルタはフィルタチェーン内で直接使うことができます。
このフィルタはトークンから指定された文字列を削除します。
| 属性 | 説明 | 必須 |
| chars | 削除する文字列。この属性はバックスラッシュが有効です。 | Yes |
<tokenfilter>
<deletecharacters chars="\t"/>
<trim/>
<ignoreblank/>
</tokenfilter>
これは、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>
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.