ヘッダーをスキップ
Oracle Application Development Framework Forms/4GL開発者のための開発者ガイド
10g(10.1.3.0)
B40013-02
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

2 Oracle ADFおよびJSFを使用した開発プロセスの概要

この章では、Oracle JDeveloper 10gリリース3(10.1.3)の使用による、Oracle ADFおよびJSFを使用したWebアプリケーションの作成、Oracle ADF Business Componentsを使用したビジネス・サービス・レイヤーの実装に関する一般的な開発プロセスについて説明します。

この章の内容は次のとおりです。

2.1 開発プロセスの概要

JDeveloperおよびOracle ADFを使用したJ2EE開発がいかに簡単であるかを理解する最も単純な方法は、一般的なエンドツーエンドの開発プロセスを体験することです。Oracle ADFを使用すると、エンタープライズJ2EEアプリケーション開発はコードが不要な視覚的作業となります。当然、実際のアプリケーションでは最終的にコードを作成することになります。しかし、Oracle ADFを使用すると、アプリケーションのビジネス要件に直接かかわるコードに作業を集中できることが重要です。

このガイドの残りの部分で実際のアプリケーションの例として使用するサービス・リクエスト追跡システムでは、購入した製品の技術的なサポートを求めるサービス・リクエストを外部ユーザーが登録します。内部ユーザーは、自分が専門とする領域で顧客をサポートします。ここでは、システム全体の機能に関する1つの小さなユースケース向けソリューションの実装にかかわる一般的な手順に焦点を当てます。ここでは、技術者ユーザーのプロファイルとその専門技術領域を管理するための小規模システムを作成します。

