Mayaa洞窟ソースコード探検隊 その3

やってきました。ソースコード探検隊その3。不定期な更新ですが、気の向くまま探検します。*1
今回は下調べとして、パッケージ構成を見てみます。Mayaa洞窟のSVNリポジトリのリビジョンは2896です。洞窟の中を探検するための灯りは、Eclipseをつかいます。闇を日食で照らしてみます。
まずは、ソースフォルダから見てみましょう。

ソースフォルダ

洞窟には2つの入り口がありました。

  • src-api
    • 各種のAPIをインタフェースとして定義
  • src-impl
    • 実装の本体

なぜわざわざAPIを別定義してるのでしょうか。おそらく別実装を作れるような汎用化を意図してるのだろう、と思われます。
しかし、このことが原因の一端となり、某ASIPさんは「何でもできるために汎用化したコードはまるで迷路のよう」という名言を残しています(名言なのか迷言なのかは隊員諸君に判断を任せます)。*2
次はパッケージです。

src-api

1つ1つの中身は後ほど見ていきます。

- org.seasar.mayaa
                  - builder
                  - cycle
                  - engine
                  - provider
                  - source

src-impl

実装フォルダの方はAPIフォルダよりも若干数が多いです。(*印で表現)

- org.seasar.mayaa.impl
                  - builer
                  - cycle
                  - engine
                  - factory*
                  - provider
                  - source
                  - standalone*
                  - util*

本当はbuilderの中身がさらにbuilder.injectionとかbuilder.libraryに分かれるのですが、いきなり深いところまで入り込むと迷子になってしまう*3ので、これくらいにしておきます。幅優先のアルゴリズムで進みます。
さて、パッケージの名前からその役割が想像できるでしょうか?とりあえず全ての実装はorg.seasar.mayaa.implの下におかれていそうなのはわかりましたが、builderはHTMLを組み立てるために使うのかな?とかcycleで何かのライフサイクルを管理して、engineが他のオブジェクトに処理を振るのかな?とか色々想像してしまいますよね。Mayaa洞窟の地図作りの第一歩を踏み出しました。

1つ1つのパッケージをちょっとずつ調べる

とりあえずは、src-apiで定義されてるパッケージが重要そうなのでそっちを見てみます。パッケージの中で定義されてるインタフェース/クラスをかいつまんでその役割を推測してみることにします。

org.searsar.mayaa.builder

implフォルダのSpecificationBuilderImplにこんなコードを発見しました。(適当に端折ってます)

public void build(Specification specification) {
    ...
    SourceDescriptor source = specification.getSource();
    if (source.exists()) {
        SpecificationNodeHandler handler =
            createContentHandler(specification);
        
        XMLReaderPool pool = getXMLReaderPool(source.getSystemID());
        XMLReader xmlReader =
            pool.borrowXMLReader(handler, true, false, false);
        InputStream stream = source.getInputStream();
        InputSource input = new InputSource(stream);
        input.setPublicId(getPublicID());
        input.setSystemId(source.getSystemID());
        ...
            xmlReader.parse(input);
            afterBuild(specification);
        ...
    }
}

おそらく、テンプレートのHTMLをパースしてページを組み立てる役割みたいですね。おそらく…。

org.seasar.mayaa.cycle

パッケージ名から察するに、何かのサイクルを管理するのでしょう。apiフォルダにServiceCycleというインタフェースを発見しました。パピルス(JavaDocコメント)にこんな記述があります。

サービスのライフサイクルオブジェクト。HTTPリクエストの期間、サービスのコンテキストとなる。

ずばり、このパッケージの役割そのものじゃないでしょうか。クライアントからの「リクエストに関するコンテキストのライフサイクル」を管理するみたいです。
他にもResonseというインタフェースを見つけました。これはHttpResponseみたいにクライアントへのレスポンスを行うためのインタフェースみたいです。HTML出力もこのパッケージの役割だということでしょうか?とりあえずそういうことにしておきましょう。

org.seasar.mayaa.engine

このパッケージはEngineインタフェースを見れば一目瞭然ですね。

ランタイムエンジン。ホストサーブレットからservice()が呼び出される。リクエストに対して、ステートレスに実装。

PageインタフェースやTemplateインタフェースから推察するに、このパッケージがMayaa全体の世界観を担っているいるような感じです。
処理を追うときは、ここを基点に見てみるとよいかもしれません。

org.seasar.mayaa.provider

apiフォルダにはServiceProviderとProviderFactoryというインタフェースが存在します。ProviderFactoryには「アプリケーションサービスプロバイダのファクトリ」と書かれてあって、そのアプリケーションサービスプロパイダというのがServiceProviderみたいです。
そして、ServiceProviderのパピルス(JavaDoc)にはこう書かれてあります。「アプリケーションスコープでのサービス提供オブジェクト。」何のことだかさっぱりです。アプリケーションスコープはMayaa全体としてのスコープのことかな、と想像はつきますが、サービス提供オブジェクトというのが何を意味しているのか理解できません。
何故ここにサービス提供オブジェクトなんてものがあるんだろう?頭に疑問符を浮かべたまま、インタフェースのメソッド定義を見たら、ちょっとわかったような気がします。

void setEngine(Engine engine);
Engine getEngine();

void setScriptEnvironment(ScriptEnvironment environment);
ScriptEnvironment getScriptEnvironment();

void setLibraryManager(LibraryManager libraryManager);
LibraryManager getLibraryManager();

void setSpecificationBuilder(SpecificationBuilder specificationBuilder);
SpecificationBuilder getSpecificationBuilder();

void setTemplateBuilder(TemplateBuilder templateBuilder);
TemplateBuilder getTemplateBuilder();

要するに、アプリケーションに対する設定を色々できるようにするためのProviderさんなわけですね。たぶんですが。

org.seasar.mayaa.source

SourceDescriptorから推測するに、テンプレート(.html)や設定ファイル(.mayaa)のディスクリプタとなるみたいです。
ちなみに、この場合のディスクリプタとはディスクリプタとは - はてなキーワードと同様の意味だと思ってます。間違ってないか心配ですが。

重要そうなパッケージ

ざっと見てみましたが、重要そうなのは、builder, cycle, engineといったあたりでしょうか。この3つを制覇すれば、Mayaaで迷うことはなさそうです。

次回

前回で予告したとおり、org.seasar.mayaa.impl.MayaaServletから始まる基本的な処理の流れを追ってみたいと思います。

*1:隊長は私で、隊員はあなたです。Follow me!

*2:現地の人(コミッタ)からすれば怒り心頭でしょうが

*3:なんていったって迷路ですからね