Oracle® Fusion Middleware Oracle Application Development FrameworkによるFusion Webアプリケーションの開発 12c (12.2.1) E70030-02 |
|
![]() 前 |
![]() 次 |
この章の内容は次のとおりです。
Fusionテクノロジ・スタックにはアクティブ・データ・サービス(ADS)が含まれます。これは、ADF Facesコンポーネントに対してリアルタイムでデータ更新を提供するためのサーバー側のプッシュ・フレームワークです。ADF Facesコンポーネントをデータ・ソースにバインドすると、ADSでは、ブラウザ・クライアントに明示的な更新リクエストを要求することなく、ブラウザ・クライアントにデータ更新をプッシュします。たとえば、ADFデータ・コントロールの属性にバインドされた表があり、その属性値はサーバー上で定期的に変化するため、表には更新された値が表示されるようにします。サーバー上でデータが変更されたときには必ず、ADFモデル・レイヤーがコンポーネントに通知し、コンポーネントが変更後のデータを再レンダリングして、新しくなった値をハイライトするように(図52-1を参照)アプリケーションとコンポーネントを構成できます。
図52-1 更新されたデータを強調表示で示す表
ADF FacesコンポーネントにバインドされているADFデータ・コントロールに関連付けられたビジネス・ロジックの結果として、バックエンドで変化するデータをレンダリングするには、自動部分ページ・レンダリング(PPR)のかわりにADSを使用します。自動PPRでは(通常、ユーザーが)サーバーに要求を送信する必要がありますが、ADSは、変更されたデータがサーバーに到着したときに、このデータをデータ・ストアからプッシュできるようにします。また、PPRとは対照的に、ADSにより、コンポーネントはコンポーネント全体ではなく、変更されたデータのみをレンダリングできるようになります。したがって、アプリケーションが、定期的に変化するデータに対応する必要がある場合にはADSが理想的です。
この機能を使用するには、ADSを使用するようにアプリケーションを構成する必要があります。アプリケーション・サービスがADSをサポートしていない場合は、サービスのプロキシを作成して、データがソースで更新されたときに、コンポーネントがこのデータを表示できるようにする必要もあります。
どのADF FacesページでもADSを使用できます。ただし、アクティブ・データを処理するように構成できるのは、次のADF FacesコンポーネントおよびADFデータ視覚化(DVT)コンポーネントのみです。
activeImage
activeOutputText
chart
(すべてのタイプ)
gauge
(すべてのタイプ)
pivotTable
tree
treeTable
geoMap
(mapPointTheme
のみ)
sunburst
treemap
DVTコンポーネントのADSサポートの詳細は、『Oracle ADF FacesによるWebユーザー・インタフェースの開発』のアクティブ・データのサポートに関する項を参照してください。
また、コレクションベースのコンポーネント(table
、tree
、pivotTable
など)は、outputText
コンポーネントまたはsparkChart
がアクティブ・データを表示するように構成されている場合にのみADSをサポートします。その他のコンポーネントは、コレクションベース・コンポーネントの内部でサポートされません。
ADS対応フレームワークの制限事項は次のとおりです。
ADSは、フィルタリングが有効化されているADF Faces表コンポーネントのアクティブ・データをサポートしません。実行時に表をフィルタリングすると、アクティブ・データは表示されません。
ADSは、デフォルトでは、ユーザーの非アクティブ状態によってタイムアウトしません。アクティブ・セッションが無期限に維持されないように、web.xml
context-parameter oracle.adf.view.rich.poll.TIMEOUT
を構成し、ユーザーが非アクティブになってからタイムアウトするまでのADSの実行時間を指定できます。詳細は、「アクティブ・データ・サービスのセッション・タイムアウトの構成方法」を参照してください。
ユーザーがブラウザ・ページから移動しようとし、ブラウザによって表示された警告ダイアログで終了アクションを取り消してそのページに留まった場合、ADSは再起動しません。この制限を回避するために、ADF Facesでは、ページ終了時の確認ダイアログの表示をサポートするブラウザのbeforeunload
イベントを処理するクライアント・リスナーをサポートしています。このイベントを処理するADFドキュメントでは、ユーザーはADSによって処理が停止される前に終了を取り消すことができます。詳細は、『Oracle ADF FacesによるWebユーザー・インタフェースの開発』のADS対応ページからの移動に関する必知事項に関する項を参照してください。
注意:
ADF DVTコンポーネントによって追加の制限が適用される場合があります。詳細は、『Oracle ADF FacesによるWebユーザー・インタフェースの開発』のアクティブ・データのサポートに関する項を参照してください。
ADSのフレームワークには、ソースからUIコンポーネントにアクティブ・データを送信するために提携しあう、多数のコンポーネントが含まれます。データ・イベントが発生したとき、関連するADFモデル・レイヤー・バインディングがアクティブ・データ用に構成されている場合、アクティブ・データ・モデルにより、データがイベント・マネージャに配信されます。その後、イベント・マネージャはデータを取得してプッシュ・サービスを起動し、このデータは、プッシュ・サービスによって、その構成内容(詳細は「データ・トランスポート・モード」を参照)に基づいて適切なコンポーネントに配信されます。その後、このコンポーネントはサーバーからプッシュされた新しいデータを適用します。図52-2に、ADSフレームワークを示します。
図52-2 アクティブ・データ・サービスのフレームワーク
アクティブ・データ・サービスを使用するには、データが変化したときにイベントを公開するデータ・ストアが必要です。また、このようなイベントに反応するビジネス・サービスを作成する必要もあります。デフォルトでは、ADFビジネス・コンポーネントは、データ・イベントには反応しません。アクティブ・データ・プロキシ・フレームワークでは、ADFビジネス・コンポーネントを含むあらゆるタイプのデータ・ソースとADSを提携させることができます。このフレームワークはActiveDataModel
をJSFモデルと組み合せます。したがって、ActiveDataModel
とJSFモデルの両方ではなく、このプロキシのみの機能をオーバーライドする必要があります。
ADSフレームワークは次のアイテムにより構成されています。
ActiveDataModel
インタフェース: アクティブ・データ・モデルを抽象化したもの。その役割は次のとおりです。
アクティブ・データの開始と停止
現在のアクティブ・データのイベントIDを追跡
モデルがアクティブ・データを必要としているかどうかをレンダラに通知
イベント・マネージャ: ADFモデル・レイヤーと提携するサーバー側コンポーネント。次の役割があります。
バインディング・イベントのリスニング
アクティブ・データの取得
アクティブ・データ・エンコーディングの管理
エンコード済みアクティブ・データを送信するためにプッシュ・サービスを起動
プッシュ・サービス: 配信チャネルの1つで、サーバー側のイベント・マネージャ、およびクライアント側のアクティブ・データ・マネージャと対話します。その機能は次のとおりです。
サーバーとクライアントの間の接続を確立し維持
サーバーからクライアントへ、この接続を経由してアクティブ・データを転送
望ましいパラメータの範囲内でアクティブ・データが配信されることを保証し、配信されない場合はコンポーネントの更新を強行
アクティブ・データ・マネージャ: クライアント側コンポーネントの1つで、アクティブ・データを適切なコンポーネントに配信します。特に次の役割があります。
チャネル経由でサーバー側からやってきたイベントを、イベント配信サービスを使用して配信
共有チャネルを通じて複数のブラウザ・ウィンドウに対応
コンポーネントが変更を適宜、レンダリングできるように、リッチ・クライアント・コンポーネントにアクティブ・データ・イベントをディスパッチ
アクティブ・データ・プロキシ: すべてのタイプのデータ・ソースがプッシュ機能を有効化できるようにするプロキシプロキシには特に次のような役割があります。
ActiveDataModel
機能の実装と委譲
JSFモデルへの委譲
データ・ソースからデータ変更イベントをリスニング
データ変更イベントに基づいてアクティブ・データ・イベントを生成
アクティブ・データは、データ・ストリーミング(プッシュ)、または2種類のデータ・ポーリングのいずれか1つを用いて、クライアントに送信されます。データ・ストリーミングを使用する場合、リクエストは1つのみで、これは開かれたままになります。データ変更イベントが発生した場合、部分的な応答が送信され(この応答はクローズされない)、クライアントに通知が送られて、関連するコンポーネントが更新されて、新しいデータが表示されます(図52-3 を参照)。
図52-3 ストリーミング・モード
データ・ポーリングでは、アプリケーションは指定された間隔でデータソースをポーリングするように構成されています(図52-4を参照)。データ変更イベントが発生したかどうかに関係なく、応答は要求ごとに送信され、閉じられます。データが変更された場合は、クライアントに通知が送られ、コンポーネントが更新されます。
図52-4 ポーリング・モード
ロング・ポーリングはストリーミングに似ています。ページがレンダリングされるとき、アクティブ・チャネルに要求が送信されます。しかし、データ変更イベントが発生するまで、応答は返されません。このイベントが発生した時点で、接続が閉じられます。接続が閉じられると同時に、新しい接続が開始されます。これにより、ほとんど常時接続されていることになります。特定のインターバルはありません。ロング・ポーリングの結果、データ変更イベントが起きたときに、その大半が受信されます。これは、接続が常時確立され、クライアントに応答を送信できる体制が整っているからです(図52-5 参照)。
図52-5 ロング・ポーリング・モード
詳細は、「ADSトランスポート・モードの構成に関する必知事項」を参照してください。
ADSを使用するには、アプリケーションを構成して、データ・トランスポート方法などのパフォーマンス・オプションを決定する必要があります。また、コンポーネントがADSを使用できるように、コンポーネントのバインディングを構成する必要もあります。ADFビジネス・コンポーネントを使用している場合、アクティブ・データ・プロキシを使用し、アクティブ・データ・イベントのリスナーとしてモデル自身を登録するために、ActiveModel
インタフェースを実装するようにモデルを修正する必要があります。
データ・トランスポート・モードを決定すると同時に、待機しきい値や再接続情報など、その他の構成を行うようにADSを構成する必要があります。
注意:
ADSを有効化したが、ADSを構成していない場合、ADSフレームワークでは表52-1に示すデフォルト値が使用されます。
JDeveloperおよび統合WebLogic ServerでADSを使ってFusion Webアプリケーションを実行するための構成は、adf-config.xml
ファイルで行われます。必要な場合の作成方法を含む、adf-config.xml
ファイルの詳細は、『Oracle ADF FacesによるWebユーザー・インタフェースの開発』のadf-config.xmlでの構成に関する項を参照してください。
注意:
クラスタ環境内のWebアプリケーションに対して自動的なレプリケーションとフェイルオーバーをサポートするために、Oracle WebLogic Serverは、クラスタ間でHTTPセッションの状態をレプリケートするメカニズムをサポートしています。Oracle Application Development Framework (Oracle ADF)を構成して、Fusion Webアプリケーションの状態をサーバーからクラスタにリストアできます。アクティブ・データを表示するように構成されているページに対してフェイルオーバーをサポートするには、ADFビジネス・コンポーネント・アプリケーション・モジュールのフェイルオーバーを有効にし、ADF ControllerがADFメモリー・スコープへの変更を追跡できるようにする必要があります。これらのADF設定を構成すると、フェイルオーバーの発生時にADFサーバーがフェイルオーバーを検出し、アクティブ・データを表示するように構成されているすべてのページに対し、ページをリフレッシュするように要求します。その後でADSが再起動し、データがクライアントにプッシュされます。高可用性環境でFusion Webアプリケーションのフェイルオーバーを有効にする方法の詳細は、『高可用性ガイド』を参照してください。
始める前に:
ADS構成の選択項目に関する知識が役立つ場合があります。詳細は、「アクティブ・データ・サービスの構成」を参照してください。
他のOracle ADF機能を使用して追加できる機能を理解しておくことも役立ちます。詳細は、「アクティブ・データ・サービスについて」を参照してください。
アクティブ・データ・サービスを構成するには:
ADSは3種類のトランスポート・モード(ストリーミング、ポーリング、またはロング・ポーリング)の1つを使用していコンポーネントにアクティブ・データを配信します。
ストリーミング・モードを使用するようにADSを構成すると、データにより変更イベントが発生するたびに、このデータがクライアントにプッシュされます。クライアント側では、プッシュ・チャネルの確立後、latency-threshold
要素とkeep-alive-interval
要素の合計時間以内にアクティビティが何も発生しなかった場合、reconnect-wait-time
要素の値に基づいて、経過時間がmax-reconnect-attempt-time
要素の値に到達するまで、establish-channel-request
が繰り返し送信されます。その後、接続は切断されているものとみなされます。たとえば、「アクティブ・データ・サービスの構成方法」に示された値が指定されている場合、15,000ミリ秒間にアクティビティが発生しないと、チャネルの確立要求が、8,000ミリ秒間隔で最高90,000ミリ秒間送信されます。その後、接続は切断されているものとみなされます。
サーバー側では、サーバーにより、プッシュ・チャネルが切断され、空のアクティブ・データ・メッセージがある、またはアクティブ・データ・メッセージの送信に失敗したときに、cleanup-delay-time
を使ってクリーンアップするためのタイマーが起動されます。cleanup-delay-time
は、max-reconnect-attempt-time
+ 30 × 1000 msの式で求められます。デフォルト値は30分です。
ポーリング・モードを使用するようにADSを構成すると、クライアント側では、polling-interval
要素の値に達した後で、ポーリング要求を繰り返し送信するようにスケジュールが設定されます。max-reconnect-attempt-time
だけの時間が経過しても応答が得られない場合、接続は切断されているものとして扱われ、それ以上、要求は送信されません。ポーリング応答の受信後、応答にかかった時間がpolling-interval
要素を超える場合、サービスは次の要求を即座に送信します。超えていない場合、次の要求はスケジュールどおり送信されます。
サーバー側では、ポーリング応答が返された後で、セッションが終了します。その時点で、クリーンアップをトリガーするために、cleanup-delay-time
を使ったタイマーが設定されます。このタイマーの起動前に新しい要求が到着した場合、古いタイマーはキャンセルされ、新しいタイマーが作成されます。
ロング・ポーリング・モードを使用するようにADSを構成した場合、要求はストリーミング・モードと同じように行われます。ただし、接続が切断と判断されると同時に、新しい接続が開始されます。その結果、待機時間が大幅に短縮されます。
表52-2 はこれら3種類のモードを比較したものです。
表52-2 ストリーミング、ポーリングおよびロング・ポーリング・モードの比較
ストリーミング | ポーリング | ロング・ポーリング | |
---|---|---|---|
待機時間 |
非常に良好。 サーバー側でイベントが発生した直後、クライアントに部分的な応答が送信される。別のイベントが発生した場合も、即座に部分的な応答が送信される。このアプローチには待機時間はほとんどない。 |
よくない(ただし、ポーリング間隔による)。 ポーリング間隔が短い(たとえば、0.5秒)場合、接続が繰り返し開かれるため、ネットワークの速度が低下する原因となる。また、クライアント側リソースおよびサーバー側リソースが大量に消費される。 |
よい。 ただし、応答がクローズされた直後に新しいイベントが発生したとき、新しいデータがクライアント側に現れるまでに多少の待機時間を要する。ほとんどの場合、これは問題にはならない。 |
HTTPプロキシ |
よくない。 一部の古いサーバーでは応答が絶対にリリースされないため、クライアントとサーバーの間にプロキシが存在するとき、このプロキシが応答をバッファする可能性がある。 これはリアルタイムのデータがブラウザに流入することを妨げる、不適切な最適化である。プロキシを使用している場合は、ロング・ポーリングを使用すべきである。 |
よい。 |
よい。 |
ライブ接続数 |
よくない。 ストリームが常に有効であるため、多数の接続が同時に存在する。 |
よい。 接続は、実際のポーリング中のみ有効である。ただし、ポーリング・レートが高い場合、同時接続数も増えますので注意してください。 |
よくない。 ストリームがほとんど常に有効であるため、多数の接続が同時に存在する。 |
通信チャネル |
この結果、ビジー・カーソル、またはブラウザのスロバー・アイコンのアニメーションが表示される。 |
|
|
デフォルトでは、ADSを使用する構成のアプリケーションはタイムアウトしません。ポーリング・モードでは、クライアントがサーバーにポーリング要求を定期的に送信します。ロング・ポーリング・モードでは、サーバーからポーリング要求が返されると、即座にクライアントが新しいポーリング要求を送信します。ストリーミング・モードでは、 サーバーがGETリクエスト・レスポンスを保持し、アクティブ・データを無期限に書き込みます。各データ・トランスポート・モードの動作のために、ユーザーがアプリケーションと対話しているかどうかにかかわらず、ADSはアプリケーション・セッションをアクティブに維持します。
ADSのためにアクティブ・セッションが無期限に維持されるこの状況を防止するために、web.xml
構成ファイルには、ユーザーが非アクティブになってからタイムアウトするまでのADSの実行時間を指定するoracle.adf.view.rich.poll.TIMEOUT
コンテキスト・パラメータが含まれています。キーボードまたはマウスのアクティビティがない場合、ADSクライアントはタイムアウトできるとみなされます。デフォルトのタイムアウト時間は10分です。このため、ユーザーのアクティビティが10分間ない場合(キーボードやマウスを使用しない時間)は、ADSはポーリングを停止するかサーバーとの接続を中断し、その時点から、アプリケーションは標準のサーバー側セッション・タイムアウトに入ります。たとえば、サーバー側セッション・タイムアウトが65分で、ポーリング・タイムアウト・パラメータが15分に設定されている場合、ユーザーが非アクティブな状態が80分を超えると、セッションのタイムアウト期限が切れることになります。
ADF Facesポーリング・コンポーネントのtimeout
属性を使用して、特定のWebページでこのタイムアウト設定をオーバーライドできます。ポーリング・コンポーネントを使用して、サーバーにハートビートを配信して、特定のページでそれらのセッションがタイムアウトするのを防ぐことができます。oracle.adf.view.rich.poll.TIMEOUT
コンテキスト・パラメータと個々のWebページの詳細は、『Oracle ADF FacesによるWebユーザー・インタフェースの開発』のポーリング・イベントを使用したページの更新に関する項を参照してください。
始める前に:
ADS構成の選択項目に関する知識が役立つ場合があります。詳細は、「アクティブ・データ・サービスの構成」を参照してください。
他のOracle ADF機能を使用して追加できる機能を理解しておくことも役立ちます。詳細は、「アクティブ・データ・サービスについて」を参照してください。
セッションが非アクティブになったらタイムアウトするようにアクティブ・データ・サービスを構成するには:
ADSの使用に向けてコンポーネントを構成する方法は、アクティブ・データ・プロキシを使用する必要があるかどうかによって異なります。データが変更されたときにイベントを公開するデータ・ストアをアプリケーションが使用しているときに、ビジネス・サービスがこのようなイベントに反応する(たとえば、アプリケーションがBAMを使用している)場合、アクティブ・データ・プロキシを使用する必要はありません。
ビジネス・サービスがこれらのイベントに反応しない(たとえば、アプリケーションがADFビジネス・コンポーネントを使用している)場合は、アクティブ・データ・プロキシを使用し、別の手順に従って、コンポーネントを構成する必要があります。
注意:
ビジネス・サービスでアクティブ・データ・プロキシを使用する必要がある場合、アクティブ・データとともに使用できるのは次のコンポーネントのみです。
table
tree
treeTable
ADFデータ視覚化コンポーネント(chart
、gauge
、mapPointTheme
、pivotTable
、pivotFilterBar
、sunburst
、treemap
)
プロキシを使わずにADSを使用するには、対応するページ定義ファイルでバインディング要素に値を設定する必要があります。
始める前に:
ADS構成の選択項目に関する知識が役立つ場合があります。詳細は、「アクティブ・データ・サービスの使用に向けたコンポーネントの構成」を参照してください。
他のOracle ADF機能を使用して追加できる機能を理解しておくことも役立ちます。詳細は、「アクティブ・データ・サービスについて」を参照してください。
アクティブ・データ・プロキシを使わずに、アクティブ・データを表示するコンポーネントを構成するには:
ヒント:
サーバーの状態を示すために、statusIndicator
コンポーネントを使用できます。詳細は、『Oracle ADF FacesによるWebユーザー・インタフェースの開発』のアイコンを使用したアプリケーション・ステータスの表示に関する項を参照してください。
プロキシとADSを併用するには、コンポーネントの値と、このプロキシを使用するデコレータ・クラスをバインドする必要があります。対応するページ定義ファイルでバインディング要素に値を設定するには、「アクティブ・データ・プロキシの使用」でこのクラスの詳細を参照してください。
始める前に:
ADS構成の選択項目に関する知識が役立つ場合があります。詳細は、「アクティブ・データ・サービスの使用に向けたコンポーネントの構成」を参照してください。
他のOracle ADF機能を使用して追加できる機能を理解しておくことも役立ちます。詳細は、「アクティブ・データ・サービスについて」を参照してください。
アクティブ・データ・プロキシを使って、アクティブ・データを表示するコンポーネントを構成するには:
ADF Facesツリー(または、ツリー表)コンポーネントを作成するときには、nodeStamp
ファセットを構成します。これはツリーの各ノードのデータを表示するために使用されるコンポーネントのホルダーです。各ノードが一度ずつ、すべてのノードで繰り返しレンダリング(スタンプ設定)されます。
このスタンプ設定動作のため、ADF Facesツリー・コンポーネントで子としてサポートされるのは、特定タイプのコンポーネントのみです。ツリー・コンポーネントがアクティブ・データ・ソースにバインドされていない場合、動作を持たないコンポーネントがすべてサポートされます。ただし、ADSを使用するツリーを構成する場合、次の例に示すとおり、nodeStamp
ファセット内ではoutputText
コンポーネントのみがサポートされます。nodeStamp
ファセットには他のタグが含まれていてはいけません。したがって、たとえば、ADSを使用するように構成されたツリーのnodeStamp
ファセットにpanelGroupLayout
タグを追加した場合、アクティブ・データは機能しません。
<f:facet name="nodeStamp"> <af:outputText value="#{row.str2}"/> </f:facet>
アプリケーションとADSのコンポーネントの構成後、サーバーでデータが変化すると必ず、コンポーネントに通知が送られ、変更されたデータのみを使って再レンダリングが行われます。対照的に、アクティブ・データまたは自動PPRのどちら向けにも構成されていないコンポーネントは、データ変更後に明示的にリフレッシュする必要があります。明示的なリフレッシュは、変更されていないデータを含め、クライアントに表示されているデータすべてを再フェッチします。この結果、コンポーネント全体が強制的に再レンダリングされます。さらに、コンポーネントが(アクティブ・データ・ポリシー「Push」を使用して)アクティブ・データ・ソースにバインドされている場合、このコンポーネントによる再レンダリングが行われ、新しい値がハイライトされます。
Fusion WebアプリケーションがGoogle Chrome Webブラウザで実行されているときに、ユーザーが[Ctrl]+[N]キー(または[Ctrl]+[T]キー)を押して、新しいウィンドウ(またはタブ)を開き、元のウィンドウから新しいウィンドウにURLをコピーすると、元のウィンドウのアクティブ・データはストリーミングを停止します。Google Chromeのプロセス・モデルによれば、新しいブラウザ・ウィンドウは別のプロセスで作成され、両方のウィンドウは同じHTTPセッションを共有します。ただし、2つの異なるプロセスで作成されたブラウザ・ウィンドウは互いに通信できないため、クライアントとサーバーの間でADSが同期しなくなり、ADSのストリーミングが停止します。回避策として、複数のGoogle Chromeウィンドウでアクティブ・データを許可するには、元のウィンドウから新しいウィンドウにURLをコピーする前に、ユーザーは[Ctrl]キーと[Shift]キーと[N]キーを同時に押して、ブラウザ・ウィンドウを匿名モードで開きます(プライベート・ブラウジング)。[Ctrl]キーと[Shift]キーと[N]キーを同時に押すと、別のプロセスと別のHTTPセッションでウィンドウが開かれるため、ADSは2つのウィンドウを同期しようとしなくなり、ストリーミングは影響を受けません。
ビジネス・サービスがデータ・イベントに反応しないときには、アクティブ・データ・プロキシを使用します。ADFビジネス・コンポーネントに渡されたイベントに基づいてコンポーネントを更新する必要がある場合は、アクティブ・データ・プロキシを使用する必要があります。
ヒント:
アプリケーションがビジネス・サービスにBAMを使用している場合、アクティブ・データ・プロキシを使用する必要はありません。
注意:
ビジネス・サービスでアクティブ・データ・プロキシを使用する必要がある場合、アクティブ・データとともに使用できるのは次のコンポーネントのみです。
table
tree
treeTable
ADFデータ視覚化コンポーネント(mapPointTheme
、pivotTable
,、pivotFilterBar
、sunburst
、treemap
)
次のデコレータ・クラスの1つをサブクラスするJavaクラスを作成します。
ActiveCollectionModelDecorator
クラス
ActiveGeoMapDataModelDecorator
クラス
これらのクラスは、アクティブ・データ機能をActiveDataModel
のデフォルト実装に委譲するラッパー・クラスです。ActiveDataModel
クラスは、データ変更イベントをリッスンし、イベント・マネージャと対話します。具体的には、次の処理が行われます。
アクティブ・データおよびActiveDataModel
オブジェクトを開始および停止し、データ・ソースへのリスナーの登録および登録解除を行います。
JSFモデル・インタフェースをラップします。たとえば、ActiveCollectionModelDecorator
クラスはCollectionModel
クラスをラップします。
データ・ソースから、データ変更イベントに基づいてアクティブ・データ・イベントを生成します。
イベント・マネージャからリスナーを管理し、アクティブ・データ・イベントをイベント・マネージャにプッシュします。
アクティブ・データ・ソースのリスナーとして自分自身を登録し、データの送信先モデルを取得するこのJavaクラスにメソッドを実装する必要があります。
注意:
アクティブ・データ・フレームワークは、ユーザー・プロファイルやセキュリティなどADF実行時コンテキストを必要とする複雑なビジネス・ロジックや変換をサポートしません。たとえば、このフレームワークはADFコンテキストのロケール依存値を変換し、ロケール固有の値を返すことはできません。
複雑なビジネス・ロジックの例として、たとえば、注文をopen
ステータスからpending
ステータスに変更することをユーザーに許可するロジックがあるとします。この変更の結果がupdate
イベントで、このイベントにより、データ・オブジェクト"Open Orders"から注文が削除されます。フレームワークでは、このイベント・タイプをビジネス・ロジックに基づいて処理することはできません。そのかわりに、ユーザーは、データ変更イベントを公開する前に、データ・ソースにこれを処理させる必要があります。
始める前に:
アクティブ・データ・プロキシに関する知識が役立つ場合があります。詳細は、「アクティブ・データ・プロキシの使用」を参照してください。
他のOracle ADF機能を使用して追加できる機能を理解しておくことも役立ちます。詳細は、「アクティブ・データ・サービスについて」を参照してください。
次のタスクを完了する必要があります。
アクティブ・データ・サービスを使用するには:
アクティブ・データを使用するということは、コンポーネントに2つのデータ・ソース(アクティブ・データ・フィードと標準データ・フェッチ)があることを意味します。このため、アプリケーションでは読取り一貫性が確保されるようにする必要があります。
たとえば、ページには表が1つ含まれ、この表ではアクティブ・データが有効化されているとします。この表は、データを更新するための配信メソッドとして、標準の表データ・フェッチとアクティブ・データ・プッシュの2種類を持っています。ここで、バック・エンド・データがfoo
からbar
に変更され、さらにfred
に変更されたとしましょう。変更のたびに、アクティブ・データ・イベントが起動されます。これらのイベントがブラウザに到着する前に表をリフレッシュした場合、表にはfred
と表示されます。これは、標準のデータ・フェッチでは、必ず最新のデータが取得されるからです。しかし、アクティブ・データ・イベントに長い時間がかかることもあるため、場合によっては、リフレッシュの後で、このデータ変更イベントの結果、foo
がブラウザに到着し、表が更新されて、しばらくの間、fred
のかわりにfoo
と表示されます。したがって、読取り一貫性を維持する方法を実装する必要があります。
読取り一貫性を実現するために、ActiveDataModel
は、効果的にデータにタイムスタンプを押す変更カウントの概念を採用しています。データ・フェッチとアクティブ・データ・プッシュのどちらも、このchangeCount
オブジェクトを単調にカウントを増やすことで維持する必要があるため、返されたデータのchangeCount
が現在のカウントより低い場合は、アクティブ・イベントにより廃棄される可能性があります。読取り一貫性を維持するActiveDataModel
クラスの実装の例は、「アクティブ・データ・プロキシの使用方法」を参照してください。
コレクションベースのデータを表示するADFコンポーネントは、ADSと提携するように構成することができます。ビュー・レイヤーでは余分なセットアップは必要ありません。しかし、JSPXページで、Javaタイマーに基づき新しいカウントを表示するために、activeOutputText
コンポーネントを使用する例を考えてみましょう。この場合、モデル・レイヤーを、JavaBeanから表示されるスカラー、つまり"フラットな"データで置き換えます。
スカラー・モデルを実装するには、次の基本手順に従います(後に例を示しています)。
このBean(スカラー・モデル)が実際のモデルを模倣するように、ActiveModelContext
APIを使用して、ADSとともにBeanを登録します。
アクティブな属性のgetterメソッドに登録コードを追加します。Beanのコンストラクタに登録コードを追加すると、ADSが失敗することがあります。
次の例に示すように、データをビュー・レイヤーにプッシュするカスタム・メカニズムを実装します。
package oracle.adfdemo.view.feature.rich; import java.util.Collection; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.atomic.AtomicInteger; import oracle.adf.view.rich.activedata.ActiveModelContext; import oracle.adf.view.rich.activedata.BaseActiveDataModel; import oracle.adf.view.rich.activedata.ActiveDataEventUtil; import oracle.adf.view.rich.event.ActiveDataEntry; import oracle.adf.view.rich.event.ActiveDataUpdateEvent; public class CounterBean extends BaseActiveDataModel // Example using a Java timer to create new counts { public CounterBean() { timer.schedule(new UpdateTask(), 2000, 2000); } public String getState() { // 1. Use the ActiveModelContext API to register the scalar model key path for // the "state" attribute. ActiveModelContext context = ActiveModelContext.getActiveModelContext(); Object[] keyPath = new String[0]; context.addActiveModelInfo(this, keyPath, "state"); return String.valueOf(counter); } // Not needed. We do not need to connect to a (real) active data scource. protected void startActiveData(Collection<Object> rowKeys, int startChangeCount) {} // Not needed. We do not need to connect to a (real) active data scource. protected void stopActiveData(Collection<Object> rowKeys) {} public int getCurrentChangeCount() { return counter.get(); } protected class UpdateTask extends TimerTask { public void run() { counter.incrementAndGet(); // 2. Use ActiveDataEventUtil to create an event object to update the model. ActiveDataUpdateEvent event = ActiveDataEventUtil.buildActiveDataUpdateEvent( ActiveDataEntry.ChangeType.UPDATE, counter.get(), new String[0], null, new String[] { "state" }, new Object[] { counter.get() }); fireActiveDataUpdate(event); } } private static final Timer timer = new Timer(); private final AtomicInteger counter = new AtomicInteger(0); }
Beanの作成後、これをマネージドBeanとしてfaces-config.xml
ファイルに登録します(次の例のcounterBean
を参照)。
... <managed-bean> <managed-bean-name>counterBean</managed-bean-name> <managed-bean-class> oracle.adfdemo.view.feature.rich.CounterBean </managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean>
Beanの登録が完了すると、ADSを使用して、データをビュー・レイヤーにストリーミングできるようになります。ADF Facesコンポーネントでは、プッシュされたデータを受け取るために式言語が使用されます(次の例のactiveOutputText
コンポーネントのvalue
属性を参照)。
... <f:view> <af:document title="Active Data Visual Design Demo" binding="#{templateBindings.documentComponent}" smallIconSource="#{aboutBean.smallIconSource}" largeIconSource="#{aboutBean.largeIconSource}" theme="dark" id="d1"> <af:pageTemplate id="dmoTpl" viewId="#{templates.componentTemplate}"> <f:attribute name="tagName" value="Active Data Visual Design"/> <f:attribute name="demoKind" value="visualDesign"/> <f:attribute name="customEditorPresent" value="true"/> <f:facet name="center"> <af:panelGroupLayout layout="scroll"> <af:activeOutputText value="#{counterBean.state}" inlineStyle= "color:brown; font-size:100px; font-weight:bold; text-align:center;" /> </af:panelGroupLayout> </f:facet> </af:pageTemplate> </af:document> </f:view>