Home of: [工房 "藤車"] > [SourceForge.net における PageMixer]

"NOP" フィルタ

本節では、 PageMixer フレームワークにおける HTML ページの解析および描画の方法に関して説明します。

概要

クラス図

本節におけるクラス図を以下に示します。

クラス図
クラス図 (クリックで拡大表示)

色づけされているのが本節で定義するクラスで、 それ以外は PageMixer において定義済みです。

オブジェクト図

本節におけるオブジェクト図を以下に示します。

オブジェクト図
オブジェクト図 (クリックで拡大表示)

シーケンス図

HTML ページの解析および描画における処理フローは以下のようになります。

  1. 固有 Filter の生成
  2. Renderer インスタンスの生成
  3. Producer インスタンスの取得(あるいは生成)
  4. ConsumerContext インスタンスの生成
  5. 固有 FilterRenderer への接続
  6. Filter および ConsumerContext を用いた Producer#produce の起動

Producer#produce 起動後のシーケンス図を以下に示します。

シーケンス図
シーケンス図 (クリックで拡大表示)

クラス名

本チュートリアルでは、 クラスは全てクラス名のみで表記されています。 完全な名称は以下の通りです。

PageMixer フレームワークのクラス

表記完全名
ConsumerContext jp.ne.dti.lares.foozy.pagemixer.mixer.ConsumerContext
Filter jp.ne.dti.lares.foozy.pagemixer.mixer.Filter
HashMapConsumerContext jp.ne.dti.lares.foozy.pagemixer.mixer.HashMapConsumerContext
LoosePageState jp.ne.dti.lares.foozy.pagemixer.parser.LoosePageState
PageParser jp.ne.dti.lares.foozy.pagemixer.mixer.PageParser
PageState jp.ne.dti.lares.foozy.pagemixer.parser.PageState
Producer jp.ne.dti.lares.foozy.pagemixer.mixer.Producer
Renderer jp.ne.dti.lares.foozy.pagemixer.mixer.Renderer
Token jp.ne.dti.lares.foozy.pagemixer.Token

チュートリアルの固有クラス

表記完全名
Bootstrap pagemixer.filter.Bootstrap
Bootstrap.Default pagemixer.filter.Bootstrap.Default
NopFilter pagemixer.filter.NopFilter

"NOP" フィルタの定義

まず始めに、 Token 列を接続先 Consumer に渡す以外には何もしない(NOP:No OPeration) フィルタを定義します。

public class NopFilter
    extends Filter
{
    public NopFilter(){ super(); }

    public void consume(ConsumerContext context, Token token){
        getConsumer().consume(context, token);
    }

    public void flush(ConsumerContext context){
        getConsumer().flush(context);
    }
}
NopFilter クラス

"consume" および "flush" の両メソッドは、 接続先 Consumer の同一シグネチャのメソッドの起動しか行いません。

備考: 実のところ、 同様の機能のフィルタとして "DefaultFilter" が既に定義されていますので、 "NOP" フィルタが必要であれば、 こちらを使ってください。

Renderer の生成

PageMixer フレームワークでは、 HTML ページが Token シーケンスとして扱われます。 しかし、処理結果として HTML ページを提示するためには、 文字列(ないしはバイト列)表現形式が必要とされます。

"Renderer" クラスは、 コンストラクタで指定された java.io.Writer に対して Token シーケンスを描画します。 例えば、 標準出力に書き出す Renderer は以下のようにして生成されます。


Renderer renderer =
new Renderer(new OutputStreamWriter(System.out));

標準出力に書き出すRenderer

Producer の生成

繰り返しますが、 PageMixer フレームワークでは、 HTML ページは "Token" シーケンスとして扱われます。 そのため、シーケンスを提供する "Producer" が必要となります。

指定された HTML ファイルを表現する シーケンスを提供する Producer を得るための、 非常に簡単な方法があります。 "PageParser" および "LoosePageState" の利用がそうです。


LoosePageState pageState = new LoosePageState();
PageParser parser = new PageParser(pageState);
Producer producer = parser.parse(filename);

Producer の生成

"filename" 変数は、 HTML ページのファイル名を保持するものとします。

注意: "LoosePageState" は その名前の "Loose" が "文法的に Loose" から来ています。

この実装は、 例えば 'h1' 配下の 'table' といった不正なタグ構造を許容するため、 HTML ソースの正当性通知を期待してはいけません。

ConsumerContext の生成

"ConsumerContext" は、 動的な値や、フィルタ間連携のために使用します。

スタンドアロン環境用に、 java.util.HashMap を用いた ConsumerContext インタフェースの実装として "HashMapConsumerContext" クラスがあり、 以下のようにして生成します。


HashMapConsumerContext context = 
new HashMapConsumerContext();

ConsumerContext の生成

本節では、この "context" は必要ではありませんが、 このオブジェクトの作り方 (あるいはどのクラスを利用するか)を知ることが重要です。

繋いで混ぜる

以上で HTML ページの解析および描画に必要なものが全て揃いましたので、 後は以下の手順を踏むだけです。

  1. NopFilter の生成
  2. NopFilterRenderer への接続
  3. NopFilter および ConsumerContext を用いた Producer#produce の起動

NopFilter filter = new NopFilter(); // --- (1)
filter.connectTo(renderer); // --- (2)

producer.produce(context, filter); // --- (3)

繋いで混ぜる(本当は混ぜていない)

実は、 ユーティリティクラスである "Bootstrap" あるいはその派生クラスは、 前述の "Renderer の生成" から "繋いで混ぜる" までを補助してくれます。

以下のようにして、描画された HTML を標準出力から得ることが出来ます。

  1. 解析対称 HTML ページのファイル名で "Bootstrap.Default" インスタンスを生成
  2. 固有 Filter を使って "execute(Filter)" を起動

実行コードは以下の通りです (詳細は pagemixer.filter.NopFilter を参照してください)。

try{
    Bootstrap bootstrap =
    new Bootstrap.Default(filename);

    bootstrap.execute(new NopFilter());
}
catch(Exception e){
    e.printStackTrace(System.err);
}
Bootstrap クラスによる起動

次節「Token の刈り込み」へ