MktableService

id:goldenport:20060919でRelaxer5フレームワークのデモ用テスト・ケースMktableTest、id:goldenport:20060920でMktableTestからRelaxer5フレームワークに登録されていたサービスMktableServiceClassについて説明した。

MktableServiceClassで生成されるMktableServiceは以下のものである。

public class MktableService extends AbstractRService {
    public MktableService(IRServiceCall call, MktableServiceClass modelClass, IRServiceContext context, RUnitofwork unitofwork) {
        super(call, modelClass, context, unitofwork);
    }

    @Override
    protected Object doExecute() throws Exception {
        addModelClass(ExcelTabularModelClass.class);
        ServiceRequestModel request = getServiceRequestModel();
        IRValueTableModel source = request.mountTableModel(0);
        IRValueTableModel target = request.mountTableModel(1);
        target.putAll(source);
        return null;
    }
}

doExecute

サービスのアプリケーション・ロジック本体はdoExecuteメソッドに記述されている。

addModelClass

addModelClassによってモデルExcelTabularModelClassを登録している。このモデルを登録することでサフィックス"xls"を持つファイルをマウントするとIRValueTableModelタイプのモデルであるExcelTabularModelがマウントされる。

ここで「マウント」という概念が登場しているが、これはRelaxer5フレームワークがモデル空間とモデルを接続するための仕掛けとして導入したものである。詳細はいずれ取り上げる予定である。

getServiceRequestModel

getServiceRequestModelはServiceRequestModelを取得するユーティリティメソッドであり、以下のように実装されている。

    protected final ServiceRequestModel getServiceRequestModel() throws RModelException {
        return (ServiceRequestModel)_modelSpace.getModel(MODELSPACE_SERVICE_REQUEST);
    }

ここで、MODELSPACE_SERVICE_REQUESTの定義は以下の通り。

    String MODELSPACE_SERVICE_REQUEST = "/service/request";

つまり、サービスに割り当てられているモデル空間の"/service/request"というパスにServiceRequestModelがマウントされているので、これを取得するというのがgetServiceRequestModelの目的である。"/service/request"へServiceRequestModelをマウントするのはサービスの開始時にフレームワークが行う。
なお、モデル空間はサービス毎に異なっているので異なるサービスでは"/service/request"という名前に対して異なるServiceRequestModelのインスタンスがマウントされている。

mountTableModel

ServiceRequestModelはIRListModelなので、リスト形式でモデルを格納する機能を持っている。
ServiceRequestModelでは、リストにサービスのパラメタが格納される。

そこで、このパラメタに対してmountTableModelを行うと、各パラメタに対して自動的にモデルがマウントされ、マウントされたモデルが返される。

MktableTestから呼ばれる場合には、第一引数は".../test.xls"、第二引数は".../test.csv"なので前者にはExcelTabularModel、後者にはCsvModelが選択される。なおExcelTabularModelは前述したとおり、MktableService内で登録しているが、CsvModelはここまで姿が見えない。というのはCsvModelはフレームワークのデフォルトとして事前に登録されているからである。

IRValueTableModelの種類

IRValueTableModelには、ExcelTabularModelとCsvModel以外に以下のものが用意されている。

  • ExcelSheetModel
  • FsDirectoryTableModel
  • Html_4_0_TableModel
  • XHtml_1_0_TableModel

これらの詳細についてはいずれ取り上げたいが、ExcelSheetModelとExcelTabularModelの違いについて説明しておく。
Excelは単に表データとして扱うのは不十分で、表のリストあるいはマップとして扱わなければならない。このためRelaxer5フレームワークでは、IRMapModelであるExcelBookModelを用意しており、このExcelBookModelに格納されるモデルとしてIRValueTableModelのExcelSheetModelを用意しているのである。
とはいえ、Excelに表データを一枚だけ格納するケースがかなり多いはずなので、これに対応するためにExcelTabularModelを用意している。ExcelTabularModelはExcelに格納されている最初のシートを決めうちで表データとして扱うIRValueTableModelなのである。

putAll

ここまでで、データ入力元のIRValueTableModelとデータ出力先のIRValuTableModelを取得した。
次は、putAllメソッドで入力元から出力元へデータの複写を行う。これで処理は完了である。
ただし、この時点ではデータの書き出しは行われていない。

ファイルの書き出し

putAllメソッドでデータの複写を行った時点では、メモリ内のモデルが更新されたのみである。それでは、ファイルへの書き出しはどのように行うのであろうか。
それは、フレームワークがUnitofworkという実行単位の終了時に、ダーティなモデルを自動的にコミットする処理の中で行われる。doExcuteメソッド内でputAllメソッドが呼ばれた時点で、データ出力先のIRValueTableModelであるCSVModelがダーティになっている。このダーティデータが自動的に実ファイルに出力されるのである。

MktableServiceから分かること

MktableServiceでは、表構造のモデル操作を行うアプリケーションをデモしている。このデモではRelaxer5フレームワークの以下の効果をアピールしている。

  • モデルの入力、出力はフレームワークが自動的に行う。
  • 表構造を抽象化したインタフェースIRValueTableModelが定義されており、これに準拠したモデルを追加すれば、扱える表モデルの数をアプリケーションロジックの変更なしに増やしていくことができる。
  • ダーティ・モデルのコミット処理のメカニズムをフレームワークが持っている。
  • モデルはモデル空間上で管理され、パス名でアクセスすることができる。