30 Oracle XML DBリポジトリ・イベント

Oracle XML DBリポジトリを使用して、あらゆるリポジトリ・リソース形式のデータを格納、またはデータにアクセスできます。リポジトリ・データには、任意のアプリケーションからアクセスできます。特定のリポジトリ操作が発生するたびに、アプリケーションによる特定のアクションの実行が必要な場合があります。リポジトリ・イベントを使用してこれを行うことができます。

30.1 リポジトリ・イベントの概要

リポジトリ操作に関連するイベントが発生した場合、アプリケーションで特定のアクションを実行できます。たとえば、リソースを削除するたびに、ごみ箱への移動やバックアップ操作を実行する場合があります。

リポジトリ・リソース操作には、作成、削除、ロック、ロック解除、レンダリング、リンク付け、リンク解除、バージョン管理、チェックイン、チェックアウト、チェックアウト解除(チェックアウトされたバージョンの回復)、オープン、更新があります。

30.1.1 リポジトリ・イベント: ユースケース

リポジトリ・イベントを使用できる場合の例として、ごみ箱へのリソースの移動やMIMEタイプに基づくリソースの分類などがあります。

  • ごみ箱– UnLink前処理イベント・ハンドラを使用して、リソースを削除するのではなく、効率的にごみ箱に移動できます。つまり、元のリンクを削除する前にごみ箱フォルダにリンクを作成します。ごみ箱のリンクにより、リソースは削除されません。その後、削除されたリソースをごみ箱から元に戻す場合、元のリンクが再作成され、ごみ箱のリンクが削除されます。特定のパスのリソースは、そのパスから複数回リンク解除できるため、ごみ箱のリンク名は、削除されるリンク名と異なるリンク名にできます。ごみ箱には、そのパスに対応する、リンク・プロパティが異なり、それぞれ別のリソースを指している可能性のあるリンクが複数存在します。

  • カテゴリ分け: アプリケーションにより、管理するリソースがMIMEタイプや他のプロパティに基づいて分類される場合があります。リポジトリ・フォルダ/my-app/gif/my-app/txt、および/my-app/xmlからGIFファイル、テキスト・ファイル、およびXMLファイルのリンクが保持され、そのファイルが追跡されることがあります。ここでは、LinkInUnlinkInUpdateの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組のイベントと関連付けられ、これらのイベントは次の順に発生します。

  1. Pre-creationイベント

  2. Post-creationイベント

  3. Pre-link-inイベント

  4. Pre-link-toイベント

  5. Post-link-toイベント

  6. Post-link-inイベント

表30-1に、各リポジトリ操作に関連付けられたイベントを示します。この順序をハンドラ列に示します。

表30-1 事前定義リポジトリ・イベント

リポジトリ・イベント型 説明 プリハンドラ実行 ポストハンドラ実行

Render

Renderイベントは、フォルダ・リソースではなく、file・リソースにのみ発生します。

次のいずれかを使用してリソース・コンテンツにアクセスする際に発生します。

  • プロトコル

  • XDBURITypeメソッドgetCLOB()getBLOB()、およびgetXML()

次のいずれかを使用してリソース・コンテンツにアクセスする場合は発生しません

  • SELECT ... FROM RESOURCE_VIEW

  • XDBURITypeメソッドgetResource()

レンダリング出力を設定できるのはRenderイベントのハンドラ1つのみです。setRenderStreamまたはsetRenderPathをコールする最初のハンドラが、レンダリングを制御します。

該当なし

該当なし

Create

リソースが作成されるときに発生します。実行されたプリハンドラとポストハンドラは、新規リソースのフォルダに定義されているハンドラです。

事前解析後、親リソースACLおよびロックの検証後、およびデフォルト値の未定義プロパティへの割当て前

リソースのシステム・リソース表への挿入後

Delete

リソースとそのコンテンツがディスクから削除される場合、つまりリソースREFカウントがゼロ(0)の場合に発生します。

リソースACLおよびロックの検証後、およびリソースのディスクからの削除前

リソースとそのコンテンツのディスクからの削除後、および親フォルダの最終変更者と変更時間の更新のためのフォルダ変更後

Update

ディスクでリソースを更新する場合に発生します。

リソースACLおよびロックの検証後、および最終変更者と変更時間の更新前

リソースのディスクへの書込み後

Lock

リソース・ロック操作中に発生します。

リソースACLおよびロックの検証後、およびリソースでの新規ロックの作成前

新規ロック作成後

Unlock

リソース・ロック解除操作中に発生します。

リソースACLおよび削除トークン検証後

ロック削除後

LinkIn

リンク操作中のLinkToイベント前に発生します。イベント・ターゲットはリンクが作成されるフォルダです。常にLinkToイベントを伴います。

リソースACLおよびロックの検証後、およびリンク作成前

LinkToポストハンドラ実行後

LinkTo

リンク操作中のLinkInイベント後に発生します。イベント・ターゲットは、リンク宛先となるリソースです。

LinkInプリハンドラ実行後、およびリンク作成前

