• 検索結果がありません。

第 5 章 フレームワークの動作上の特徴 43

5.2 テンプレート処理

5.2.7 テンプレート処理のアルゴリズム

ここまでに説明したページ合成のアルゴリズムを説明する.図5.6は,ページ合成の概略を示したもので,

ボックスに記載された「ExpandRepater」などは,この後に具体的に示すアルゴリズムで定義されているプ

ロシージャ名である.ルートノードとなるBODY要素からSeekEnclosureプロシージャーを呼び出し,エ ンクロージャーを発見するまで前順走査を行う.エンクロージャーが見つかれば,ExpandEnclosreプロシー ジャーが呼び出され,内部のリンクノードを探索してコンテキストを確定し,関連するレコードをデータベー スから取り出す.そして,ExpandRepeaterプロシージャーが呼び出されて,各レコードのフィールド値をリ ピーター内のリンクノードに挿入する.リピーター内部にエンクロージャーがあるかをさらにSeekEnclosure プロシージャーを呼び出して走査を続ける.内部にエンクロージャーがあれば,リレーションシップの定義 を考慮したデータベースアクセスを行い,リピーターを複製して追加する作業を行う.アルゴリズム上は,

再帰呼び出しの形式になっていることから,エンクロージャーとリピーターの組み合わせは,何段階にも定 義されていても正しくレコードの取り出しとHTML要素への展開ができる.

PageConstruct SeekEnclosure

ExpandEnclosure

ExpandRepeater

ノードを前順走査 エンクロージャ

ーを発見

HTMLページの内容を読み込んだ後に呼び出す ルートから開始

リピーターを取り除いて別途保持 コンテキストの特定

対応するレコードをクエリー

(リレーションシップがある場合は検索条件として追加)

コンテキストが求め られない場合、各リ ピーターに関して

各レコードに対して繰り返し:

・レコードの値を記録

・リピーターの複製にフィールドの値を合成

・リピーターの複製をエンクロージャーに追加 複製したリピーター

の内部に関して

レコードが 取得できた

図5.6:ページ合成処理の概要

以下,それぞれのプロシージャーを詳細に説明する.ページ合成は,例えばページをロードした直後の イベントを捉えて,アルゴリズム5.1に示したPageConstruct関数を呼び出すことで実施される.以下,複 数のアルゴリズムを記述するが,下線が引かれた動作は,そのアルゴリズムあるいは別のアルゴリズムに

procedureとして記述されたものを示す.

SeekEnclosureプロシージャーはエンクロージャーを求めて,存在すればExpandEnclosureプロシージャー

を呼び出す.エンクロージャーであるためには,決められたタグ名あるいはタグ名と属性であって,その要 素よりも下位の階層にはリンクノードが存在している必要がある.しかしながら,SeekEnclosureプロシー ジャーの最初の条件判断では,ここではタグの種類と属性を確認するだけで判定している.例えばTBODY タグ要素であってその子要素としてTRが1つあるいは複数存在しているかどうかを確認しているのみであ る.以下の一連のアルゴリズムでは,リンクノードが存在していない場合でもエンクロージャーとみなして しまうが,リンクノードが存在しない場合は何もしないように実装している.

ExpandEnclosureプロシージャーのアルゴリズムはアルゴリズム5.2に記述した.一度リピーターを削除

5.2. テンプレート処理 53 アルゴリズム5.1ページ合成のアルゴリズムの開始

procedurePageConstruct

S eekEnclosure(ページのBODYタグ要素,NULL) end procedure

procedureSeekEnclosure(node,record)

ifnodeがリピーターを持つエンクロージャーかどうかthen ExpandEnclosure(node,record)

else

for eachchildNodeinnodeの子ノードの配列do S eekEnclosure(childNode,record)

end for end if end procedure

するエンクロージャー以下を解析して,リンクノードを収集するが,その中にあるエンクロージャーより下 位の階層の要素は無視し,これらは展開後に改めて解析する.リンクノードを収集して,それぞれのdata-im 属性の値を調べて,設定されているコンテキスト名を集める.複数のコンテキスト名が混在する可能性が あるが,ここでいちばん多く使われているコンテキスト名を,そのエンクロージャーで利用するコンテキ スト名として,コンテキスト名を確定する.リンクノードがないなどコンテキストが決定できない場合に は,元の状態に戻して,リピーターを出発点としてSeekEnclosureプロシージャーを呼び出し,エンクロー ジャーの探索を再開する.コンテキスト名が決まれば,コンテキスト定義を参照し,さらにコンテキストモ デルを生成し,リピーターの複製をコンテキストモデルのプロパティとして記録する.ページの合成を始 めて,最初にExpandEnclosureプロシージャーを実行するときには,引数recordはNULLになるので,リ レーションシップに関する処理はない.コンテキスト定義に指定されたテーブルや検索条件に従ってデータ を取得して,ExpandRepeatersプロシージャーを呼び出す.

