30 Oracle XML DBリポジトリ・イベント
Oracle XML DBリポジトリを使用して、あらゆるリポジトリ・リソース形式のデータを格納、またはデータにアクセスできます。リポジトリ・データには、任意のアプリケーションからアクセスできます。特定のリポジトリ操作が発生するたびに、アプリケーションによる特定のアクションの実行が必要な場合があります。リポジトリ・イベントを使用してこれを行うことができます。
- リポジトリ・イベントの概要
アプリケーションでは、リポジトリ操作に関連付けられたイベントの発生時に特定のアクションを実行できます。たとえば、リソースを削除するたびに、ごみ箱への移動やバックアップ操作を実行する場合があります。 - 可能なリポジトリ・イベント
リポジトリ操作は、事前定義されたイベントに関連付けられます。レンダリング操作を除いて、イベントは事前と事後のペアで発生します。 - リポジトリ操作とイベント
異なるOracle XML DBリポジトリ操作で同じリポジトリ・イベントが発生する可能性があり、また指定のリポジトリ操作により複数のリポジトリ・イベントが生成される可能性があります。 - リポジトリ・イベント・ハンドラの考慮事項
Oracle XML DBリポジトリ・イベントのハンドラを定義する場合のいくつかの考慮事項を示します。 - リポジトリ・イベントの構成
リソース構成ファイルでは、要素ResConfig
の子である要素event-listeners
を使用して、Oracle XML DBリポジトリ・イベント処理を構成します。
関連トピック
親トピック: Oracle XML DBリポジトリ
30.1 リポジトリ・イベントの概要
リポジトリ操作に関連するイベントが発生した場合、アプリケーションで特定のアクションを実行できます。たとえば、リソースを削除するたびに、ごみ箱への移動やバックアップ操作を実行する場合があります。
リポジトリ・リソース操作には、作成、削除、ロック、ロック解除、レンダリング、リンク付け、リンク解除、バージョン管理、チェックイン、チェックアウト、チェックアウト解除(チェックアウトされたバージョンの回復)、オープン、更新があります。
- リポジトリ・イベント: ユースケース
リポジトリ・イベントを使用できる場合の例として、ごみ箱へのリソースの移動やMIMEタイプに基づくリソースの分類などがあります。 - リポジトリ・イベントとデータベース・トリガー
データベース・トリガーは、アプリケーションによるリポジトリ操作への反応には使用できません。指定のリポジトリ操作は、複数の基礎となる内部表において、複数のデータベース操作で構成されている場合があります。これらの基礎となる表はOracle XML DB内部にあるため、特定のリポジトリ操作に簡単にはマップできません。 - リポジトリ・イベント・リスナーとイベント・ハンドラ
各リポジトリ操作はイベントに関連付けられます。アプリケーションは、イベント・リスナーを特定のリソース、またはリポジトリ全体に対して構成できます。リスナーは、ノードが存在することという前提条件によって制限できます。リスナーは、それぞれが単一のイベントを処理する、一連のPL/SQLまたはJavaハンドラです。 - リポジトリ・イベント構成
リポジトリ・イベント構成には、リソース構成ファイルの定義と、その処理順序の定義が含まれます。ファイルは、イベント・リスナーを定義します。このような構成は、個々のリソースのイベントとリポジトリ全体のイベントに適用されます。
親トピック: Oracle XML DBリポジトリ・イベント
30.1.1 リポジトリ・イベント: ユースケース
リポジトリ・イベントを使用できる場合の例として、ごみ箱へのリソースの移動やMIMEタイプに基づくリソースの分類などがあります。
-
ごみ箱–
UnLink
前処理イベント・ハンドラを使用して、リソースを削除するのではなく、効率的にごみ箱に移動できます。つまり、元のリンクを削除する前にごみ箱フォルダにリンクを作成します。ごみ箱のリンクにより、リソースは削除されません。その後、削除されたリソースをごみ箱から元に戻す場合、元のリンクが再作成され、ごみ箱のリンクが削除されます。特定のパスのリソースは、そのパスから複数回リンク解除できるため、ごみ箱のリンク名は、削除されるリンク名と異なるリンク名にできます。ごみ箱には、そのパスに対応する、リンク・プロパティが異なり、それぞれ別のリソースを指している可能性のあるリンクが複数存在します。 -
カテゴリ分け: アプリケーションにより、管理するリソースがMIMEタイプや他のプロパティに基づいて分類される場合があります。リポジトリ・フォルダ
/my-app/gif
、/my-app/txt
、および/my-app/xml
からGIFファイル、テキスト・ファイル、およびXMLファイルのリンクが保持され、そのファイルが追跡されることがあります。ここでは、LinkIn
、UnlinkIn
、Update
の3つの後処理イベント・ハンドラを使用できます。LinkIn
後処理イベント・ハンドラはリソースを調べ、リソースがまだ存在しない場合は、適切なカテゴリ・フォルダにリンクを作成します。UnlinkIn
後処理イベント・ハンドラは、カテゴリ・フォルダからリンクを削除します。Update
後処理イベント・ハンドラは、そのカテゴリが変更された場合に、1つのカテゴリ・フォルダから別のカテゴリ・フォルダへリソースを効率的に移動します。
親トピック: リポジトリ・イベントの概要
30.1.2 リポジトリ・イベントとデータベース・トリガー
データベース・トリガーは、アプリケーションによるリポジトリ操作への反応には使用できません。指定のリポジトリ操作は、複数の基礎となる内部表において、複数のデータベース操作で構成されている場合があります。これらの基礎となる表はOracle XML DB内部にあるため、特定のリポジトリ操作に簡単にはマップできません。
たとえば、内部表XDB$H_INDEX
は、(ACLが変更された場合は)データベース更新操作、またはリンク操作により更新されます。データベース・トリガーによって同様の操作が可能な場合でも、これを使用しません。リポジトリ・イベントとは、基礎となる表の一連のデータベース・トリガーより高いレベルの抽象的概念です。
リポジトリ・イベントが発生すると、使用されているリソース・パスなど、その操作に関連した情報が対応するイベント・ハンドラに渡されます。このような情報は、データベース・トリガーを使用した場合はすぐに使用できません。
リポジトリ・イベントとデータベース・トリガーは両方ともXMLデータに適用できます。たとえば、トリガーはXMLType
表で使用できます。ただし、XMLType
表も(階層対応の)リポジトリ表である場合は、表に適用されるトリガー・コードをイベント・ハンドラでコピーしないでください。コピーした場合、そのコードは2回実行されます。
親トピック: リポジトリ・イベントの概要
30.1.3 リポジトリ・イベント・リスナーとイベント・ハンドラ
各リポジトリ操作は、イベントに関連付けられています。アプリケーションは、イベント・リスナーを特定のリソース、またはリポジトリ全体に対して構成できます。リスナーは、ノードが存在することという前提条件によって制限できます。リスナーは、それぞれが単一のイベントを処理する、一連のPL/SQLまたはJavaハンドラです。
リポジトリ・イベント・リスナーはJavaクラス、PL/SQLパッケージまたはオブジェクト型です。このリポジトリは一連のPL/SQLプロシージャまたはJavaメソッドで構成され、それぞれがイベント・ハンドラと呼ばれます。
リソース構成ファイルをリソースとマップして、リポジトリ・イベント・リスナーとリソースを関連付けます。PL/SQLパッケージDBMS_RESCONFIG
を使用して、リソース構成ファイルとそれを構成するリソースと関連付けるなど、リソース構成ファイルを操作します。特に、PL/SQLファンクションDBMS_RESCONFIG.getListeners
には、特定のリソースのすべてのイベント・リスナーが一覧されています。
親トピック: リポジトリ・イベントの概要
30.1.4 リポジトリ・イベント構成
リポジトリ・イベント構成には、リソース構成ファイルの定義と、その処理順序の定義が含まれます。ファイルは、イベント・リスナーを定義します。このような構成は、個々のリソースのイベントとリポジトリ全体のイベントに適用されます。
複数のリソース構成ファイルにより、特定のリソースが構成されます。これらはリソース構成リストに格納されており、リストに記載された順番で処理されます。リポジトリ全体のイベントも複数のリソース構成ファイルで構成される場合があります。同様に、リポジトリにもリソース構成リストがあります。リポジトリ全体について構成されるイベント処理は、任意のリソース固有のイベント処理前に有効になります。つまり、リポジトリ全体に渡る当該イベントはすべて、リソース固有のイベント前に処理されます。
指定のリソース構成ファイルによって構成するリソースの複数のイベント・リスナーが定義され、各イベント・リスナーによって複数のイベント・ハンドラが定義されます。
30.2 可能なリポジトリ・イベント
リポジトリ操作は、事前定義されたイベントに関連付けられます。レンダリング操作を除いて、イベントは事前と事後のペアで発生します。
レンダリング操作は、単一のリポジトリ・イベントと関連付けられています。レンダリングを除き、すべてのリポジトリ操作は、1つ以上のイベントのペアに関連付けられています。
たとえば、リソース作成は3組のイベントと関連付けられ、これらのイベントは次の順に発生します。
-
Pre-creationイベント
-
Post-creationイベント
-
Pre-link-inイベント
-
Pre-link-toイベント
-
Post-link-toイベント
-
Post-link-inイベント
表30-1に、各リポジトリ操作に関連付けられたイベントを示します。この順序をハンドラ列に示します。
表30-1 事前定義リポジトリ・イベント
リポジトリ・イベント型 | 説明 | プリハンドラ実行 | ポストハンドラ実行 |
---|---|---|---|
|
次のいずれかを使用してリソース・コンテンツにアクセスする際に発生します。
次のいずれかを使用してリソース・コンテンツにアクセスする場合は発生しません。
レンダリング出力を設定できるのは |
該当なし |
該当なし |
|
リソースが作成されるときに発生します。実行されたプリハンドラとポストハンドラは、新規リソースのフォルダに定義されているハンドラです。 |
事前解析後、親リソースACLおよびロックの検証後、およびデフォルト値の未定義プロパティへの割当て前 |
リソースのシステム・リソース表への挿入後 |
|
リソースとそのコンテンツがディスクから削除される場合、つまりリソース |
リソースACLおよびロックの検証後、およびリソースのディスクからの削除前 |
リソースとそのコンテンツのディスクからの削除後、および親フォルダの最終変更者と変更時間の更新のためのフォルダ変更後 |
|
ディスクでリソースを更新する場合に発生します。 |
リソースACLおよびロックの検証後、および最終変更者と変更時間の更新前 |
リソースのディスクへの書込み後 |
|
リソース・ロック操作中に発生します。 |
リソースACLおよびロックの検証後、およびリソースでの新規ロックの作成前 |
新規ロック作成後 |
|
リソース・ロック解除操作中に発生します。 |
リソースACLおよび削除トークン検証後 |
ロック削除後 |
|
リンク操作中の |
リソースACLおよびロックの検証後、およびリンク作成前 |
|
|
リンク操作中の |
|
リンク作成後、および親フォルダの最終変更者と変更時間の更新後 |
|
リンク解除操作中の |
リソースACLおよびロックの検証後、およびリンク削除前 |
|
|
リンク解除操作中の |
|
リンク削除後 |
|
リソースのチェックイン中に発生します。 |
リソースACLおよびロック検証後、およびリソースがバージョン管理対象であり、チェックアウト済であることを検証後 |
リソースのチェックイン後 |
|
リソースのチェックアウト中に発生します。 |
リソースACLおよびロック検証後、およびリソースがバージョン管理対象であり、チェックアウト前であることを検証後 |
リソースのチェックアウト後 |
|
リソースのチェックアウト解除中に発生します。 |
リソースがチェックアウトされている記録の削除前 |
リソースのチェックアウト解除後 |
|
リソースのバージョン履歴が作成されるときに発生します。 注意: |
リソースのバージョン履歴作成前 |
リソースの最初のバージョン作成後 |
簡単にするため、一般的にこのドキュメントでは、イベント型pre-link-inおよびpost-link-inの略記としてLinkIn
イベント型を参照するなど、リポジトリ・イベント・ペアの両方のメンバーを扱います。同様に、ここで使用するイベント型名は、JavaインタフェースXDBRepositoryEventListener
から接頭辞handlePre
およびhandlePost
を削除して導出されたものです。
関連項目:
PL/SQLリポジトリ・イベント型は、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスを参照してください。
親トピック: Oracle XML DBリポジトリ・イベント
30.3 リポジトリ操作とイベント
異なるOracle XML DBリポジトリ操作で同じリポジトリ・イベントが発生する可能性があり、また指定のリポジトリ操作により複数のリポジトリ・イベントが生成される可能性があります。
表30-2に、各リポジトリ操作に関連付けられたイベントを示します。同じ操作に複数のリポジトリ・イベントが発生する場合のイベントの順序は、表30-1を参照してください。
表30-2 Oracle XML DBリポジトリ操作とイベント
操作 | 発生しているリポジトリ・イベント |
---|---|
パス名によるリソース・コンテンツのバイナリ表現の取得 |
|
パス名によるリソース・コンテンツのXML表現の取得 |
|
リソースの作成または更新 |
リソースがすでに存在している場合: リソースが存在していない場合(HTTPおよびFTPのみ): |
フォルダの作成 |
|
既存のリソースへのリンクの作成 |
リンク・ターゲットを含むフォルダでは |
ファイル・リソースまたは空フォルダ・リソースのリンク解除( |
|
フォルダとそのコンテンツの強制削除 |
リソースのリンク解除のため、再帰イベントを生成します。フォルダの子リソースは再帰的に削除され、次にフォルダが削除されます。 |
リソースへのすべてのリンクの強制削除 |
削除されたリンクごとにリンク解除イベントを生成します。 |
パス名によるリソースのコンテンツ、プロパティ、ACLの更新 |
|
深さゼロのWebDAVロックのリソースへの配置 |
|
深さゼロのWebDAVロックのリソースからの削除 |
|
リソースの名前変更 |
新規の位置では |
リソースのコピー |
新規の位置では |
リソースのチェックアウト |
|
リソースのチェックイン |
|
リソースのバージョン管理への配置 |
|
リソースのチェックアウト解除 |
|
表30-2に示すすべての操作は、次の操作を除き、基本操作です。
-
フォルダとそのコンテンツの強制削除
-
HTTP(のみ)を使用したパス名によるリソース・プロパティの更新
-
HTTP(のみ)を使用したフォルダのコピー
関連項目:
APIとプロトコルを使用したリソースへのアクセスの詳細は、表21-3を参照してください。
親トピック: Oracle XML DBリポジトリ・イベント
30.4 リポジトリ・イベント・ハンドラの考慮事項
Oracle XML DBリポジトリ・イベントのハンドラを定義する場合のいくつかの考慮事項を示します。
-
すべてのハンドラ: ハンドラ内で
COMMIT
、ROLLBACK
またはデータ定義言語(DDL)文を使用しないでください。DDL文と同様の動作をするPL/SQLファンクションまたはプロシージャ(DBMS_XMLSCHEMA.registerSchema
など)をコールしないでください。Render
ハンドラ: データ操作言語(DML)文を使用しないでください。これらの制約を回避するには、ハンドラは自律型トランザクション内でこのような文を使用できます。ただし、ロック競合が発生しないようにすることが必要です。
-
Render
ハンドラ内で出力ストリームをクローズしないでください。(ストリームに追加できます。) -
Pre-Createおよび
Pre-Update
以外のハンドラ内では、クラスXDBResource
から修飾子メソッドを使用しない
でください。いずれのハンドラ内でも、メソッドXDBResource.save()を使用しない
でください。 -
安全なリポジトリ・イベント・ハンドラのみ開発することをお薦めします。特に、次の点に注意してください。
-
xdb
名前空間ではなく、アプリケーションが所有する名前空間にあるリソース・プロパティのみを記述してください。 -
リソースの作成中は、リソースを削除しないでください。
-
-
リポジトリ・イベント・ハンドラには、現在のSQL文またはプロトコル操作中にのみ存在する
XDBRepositoryEvent
オブジェクトが渡されます。このオブジェクトでPL/SQLプロシージャとJavaメソッドを使用して、リソース、イベントおよび関連イベント・ハンドラの情報を取得できます。 -
イベント・ハンドラが他のリポジトリ・イベントを生じさせる操作を実行すると、それらのカスケーディング・イベントがただちに発生します。ただし、現在のイベントのハンドラが完了した後は、これらのイベントはキューに入れられず発生しません。つまり、各イベントはその対応する操作に関連して発生します。
-
複数のリポジトリ・イベント・ハンドラが同時にコールされます。これらは対応する操作のプロセス、セッション、トランザクションにおいて実行されます。ただし、ハンドラではOracle Databaseアドバンスト・キューイング(AQ)により、他のプロセスで非同期的に処理されるリポジトリ・イベントがキューに入れられます。
-
リポジトリ・イベント・ハンドラは、対応する操作のトランザクションにおいて実行されるため、その操作またはトランザクションで以前実行された他の操作によって取得したロックはアクティブなままです。イベント・ハンドラでは、そのようなロックを取得する個別セッションまたはトランザクションは開始できません。開始するとハンドラは停止します。
-
リポジトリ・イベント・ハンドラは、リソース構成ファイルに出現する順にコールされます。リソース構成に前提条件が定義されている場合、前提条件を満たしているハンドラのみコールされます。
-
ハンドラは構成ファイルで定義されている順にコールされますが、これにはコードを依存させないでください。ハンドラの起動時の現行ユーザーに
write-config
権限がある場合、ハンドラの起動順序は実行中のハンドラ内で変更できます。 -
指定のリポジトリ・イベント発生に該当するハンドラの全体リストは、ハンドラの起動前に決定されます。つまり、具体的には、各ハンドラの前提条件はハンドラの起動前に評価されます。
-
次の考慮事項は、リポジトリ・イベントのエラー処理に適用されます。
-
操作のアクセス確認に失敗した場合、事前操作イベント・ハンドラは起動されません。
-
指定のイベントのすべてのハンドラは、コールされる前にチェックされます。(すでに存在しないなど)どのハンドラも使用できない場合は、いずれもコールされません。
-
イベント処理中にエラーが発生すると、他の後続イベント・ハンドラは同じSQL文またはプロトコル操作に対して起動されません。現在の文または操作は取り消され、その変更はすべてロールバックされます。
-
-
次の考慮事項は、リポジトリ・イベントのリソース・セキュリティに適用されます。
-
イベント・ハンドラには起動者の権限または定義者の権限があります。パッケージを作成する際、PL/SQLパッケージの実行権限を指定します。
loadjava
ユーティリティを使用してJavaクラスの実行権限をデータベースにロードする際、これらの実行権限を指定します。起動者の権限を指定しても、指定のハンドラが起動者の権限に対して構成されていない場合、権限不足エラーが発生します。 -
イベント・ハンドラ内では、起動者権限または定義者権限のどちらで取得されていても、現在のユーザー権限はそのACLにより指定のリソースに対して詳細に決定されます。これらの権限は、リソースに対してハンドラが処理可能な内容を決定します。たとえば、現行ユーザーが特定のリソースに対する
read-properties
およびread-contents
権限を持っている場合、イベント・ハンドラはそのリソースを読み取ることができます。
-
-
次の考慮事項は、リンクおよびリンク解除のリポジトリ・イベントに適用されます。
-
リソースにリンクを作成後、親フォルダのリソース構成ファイルをリンク済リソースに適用させる場合は、プロシージャ
DBMS_RESCONFIG.appendResConfig
を使用して構成ファイルをリンク済リソースに追加します。このプロシージャは、リンク済リソースのPost-LinkTo
イベント・ハンドラから起動できます。 -
リソースのリンク解除後、リンク時に追加した該当リソース構成ファイルを削除する場合は、プロシージャ
DBMS_RESCONFIG.deleteResConfig
を使用してリンク解除済リソースからファイルを削除します。このプロシージャは、リンク解除済リソースのPost-UnlinkFrom
イベント・ハンドラから起動できます。
-
-
フォルダ
/sys/schemas
や、その配下のリソースでのイベントにはハンドラを定義しないでください。それらのリソースにはイベントが発生しないため、そうしたイベント・ハンドラは無視されます。つまり、リポジトリに影響を与えるXML Schema操作(登録、削除など)はイベントを生成しません。
関連項目:
-
リポジトリ・イベント操作のためのPL/SQLファンクションおよびプロシージャの詳細は、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスを参照してください。
-
リポジトリ操作のためのJavaメソッドの詳細は、Oracle Database XML Java APIリファレンスのクラス
XDBRepositoryEvent
およびXDBEvent
を参照してください。 -
起動者権限によるリポジトリ・イベント・ハンドラの定義の詳細は、リポジトリ・イベントの構成を参照してください。
親トピック: Oracle XML DBリポジトリ・イベント
30.5 リポジトリ・イベントの構成
リソース構成ファイルでは、要素ResConfig
の子である要素event-listeners
を使用して、Oracle XML DBリポジトリ・イベント処理を構成します。
リポジトリ・リソースの他の処理を構成するように、Oracle XML DBリポジトリ・リソースのイベント処理を構成します。リソースの構成を参照してください。
デフォルトではリポジトリ・イベントは有効になっていますが、パラメータXML_DB_EVENTS
をDISABLE
に設定して無効にできます。セッション・レベルでリポジトリ・イベントを無効にするには、次のSQL*Plusコマンドを使用します。これを行うには、ロールXDBADMIN
が必要です。
ALTER SESSION SET XML_DB_EVENTS = DISABLE;
システム・レベルでリポジトリ・イベントを無効にするには、次のSQL*Plusコマンドを使用した後、データベースを再起動します。以降のセッションでは、リポジトリ・イベントが無効になります。これを行うには、権限ALTER SYSTEM
が必要です。
ALTER SYSTEM SET XML_DB_EVENTS = DISABLE;
再度リポジトリ・イベントを有効にするには、XML_DB_EVENTS
の値をENABLE
に設定します。
リソース構成ファイルは、パス/sys/schemas/PUBLIC/xmlns.oracle.com/xdb/XDBResConfig.xsd
にあるOracle XML DBリポジトリでアクセス可能な、XML Schema XDBResConfig.xsd
準拠のXMLファイルです。要素ResConfig
の子である要素event-listeners
を使用してリポジトリ・イベント処理を構成します。
- 構成要素event-listeners
各リソース構成ファイルには、要素ResConfig
の子として1つのevent-listeners
要素があります。これにより、ターゲット・リソースのすべてのイベント処理が構成されます。リソース構成ファイルが特定のリソースではなくリポジトリ全体に適用される場合、リポジトリのすべてのリソースに対してイベント処理が定義されます。 - 構成要素listener
要素listener
は要素event-listeners
の子で、個々のリポジトリ・イベント・リスナーを構成します。 - リポジトリ・イベント構成の例
リポジトリ・イベントの構成の例を示します。リソース構成ファイルにより、前提条件のあるJavaイベント・リスナーと前提条件のないPL/SQLイベント・リスナーが定義されます。例では、MIMEタイプに応じてリソースが分類されています。これには、リソース構成ファイルを作成するためのPL/SQLコードが含まれます。例では、JavaおよびPL/SQLでリスナーを実装します。
関連項目:
リポジトリ・リソースの構成の詳細は、Oracle XML DBリポジトリの構成を参照してください。
親トピック: Oracle XML DBリポジトリ・イベント
30.5.1 構成要素event-listeners
各リソース構成ファイルには、要素ResConfig
の子として1つのevent-listeners
要素があります。これにより、ターゲット・リソースのすべてのイベント処理が構成されます。リソース構成ファイルが特定のリソースではなくリポジトリ全体に適用される場合、リポジトリのすべてのリソースに対してイベント処理が定義されます。
要素event-listeners
には、次のオプション属性があります。
-
set-invoker
: リソース構成で1つ以上のリポジトリ・イベント・ハンドラが起動者権限を持つように定義する場合はtrue
に設定します。デフォルト値はfalse
で、これは定義者権限が使用されていることを意味します。起動者権限のリポジトリ・イベント・ハンドラを定義する場合、データベース・ロール
XDB_SET_INVOKER
が必要です。このロールはDBA
には付与されていますが、XDBADMIN
には付与されていません。ロールXDB_SET_INVOKER
は、リソース構成ファイルの作成または更新時にのみチェックされます。十分な権限があることを保証するため、ロールXDB_SET_INVOKER
ではなく、属性set-invoker
のみ実行時にチェックされます。関連項目:
権限不足によるエラーは、リポジトリ・イベント・ハンドラの考慮事項を参照してください。
-
default-schema
:schema
要素が定義されていないリスナーに使用されるデフォルトのスキーマ値です。 -
default-language
:language
要素が定義されていないリスナーに使用されるデフォルトの言語値です。
要素event-listeners
には子として一連のlistener
要素があります。これにより、個々のリポジトリ・イベント・リスナーが構成されます。リスナーは、listener
要素の順に実行時に処理されます。
親トピック: リポジトリ・イベントの構成
30.5.2 構成要素listener
要素listener
は要素event-listeners
の子で、個々のリポジトリ・イベント・リスナーを構成します。
各listener
要素には、次の子要素があります。source
を除き、これらはすべてオプションで、どのような順序でも出現できます(順序は関係ありません)。
-
description
: リスナーの説明です。 -
schema
: リポジトリ・イベント・ハンドラのJavaまたはPL/SQL実装のデータベース・スキーマです。これとdefault-schema
がどちらも定義されていない場合、エラーが発生します。 -
source
(必須): ハンドラ・メソッドを提供するJavaクラス、PL/SQLパッケージ、またはオブジェクト型の名前です。Javaクラス名はパッケージ名で修飾されている必要があります。空のsource
要素を使用して、リポジトリ・イベント・ハンドラがスタンドアロンのPL/SQLストアド・プロシージャであることを示します。 -
language
: リスナーのクラス(Java)またはパッケージ(PL/SQL)の実装言語です。これとdefault-language
がどちらも定義されていない場合、エラーが発生します。 -
pre-condition
: このリスナーのリポジトリ・イベント・ハンドラの実行のために満たす必要のある前提条件です。これは、一般リソース構成要素configuration
の子pre-condition
と同じです。「構成要素defaultChildConfigおよびconfiguration」を参照してください。 -
events
:Render
、Pre-Create
など一意のリポジトリ・イベント型名のシーケンスです。リスナーには、これらの型のリポジトリ・イベントのハンドラのみ有効化されています。可能なリポジトリ・イベント型のリストは、可能なリポジトリ・イベントを参照してください。要素events
が存在しない場合、すべての型のリポジトリ・イベントのハンドラがリスナーに有効になり、無駄になります。重要性の低いリポジトリ・イベントのハンドラの起動を削減するため、要素events
を提供します。
親トピック: リポジトリ・イベントの構成
30.5.3 リポジトリ・イベント構成の例
リポジトリ・イベントの構成の例を示します。リソース構成ファイルにより、前提条件のあるJavaイベント・リスナーと前提条件のないPL/SQLイベント・リスナーが定義されます。例では、MIMEタイプに応じてリソースが分類されています。これには、リソース構成ファイルを作成するためのPL/SQLコードが含まれます。例では、JavaおよびPL/SQLでリスナーを実装します。
例30-1は、2つのイベント・リスナーを定義するリソース構成ファイルの内容を示しています。各リスナーは、Post-LinkIn
、Post-UnlinkIn
、およびPost-Update
型のリポジトリ・イベントのハンドラを定義します。これは、前提条件、デフォルト言語(Java)およびデフォルトのデータベース・スキーマを定義します。
最初のリスナーのハンドラは、データベース・スキーマCM
で定義されたJavaクラスoracle.cm.quota
に実装されています。これらのハンドラは、ContentType
image/gif
のリソース上のイベントに対してのみ起動されます。
2番目のリスナーのハンドラは、データベース・スキーマIFS
(このリソース構成ファイルのデフォルトのスキーマ)で定義されたJavaクラスoracle.ifs.quota
に実装されています。これらのハンドラは、名前空間http://foo.xsd
のifs-file
型のリソース上のイベントに対してのみ起動されます。
関連項目:
要素defaultChildConfig
およびapplicationData
は、「構成要素defaultChildConfigおよびconfiguration」を参照してください。
簡単なエンドツーエンドの説明として、リソースのMIMEタイプに従ってフォルダ/public/res-app
のリソースを分類する必要があるとします。リソースのMIMEタイプがそれぞれtext/xml
、image/gif
またはapplication/octet-stream
のどれであるかに応じて、フォルダ/public/app/XML-TXT
、/public/app/IMG
および/public/app/FOLDER
のリソースへのリンクが作成されます。これは例30-2、例30-3、例30-5で説明しています。
例30-2は、この分類の説明のため、構成ファイルを作成するPL/SQLコードを示しています。これはPre-UnlinkIn
およびPost-LinkIn
型のイベントを処理する単一のリスナーを定義しています。言語(PL/SQL)およびデータベース・スキーマは明示的に定義されています。前提条件は定義されていません。
例30-3は、例30-2で構成されているイベント・ハンドラを実装するPL/SQLコードを示しています。Post-LinkIn
イベント・ハンドラは、eventObject
リソースへのリンクをリソースのMIMEタイプに応じて、フォルダ/public/app/XML-TXT
、/public/app/IMG
、/public/app/FOLDER
のいずれかに作成します。Pre-UnlinkIn
イベント・ハンドラは、Post-LinkIn
イベント・ハンドラによって作成されたリンクを削除します。
関連項目:
-
新規PL/SQLパッケージ
DBMS_XDBRESOURCE
の詳細は、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスを参照してください。 -
PL/SQLパッケージ
DBMS_XEVENT
の詳細は、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスを参照してください。 -
PL/SQLパッケージ
DBMS_XDB_REPOS
の詳細は、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスを参照してください。
Javaの例は次に示す2行を除き例30-2と同様に構成されます。この2行は要素を例30-2にある同じ名前と置換します。
<source>category</source> <language>Java</language>
例30-1 前提条件のあるJavaイベント・リスナーのリソース構成ファイル
<ResConfig xmlns="http://xmlns.oracle.com/xdb/XDBResConfig.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/xdb/XDBResConfig.xsd http://xmlns.oracle.com/xdb/XDBResConfig.xsd"> <event-listeners default-language="Java" default-schema="IFS"> <listener> <description>Category application</description> <schema>CM</schema> <source>oracle.cm.category</source> <events> <Post-LinkIn/> <Post-UnlinkIn/> <Post-Update/> </events> <pre-condition> <existsNode> <XPath>/Resource[ContentType="image/gif"]</XPath> </existsNode> </pre-condition> </listener> <listener> <description>Check quota</description> <source>oracle.ifs.quota</source> <events> <Post-LinkIn/> <Post-UnlinkIn/> <Post-Update/> </events> <pre-condition> <existsNode> <XPath>r:/Resource/[ns:type="ifs-file"]</XPath> <namespace>xmlns:r="http://xmlns.oracle.com/xdb/XDBResource.xsd" xmlns:ns="http://foo.xsd" </namespace> </existsNode> </pre-condition> </listener> </event-listeners> <defaultChildConfig> <configuration> <path>/sys/xdb/resconfig/user_rc.xml</path> </configuration> </defaultChildConfig> <applicationData> <foo:data xmlns:foo="http://foo.xsd"> <foo:item1>1234</foo:item1> </foo:data> </applicationData> </ResConfig>
例30-2 前提条件のないPL/SQLイベント・リスナーのリソース構成ファイル
DECLARE b BOOLEAN := FALSE; BEGIN b := DBMS_XDB_REPOS.createFolder('/public/resconfig'); b := DBMS_XDB_REPOS.createResource( '/public/resconfig/appcatg-rc1.xml', '<ResConfig xmlns="http://xmlns.oracle.com/xdb/XDBResConfig.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/xdb/XDBResConfig.xsd http://xmlns.oracle.com/xdb/XDBResConfig.xsd"> <event-listeners> <listener> <description>Category application</description> <schema>APPCATGUSER1</schema> <source>APPCATG_EVT_PKG1</source> <language>PL/SQL</language> <events> <Pre-UnlinkIn/> <Post-LinkIn/> </events> </listener> </event-listeners> <defaultChildConfig> <configuration> <path>/public/resconfig/appcatg-rc1.xml</path> </configuration> </defaultChildConfig> </ResConfig>', 'http://xmlns.oracle.com/xdb/XDBResConfig.xsd', 'ResConfig'); END; / BEGIN DBMS_RESCONFIG.appendResConfig('/public/res-app', '/public/resconfig/appcatg-rc1.xml', DBMS_RESCONFIG.APPEND_RECURSIVE); END; /
例30-3 イベント・リスナーを実装するPL/SQLコード
CREATE OR REPLACE PACKAGE appcatg_evt_pkg1 AS PROCEDURE handlePreUnlinkIn (eventObject DBMS_XEVENT.XDBRepositoryEvent); PROCEDURE handlePostLinkIn (eventObject DBMS_XEVENT.XDBRepositoryEvent); END; / CREATE OR REPLACE PACKAGE BODY appcatg_evt_pkg1 AS PROCEDURE handlePreUnlinkIn (eventObject DBMS_XEVENT.XDBRepositoryEvent) AS XDBResourceObj DBMS_XDBRESOURCE.XDBResource; ResDisplayName VARCHAR2(100); ResPath VARCHAR2(1000); ResOwner VARCHAR2(1000); ResDeletedBy VARCHAR2(1000); XDBPathobj DBMS_XEVENT.XDBPath; XDBEventobj DBMS_XEVENT.XDBEvent; SeqChar VARCHAR2(1000); LinkName VARCHAR2(10000); ResType VARCHAR2(100); LinkFolder VARCHAR2(100); BEGIN XDBResourceObj := DBMS_XEVENT.getResource(eventObject); ResDisplayName := DBMS_XDBRESOURCE.getDisplayName(XDBResourceObj); ResOwner := DBMS_XDBRESOURCE.getOwner(XDBResourceObj); XDBPathobj := DBMS_XEVENT.getPath(eventObject); ResPath := DBMS_XEVENT.getName(XDBPathObj); XDBEventobj := DBMS_XEVENT.getXDBEvent(eventObject); ResDeletedBy := DBMS_XEVENT.getCurrentUser(XDBEventobj); BEGIN SELECT XMLCast( XMLQuery( 'declare namespace ns = "http://xmlns.oracle.com/xdb/XDBResource.xsd"; /ns:Resource/ns:ContentType' PASSING r.RES RETURNING CONTENT) AS VARCHAR2(100)) INTO ResType FROM PATH_VIEW r WHERE r.PATH=ResPath; EXCEPTION WHEN OTHERS THEN NULL; END; IF ResType = 'text/xml' THEN LinkFolder := '/public/app/XML-TXT/'; END IF; IF ResType = 'image/gif' THEN LinkFolder := '/public/app/IMG/'; END IF; IF ResType = 'application/octet-stream' THEN LinkFolder := '/public/app/FOLDER/'; END IF; DBMS_XDB_REPOS.deleteResource(LinkFolder || ResDisplayName); END; PROCEDURE handlePostLinkIn (eventObject DBMS_XEVENT.XDBRepositoryEvent) AS XDBResourceObj DBMS_XDBRESOURCE.XDBResource; ResDisplayName VARCHAR2(100); ResPath VARCHAR2(1000); ResOwner VARCHAR2(1000); ResDeletedBy VARCHAR2(1000); XDBPathobj DBMS_XEVENT.XDBPath; XDBEventobj DBMS_XEVENT.XDBEvent; SeqChar VARCHAR2(1000); LinkName VARCHAR2(10000); ResType VARCHAR2(100); LinkFolder VARCHAR2(100); BEGIN XDBResourceObj := DBMS_XEVENT.getResource(eventObject); ResDisplayName := DBMS_XDBRESOURCE.getDisplayName(XDBResourceObj); ResOwner := DBMS_XDBRESOURCE.getOwner(XDBResourceObj); XDBPathobj := DBMS_XEVENT.getPath(eventObject); ResPath := DBMS_XEVENT.getName(XDBPathObj); XDBEventobj := DBMS_XEVENT.getXDBEvent(eventObject); ResDeletedBy := DBMS_XEVENT.getCurrentUser(XDBEventobj); SELECT XMLCast( XMLQuery( 'declare namespace ns = "http://xmlns.oracle.com/xdb/XDBResource.xsd"; /ns:Resource/ns:ContentType' PASSING r.RES RETURNING CONTENT) AS VARCHAR2(100)) INTO ResType FROM PATH_VIEW r WHERE r.PATH=ResPath; IF ResType = 'text/xml' THEN LinkFolder := '/public/app/XML-TXT'; END IF; IF ResType = 'image/gif' THEN LinkFolder := '/public/app/IMG'; END IF; IF ResType = 'application/octet-stream' THEN LinkFolder := '/public/app/FOLDER'; END IF; DBMS_XDB_REPOS.link(ResPath, LinkFolder, ResDisplayName); END; END; /
例30-4 イベント・リスナーを実装するJavaコード
import oracle.xdb.event.*; import oracle.xdb.spi.*; import java.sql.*; import java.io.*; import java.net.*; import oracle.jdbc.*; import oracle.sql.*; import oracle.xdb.XMLType; import oracle.xdb.dom.*; public class category extends oracle.xdb.event.XDBBasicEventListener { public Connection connectToDB() throws java.sql.SQLException { try { String strUrl="jdbc:oracle:kprb:"; String strUname="appcatguser1"; String strPwd="appcatguser1 "; Connection conn=null; OraclePreparedStatement stmt=null; DriverManager.registerDriver(new oracle.jdbc.OracleDriver()); conn = DriverManager.getConnection(strUrl, strUname, strPwd); return conn; } catch(Exception e1) { System.out.println("Exception in connectToDB java function"); System.out.println("e1:" + e1.toString()); return null; } } public void handlePostLinkIn (XDBRepositoryEvent eventObject) { XDBPath objXDBPath = null; String strPathName=""; objXDBPath = eventObject.getPath(); strPathName = objXDBPath.getName(); XDBResource objXDBResource1; objXDBResource1 = eventObject.getResource(); String textResDisplayName = objXDBResource1.getDisplayName(); String resType = objXDBResource1.getContentType(); String linkFolder=""; System.out.println("resType" + resType+"sumit"); System.out.println("strPathName:" + strPathName); System.out.println("textResDisplayName:" + textResDisplayName); if (resType.equals("text/xml")) linkFolder = "/public/app/XML-TXT/"; else if (resType.equals("image/gif")) linkFolder = "/public/app/IMG/"; else if (resType.equals("application/octet-stream")) linkFolder = "/public/app/FOLDER/"; System.out.println("linkFolder:" + linkFolder); try { Connection con1 = connectToDB(); OraclePreparedStatement stmt=null; stmt = (OraclePreparedStatement)con1.prepareStatement( "CALL DBMS_XDB_REPOS.link(?,?,?)"); stmt.setString(1,strPathName); stmt.setString(2,linkFolder); stmt.setString(3,textResDisplayName); stmt.execute(); stmt.close(); con1.close(); } catch(java.sql.SQLException ej1) { System.out.println("ej1:" + ej1.toString()); } /* Make sure the link is not in the category folders. Then check the target resource's mime type and create a link in the appropriate category folder. */ } public void handlePreUnlinkIn (XDBRepositoryEvent eventObject) { XDBPath objXDBPath = null; String strPathName=""; objXDBPath = eventObject.getPath(); strPathName = objXDBPath.getName(); XDBResource objXDBResource1; objXDBResource1 = eventObject.getResource(); String textResDisplayName = objXDBResource1.getDisplayName(); String resType = objXDBResource1.getContentType(); String linkFolder=""; if (resType.equals("text/xml")) linkFolder = "/public/app/XML-TXT/"; else if (resType.equals("image/gif")) linkFolder = "/public/app/IMG/"; else if (resType.equals("application/octet-stream")) linkFolder = "/public/app/FOLDER/"; try { Connection con1 = connectToDB(); OraclePreparedStatement stmt=null; stmt = (OraclePreparedStatement)con1.prepareStatement( "CALL DBMS_XDB_REPOS.deleteResource(?)"); stmt.setString(1,linkFolder+textResDisplayName); stmt.execute(); stmt.close(); con1.close(); } catch(java.sql.SQLException ej1) { System.out.println("ej1:" + ej1.toString()); } } }
例30-5 イベント・ハンドラの起動
DECLARE ret BOOLEAN; BEGIN ret := DBMS_XDB_REPOS.createResource('/public/res-app/res1.xml', '<name>TestForEventType-1</name>'); END; / DECLARE b BOOLEAN := FALSE; dummy_data CLOB := 'AAA'; BEGIN b := DBMS_XDB_REPOS.createResource('/public/res-app/res2.gif', dummy_data); END; / DECLARE b BOOLEAN := FALSE; dummy_data CLOB := 'AAA'; BEGIN b := DBMS_XDB_REPOS.createFolder('/public/res-app/res-appfolder1'); END; SELECT PATH FROM PATH_VIEW WHERE PATH LIKE '/public/app/%' ORDER BY PATH; PATH --------------------------------- /public/app/FOLDER /public/app/FOLDER/res-appfolder1 /public/app/IMG /public/app/IMG/res2.gif /public/app/XML-TXT /public/app/XML-TXT/res1.xml 6 rows selected. -- Delete the /res-app resources. The /app resources are deleted also. EXEC DBMS_XDB_REPOS.deleteResource('/public/res-app/res2.gif'); EXEC DBMS_XDB_REPOS.deleteResource('/public/res-app/res1.xml'); EXEC DBMS_XDB_REPOS.deleteResource('/public/res-app/res-appfolder1'); SELECT PATH FROM PATH_VIEW WHERE PATH LIKE '/public/app/%' ORDER BY PATH; PATH ------------------- /public/app/FOLDER /public/app/IMG /public/app/XML-TXT 3 rows selected.
親トピック: リポジトリ・イベントの構成