リンク作成後、および親フォルダの最終変更者と変更時間の更新後

UnLinkIn

リンク解除操作中のUnlinkFromイベント前に発生します。常にUnlinkFromイベントを伴います。

リソースACLおよびロックの検証後、およびリンク削除前

UnlinkFromポストハンドラ実行後

UnlinkFrom

リンク解除操作中のUnlinkInイベント後に発生します。

UnlinkInプリハンドラ実行後

リンク削除後

CheckIn

リソースのチェックイン中に発生します。

リソースACLおよびロック検証後、およびリソースがバージョン管理対象であり、チェックアウト済であることを検証後

リソースのチェックイン後

CheckOut

リソースのチェックアウト中に発生します。

リソースACLおよびロック検証後、およびリソースがバージョン管理対象であり、チェックアウト前であることを検証後

リソースのチェックアウト後

UncheckOut

リソースのチェックアウト解除中に発生します。

リソースがチェックアウトされている記録の削除前

リソースのチェックアウト解除後

VersionControl

リソースのバージョン履歴が作成されるときに発生します。

注意: DBMS_XDB_VERSION.MakeVersioned()は複数回コールできますが、バージョン履歴は初回コール時のみ作成されます。それ以降のコールによる影響はなく、VersionControlイベントは発生しません。

リソースのバージョン履歴作成前

リソースの最初のバージョン作成後

簡単にするため、一般的にこのドキュメントでは、イベント型pre-link-inおよびpost-link-inの略記としてLinkInイベント型を参照するなど、リポジトリ・イベント・ペアの両方のメンバーを扱います。同様に、ここで使用するイベント型名は、JavaインタフェースXDBRepositoryEventListenerから接頭辞handlePreおよびhandlePostを削除して導出されたものです。

関連項目:

PL/SQLリポジトリ・イベント型は、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスを参照してください。

30.3 リポジトリ操作とイベント

異なるOracle XML DBリポジトリ操作で同じリポジトリ・イベントが発生する可能性があり、また指定のリポジトリ操作により複数のリポジトリ・イベントが生成される可能性があります。

表30-2に、各リポジトリ操作に関連付けられたイベントを示します。同じ操作に複数のリポジトリ・イベントが発生する場合のイベントの順序は、表30-1を参照してください。

表30-2 Oracle XML DBリポジトリ操作とイベント

操作 発生しているリポジトリ・イベント

パス名によるリソース・コンテンツのバイナリ表現の取得

Render

パス名によるリソース・コンテンツのXML表現の取得

Render

リソースの作成または更新

リソースがすでに存在している場合: CreateLinkInLinkTo

リソースが存在していない場合(HTTPおよびFTPのみ): Update

フォルダの作成

CreateLinkInLinkTo

既存のリソースへのリンクの作成

リンク・ターゲットを含むフォルダではLinkIn、リンクするターゲット・リソースではLinkTo

ファイル・リソースまたは空フォルダ・リソースのリンク解除(RefCountを減少させます。これがゼロの場合はディスクからリソースを削除します。)

UnlinkInUnlinkFrom、(RefCountがゼロの場合は)Delete

フォルダとそのコンテンツの強制削除

リソースのリンク解除のため、再帰イベントを生成します。フォルダの子リソースは再帰的に削除され、次にフォルダが削除されます。

リソースへのすべてのリンクの強制削除

削除されたリンクごとにリンク解除イベントを生成します。

パス名によるリソースのコンテンツ、プロパティ、ACLの更新

Update

深さゼロのWebDAVロックのリソースへの配置

Lock

深さゼロのWebDAVロックのリソースからの削除

Lock

リソースの名前変更

新規の位置ではLinkInおよびLinkTo、古い位置ではUnlinkInおよびUnlinkFrom

リソースのコピー

新規の位置ではCreateLinkInLinkTo

リソースのチェックアウト

CheckOut

リソースのチェックイン

CheckIn

リソースのバージョン管理への配置

VersionControl

リソースのチェックアウト解除

UncheckOut

表30-2に示すすべての操作は、次の操作を除き、基本操作です。

  • フォルダとそのコンテンツの強制削除

  • HTTP(のみ)を使用したパス名によるリソース・プロパティの更新

  • HTTP(のみ)を使用したフォルダのコピー

関連項目:

APIとプロトコルを使用したリソースへのアクセスの詳細は、表21-3を参照してください。

30.4 リポジトリ・イベント・ハンドラの考慮事項