この概要では、Oracle ADFを使用した一般的な開発プロセスの最も基本的な部分について説明しますが、1手順ずつ詳細に説明することはしません。使用可能なすべてのOracle ADFチュートリアルのリストは、OTNのOracle ADFプロダクト・センター(http://otn.oracle.com/products/adf)にアクセスしてください。


注意:

この章を読み終えた後、ここで説明する小規模アプリケーションの完全バージョンを試用するには、サンプルのダウンロード・ページ(http://otn.oracle.com/documentation/jdev/b25947_01/)からADFIntroワークスペースをダウンロードしてください。

2.2 ファイルを格納するアプリケーション・ワークスペースの作成

新規アプリケーションを作成する最初の手順は、アプリケーションに名前を割り当て、そのソース・ファイルを保存するディレクトリを指定することです。JDeveloperの「新規ギャラリ」「アプリケーション」を選択すると、図2-1に示された「アプリケーションの作成」ダイアログが表示されます。このダイアログで、ADFInfoなどのアプリケーション名の指定、作業ディレクトリの設定、およびアプリケーションで作成するクラスのパッケージ接頭辞の指定を行います。通常、oracle.srdemoなどのパッケージ接頭辞を入力すると、デフォルトで、アプリケーションを構成するすべてのコンポーネントがoracle.srdemo.*で始まる名前を持つパッケージ内に作成されます。JSFおよびADF Business Componentsを使用してWebアプリケーションを作成するため、図2-1には、対応するアプリケーション・テンプレートがリストから選択されて表示されています。このアプリケーション・テンプレートは、アプリケーションの各レイヤーを構築するための適切なテクノロジを選択して、ModelおよびViewControllerという名前の個別プロジェクトを作成するよう構成されています。

図2-1 ファイルを格納するアプリケーション・ワークスペースの作成

「アプリケーションの作成」ダイアログの図

各プロジェクトに含まれるデフォルトのテクノロジを確認する場合は、「プロジェクト・プロパティ」ダイアログで「テクノロジ・スコープ」ページを開きます。図2-2は、ModelプロジェクトのリストにDatabaseおよびUMLテクノロジを追加した後のこのページの外観を示します。各プロジェクトで使用するテクノロジを正確に指定すると、「新規ギャラリ」ダイアログなどのダイアログに示される選択肢が簡略化され、現在のプロジェクトのテクノロジに関する選択肢のみ表示されるようになります。

図2-2 プロジェクトで使用されるテクノロジを定義するテクノロジ・スコープ

「テクノロジ・スコープ」ダイアログの図

2.3 ユースケースおよびページ・フローについて

アプリケーション・ワークスペースを作成した後、ユースケースをモデル化して構築対象のシステムに関するエンド・ユーザー要件を取得して伝達すると、開発プロセスを開始できます。図2-3に、数ある組込みUMLダイアグラム作成ツールの1つであるユースケース・ダイアグラマを使用して作成された簡単なダイアグラムを示します。このダイアグラムは、マネージャから構築を依頼されている簡単な技術者管理システムを表しています。このダイアグラムは、「Search for Technician by Name」および「Update Technician Profile」という2つの関連するユースケースで構成されています。ダイアグラムの注釈を使用すると、ユースケースを実装する画面上でエンド・ユーザーが参照する必要がある内容に関する特定の要件を取り込むことができます。たとえば、マネージャが検索結果を参照しながら製品名と技術者の専門技術レベルを確認する必要があるということを指摘できます。

図2-3 簡易な技術者管理システムのユースケース・ダイアグラム

ユースケース・ダイアグラムの図

ユースケースのモデル化により、エンド・ユーザー要件を実装するために必要なユーザー・インタフェース・ページの種類を把握していきます。図2-4のように、JSFページ・フロー・ダイアグラマを使用して、システムのスケルトン・ページ・フローを作成できます。ページ・フローはユーザー・インタフェースと関連しているため、この作業はワークスペースのViewControllerプロジェクトのコンテキストで行われます。

コンポーネント・パレットを使用して、ページおよび名前付きナビゲーション・ルールをドロップしてこれらを接続します。searchtechniciansページとupdateprofileページの組合せを使用して、要件を実装できます。マネージャは、searchtechniciansページを使用して更新対象の技術者を検索した後、updateprofileページに進んでこの技術者のプロファイルを変更します。変更を保存した後、searchtechniciansページに戻ります。ページ・ダイアグラムにあるナビゲーションの線はこのフローを示します。表示されている警告記号はアラームを示すものではありません。これらの記号は、ページ・アイコンが表すページを作成する必要があることを示します。この手順については後で説明します。

図2-4 ViewControllerプロジェクトのスケルトンJSFページ・フロー・ダイアグラム

プロジェクトのスケルトンJSFページ・フローの図

注意:

JDeveloperでは最初にUIを開発する機能をサポートしており、これによってバインドされていないUIコンポーネントを使用してWebページ表示のモデルを作成した後で、これらをデータとしてまとめます。しかし、ここでは、従来の4GLツールによる問題解決手法に最も近い、より一般的なボトムアップ手法を採用します。これらいずれかの開発スタイルを使用するのみでなく、両手法を同時に使用した折衷的な開発を行うこともできます。

2.4 データベース・スキーマの設計

特定の製品に関する技術者ロールおよび専門技術を持つユーザーに関する情報を格納するためのUSERSPRODUCTSおよびEXPERTISE_AREASのデータベース表がすでにある場合、それらに対する作業をすぐに開始できます。データ・ダイアグラムにそれらを表示すると、新しいユースケースをサポートするためにスキーマを変更する必要があるかどうかを確認できます。

データベース・スキーマ・オブジェクトを参照するために接続ナビゲータで名前付き接続を作成した後、Tablesフォルダの下に既存の表が表示されます。「新規ギャラリ」を使用して、データベース・ダイアグラムを新たに作成し、接続ナビゲータからUSERSPRODUCTSおよびEXPERTISE_AREASの表を選択し、それらをダイアグラムにドロップできます。図2-5に、データベース・ダイアグラムの表示内容を示します。

表がまだ存在しない場合も、同じダイアグラマを使用してそれらの表を設計し、DDLスクリプトを生成して表をはじめから作成できます。

図2-5 技術者管理システムのスキーマを示すデータベース・ダイアグラム

データベース・スキーマのダイアグラムの図

2.5 表のビジネス・ドメイン・オブジェクトのレイヤーの作成

データベース表が準備されている場合、これらの表を示す一連のJavaコンポーネントを作成し、これらの表に含まれるデータの変更を簡略化できます。エンティティ・オブジェクトを使用して表に関するデータ・アクセスおよび検証をカプセル化することにより、今日または将来作成するこれらの表と連携するページを一貫性のある方法で検証できます。このタスクはアプリケーションのデータ・アクセスおよびビジネス・ロジックに関連しているため、Modelプロジェクトのコンテキストで実行します。作業の実行に応じて、実行時にアプリケーションで必要なOracle ADFライブラリを参照するように、JDeveloperによってプロジェクトが自動的に構成されます。

2.5.1 表のエンティティ・オブジェクトをリバース・エンジニアリングするためのドラッグ・アンド・ドロップ

ビジネス・コンポーネントは、ウィザードまたはダイアグラムを使用して作成できます。ウィザードを使用する場合、多くのコンポーネントを同時に作成できるため、作業が速くなります。たとえば、表からのビジネス・コンポーネント・ウィザードを使用すると、ビジネス・サービスとして使用するエンティティ、オブジェクト、関連ビュー・オブジェクト、アプリケーション・モジュールを1ステップで作成できます。一方、多くの場合、ダイアグラムでのビジネス・コンポーネント作成はさらに直感的で、様々なビジネス・コンポーネントが担う役割を理解できます。ウィザードを使用したビジネス・コンポーネントの作成については後半の各章で説明するため、ここでは、1手順ずつ順に画面を確認しながら説明していきます。

ビジネス・コンポーネント・ダイアグラムを作成するには、「新規ギャラリ」を開き、「ビジネス・コンポーネント・ダイアグラム」を選択します。新規ダイアグラムを作成した後、接続ナビゲータから表をダイアグラムの上にドロップし、これらの表のエンティティ・オブジェクトを作成します。デフォルトでは、表の名前に基づいたUsersExpertiseAreasおよびProductsという名前のエンティティ・オブジェクトが作成されます。エンティティ・オブジェクトはビジネス・ドメイン・データの単一要素を表すため、エンティティ・オブジェクトには単数形の名前を付けることをお薦めします。ダイアグラムに用意されている編集サポートを使用すると、エンティティ・オブジェクトの名前をUserExpertiseAreaおよびProductに変更できます。JDeveloperでは、新しい名前を使用するために関連ファイルを自動的に変更するリファクタを幅広くサポートしています。エンティティ・オブジェクトの他、基礎となる表を関連付ける外部キーを反映する関連付けもそのツールによって作成されます。エンティティ・オブジェクトがどのように表に関連付けられているかをわかりやすくするため、図2-6のように、表自体を同じダイアグラムに追加し、これらの表の間に依存関係を示す線を引くことができます。

図2-6 エンティティ・オブジェクトと関連表を示すビジネス・コンポーネント・ダイアグラム

この図は、エンティティ・オブジェクトと関連表のダイアグラムを示しています。

2.5.2 エンティティ・オブジェクトへのビジネス検証規則の追加

関連付けられた一連のエンティティ・オブジェクトは、再使用可能なビジネス・ドメイン・コンポーネントのレイヤーを示します。このレベルで順守するビジネス検証規則は、UsersExpertiseAreasおよびProductsと関連するユースケースに適合する構築アプリケーション全体にわたって実施されます。これは、使用するユーザー・インタフェース・テクノロジとは関係ありません。このガイドではJSFを使用したWebアプリケーションの開発に焦点を当てていますが、ビジネス・ドメイン・レイヤーにカプセル化された検証規則は、Web、ワイヤレス、Swingユーザー・インタフェースのいずれを経由しても、Webサービスを経由するのと同様に機能します。検証規則の範囲は、最も簡単な構文上の値チェックから最も複雑なエンタープライズ・データベースをベースとしたプログラム規則にまで及びます。

ダイアグラムでエンティティ・オブジェクトUsersをダブルクリックすると、エンティティ・オブジェクト・エディタにアクセスし、ユーザーの宣言的な検証規則を定義できます。エディタの「検証」ページを開き、検証規則を追加します。「新規」をクリックして新しい規則を追加し、新しいUser行の主キーが一意であることを確認する「UniqueKeyValidator」を追加します。図2-7のように、マネージャがすでに使用されているIDを使用して新しいユーザーを入力しようとすると表示される検証エラー・メッセージを入力できます。JDeveloperでは、様々な言語でのローカライズを簡略化するために、標準のJavaメッセージ・バンドルでこのエラー・メッセージが保存されます。

図2-7 新しいUniqueKey Validatorの追加

新しいユーザー用の「検証規則の追加」ダイアログの図

次に、Emailという属性に正規表現バリデータを追加し、マネージャが電子メール・アドレスを8文字の小文字書式でのみ入力するようにします。「宣言済の検証規則」ツリーで属性Emailを選択し、「新規」を再クリックすると、「Regular Expression Validator」を追加できます。図2-8は、3〜8文字の小文字書式を規定する正規表現と、マネージャが誤った書式で電子メール・アドレスを入力したときに表示されるエラー・メッセージを示しています。

図2-8 電子メール・アドレスの書式が正しいことを確認するRegular Expression Validator

電子メール・アドレス用の「検証規則の追加」ダイアログの図

UserRoleという属性を選択し、「新規」をクリックして図2-9のとおり「List Validator」を追加し、新しいユーザーのロールがusertechnicianまたはmanagerのみとなるようにします。ここでも、マネージャがデータを誤って入力したときに表示されるエラー・メッセージを入力できます。

図2-9 UserRoleの値が3つの正規値の1つであることを確認するList Validator

UserRole用の「検証規則の追加」ダイアログの図

この作業の後、図2-10のように、エンティティ・オブジェクト・エディタの「検証」ページに有効な検証規則がすべて表示されます。

図2-10 有効なすべての検証規則がまとめて表示された「検証」ページ

「検証」ダイアログの図

実際のアプリケーションでは、Javaで作成するカスタム検証イベント・ハンドラを起動するメソッド・バリデータを多数追加していきます。組み込まれている検証規則と同様に、これらの規則は、特定の1つの属性のみに関連付けられている場合は属性レベルの規則となり、より複雑で有効性を判定するために複数の属性値やその他のエンティティを調べる必要がある場合はエンティティ・レベルの規則となります。検証イベント内で作成されたコードによって、ビジネス・ドメイン・レイヤー内のエンティティ・オブジェクトのプロパティに簡単にアクセスできる他、メソッド・ベースの検証規則の検証チェックが成功か失敗かどうかの確認処理の一環としてSQL問合せを簡単に実行できます。

チームが実行するJavaベースのカスタム検証の種類に一定のパターンがあることがわかった場合、パラメータ駆動型の独自のカスタム規則を使用して、JDeveloperに組み込まれている一連の検証規則を拡張できます。カスタム規則により、チーム内の他の開発者は、今後の作業で共通の検証パターンを再使用できるようになります。この場合、コードを自分自身で作成する必要はありません。かわりに、リストからカスタム検証規則を選択し、いくつかのプロパティを設定します。いずれにせよ、宣言的に実装されているか、Javaで作成された検証イベント・ハンドラを使用して実装されているかとは関係なく、ビジネス・ルールはエンティティ・オブジェクト・エディタの「検証」ページにすべて表示されます。このため、オブジェクトについて有効なすべてのビジネス・ルールを1箇所で参照できます。

2.5.3 エンティティ・オブジェクトのUIコントロール・ヒントの定義

ビジネス・ルール以外にも、エンティティ・オブジェクト・レイヤーで一元管理できるその他の有用なリソースには、構築するすべてのアプリケーションを対象としてビジネス情報に使用される標準UIラベルやフォーマット・マスクがあります。エンティティ・オブジェクト・エディタを開いて個々の属性を選択すると、「コントロール・ヒント」タブを使用して、「ラベル・テキスト」「ツールチップ・テキスト」「フォーマットの種類」「フォーマット」マスクや他のヒントを使用できます。ユーザーから見えるこれらのラベルやフォーマット・マスクはエンド・ユーザーの優先言語に対応する必要があるため、これらはJDeveloperによって標準のJavaリソース・バンドルで管理されます。これにより、多言語アプリケーションを作成するためにこれらをその他のロケール言語に直接翻訳できるようになります。

ここでは、すべての属性のラベル・テキストのヒントを定義するためにUserExpertiseAreaおよびProductというエンティティを編集したことを前提とします。これらのエンティティ・オブジェクトに関連付けられたデータを使用して作成するページで、一元管理されるこれらのUIラベルのヒントを自動的に利用する方法については、後ほど説明します。

2.6 ユースケースを処理するビジネス・サービスの作成

再使用可能なエンティティ・オブジェクトのレイヤーを作成すると、ユースケースの当面のニーズを満たすために特定のビジネス・サービスを実装できます。このタスクはアプリケーションのデータ・アクセスおよびビジネス・ロジックに関連しているため、Modelプロジェクトのコンテキストで実行します。

2.6.1 技術者を管理するアプリケーション・モジュールの作成

アプリケーション・モジュールは、UIクライアントがアプリケーション・データを処理するために使用するOracle ADFのトランザクション・コンポーネントです。アプリケーション・モジュールによって、エンド・ユーザー・タスクに関連した作業論理ユニットについて、更新可能なデータ・モデルやトップレベルのプロシージャおよびファンクション(サービス・メソッド)を定義します。

ダイアグラムのビジュアル・プロパティを調整してグリッド表示をオフにした後、コンポーネント・パレットを使用して、図2-11のように、ビジネス・コンポーネント・ダイアグラムに新しいアプリケーション・モジュールをドロップできます。このアプリケーション・モジュールは技術者に関するサービスとなるため、このロールを反映してTechnicianServiceと呼ぶことができます。

図2-11 ビジネス・コンポーネント・ダイアグラムでのアプリケーション・モジュールの新規作成

この図は、ビジネス・コンポーネント・ダイアグラムの使用方法を示しています。

アプリケーション・モジュールのデータ・モデルは、エンド・ユーザーが画面上で参照するデータを定義するSQL問合せで構成されています。SQL問合せの結果を処理するには、必要な問合せをカプセル化するビュー・オブジェクト・コンポーネントを定義します。エンド・ユーザーがデータを更新する必要がある場合、ビュー・オブジェクトでは、再使用可能なビジネス・ドメイン・レイヤー内のエンティティ・オブジェクトを参照します。これらのエンティティ・オブジェクトにより、エンド・ユーザーが変更するデータが一貫した方法で検証および保存されるようになります。

2.6.2 ユースケースに適したデータを問い合せるビュー・オブジェクトの作成

はじめに、「Search for Technician by Name」というユースケースに必要なデータについて検討します。技術者はUSERS表にデータが格納されているユーザーであるため、User情報が含まれる問合せが必要であることは確かです。そこで、新しいビュー・オブジェクト・コンポーネントをダイアグラムにドロップし、SearchTechniciansByNameという名前を付けます。ダイアグラム内で、エンティティ・オブジェクトUserを、新しいビュー・オブジェクト・コンポーネントSearchTechniciansByNameにドラッグ・アンド・ドロップします。この方法でビュー・オブジェクトを作成すると、ビュー・オブジェクトのSQL問合せが更新され、このエンティティ・オブジェクトのすべてのデータが組み込まれます。

検索ページで表示が必要なのは、UserIdEmailFirstNameおよびLastNameという属性のみです。ダイアグラムを使用して、ビュー・オブジェクトSearchTechniciansByNameのその他の属性を選択し、[Del]キーを使用してこれらを削除できます。必要なデータのみを問合せに含めることにより、当面のタスクに必要な情報のみを取得できるため、アプリケーションがより効率的になります。

スペースを節約するためにビュー・オブジェクトを標準モードで表示したり、ダイアグラム上の様々なタイプのビジネス・コンポーネントを区別するために色を調整できます。図2-12に、これまでに説明した手順に対して効率的に編成されたビジネス・コンポーネント・ダイアグラムの状態を示します。

図2-12 ビュー・オブジェクトSearchTechniciansByNameが含まれるビジネス・コンポーネント・ダイアグラム

検索機能が含まれるビジネス・コンポーネント・ダイアグラムの図

ビュー・オブジェクトSearchTechniciansByNameに必要な機能は、次のとおりです。

  • technicianロールを持つユーザーのみ検索

  • ユーザー指定の名前パラメータによる検索が可能

これを実現するには、ビュー・オブジェクトを編集してこれらの機能を構成する必要があります。ダイアグラムでビュー・オブジェクトをダブルクリックすると、ビュー・オブジェクト・エディタが開きます。

名前による技術者の検索をサポートするバインド変数を追加するには、図2-13のようにエディタの「バインド変数」ページを開き、タイプはString、デフォルト値はnullとしてTechNameと呼ばれる変数を定義します。「コントロール・ヒント」タブで、バインド変数の「ラベル・テキスト」のヒントとして「Name Contains」を定義できます。このラベルは、検索用のこのバインド変数を使用して作成するすべてのページに表示されます。

図2-13 名前による検索用の名前付きバインド変数の追加

「バインド変数」ダイアログの図

次に、「SQL文」ページを開き、SELECT文を細かく調整します。図2-14のように、適切なWHERE句を入力し、大文字と小文字を区別して名前または姓がTechNameというバインド変数の値と一致する技術者のみを検索できます。また、ORDER BY句を入力し、姓別、名前別の順に結果をソートすることもできます。

図2-14 問合せのWHERE句およびORDER BY句の調整

「SQL文」ページとWHERE句による検索の図

前述のユースケースのダイアグラムでは、マネージャは、検索結果を参照しながら技術者の専門技術に関する一連の関連情報を参照することを求めていました。また、専門技術レベルに関連する製品名情報を参照することも必要としていました。ここで、2つ目のビュー・オブジェクトをダイアグラムにドロップし、TechnicianSkillsという名前を付けることができます。この場合、ExpertiseAreaおよびProductというエンティティ・オブジェクト双方の情報を含める必要があるため、これらエンティティを両方とも選択し、新しいビュー・オブジェクトにまとめてドロップできます。ビュー・オブジェクトTechnicianSkillsをダブルクリックすると、結合問合せが自動的に決定されていることを確認できます。また、「属性」ページを使用して、不要な属性を削除できます。

最後に、問合せSearchTechniciansByNameと問合せTechnicianSkillsの結果の間にマスター/ディテールを表示する必要があるため、パレットのビュー・リンク・ツールを使用して、マスター・ビュー・オブジェクトをディテール・ビュー・オブジェクトに接続できます。図2-15に、新しいディテールのビュー・オブジェクトTechnicianSkillsを作成し、これをマスター/ディテール関係としてSearchTechniciansByNameにリンクした結果を示します。

図2-15 ビジネス・コンポーネント・ダイアグラムのマスター/ディテール・ビュー・オブジェクト

ダイアグラムのマスター/ディテール・オブジェクトの図

2.6.3 アプリケーション・モジュールのデータ・モデルにおけるビュー・オブジェクトの使用

アプリケーション・モジュールTechnicianServiceを完成するための最後の手順は、ビュー・オブジェクトを使用したデータ・モデルの定義です。エンティティ・オブジェクトの場合と同様、ビュー・オブジェクトは、複数のユースケースでの問合せに意味があるときに複数のアプリケーション・モジュールで使用できる再使用可能なコンポーネントです。ダイアグラムでビュー・オブジェクトSearchTechniciansByNameおよびTechnicianSkillsを両方とも選択し、これらをアプリケーション・モジュールにドロップすると、タスクが完了します。データ・モデルで使用されるビュー・オブジェクト・インスタンスの名前は短縮できます。これらの名前は、実行時にビュー・オブジェクトの問合せによって作成されるデータ・コレクションをクライアントが識別するときに使用されます。図2-16には、TechnicianServiceのデータ・モデルでマスター/ディテール・コレクションに名前を付けるときにTechniciansおよびSkillsという短縮名を選択した場合の状態が示されています。点線は、UMLダイアグラムのコンポーネントの依存関係を明らかにするために追加する依存線です。

図2-16 2つのビュー・オブジェクトの名前付きインスタンスが含まれるTechnicianServiceアプリケーション・モジュール

名前付きビュー・オブジェクトが含まれるアプリケーション・モジュールの図

ウィザード、エディタまたはビジュアル・ダイアグラマのいずれを使用してアプリケーション・コンポーネントを処理するかどうかとは関係なく、図2-17のように、アプリケーション・ナビゲータには、作成したコンポーネントがすべて表示されます。アプリケーション・モジュールTechnicianServiceなどの特定のコンポーネントを選択すると、このコンポーネントに関する追加情報が構造ウィンドウに表示されます。

構造ウィンドウにより、TechnicianServiceコンポーネントのSourcesフォルダに含まれるXMLファイルは1つのみであることがわかります。ビジネス・サービス・レイヤーの「ADF Business Components」を使用すると、関連するXMLコンポーネント定義ファイルが各コンポーネントに用意されます。所定のコンポーネントの動作を拡張したりそのイベントを処理するためにカスタムJavaコードを記述する必要がない場合、コンポーネントをXML専用モードで使用できます。かわりに、実行時にはベース・フレームワークが提供するクラスが使用され、その動作はXMLコンポーネント定義ファイルのメタデータによって決定されます。

図2-17 アプリケーションを構成するコンポーネントが表示されたアプリケーション・ナビゲータ

コンポーネントが表示されたアプリケーション・ナビゲータの図

2.6.4 サービスのテスト

ユーザー・インタフェースを作成する前でも、統合されているビジネス・コンポーネント・ブラウザを使用してコンポーネントTechnicianServiceを対話的にテストできます。このテスト・ツールを起動するには、アプリケーション・ナビゲータまたはダイアグラムでアプリケーション・モジュールを選択し、ポップアップ・メニューから「テスト...」を選択します。ビジネス・コンポーネント・ブラウザの「接続」ダイアログが表示されたら、「接続」をクリックします。

図2-18のように、コンポーネントTechnicianServiceのデータ・モデルを構成するマスター/ディテール・ビュー・オブジェクト・インスタンスTechniciansおよびSkillsが左側のツリーに表示されます。ツリーにあるこれら2つのインスタンスを関連付けるViewLink11というノードをダブルクリックすると、「バインド変数」ダイアログが表示され、バインド変数TechNameの値を入力するよう求められます。anなどの値を入力し、「OK」をクリックすると、Techniciansというビュー・オブジェクト問合せが実行され、その結果が表示されます。この場合、名前または姓にanが含まれる技術者が表示されます。ビジネス・ドメイン・レイヤーのエンティティ・オブジェクトのUIコントロール・ヒントで定義したラベルとともにUIコントロールが表示されます。

図2-18 アプリケーション・モジュールTechnicianServiceの対話的テスト

ビジネス・コンポーネント・ブラウザの図

ツールバー・ボタンを使用すると、マスター・データをスクロールし、マスター/ディテールの自動調整を確認できます。Alexander Hunoldの電子メール・アドレスをahunold@srdemo.comに更新するために別のフィールドをクリックすると、図2-19のような検証例外メッセージが表示されます。これは、ビジネス・ドメイン・レイヤーのUserエンティティ・オブジェクトにカプセル化したビジネス・ルールの1つです。この例外により、ビュー・オブジェクト内の更新可能な行と、これらが参照する基礎的エンティティ・オブジェクト間で行われる自動調整が検証されます。

図2-19 失敗したエンティティ・オブジェクトの検証規則を示すビジネス・コンポーネント・ブラウザ

テストの失敗を示すビジネス・コンポーネント・ブラウザの図

Oracle ADFを使用した開発時には、ビジネス・コンポーネント・ブラウザが非常に便利です。エンド・ユーザーのUIページを作成(または使用)しなくても、ビジネス・サービス・コンポーネントのデータ・モデルをすべて実行できます。これにより、問題の診断に要する時間の節約や、ビジネス・サービス・レイヤーに追加した最新の問合せやビジネス・ルールのみのテストが可能になります。

2.6.5 データ・バインディングを可能にするアプリケーション・モジュールのデータ・コントロール

ビジネス・サービスを準備してから、ユーザー・インタフェースの作成について検討します。作成したアプリケーション・モジュールはJSR-227準拠のデータ・コントロールとして自動的に公開されるため、この仕様に応じたJDeveloperの豊富な設計時サポートを使用してデータ・バインディングをドラッグ・アンド・ドロップできるようになります。図2-20に、データ・コントロール・パレットを示します。このパレットには、アプリケーション・モジュール定義の作成および変更に応じてこの定義と自動的に同期がとられるTechnicianServicesDataControlが表示されています。この中には、TechnicianServiceのデータ・モデルでのビュー・オブジェクト・インスタンスを表すTechniciansおよびSkillsというデータ・コレクションがあります。Skillsというデータ・コレクションはTechniciansの子として表示されており、ビジネス・サービスの作成時に設定したマスター/ディテール関係を反映しています。それぞれのデータ・コレクションの各行で使用可能な属性は、子ノードとして表示されています。図で閉じられているデータ・コレクション・レベルの「Operations」フォルダには、ADF Modelレイヤーでサポートされるデータ・コレクションに対する組込み操作(「前へ」、「次へ」、「先頭へ」、「最後へ」など)が含まれます。

図2-20 宣言的なデータ・バインディングのためにビジネス・サービスを表示するデータ・コントロール・パレット

データ・コントロール・パレットおよびデータ・バインディング設定の図

注意:

Webサービス、URLから取得されたXMLデータ、JavaBeans、EJBを操作するために別の種類のデータ・コントロールを作成する場合、これらのデータ・コントロールはデータ・コントロール・パレットに適切に表示されます。プロジェクトでこれらのデータ・コントロールの1つを初めて作成する場合、JDeveloperでは、これらのデータ・コントロールに関する構成情報が含まれるDataControls.dcxファイルが作成されます。さらに、サービス・インタフェースに関連するデータ型ごとにXML構造定義ファイルが作成されます。

アプリケーション・モジュールを操作する場合、これらの追加ファイルは必要ありません。これは、アプリケーション・モジュールがすでにメタデータ駆動型のコンポーネントであり、JSR 227データ・コントロールとして自動的に公開するために必要なすべての情報がそのXMLコンポーネント定義ファイルに含まれているためです。


2.7 データのドラッグ・アンド・ドロップによる新規JSFページの作成

データ・コントロール・パレットの基本事項について理解したところで、ドラッグ・アンド・ドロップによるデータ・バインディングを実行して、ページ作成を開始します。このページではADF Facesコンポーネントを使用するため、最初にそれらのコンポーネントを使用するようプロジェクトのタグ・ライブラリが構成されていることを確認します。アプリケーション・ナビゲータのViewControllerプロジェクトをダブルクリックすると、「プロジェクト・プロパティ」ダイアログが表示されます。図2-21のように、このダイアログの「JSPタグ・ライブラリ」ページで、構成されているライブラリを確認できます。ADF Faces ComponentsライブラリおよびADF Faces HTMLライブラリが含まれていない場合は、このページで追加できます。

図2-21 ADF Facesを使用するためのViewControllerプロジェクトのタグ・ライブラリの構成

ADFタグ・ライブラリ用の「プロジェクト・プロパティ」ページの図

次に、アプリケーション・ナビゲータでViewControllerプロジェクトを選択し、ポップアップ・メニューから「JSFナビゲーションを開く」を選択し、前に作成したスケルトンJSFページ・フローに戻ります。ダイアグラムで/searchtechnicians.jspxのページ・アイコンをダブルクリックし、図2-22のように、JSF JSPの作成ウィザードを起動します。このページを使用して、Webページsearchtecnicians.jspxを表すファイルを作成します。

図2-22 JSF JSPページの新規作成

JSF JSPの作成ウィザードのステップ1の図

*.jsp拡張子を持つJSPページの操作に慣れている読者が多いと思われますが、そのかわりに標準のXMLベースのJSPドキュメントを使用することは、次の理由からJSF開発のベスト・プラクティスとなります。

ウィザードの最初のページで「終了」をクリックすると、すべてデフォルト設定のままにできます。JSF JSPの作成ウィザードが完了した後、ビジュアル・エディタで新しいページが開きます。このページでは、図2-23のように、ドラッグ・アンド・ドロップするのみでデータがバインドされたページを作成できます。データ・コントロール・パレットからページに各要素をドロップすると、その要素に対して作成できるUI要素の適切なオプションを示すポップアップ・メニューが表示されます。

図2-23 ビジュアル・デザイナでのユーザー参照JSFページ

ビジュアル・デザイナでのJSFページの図

このページを作成する基本手順は、次のとおりです。

  1. コンポーネント・パレットの「ADF Faces Core」ページからpanelHeaderコンポーネントをページにドロップし、プロパティ・インスペクタでそのtext属性を「Search Technicians」に設定します。

  2. データ・コントロール・パレットにデータ・コレクションTechniciansの組込み操作ExecuteWithParamsをドロップし、ADFパラメータ・フォームを作成します。この手順により、バインド変数TechNameの値を収集してボタンがクリックされたときに値をビュー・オブジェクトに渡すためのラベル、フィールドおよびボタンを格納するpanelFormコンポーネントが作成されます。プロパティ・インスペクタを使用して、作成されるコマンド・ボタンのテキストを「Go」に設定します。

  3. データ・コントロール・パレットからデータ・コレクションTechniciansをドロップし、ADF読取り専用フォームを作成します。この操作により、データ・コレクションTechniciansの行の属性のラベルおよびフィールドを格納するpanelFormコンポーネントが作成されます。表示される「フォーム・フィールドの編集」ダイアログで、リストからUserIdという属性を削除し、ページに表示されないようにすることができます。

  4. 再度、データ・コレクションTechnicians「Operations」フォルダから組込み操作Previousをコマンド・ボタンとしてページにドロップします。続けて、このボタンの右に組込み操作Next「Next」ボタンをドロップします。

  5. データ・コントロール・パレットにSkillsというデータ・コレクションをADF読取り専用表としてドロップします。表示される「表の列の編集」ダイアログで、ExpertiseLevelおよびNameという属性の列のみを表に含め、「上へ」ボタンおよび「下へ」ボタンを使用してNameが先頭になるように順序を変更します。「ソートの有効化」チェック・ボックスを選択し、列ヘッダーをクリックしてデータをソートします。

  6. コンポーネント・パレットからcommandButtonをページの下部にドロップし、Textというプロパティを「Update Profile」に変更します。Actionというプロパティを「UpdateProfile」に設定します。これを行うには、このプロパティをリストから選択し、前にJSFページ・フロー・ダイアグラムで作成したUpdateProfileナビゲーション・ルールにこのボタンが従うようにします。


注意:

図2-23とまったく同じ内容のページを作成するには、さらにいくつかのドラッグ・アンド・ドロップ操作を実行する必要があります。これには、デフォルト・コンポーネントのグループ化、オブジェクト間のオブジェクト・セパレータの追加、ELの使用による現在の行数および合計行にバインドされた読取り専用テキスト・ファイルのドロップなどの操作があります。これらの手順は、後半の項で説明します。

ページは、いつでも実行またはデバッグして、作成したユーザー・インタフェースをテストできます。ビジネス・ドメイン・レイヤーのエンティティ・オブジェクト属性に設定したUIコントロール・ヒントは、ユーザー・インタフェースに自動的に表示されます。名前による検索を行うと、姓または名前に入力した文字列が含まれている技術者が検索されます(大文字と小文字が区別されます)。「前へ」および「次へ」ボタンを使用すると、検索で見つかった技術者間を移動して、各技術者に関連する一連のスキルとともに、その専門技術が対応している製品名を表示できます。図2-24に、単純なマスター/ディテール検索ページを示します。

図2-24 マスター/ディテール・データを含む単純な技術者検索ページ

マスター/ディテール・データを含むWebページの図

2.8 関連するバインディング・メタデータ・ファイルの詳細

ページのUIコンポーネントをサポートするバインディングのグループは、ページ定義ファイルというページ固有のXMLファイルに記述されます。データ・コントロール・パレットからデータ・バインドされたコンポーネントが最初にページにドロップされたときに、JDeveloperによりそのコンポーネントのページ定義ファイルが作成されます。図2-25は、構造ウィンドウのsearchtechniciansPageDef.xmlファイルの内容を示しています。データ・コントロール・パレットを使用してコンポーネントをページに追加するたびに、適切な宣言的バインディング・エントリがこのページ定義ファイルに追加されます。

たとえば、前の項の手順を実行し、データ・バインドされたUIコンポーネントをsearchtechnicians.jspxページで作成した後、同じ名前の組込みデータ・コントロール操作を起動するExecuteWithParamsという名前のアクション・バインディングが追加されたことをこの図で確認できます。また、TechniciansおよびSkillsビュー・オブジェクト・インスタンスの行のデータ・コレクションを処理するために、TechniciansIteratorおよびSkillsIteratorという名前のイテレータ・バインディングがそれぞれ追加されています。さらに、ドロップされたボタンをサポートするために、NextおよびPreviousというアクション・バインディングが追加されています。最後に、読取り専用のoutputTextフィールドおよび表をサポートするために、適切な名前の値バインディングが追加されています。

図2-25 searchtechnicians.jspxのページ定義XMLファイル

この図は、ページ定義XMLが表示された構造ウィンドウを示しています。

Oracle ADF Modelのデータ・バインディングをプロジェクトで最初に実行したときに、JDeveloperによりDataBindings.cpxという追加のXMLファイルが1つ作成されます。このファイルには、ページ名とページ定義名のマッピングに関する情報が格納され、プロジェクトで使用中のデータ・コントロールがリストされます。図2-26は、構造ウィンドウに表示されたDataBindings.cpxファイルを示しています。このファイルは、実行時にOracle ADF Modelのバインディング・コンテキスト全体を作成するために使用されます。また、このファイルのページ・マップ情報とページ定義情報は、ユーザーがアクセスしたアプリケーション・ページで必要とされたときに、そのページのバインディング・コンテナをインスタンス化するために使用されます。

図2-26 DataBindings.cpxの構造

DataBindings.cpxファイルの構造ウィンドウの図

DataControls.dcxDataBindings.cpxおよびPageDef.xmlメタデータ・ファイルの構造および内容の詳細は、付録A「ADF XMLファイルのリファレンス」を参照してください。

2.9 コンポーネントが式言語(EL)を通じてバインディングを参照する仕組み

ドラッグ・アンド・ドロップによるデータ・バインディング操作を実行すると、JDeveloperにより、必要なADF Modelのバインディング・メタデータがページ定義ファイルに作成され、目的のJSF UIコンポーネントを示すタグが生成されます。重要なのは、コンポーネントの様々なプロパティが構成されてバインディングを参照するEL式の値が割り当てられ、コンポーネントとバインディング定義が結び付けられることです。図2-27に、ページのUIコンポーネントがページ定義内のバインディングを参照する仕組みを示します。実行時には、これらのバインディングは、ページに関連するバインディング・コンテナに含まれます。

図2-27 ページのUIコンポーネントとバインディングを関連付けるEL式

この図は、EL式、UIコンポーネントおよびバインディング・フローを示しています。

簡単な例として、「Previous」ボタンを検討します。この組込み操作をボタンとしてドロップすると、Previousというアクション・バインディングがページ定義ファイルに作成され、commandButtonコンポーネントの2つのプロパティが次のように設定されます。

最初のEL式により、関連するデータ・コレクションのPrevious組込み操作にバインドされたバインディング・コンテナに含まれるPreviousという名前のアクション・バインディングを実行するボタンが関連付けられます。2番目のEL式により、Previous操作が無意味なとき(ユーザーがデータ・コレクションの最初の行に移動しているときなど)にボタンが自動的に無効化されます。

ページ内の別の例として、ユーザーの電子メール・アドレスを表示する読取り専用のoutputTextフィールドや、このフィールドが含まれるpanelLabelAndMessageコンポーネントなどを検討すると、Email値バインディングを参照するためにこれらのコンポーネントに次のプロパティが設定されていることがわかります。

これらの設定の組合せにより、値をEmailバインディングから取得するoutputTextコンポーネントと、表示ラベルとしてEmailバインディングのlabelプロパティを使用するpanelLabelAndMessageコンポーネントが関連付けられます。ビジネス・ドメイン・レイヤーのエンティティ・オブジェクトの属性にUIコントロール・ヒントを構成したため、これらのコントロール・ヒントがビュー・オブジェクトの属性によって継承されます。この情報はバインディングによって実行時に公開されるため、EL式を使用して、ラベルやフォーマット・マスクなどのコントロール・ヒントをコンポーネントから簡単に参照できます。

前述のドラッグ・アンド・ドロップによるデータ・バインディングの手順では、ページ上に現在のレコードを表示する方法(「N of M」など)について説明していませんでした。これを作成するには、次のプロパティを参照する必要があります。

バインディングによってこれらのプロパティが公開されるため、このような現在のレコード表示を作成するのは簡単です。コンポーネント・パレットから3つのoutputTextコンポーネントをドロップし、各コンポーネントのvalue属性を適切なEL式に設定します。最初のコンポーネントでは、Techniciansデータ・コレクションから戻される結果のレンジ内における現在の行番号を表示するため、そのvalue属性には、TechniciansIteratorバインディングの(ゼロ・ベースの)rangeStartプロパティを参照するEL式を設定する必要があります。

#{bindings.TechniciansIterator.rangeStart + 1}

2番目のoutputTextコンポーネントでは、ofという語のみを表示するため、そのvalueプロパティに文字列定数のofを設定するのみで十分です。3番目のoutputTextコンポーネントでは、コレクションの合計行数を表示する必要があります。この場合、イテレータ・バインディングのestimatedRowCountプロパティを参照するようにします。

#{bindings.TechniciansIterator.estimatedRowCount}

2.10 必要に応じたバインディング・プロパティの構成

ページ定義でバインディングのプロパティを参照または設定する場合、ページのポップアップ・メニューで「ページ定義に移動」を選択します。たとえば、各イテレータ・バインディングでページごとに表示される行数を変更するには、このメニューを使用してRangeSizeプロパティを設定します。図2-27のように、ページ定義を開いた後に、プロパティ・インスペクタを使用してTechniciansIteratorバインディングのRangeSize1に、SkillsIteratorの同じプロパティを2に設定してあります。各イテレータのRangeSizeプロパティを設定すると、ページ上に1人のユーザーと2つの専門技術領域が同時に表示されます。

2.11 実行時にバインディングが作成される仕組み

JSFページ用のADF Modelバインディングの基本事項の説明の仕上げとして、実行時にデータ・コントロールと宣言的バインディングが作成される仕組みについて説明します。Oracle ADFのデータ・バインディングを操作するためのプロジェクト構成の一環として、JDeveloperでは、クライアントからJSPページがリクエストされるたびにトリガーされる追加ハンドラが登録されます。このハンドラは、ViewControllerプロジェクトの標準のJ2EE Webアプリケーション構成ファイル(web.xml)にリストされます。これにより、関連するADF Model XML構成ファイルに基づいて現在のページに適したバインディング・コンテナが設定され、EL式#{bindings}を使用してアクセスできるようになります。Webページ・リクエストの後続の処理時には、JSF標準により、ページのライフサイクルと呼ばれる一連の予測可能な処理手順が指示されます。Oracle ADFは、標準メカニズムを使用してこれらの処理手順を利用し、表示用データの準備、組込み操作またはカスタム・サービス・メソッドの起動、アプリケーション・モジュールのデータ・モデル内のビュー・オブジェクトに対するデータの更新および検証を自動化します。


注意:

JSFおよびOracle ADFの使用時にページ・リクエストを処理する方法に関する手順の詳細は、29.2項「Oracle ADFおよびJSFを使用したWebページ・リクエストのライフサイクル」を参照してください。

2.12 表示のデータ駆動性の向上

基本的なページ作業に慣れたら、ページのいくつかの部分に手を加えて機能性を向上することも可能です。たとえば、ADFバインディングのプロパティを参照して、コンポーネント・グループの表示と非表示を切り替えることや、コンポーネントの代替セットを交互に入れ替えることができます。

2.12.1 バインディング・プロパティに基づくコンポーネント・グループの表示と非表示

マネージャが1人のユーザーと一致する名前をsearchtechnicians.jspxページに入力したときに、無効化された「Next」および「Previous」ナビゲーション・ボタンや「1 of 1」というレコード・カウンタは不適切です。かわりに、図2-28のように、単一行のみが戻された場合はこれらのコンポーネントを非表示にできます。

図2-28 不要な場合に非表示にされるナビゲーション・ボタン付きのパネル

この図は、非表示にされる表示結果セットの情報を示しています。

実際、このような動作とすることは簡単です。まず、ナビゲーション・ボタンとレコード・カウンタ表示をpanelHorizontalなどの格納型のパネル・コンポーネントに配置します。これらを格納するパネルを作成した後、ビジュアル・エディタまたは構造ウィンドウでドラッグ・アンド・ドロップを実行し、新しいコンテナ・コンポーネントの内部に既存のコントロールを配置します。次に、パネル内のすべてのコンポーネントの表示と非表示を切り替えるため、パネルのrendered属性の値にデータ駆動型のEL式を設定します。

前述したとおり、イテレータ・バインディングのデータ・コレクションの行数は、そのestimatedRowCountプロパティを使用して取得できます。図2-29は、EL選択ダイアログを示しています。このダイアログを表示するには、panelHorizontalコンポーネントを選択してからプロパティ・インスペクタでrendered属性をクリックし、「...」ボタンをクリックします。ADF Bindingsフォルダとbindingsノードを開いて現在のページのバインディング・コンテナ内のバインディングを表示して、TechniciansIteratorを表示します。さらにこのイテレータ・バインディングを開いて、開発者がELで参照できる最も一般的なプロパティを表示します。estimatedRowCountを選択して「>」ボタンをクリックし、行数が1より大きいかどうかを比較する比較演算子を挿入することで、この式をブール式に変更します。この式を設定すると、結果の行数が2以上の場合にのみ、実行時にパネルがレンダリングされます。

図2-29 バインディング・プロパティに基づいてレンダリングされるパネルの属性の設定

この図は、レンダリング済ダイアログを示しています。

2.12.2 バインディング・プロパティに基づくコンポーネントの代替セットの入替え

サンプル・ページの別の使用例を検討してみます。行が戻されなかった場合、読取り専用フォームのデフォルトでは、通常はデータ値が表示される空白領域の横にプロンプトが表示されます。また、専門技術領域の表には、列ヘッダーと「No rows yet」という語を含む空白行が表示されます。アプリケーションの機能性を多少向上する目的で、イテレータ・バインディングの結果コレクションで行が戻されなかった場合に、このデフォルトとは異なる文字を表示できます。たとえば、図2-30のように「No matches. Try again」という簡単なメッセージを表示できます。.

図2-30 検索結果が空のコレクションである場合の代替表示

結果セットが空である場合の代替表示の図

JSFには、実行時に一定の方法でレンダリングされるコンポーネントの1つ以上の名前付き論理グループを、他のUIコンポーネントに格納できるようにするファセットという基本機能があります。ADF Facesには、実行時にレンダリングするファセットを決定するために独自のFacetName属性でEL式を評価できる便利なswitcherコンポーネントが付属しています。このコンポーネントを効果的に使用すると、動的かつ宣言的な方法でコンポーネントの任意のグループを交互に切り替えることができます。ユーザー情報と専門技術領域の表を表示するコンポーネントを1つのパネルにグループ化している場合、switcherコンポーネントを使用して、戻された行数に応じてパネルと簡単なメッセージの表示を切り替えることができます。

図2-31は、switcherコンポーネント挿入後のJSFコンポーネントの階層状態を反映したsearchtechnicians.jspxページの構造ウィンドウを示しています。まず、2つのJSFファセットを設定し、それぞれにfoundおよびnotfoundなどのわかりやすい名前を付けます。次に、構造ウィンドウでドラッグ・アンド・ドロップを使用し、適切なファセットに既存のコンポーネントを組み入れます。foundファセットには、技術者と専門技術領域の情報を表示するすべてのコンポーネントを格納したパネルを組み入れます。notfoundファセットには、「No matches. Try again」というメッセージを表示するoutputTextコンポーネントのみを組み入れます。最後に、switcherコンポーネントのDefaultFacetプロパティをfoundに設定し、このファセットがデフォルトで表示されるようにします。

図2-31 foundおよびnotfoundファセットが含まれるswitcherコンポーネント

switcherコンポーネントの構造ウィンドウの図

switcherのfacetName属性を次のEL式に設定することで、行数が0より大きい場合にはfoundファセットが使用され、0と等しい場合にはnotfoundファセットが使用されます。

#{bindings.TechniciansIterator.estimatedRowCount > 0 ? 'found' : 'notfound'}

Oracle ADFの宣言的なバインディング、ADF FacesコンポーネントおよびEL式の組合せにより、面倒で反復の多いコードを記述していた処理にも簡単に対応できます。

2.13 編集ページの追加とユースケースの完成

「Search Technicians by Name」ユースケース用のページの実装が完了したら、次は「Update Technician Profile」ユースケースです。マネージャがプロファイルを更新するときに技術者ユーザーのすべての属性を表示できるようにするには、updateprofile.jspxページをサポートするために、Userエンティティ・オブジェクトのすべての属性を含むビュー・オブジェクトを作成する必要があります。この新しいビュー・オブジェクトはTechnicianServiceのデータ・モデルに追加した後、データ・コントロール・パレットに表示されます。ここで、このビュー・オブジェクトをupdateprofile.jspxページにドロップすることにより、編集フォームを1つのステップで作成できます。

2.13.1 データ・モデルに対する別のビュー・オブジェクトの追加

Userエンティティ・オブジェクトのすべての属性を含むビュー・オブジェクトを追加するには、Modelプロジェクトでビジネス・コンポーネント・ダイアグラムを再度開き、コンポーネント・パレットから新しいビュー・オブジェクトをドロップします。この新しいビュー・オブジェクトは技術者に関するすべてのデータの表示に使用されるため、Techniciansという名前を付けます。Userエンティティ・オブジェクトをダイアグラムの新しいビュー・オブジェクトにドロップし、ビュー・オブジェクトをダブルクリックしてビュー・オブジェクト・エディタを開きます。このエディタを使用して、次を実行できます。

  • user_role = 'technician'である行のみを問い合せるためにSearchTechniciansByNameビュー・オブジェクトで使用したものと同じWHERE句を追加します。

  • UserId属性を新規の間のみ更新可能に設定し、エンド・ユーザーが既存の行のUserIdの値を更新できなくします。

ダイアグラムに戻り、Techniciansビュー・オブジェクトをTechnicianServiceにドロップしてこのデータ・モデルで使用できるようにし、ビュー・オブジェクト・インスタンスにUpdateProfileという名前を付けます。図2-32は、更新されたビジネス・サービス・モデルを示しています。ここでは、対応するUpdateProfileデータ・コレクションがデータ・コントロール・パレットに即時に表示されています。

図2-32 更新されたビジネス・サービス・ダイアグラム

更新されたビジネス・サービス・ダイアグラムの図

2.13.2 編集ページの作成

updateprofile.jspxページのビジュアル・エディタを開くには、JSFページ・フロー・ダイアグラムを開き、/updateprofile.jspxページをダブルクリックし、JSF JSPの作成ウィザードの「終了」をクリックします。

図2-33のように、次の手順を使用して編集フォームを作成できます。

  • コンポーネント・パレットの「ADF Faces Core」ページからpanelHeaderコンポーネントをページにドロップし、プロパティ・インスペクタでそのtext属性を「Update Technician Profile」に設定します。

  • データ・コントロール・パレットからUpdateProfileデータ・コレクションをドラッグし、ページにADFフォームとしてドロップします。

  • データ・コントロール・パレットでTechnicianServiceデータ・コントロールの「Operations」フォルダを開き、そのCommit組込み操作を構造ウィンドウでpanelFormのfooterファセット・フォルダにドロップします。TextプロパティをSaveに変更します。Disabledプロパティをfalseに設定します。Actionプロパティをリストから選択してBackToSearchに設定し、このボタンが、前にJSFページ・フロー・ダイアグラムで作成したBackToSearchナビゲーション・ルールに従うようにします。

  • 構造ウィンドウでRollback組込み操作をpanelFormのfooterファセットにドロップします。TextプロパティをCancelに変更します。Disabledプロパティをfalseに設定します。「Save」ボタンの場合と同様に、このボタンのActionプロパティをBackToSearchに設定します。

図2-33 技術者プロファイルの更新

ビジュアル・デザイナでの技術者プロファイルの更新の図

2.13.3 検索ページと編集ページの同期化

マネージャがプロファイルを更新する必要のある技術者を見つけた場合、「UpdateProfile」ボタンをクリックすると、updateprofile.jspxページが表示されます。updateprofile.jspxページが編集対象の技術者を認識できるようにするには、宣言技術を使用して、属性を現在の技術者の行を示すキーの値に設定します。図2-34に、宣言的なsetActionListenerコンポーネントを「Update Profile」コマンド・ボタンの子として追加した後の構造ウィンドウを示します。このsetActionListenerコンポーネントは、コピー対象の値を確認するためのEL式と、この値の割当て先のプロパティを確認するためのEL式を評価します。プロパティ・インスペクタには、EmailバインディングのrowKeyStrプロパティから値をコピーし、この値をリクエスト・スコープ内のrowKeyStrという名前の属性の値に設定する必要があることを示すEL式が示されています。

図2-34 リクエスト属性の宣言的設定

構造ウィンドウとプロパティ・パレットの属性の図

updateprofile.jspxページのページ定義で、別の宣言技術を使用し、ページがレンダリングされるたびにsetCurrentRowWithKey組込み操作のアクション・バインディングを起動できます。このアクション・バインディングが受け入れるパラメータの値は、#{requestScope.rowKeyStr}式を使用して指定できます。これにより、コードを記述せずに、ブラウザ・ページで現在行のキーを使用して、UpdateProfileデータ・コレクションで編集対象として現在行を設定できます。これらの手順により、コードを記述せずに、2つのページを同期化できます。

2.13.4 データを最初に表示するかどうかの制御

searchtechnicians.jspxのようなページでは、エンド・ユーザーの最初のページ参照時にビュー・オブジェクトの問合せ結果を即時に表示する必要がある場合があります。一方、エンド・ユーザーによる問合せ実行時には、最初に検索基準を入力可能にする必要がある場合もあります。searchtechnicians.jspxページの動作をこのように設定する場合、EL式に基づいてデータの初期表示の条件を設定できます。このタスク実行のために用意されている便利な式を使用すると、ページが初めて表示されたものかどうか、またはエンド・ユーザーがページ上のボタンやリンクをクリックしたため、ブラウザがイベントの処理リクエストをサーバーに戻したかどうかを確認できます。図2-35のように、TechniciansIteratorバインディングのRefreshConditionプロパティを次のEL式に設定します。

${adfFacesContext.postback == true}

これにより、イテレータからデータが表示されるのは、ユーザーがページと対話した後のみにすることができます。ページが初めてレンダリングされる場合、このpostbackプロパティはfalseになり、関連するデータ・コレクションは空になります。

図2-35 イテレータによるデータ表示の宣言的制御

構造ウィンドウとプロパティ・パレットのイテレータの図

2.13.5 最終結果の実行

ここでページを実行すると、ページが機能していることがわかります。マネージャは、技術者の検索、スキルの参照、技術者のプロファイルの更新、変更の保存を行うことができます。マネージャが、エンティティ・オブジェクトのドメイン・ビジネス・レイヤー内にカプセル化されたビジネス・ルールに違反するデータを誤って更新した場合は、自動的にエラー・メッセージが表示されます。図2-36に、電子メール・アドレスをドメイン名が含まれる値に更新しようとした場合の結果を示します。Userエンティティに追加した他のビジネス・ルールに違反した場合や、同一エンティティ・オブジェクトを参照する別のビュー・オブジェクトを追加した場合も、同様のエラーが表示されます。複数のマネージャがアプリケーションを同時に使用すると、ビジネス・サービスを構成するADFコンポーネントにより、行ロック、更新の上書きの阻止およびアプリケーション・モジュール・プーリングを介して、マルチユーザーが自動的に並行処理されます。

図2-36 失敗したエンティティ・オブジェクトのビジネス・ルールの自動表示

失敗した規則検証のWebページの図

2.14 必要なコードの長さについて

これまで、次を使用して、MVCアーキテクチャに基づく簡単かつ完全なJ2EEアプリケーションを作成する手順を説明してきました。

これまでの技術は視覚的であるとともに宣言的なものであり、ここで示した結果を実現するためにJavaコードを作成する必要はありませんでした。実際、これまでに作成したすべての*.javaファイルのワークスペース・ディレクトリを検索すると、結果は図2-37のようになります。ADFの初心者に対して推奨される、必要なときにのみJavaコードを生成するという方法を採用する場合、JDeveloperによって作成される*.javaファイルは4つのみです。また、これらのファイルの内容はすべてADF Business Componentsに関連する翻訳可能文字列であるため、これらのファイルはコードとして計算されることもありません。

図2-37 これまでに必要なJavaファイルはJavaメッセージ・バンドルのみ

コマンド・プロンプトでのJavaファイル・リストの図

たとえば、メッセージ・バンドル・ファイルの1つとしてUserImplMsgBundle.javaの内容を確認すると、例2-1のようになります。このファイルには、Userエンティティ・オブジェクトの属性に定義したUIコントロール・ヒントとともに、ビジネス・ルールのバリデータのエラー・メッセージ文字列が含まれています。これらの標準Javaメッセージ・バンドル・ファイルは自動的に管理されるため、多言語アプリケーションの作成が容易になります。JavaServer Facesでは、翻訳可能文字列を個別リソース・ファイルに効率的に分けるために同様のメカニズムが採用されています。実行時には、JSFとADFの両方において、ユーザーのブラウザの言語設定に基づいて最も適切なメッセージ・リソースのバージョンが使用されます。

例2-1 UserImplMsgBundleの翻訳可能なコントロール・ヒントおよびエラー・メッセージ

public class UserImplMsgBundle extends JboResourceBundle {
  static final Object[][] sMessageStrings = {
    { "UserRole_LABEL", "Role" },
    { "PostalCode_TOOLTIP", "Zip" },
    { "UserRole_Rule_0",
       "Role must be user, technician, or manager" },
    { "Email_Rule_0",
      "Please use the 8-character username without the domain name" },
    { "User_Rule_0",
      "This user id is already taken. Please choose another." },
    { "CountryId_TOOLTIP", "Country" },
    { "City_TOOLTIP", "City" },
    { "LastName_LABEL", "Last Name" },
    { "StateProvince_TOOLTIP", "State" },
    { "FirstName_LABEL", "First Name" },
    { "Email_LABEL", "Email Address" },
    { "StreetAddress_TOOLTIP", "Address" },
    { "UserId_LABEL", "User Id" }
  };
// etc.
}

このため、これらのメッセージ・バンドル・ファイルを除いて、Javaコードを1行も記述または生成せずに、すべての作業を行いました。これは、特にビジネス・サービス・レイヤーに対してADF Business Componentsテクノロジを使用する場合など、JSFとOracle ADFの組合せによって提供される宣言機能の奥行きと幅広さを証明するものです。これで、Oracle ADFを使用したJ2EEアプリケーション構築の概要説明を終了します。このガイドの残りの部分では、Oracle ADF、ADF Business ComponentsおよびJSFを使用して実用的なサンプル・アプリケーションを作成する方法を詳細に説明します。