ExpandRepeatersプロシージャーのアルゴリズムはアルゴリズム5.3に記述した.引数には,コンテキスト

モデル,エンクロージャーの要素,データベースから得られたレコードが渡される.クエリー結果にレコー ドが含まれていない場合には,リピーターの中からレコードがないときに表示される要素(data-im-control 属性が"norecord"のリピーター)を選択して,それをエンクロージャーの子要素とする.レコードがあれば,

それぞれのレコードに対して,レコードがないときのリピーターを除いたリピーターを複製する.そして,

複製したリピーター内の各リンクノードに対して,ターゲット指定を元にフィールド名と,要素のどこに データベースの値を設定するかを割り出して,実際にノードに追加する.ここでは,例えばINPUTタグに よるテキスト要素ならばvalue属性,DIVなどの一般的なタグ要素ならばテキストノードを子要素として追 加するなど,要素の種類に応じた処理を行う.データベースから得られた値を要素に合成した後,複製した リピーターをエンクロージャーの子要素とする.ここで,リピーターの中に,エンクロージャーがあるか

どうかをSeekEnclosureプロシージャーを呼び出して調べる.最初にSeekEnclosureプロシージャーを呼び

出した時には,record引数はNULLであったが,エンクロージャー/リピーターによる合成処理をした後は,

現在のレコードを引数としてSeekEnclosureプロシージャーを呼び出す.次に見つかったエンクロジャーに

対してExpandEnclosureプロシージャーを呼び出すときに,上位のエンクロージャーのレコードが引き渡さ

アルゴリズム5.2エンクロージャーを元にデータベースからデータを取得 procedureExpandEnclosure(enclosureNode,record)

repeaters←リピーターの複製を作る リピーターをエンクロージャーから取り除く

linkedNodes←repeatersからリンクノードの配列を取得する contextDe f ←linkedNodesからコンテキストを確定する

if(コンテキストが確定できない(リンクノードがない,コンテキスト定義がないなど)then

for eachrepeaterinrepeatersdo

repeaterをエンクロージャーの子ノードに戻す

S eekEnclosure(repeater,record) end for

else

contextModel←contextDe fからコンテキストモデルを生成する contextModel.repeaters←repeaters

ifrecord!=NULLthen

recordからリレーションシップに関連するデータを得てクエリー条件に付加

end if

recordS et←コンテキストに従ってクエリーを実施してレコードセットを得る

ExpandRepeaters(contextModel,enclosureNode,recordS et) end if

end procedure

れ,そのときにはrecord引数はNULLでなく,コンテキスト定義に従って,外部キーに対応するフィール ドが上位レコードの主キー値と同じであるという検索条件が付加されてクエリーが実施される.

テキストフィールドなどのバインドされたユーザーインタフェースオブジェクトにおいてユーザーが表 示されているデータを変更すると,アルゴリズム5.4で示した処理が実行される.定義ファイルに従った値 のチェックを行い,その後に,テキストフィールドとバインドされたコンテキストモデル上の値とと,デー タベース側の現在の値を付き合わせる.データベースへの検索の手がかりはコンテキストモデルに残され ている.もし,値が異なるとしたら,別のユーザーによってデータベースが更新されていることが考えられ るので,そのまま上書きするか,あるいはデータベース更新をキャンセルするかのダイアログボックスを表 示して,ユーザーに判断させるいわゆる楽観的ロックの仕組みが稼働している.そのまま更新をするとすれ ば,テキストフィールドの値をコンテキストモデルに反映させ,その後にデータベースアクセスしてデータ ベース側を更新し,さらに同じフィールドとバインドしている他の要素への更新も行う.

以上のアルゴリズムによって,テンプレートとなるページファイルの状態から,データベースアクセスを 行ってそのデータを合成したページを作成し,さらにユーザーによる書き戻しを行うまでの一連の処理が 実現している.エンクロージャーとリピーターを識別する処理を,再帰的な呼び出しによって内包するもの を探索して処理を進めることで,個別のレコード単位でのリレーションシップも考慮されたページ合成がで きる.

5.3. ページネーションの実現 55