Oracle XML DBリポジトリ・イベントのハンドラを定義する場合のいくつかの考慮事項を示します。

  • すべてのハンドラ: ハンドラ内でCOMMITROLLBACKまたはデータ定義言語(DDL)文を使用しないでください。DDL文と同様の動作をするPL/SQLファンクションまたはプロシージャ(DBMS_XMLSCHEMA.registerSchemaなど)をコールしないでください。Renderハンドラ: データ操作言語(DML)文を使用しないでください。

    これらの制約を回避するには、ハンドラは自律型トランザクション内でこのような文を使用できます。ただし、ロック競合が発生しないようにすることが必要です。

  • Renderハンドラ内で出力ストリームをクローズしないでください。(ストリームに追加できます。)

  • Pre-CreateおよびPre-Update以外のハンドラ内では、クラスXDBResourceから修飾子メソッドを使用しないでください。いずれのハンドラ内でも、メソッドXDBResource.save()を使用しないでください。

  • 安全なリポジトリ・イベント・ハンドラのみ開発することをお薦めします。特に、次の点に注意してください。

    • xdb名前空間ではなく、アプリケーションが所有する名前空間にあるリソース・プロパティのみを記述してください。

    • リソースの作成中は、リソースを削除しないでください。

  • リポジトリ・イベント・ハンドラには、現在のSQL文またはプロトコル操作中にのみ存在するXDBRepositoryEventオブジェクトが渡されます。このオブジェクトでPL/SQLプロシージャとJavaメソッドを使用して、リソース、イベントおよび関連イベント・ハンドラの情報を取得できます。

  • イベント・ハンドラが他のリポジトリ・イベントを生じさせる操作を実行すると、それらのカスケーディング・イベントがただちに発生します。ただし、現在のイベントのハンドラが完了した後は、これらのイベントはキューに入れられず発生しません。つまり、各イベントはその対応する操作に関連して発生します。

  • 複数のリポジトリ・イベント・ハンドラが同時にコールされます。これらは対応する操作のプロセス、セッション、トランザクションにおいて実行されます。ただし、ハンドラではOracle Streamsアドバンスト・キューイング(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操作(登録、削除など)はイベントを生成しません。

関連項目:

30.5 リポジトリ・イベントの構成

リソース構成ファイルでは、要素ResConfigの子である要素event-listenersを使用して、Oracle XML DBリポジトリ・イベント処理を構成します。

リポジトリ・リソースの他の処理を構成するように、Oracle XML DBリポジトリ・リソースのイベント処理を構成します。リソースの構成を参照してください。

デフォルトではリポジトリ・イベントは有効になっていますが、パラメータXML_DB_EVENTSDISABLEに設定して無効にできます。セッション・レベルでリポジトリ・イベントを無効にするには、次の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を使用してリポジトリ・イベント処理を構成します。

関連項目:

リポジトリ・リソースの構成の詳細は、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: RenderPre-Createなど一意のリポジトリ・イベント型名のシーケンスです。リスナーには、これらの型のリポジトリ・イベントのハンドラのみ有効化されています。可能なリポジトリ・イベント型のリストは、可能なリポジトリ・イベントを参照してください。要素eventsが存在しない場合、すべての型のリポジトリ・イベントのハンドラがリスナーに有効になり、無駄になります。重要性の低いリポジトリ・イベントのハンドラの起動を削減するため、要素eventsを提供します。

30.5.3 リポジトリ・イベント構成の例

リポジトリ・イベントの構成の例を示します。リソース構成ファイルにより、前提条件のあるJavaイベント・リスナーと前提条件のないPL/SQLイベント・リスナーが定義されます。例では、MIMEタイプに応じてリソースが分類されています。これには、リソース構成ファイルを作成するためのPL/SQLコードが含まれます。例では、JavaおよびPL/SQLでリスナーを実装します。

例30-1は、2つのイベント・リスナーを定義するリソース構成ファイルの内容を示しています。各リスナーは、Post-LinkInPost-UnlinkIn、およびPost-Update型のリポジトリ・イベントのハンドラを定義します。これは、前提条件、デフォルト言語(Java)およびデフォルトのデータベース・スキーマを定義します。

最初のリスナーのハンドラは、データベース・スキーマCMで定義されたJavaクラスoracle.cm.quotaに実装されています。これらのハンドラは、ContentType image/gifのリソース上のイベントに対してのみ起動されます。

2番目のリスナーのハンドラは、データベース・スキーマIFS(このリソース構成ファイルのデフォルトのスキーマ)で定義されたJavaクラスoracle.ifs.quotaに実装されています。これらのハンドラは、名前空間http://foo.xsdifs-file型のリソース上のイベントに対してのみ起動されます。

関連項目:

要素defaultChildConfigおよびapplicationDataは、「構成要素defaultChildConfigおよびconfiguration」を参照してください。

簡単なエンドツーエンドの説明として、リソースのMIMEタイプに従ってフォルダ/public/res-appのリソースを分類する必要があるとします。リソースのMIMEタイプがそれぞれtext/xmlimage/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イベント・ハンドラによって作成されたリンクを削除します。

関連項目:

Javaの例は次に示す2行を除き例30-2と同様に構成されます。この2行は要素を例30-2にある同じ名前と置換します。

                <source>category</source>
                <language>Java</language>

例30-4は、イベント・ハンドラを実装するJavaコードを示しています。ロジックは例30-3と同じです。

例30-5は、例30-3または例30-4で実装されているイベント・ハンドラの起動を示しています。

例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.