|
注意: 一般に、ポートレットの構築には、PL/SQLではなくJavaを使用することをお薦めします。ポートレットを構築するためのテクノロジの選択方法は、第2章「ポートレット・テクノロジのマトリックス」を参照してください。Javaを使用したポートレットの構築方法は、第6章「Javaポートレットの作成」を参照してください。 |
Oracle PortalのPL/SQL APIは、一連のPL/SQLパッケージおよびオブジェクトとして実装されます。データベース・プロバイダおよびポートレットは、データベース・スキーマにPL/SQLパッケージとしてデプロイされます。この章では、Oracle Portal Developer Kit-PL/SQL (PDK-PL/SQL)に基づいてPL/SQLポートレットを作成する方法について説明します。この章を効果的に利用するには、PL/SQLを理解し、ある程度PL/SQL Webツールキットに精通している必要があります。
この章の内容は、次のとおりです。

この章で参照される多数の例のソース・コードは、PDK-PL/SQLの一部として利用できます。PDK-PL/SQLは、Oracle Technology Network (OTN)の「Oracle Portal Developer Kit (PDK)」ページからダウンロードできます:
http://www.oracle.com/technology/products/ias/portal/pdk.html
PDK-PL/SQLを解凍すると、次の場所に例があります。
../pdk/plsql/starter ../pdk/plsql/sample ../pdk/plsql/cache ../pdk/plsql/sso ../pdk/plsql/svcex
PDK-PL/SQLのリファレンスは、次の場所にあります。
../pdk/plsql/doc
PL/SQLでポートレットを作成する際は、この項で説明するベスト・プラクティスに従う必要があります。
Javaポートレットと同様に、PL/SQLポートレットでは、様々な表示モードが使用できます。表示モードは、ポートレットの機能の一部です。使用できる次の表示モードの詳細は、第6章「Javaポートレットの作成」を参照してください。
共有画面モードは、6.1.1.1項「共有画面モード(JPSの場合は表示モード)」を参照してください。
編集モードの詳細は、6.1.1.2項「編集モード(JPSおよびPdk-Java)」を参照してください。
デフォルト編集モードの詳細は、6.1.1.3項「デフォルト編集モード(JPSおよびPDK-Java)」を参照してください。
プレビュー・モードの詳細は、6.1.1.4項「プレビュー・モード(JPSおよびPDK-Java)」を参照してください。
全画面モードの詳細は、6.1.1.5項「全画面モード(PDK-Java)」を参照してください。
ヘルプ・モードは、6.1.1.6項「ヘルプ・モード(JPSおよびOracle Portal)」を参照してください。
情報モードの詳細は、6.1.1.7項「情報モード(JPSおよびPDK-Java)」を参照してください。
リンク・モードの詳細は、6.1.1.8項「リンク・モード(PDK-Java)」を参照してください。
選択した表示モードを確認するために、wwpro_api_providerパッケージの定数を使用できます。表8-1に、これらの定数とそれに対応する表示モードを示します。
ポートレット・コードの主な目的は、Oracle Portalで必要なすべての表示モードでページに表示されるHTML出力を生成することです。ポートレットを一連の別個のPL/SQLストアド・プログラム・ユニットとして実装することは可能ですが、ポートレット・コードをPL/SQLパッケージに編成することが、関連するポートレット・コードとデータを単一のユニットとしてデータベースにカプセル化する最適な方法です。また、データベース・パフォーマンスが改善され、ポートレットのメンテナンスが容易になります。
2.4項「デプロイ・タイプ」から想起されるように、特定のポートレットに対するOracle Portalからのリクエストは、ポートレットのプロバイダを介します。ポートレットと通信するために、プロバイダには、ポートレット・コードをコールする一連の必須メソッドが含まれています。
ポートレットをPL/SQLパッケージとして実装するときは、ポートレット・コードをプロバイダ・コードとともに、同時に編成することをお薦めします。たとえば、プロバイダは、ポートレットの1つについて情報を取得する必要があるとき、get_portletファンクションを使用します。したがって、ポートレットがget_portlet_infoファンクションを含むのは当然のことで、このファンクションは、プロバイダのget_portletファンクションでコールされると、リクエストされた情報を戻します。同様に、プロバイダのshow_portletプロシージャがポートレットのshowプロシージャをコールするのは当然のことで、このプロシージャは、リクエストされた表示モード用のHTML出力を作成し、それをプロバイダに戻します。
表8-2に、データベース・プロバイダと効率的に通信するためにPL/SQLポートレットで使用する推奨プロシージャおよびファンクションを示します。
表8-2 PL/SQLポートレット用の推奨ファンクションおよびプロシージャ
| プロシージャ/ファンクション名 | 用途 |
|---|---|
get_portlet_info |
ポートレット・レコードをプロバイダに戻します。 |
show |
リクエストされた表示モード用のHTML出力を作成し、それをプロバイダに戻します。 |
register |
ポートレットをインスタンス・レベルで初期化します。登録プロシージャには、COMMIT、ROLLBACKまたはSAVEPOINTのようなトランザクション終了文はいっさい含めないでください。OracleAS Portalは、トランザクションの終了を自分で処理します。 |
deregister |
インスタンス・レベルでのクリーンアップを可能にします。登録解除プロシージャには、COMMIT、ROLLBACKまたはSAVEPOINTのようなトランザクション終了文はいっさい含めないでください。OracleAS Portalは、トランザクションの終了を自分で処理します。 |
is_runnable |
ポートレットを実行できるかどうかを決定します。セキュリティ・チェックは、このファンクションで実行できます。 |
copy |
Oracle Portalでページをコピーする際に、ポートレット・プリファレンスのパーソナライズされた値およびデフォルト値をポートレット・インスタンスから新しいポートレット・インスタンスにコピーします。 |
describe_parameters |
パブリック・ポートレット・パラメータのリストを戻します。 |
Oracle Portalのページは、HTMLデバイスおよび非HTMLデバイス(モバイル機器)の両方に対してレンダリングできます。モバイル機器用ポートレットを設計するときは、いくつかの追加のガイドラインを考慮する必要があります。モバイル・ポートレットに関するガイドラインは、6.1.4項「モバイル・ポートレットのガイドライン」を参照してください。
モバイル対応ポートレットの構築方法は、8.12項「ポートレットのモバイル機器用拡張」を参照してください。
データベース・プロバイダおよびPL/SQLポートレットの開発を容易にするために、PL/SQLジェネレータを使用できます。PL/SQLジェネレータは、データベース・プロバイダとそのポートレットに関するインストール可能なPL/SQLコードを作成するユーティリティです。PL/SQLジェネレータは、プロバイダおよびポートレットの定義をXMLファイル形式(provider.xmlファイルと同様の形式)で受信するスタンドアロンのWebアプリケーションです。プロバイダおよびポートレットの定義で使用するXMLタグは、PDK-JavaでWebプロバイダを定義するために使用するXMLタグのサブセットです。PL/SQLジェネレータは、SQL*Plusから実行できるSQLスクリプトを出力します。このスクリプトには、プロバイダおよびポートレットのパッケージを正しい順序でインストールするためのSQLコマンドが含まれています。
PL/SQLジェネレータは、次の場所からインストール手順とともにダウンロードできます:
http://www.oracle.com/technology/products/ias/portal/files/plsqlgenerator.zip
PL/SQLジェネレータを使用するための一般的なモデルは次のとおりです。
構築するプロバイダおよびポートレットを定義するXMLファイルを作成します(8.2.1項「入力XMLファイルの作成」を参照)。
作成したXMLファイルを入力として使用し、PL/SQLジェネレータを実行します(8.2.2項「PL/SQLジェネレータの実行」を参照)。
生成されたPL/SQLポートレットを公開します。手順は次のとおりです。
PL/SQLジェネレータで生成されたプロバイダをデータベースにインストールします(8.2.3.1項「データベースへのパッケージのインストール」を参照)。
データベース・プロバイダをOracle Application Serverに登録します(8.2.3.2項「データベース・プロバイダの登録」を参照)。
生成されたポートレットをページに追加します(8.2.3.3項「ページへのポートレットの追加」を参照)。
ソースのXMLファイルは、<provider>タグで始まり</provider>タグで終わります。また、1つ以上のポートレット定義を含めることができます。各ポートレット定義は、<portlet>タグと</portlet>タグで囲まれます。ポートレット定義には、ポートレット・レコード属性の値を指定し、ポートレット・ヘッダーでのリンクを有効にするXMLタグが含まれます。たとえば、<name>タグは、プロバイダ・ドメインにポートレット名を指定します。また、<title>タグは、ポートレットの表示名またはタイトルを指定します。<showEdit>タグをtrueに設定すると、ポートレットの編集モードとポートレッド・ヘッダーでの対応するリンクが有効になります。表8-3に、PL/SQLジェネレータの入力に使用できるXMLタグを示します。
表8-3 PL/SQLジェネレータの入力用XMLタグ
| XMLタグ | 定義 | 値のタイプ |
|---|---|---|
provider |
プロバイダ定義タグを囲みます。 |
該当なし |
portlet |
ポートレット定義タグを囲みます。 |
該当なし |
id |
プロバイダにポートレットIDを指定します。この値は、プロバイダ内で一意である必要があります。 |
文字列 |
name |
ポートレット名を指定します。名前には空白を含めないでください。ジェネレータでは、 |
文字列 |
title |
ポートレットの表示名を指定します。 |
文字列 |
shortTitle |
ポートレットの短い表示名を指定します。このタグは、モバイル・ポートレットに便利です。 |
文字列 |
description |
ポートレットの説明を指定します。 |
文字列 |
defaultLocale |
ポートレットがデフォルトでレンダリングする言語を指定します。この値は、2文字のISO言語コードと国コードで、 |
文字列 |
timeout |
ポートレットのタイムアウト時間(秒数)を指定します。 |
数値 |
timeoutMsg |
ポートレットがタイムアウトしたときに表示されるメッセージを指定します。 |
文字列 |
showEdit |
ユーザーがポートレットのプロパティをパーソナライズできる編集モードを、ポートレットがサポートするかどうかを指定します。 |
ブール |
showEditDefault |
ポートレットのプロパティのデフォルト値をパーソナライズできるデフォルト編集モードを、ポートレットがサポートするかどうかを指定します。 |
ブール |
showDetails |
ポートレットが全画面モードで表示できるかどうかを指定します。このモードでは、ブラウザ・ウィンドウ全体がそのポートレットのみのものになります。全画面モードを使用すると、ポートレットは、他のポートレットとページを共有しているときよりも詳細な表示を行います。 |
ブール |
showPreview |
ポートレットがプレビュー・モードをサポートするかどうかを指定します。 |
ブール |
hasHelp |
ポートレットがヘルプ・モードをサポートするかどうかを指定します。 |
ブール |
hasAbout |
ポートレットが情報モードをサポートするかどうかを指定します。 |
ブール |
language |
ポートレットのデフォルト言語(たとえば |
文字列 |
contentType |
ポートレットでサポートされるデフォルトのコンテンツ・タイプを指定します。タグは、次のいずれかの値をとります。 wwpro_api_provider.CONTENT_TYPE_HTML wwpro_api_provider.CONTENT_TYPE_XML wwpro_api_provider.CONTENT_TYPE_MOBILE |
文字列 |
apiVersion |
ポートレットが準拠するOracle PortalのPL/SQL APIのバージョンを指定します。値は、 |
文字列 |
callIsRunnable |
ポートレットを表示する前に、OracleAS Portalでユーザーの資格証明をチェックする必要があるかどうかを指定します。デフォルト値は |
ブール |
callGetPortlet |
ポートレット・レコードのプロバイダに接続するかわりに、Portlet Metadata Repository (PMR)に格納されるポートレット・レコード・データをポータルで使用できるかどうかを指定します。プロバイダから戻されるポートレット・レコード(プロバイダの |
ブール |
acceptContentType |
ポートレットで作成できるコンテンツ・タイプのカンマ区切りのリストを指定します。たとえば、ポートレットでHTMLおよびMOBILEXMLの両タイプのコンテンツを作成できる場合は、タグの値は次のとおりです。 text/html,text/vnd.oracle.mobilexml |
文字列 |
hasShowLinkMode |
ポートレットがリンク・モードを実装するかどうかを指定します。値が |
ブール |
mobileOnly |
ポートレットはモバイル機器でのみ使用可能かどうかを指定します。デフォルト値は |
ブール |
preferenceStorePath |
プロバイダがポートレットのパーソナライズ情報を格納した場所へのベース・プリファレンス・ストア・パスを指定します。このパスは、ポートレットのエクスポート時に使用されます。 |
文字列 |
createdOn |
ポートレットの作成日を定義します。デフォルト値は |
日付 |
createdBy |
ポートレット・レコードを作成したユーザーを指定します。 |
文字列 |
lastUpdatedOn |
ポートレット・レコードが変更された最新の日付を定義します。デフォルト値は |
日付 |
lastUpdatedBy |
ポートレット・レコードを最近変更したユーザーを指定します。 |
文字列 |
passAllUrlParams |
ポートレットでのパラメータの引渡し動作を指定します。タグの値が |
ブール |
cacheLevel |
ポートレットのキャッシュ・レベルを指定します。次のいずれかの値をとります。 wwpro_api_provider.CACHE_LEVEL_SYSTEM wwpro_api_provider.CACHE_LEVEL_USER |
文字列 |
rewriteUrls |
ポートレット・レンダリング・リクエストからの出力で、URLリライティングを実行するかどうかを指定します。デフォルト値は |
ブール |
次に、PL/SQLジェネレータ用の入力XMLのサンプルを示します。必須情報は太字で示されています。
<!-- This is a sample provider.xml file for the PLSQL Generator 1.2 -->
<provider>
<portlet>
<id>1</id>
<name>Test_Portlet</name>
<title>Test Portlet Title</title>
<shortTitle>Short portlet title</shortTitle>
<description>This is a Test portlet</description>
<timeout>30</timeout>
<timeoutMsg>Test Portlet Timed Out</timeoutMsg>
<showEdit>true</showEdit>
<showEditDefault>true</showEditDefault>
<showDetails>true</showDetails>
<showPreview>true</showPreview>
<hasHelp>true</hasHelp>
<hasAbout>true</hasAbout>
<language>en</language>
<contentType>wwpro_api_provider.CONTENT_TYPE_HTML</contentType>
<apiVersion>wwpro_api_provider.API_VERSION_1</apiVersion>
<callIsRunnable>true</callIsRunnable>
<callGetPortlet>true</callGetPortlet>
<acceptContentType>'text/html'</acceptContentType>
<hasShowLinkMode>false</hasShowLinkMode>
<mobileOnly>false</mobileOnly>
<passAllUrlParams>true</passAllUrlParams>
<cacheLevel>wwpro_api_provider.CACHE_LEVEL_USER</cacheLevel>
<rewriteUrls>true</rewriteUrls>
</portlet>
</provider>
有効なXML入力ファイルを作成したら、次のようにPL/SQLジェネレータを実行して、プロバイダおよびポートレットのパッケージをSQLファイル形式で生成できます。
PL/SQLジェネレータをインストールしていない場合は、一緒にダウンロードした手順に従って、PL/SQLジェネレータをインストールします。
ブラウザから、PL/SQLジェネレータのURLに移動します。図8-1に示すようなページが表示されます。
「Source XML File」フィールドで、「Browse」をクリックしてソースのXMLファイルを選択します。XMLファイルの作成方法は、8.2.1項「入力XMLファイルの作成」を参照してください。
「Provider Name」フィールドに、プロバイダの名前を入力します。プロバイダ名には空白を含めないでください。ジェネレータでは、このフィールドに入力された値をプロバイダ・パッケージ名に使用します。
「Generate」をクリックして、プロバイダおよびポートレットのパッケージに関するインストール可能なPL/SQLコードを含むSQLファイルを生成します。ブラウザからファイルの保存またはオープンを要求された場合は、「Save」を選択します。
「Save」ダイアログ・ボックスで、ファイル拡張子を.sqlに変更し、希望するファイル名に変更します。
ファイルを保存します。
PL/SQLジェネレータを実行してSQLファイルを取得した後に、Oracle Portalでプロバイダとポートレットを使用できるようにするには、次のタスクを実行する必要があります。
生成されたプロバイダおよびポートレットのパッケージを、Oracle Portalがインストールされたデータベースにインストールする手順は、次のとおりです。
SQL*Plusセッションを開始し、PORTALスキーマにログインします。
新しいデータベース・スキーマのプロバイダ・スキーマを作成し、SQL*Plusで次のコマンドを入力して生成されたプロバイダおよびポートレットのパッケージを格納します。
create user provider_schema identified by provider_schema_password; grant resource, connect to provider_schema;
次のようにprovsyns.sqlスクリプトを実行して、Oracle PortalのAPIに対するEXECUTE権限をプロバイダ・スキーマに付与します。このスクリプトは、ORACLE_HOME/portal/admin/plsql/wwcディレクトリにあります。
@provsyns.sql provider_schema
プロバイダ・スキーマにログインし、生成されたSQLファイルを実行します。プロバイダおよびポートレットのパッケージがデータベースに作成されます。
プロバイダおよびポートレットのパッケージをデータベースに作成した後は、次の手順を実行して、PL/SQLポートレットをポータル・ページに追加する前にプロバイダをOracle Portalに登録する必要があります。
Oracle Portalに管理者としてログインします。
Portalビルダーで、「管理」タブ、次に「ポートレット」タブをクリックします。
「リモート・プロバイダ」ポートレットで、「プロバイダの登録」をクリックします。
必要に応じて、「名前」、「表示名」、「タイムアウト」および「タイムアウト・メッセージ」に入力します。
「実装スタイル」リストから「データベース」を選択します。
「次へ」をクリックして残りのウィザードを入力します。
ウィザードへの入力が完了したら、「終了」をクリックします。
「ポートレット・リポジトリ」ポートレットで、「ポートレット・リポジトリの表示」をクリックします。
リポジトリを参照し、登録したばかりのプロバイダを探します。通常、新規プロバイダはリポジトリの「ポートレット・ステージング領域」に表示されます。
プロバイダが見つかったら、作成したポートレットがすべてプロバイダに含まれていることを確認します。プロバイダまたはそのポートレットが表示されない場合は、この項および前項(8.2.3.1項「データベースへのパッケージのインストール」、8.2.1項「入力XMLファイルの作成」、8.2.2項「PL/SQLジェネレータの実行」)の手順を見なおし、プロバイダおよびポートレットを正しく作成、登録したことを確認します。
プロバイダとそのポートレットがリポジトリに表示されたら、ページに追加できます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。
この項では、starterプロバイダ・サンプルに含まれるhello worldサンプルを使用して、基本的なPL/SQLポートレットの構築方法について説明します。starterプロバイダ・サンプルは、PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\starterにあり、次のファイルで構成されています。
starter_provider.pks: starterプロバイダのパッケージ仕様です。
starter_provider.pkb: starterプロバイダのパッケージ本体です。
helloworld_portlet.pks: hello worldポートレットのパッケージ仕様です。
helloworld_portlet.pkb: hello worldポートレットのパッケージ本体です。
snoop_portlet.pks: snoopポートレットのパッケージ仕様です。
snoop_portlet.pkb: snoopポートレットのパッケージ本体です。
insintpr.sql: starterプロバイダのインストール・スクリプトです。
PL/SQLポートレットを手動で構築するための一般的なモデルは、次のとおりです。
hello worldポートレットのパッケージ仕様および本体を変更し、独自のポートレット・パッケージを作成します(8.3.1項「ポートレット・パッケージの実装」を参照)。
starterプロバイダのパッケージ仕様および本体を変更し、新規作成したポートレットをプロバイダに追加します(8.3.2項「プロバイダ・パッケージの実装」を参照)。
新規作成したポートレットをページに追加します(8.3.3項「ページへのポートレットの追加」を参照)。
helloworld_portlet.pksおよびhelloworld_portlet.pkbを変更し、独自のポートレット・パッケージを作成する手順は、次のとおりです。
パッケージ仕様helloworld_portlet.pksおよびパッケージ本体helloworld_portlet.pkbをコピーします。
コピーの名前をmy_first_portlet.pksおよびmy_first_portlet.pkbにそれぞれ変更します。
エディタでmy_first_portlet.pksを開き、次のようにパッケージ名をmy_first_portletに変更します。
CREATE OR REPLACE package my_first_portlet is ... end my_first_portlet;
エディタでmy_first_portlet.pkbを開き、前述の手順で行った変更を繰り返します。つまり、パッケージ名をmy_first_portletに変更します。
my_first_portlet.pkbで、get_portlet_infoというファンクションを探し、次のように変更します。
function get_portlet_info
(
p_provider_id in integer
,p_language in varchar2
)
return wwpro_api_provider.portlet_record
is
l_portlet wwpro_api_provider.portlet_record;
begin
l_portlet.id := starter_provider.PORTLET_FIRST;
l_portlet.provider_id := p_provider_id;
l_portlet.title := 'My First Portlet';
l_portlet.name := 'My_First_Portlet';
...
my_first_portlet.pkbで、showというプロシージャを探し、次のように変更します。
procedure show
(
p_portlet_record wwpro_api_provider.portlet_runtime_record
)
is
l_portlet wwpro_api_provider.portlet_record;
l_text_name in varchar2(100);
l_text in varchar2(200);
begin
...
/*
Display the content of the portlet in the show mode.
Use the wwui_api_portlet.portlet_text() API when
generating the content of the portlet so that the
output uses the portlet CSS.
*/
htp.p(wwui_api_portlet.portlet_text(
p_string => 'Hello World - Mode Show'
,p_level => 1
));
/*
Add the functionality you want here. In this case we are adding
a welcome message addressed to the current user.
*/
l_text_name := 'Welcome to my first portlet ' || wwctx_api.get_user;
l_text := wwui_api_portlet.portlet_text(
p_string => l_text_name,
p_level => 1 );
htp.p(l_text); htp.para;
if (p_portlet_record.has_border) then
wwui_api_portlet.close_portlet;
end if;
...
my_first_portlet.pkbを保存します。
ポートレット・パッケージを実装した後は、ポートレットをプロバイダに追加する必要があります。starter_provider.pksおよびstarter_provider.pkbを変更して、新規ポートレットをプロバイダに追加する手順は、次のとおりです。
パッケージ仕様starter_provider.pksおよびパッケージ本体starter_provider.pkbをコピーします。
コピーの名前をstarter_provider2.pksおよびstarter_provider2.pkbにそれぞれ変更します。
|
注意: 新しい空のプロバイダを作成する場合、次の手順を実行する前に、 |
エディタでstarter_provider2.pksを開きます。
PORTLET_FIRSTという定数を追加します。この定数は、プロバイダ内のポートレットの識別子として使用されます。したがって、定数の値は、プロバイダ内で一意である必要があります。
CREATE OR REPLACE
package STARTER_PROVIDER
is
/**
* This package is used as an example to show how providers can be created
* in the portal system.
*
* This provider contains the following portlets:
*
* Hello World (PORTLET_HELLOWORLD)
* Snoop (PORTLET_SNOOP)
*
*/
PORTLET_HELLOWORLD constant integer := 1;
PORTLET_SNOOP constant integer := 2;
PORTLET_FIRST constant integer := 3;
starter_provider2.pksを保存します。
エディタでstarter_provider2.pkbを開きます。
starter_provider2.pkbで、新規ポートレットのget_portlet_infoファンクションに対するコールをプロバイダ・パッケージのget_portletファンクションに追加します。このためには、コールmy_first_portlet.get_portlet_infoをget_portletファンクションに追加する必要があります。get_portletファンクションによって、ポータルは、必要に応じてポートレットに関する情報を取得できます。
function get_portlet
p_provider_id in integer
,p_portlet_id in integer
,p_language in varchar2
)
return wwpro_api_provider.portlet_record
is
begin
if (p_portlet_id = PORTLET_HELLOWORLD) then
return helloworld_portlet.get_portlet_info(
p_provider_id => p_provider_id
,p_language => p_language
);
elsif (p_portlet_id = PORTLET_SNOOP) then
return snoop_portlet.get_portlet_info(
p_provider_id => p_provider_id
,p_language => p_language
);
elsif (p_portlet_id = PORTLET_FIRST) then
return my_first_portlet.get_portlet_info(
p_provider_id => p_provider_id
,p_language => p_language
);
else
raise wwpro_api_provider.PORTLET_NOT_FOUND_EXCEPTION;
end if;
end get_portlet;
starter_provider2.pkbで、プロバイダから戻されるポートレットのリストに新規ポートレットを追加します。このためには、新規ポートレットをプロバイダのget_portlet_listファンクションに追加する必要があります。get_portlet_listファンクションは、プロバイダが実装するポートレットをポータルに指示します。
function get_portlet_list
...
begin
l_cnt := 0;
if (p_security_level = false ) then l_cnt := l_cnt + 1;
l_portlet_list(l_cnt) := get_portlet(
p_provider_id => p_provider_id
,p_portlet_id => PORTLET_HELLOWORLD
,p_language => p_language
);
l_cnt := l_cnt + 1;
l_portlet_list(l_cnt) := get_portlet(
p_provider_id => p_provider_id
,p_portlet_id => PORTLET_SNOOP
,p_language => p_language
);
l_cnt := l_cnt + 1;
l_portlet_list(l_cnt) := get_portlet(
p_provider_id => p_provider_id
,p_portlet_id => PORTLET_FIRST
,p_language => p_language
);
else
if (helloworld_portlet.is_runnable(
p_provider_id => p_provider_id
,p_reference_path => null)
) then
l_cnt := l_cnt + 1;
l_portlet_list(l_cnt) := get_portlet(
p_provider_id => p_provider_id
,p_portlet_id => PORTLET_HELLOWORLD
,p_language => p_language
); end if;
if (snoop_portlet.is_runnable
p_provider_id => p_provider_id
,p_reference_path => null)
) then
l_cnt := l_cnt + 1;
l_portlet_list(l_cnt) := get_portlet(
p_provider_id => p_provider_id
,p_portlet_id => PORTLET_SNOOP
,p_language => p_language
);
end if;
if (my_first_portlet.is_runnable(
p_provider_id => p_provider_id
,p_reference_path => null)
) then
l_cnt := l_cnt + 1;
l_portlet_list(l_cnt) := get_portlet(
p_provider_id => p_provider_id
,p_portlet_id => PORTLET_FIRST
,p_language => p_language
);
end if;
end if;
return l_portlet_list;
end get_portlet_list;
starter_provider2.pkbで、is_portlet_runnableファンクションを変更して、新規ポートレットのis_runnableファンクションへのコールを追加します。
function is_portlet_runnable
(
p_portlet_instance in wwpro_api_provider.portlet_instance_record
)
return boolean
is
begin
if (p_portlet_instance.portlet_id = PORTLET_HELLOWORLD) then
return helloworld_portlet.is_runnable(
p_provider_id => p_portlet_instance.provider_id
,p_reference_path => p_portlet_instance.reference_path
);
elsif (p_portlet_instance.portlet_id = PORTLET_SNOOP) then
return snoop_portlet.is_runnable(
p_provider_id => p_portlet_instance.provider_id
,p_reference_path => p_portlet_instance.reference_path
);
elsif (p_portlet_instance.portlet_id = PORTLET_FIRST) then
return my_first_portlet.is_runnable(
p_provider_id => p_portlet_instance.provider_id
,p_reference_path => p_portlet_instance.reference_path
);
else
raise wwpro_api_provider.PORTLET_NOT_FOUND_EXCEPTION;
end if;
end is_portlet_runnable;
表8-4の情報に従ってステップ9を繰り返します。
表8-4 starter_provider2.pkbに対する変更
| プロシージャ/ファンクション | 追加内容 |
|---|---|
procedure register_portlet |
elsif (p_portlet_instance.portlet_id = PORTLET_FIRST) then my_first_portlet.register(p_portlet_instance) |
procedure deregister_portlet |
elsif (p_portlet_instance.portlet_id = PORTLET_FIRST) then my_first_portlet.deregister (p_portlet_instance) |
function describe_portlet_parameters |
elsif (p_portlet_id = PORTLET_FIRST) then return my_first_portlet.describe_parameters (p_provider_id, p_language); |
procedure show_portlet |
elsif (p_portlet_record.portlet_id = PORTLET_FIRST) then my_first_portlet.show(p_portlet_record) |
procedure copy_portlet |
elsif (p_copy_portlet_info.portlet_id = PORTLET_FIRST) then my_first_portlet.copy(p_portlet_record) |
starter_provider2.pkbを保存して閉じます。
通常どおり、Oracle Portalにログインします。
Portalビルダーで、「管理」タブ、次に「ポートレット」タブをクリックします。
「ポートレット・リポジトリ」ポートレットで、「ポートレット・リポジトリの表示」をクリックします。
リポジトリを参照し、starterプロバイダを探します(通常、リポジトリの「ポートレット・ステージング領域」に表示されます)。これには、元のポートレットhello worldおよびsnoopの2つが含まれています。
コマンドラインのプロンプトからSQL*Plusを起動し、starterプロバイダ・スキーマの所有者として接続します。
新規および変更済のPL/SQLパッケージを次の順序でコンパイルします。
starter_provider2.pks
my_first_portlet.pks
starter_provider2.pkb
my_first_portlet.pkb
コンパイル・エラーが発生した場合は、すべてのパッケージが正常にコンパイルされるまで、修正して再コンパイルします。
「ポートレット・リポジトリ」ポートレットで、「ポートレット・リポジトリの表示」をクリックします。
リポジトリを参照し、starterプロバイダを再度探します。この時点で、これには、元のポートレットに加えて、新規ポートレットmy_first_portletが含まれています。
|
注意: 既存のプロバイダまたはポートレット・レコードに変更を加える場合、Oracle Portalインスタンスに反映された変更を表示するには、プロバイダをリフレッシュする必要があります。 |
これで、ポートレット・リポジトリ内のポートレットと同様に、ポートレットをページに追加できます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。
Oracle Portalには、個々のポートレット・プリファレンスを格納、取得するためのAPI、および現行セッション用の一時データを格納、操作するためのAPIが用意されています。情報ストレージの実装は次のもので構成されます。
Oracle Portalでは、固有のポートレット・インスタンスごとに個々のプリファレンスを永続的に格納、取得するための一連のAPIを提供しています。各プリファレンスに対する一意の識別子、ユーザーごとに自動的にマップされるプリファレンス・ストア、およびPL/SQLポートレットのパーソナライズ情報を格納、取得するためのアクセス・メカニズムを提供しています。
デフォルトでは、エンドユーザーのパーソナライズを有効にすると、ポートレットのタイトル・バーに「パーソナライズ」が表示されます。このリンクにより、ユーザーがそのポートレットに対する設定を選択できるフォームが表示されます。
エンド・ユーザーのパーソナライズ・オプションは、wwpre_api_nameパッケージおよびwwpre_api_valueパッケージを介して使用できます。
一般に、プリファレンス・ストレージは次のように設定できます。
wwpre_api_name.create_pathを使用して、プリファレンス・パスを作成します。
wwpre_api_name.create_nameを使用して、プリファレンスを作成します。
プリファレンス名を指定し、値を設定するレベルを調べて、プリファレンス値を設定します。このために、wwpre_api_value.set_value_as_varchar2、set_value_as_numberまたはset_value_as_dateを使用します。
プリファレンス値を取得するときは常に、プリファレンスの名前およびパスを指定して、プリファレンス値を取得します。このために、wwpre_api_value.get_value_as_varchar2、get_value_as_numberまたはget_value_as_dateを使用します。
PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\svcexにあるサービスの例に、プリファレンス・ストレージの実装方法を示します。この例の目的は、次の機能を実現することです。
「パーソナライズ」をクリックすると、ユーザーは2つのフィールドにテキストを入力できます。
1つ目のフィールドは、パーソナライズされたテキストの入力を要求します。2つ目のフィールドは、パーソナライズされたポートレットのタイトルの入力を要求します。
これら2つのフィールドに対してユーザーが入力した値は、プリファレンス・ストアに格納されます。
パーソナライズされたテキストおよびポートレットのタイトルは、ユーザーがポートレット・インスタンスを起動するたびに取得されます。
次に示すこの例を参照すると、プリファレンス・ストアの作成方法、プリファレンス・ストアに対する値の格納および取得方法がわかります。
エディタでservices_portlet.pkbファイルを開きます。
ポートレット定義の定数部で、ポートレット・パスおよびプリファレンス名に別名を指定します。
DOMAIN constant varchar2(30) := 'provider'; SUBDOMAIN constant varchar2(32) := 'services'; PORTLET_PATH constant varchar2(256):= 'oracle.portal.pdk.servicesportlet.'; PREFNAME_STRING constant varchar2(30) := 'services_string'; PREFNAME_TITLE constant varchar2(30) := 'services_title';
registerプロシージャを探します。ポートレットでは、プリファレンスを格納するためのパスを作成する必要があります。そのためには、wwpre_api_name.create_pathをコールしてプリファレンス・パスを作成します。次に、ポートレットのパス、名前および説明を入力パラメータとして使用してwwpre_api_name.create_nameをコールし、プリファレンス名を作成します。もう1つの入力パラメータのp_type_nameは、特殊な値のタイプを指定します。NLSIDタイプは、格納される値がNLS IDであることを示します。このタイプを設定および取得するためのファンクションでは、その値を数値として処理します。それとは別に、このタイプのプリファレンス・ストア値のエクスポートまたはコピー時は、関連付けられた文字列もエクスポートまたはコピーされます。最後の入力パラメータの言語は、コンテキストAPIから取得されます。
procedure register
(
p_portlet_instance in wwpro_api_provider.portlet_instance_record
)
is
begin
--
-- Create a path for the portlet instance. This is used to create
-- the preferences for the portlet instance in the preference store.
--
wwpre_api_name.create_path(
p_path => PORTLET_PATH || p_portlet_instance.reference_path
);
--
-- Create the names to store the portlet preferences.
--
wwpre_api_name.create_name(
p_path => PORTLET_PATH
|| p_portlet_instance.reference_path,
p_name => PREFNAME_STRING,
p_description => 'Single custom row in '
|| 'Introductory Example portlet.',
p_type_name => 'NLSID',
p_language => wwctx_api.get_nls_language);
wwpre_api_name.create_name(
p_path => PORTLET_PATH
|| p_portlet_instance.reference_path,
p_name => PREFNAME_TITLE,
p_description => 'Single custom row in '
|| 'Introductory Example portlet.',
p_type_name => 'NLSID',
p_language => wwctx_api.get_nls_language);
exception
when others then
raise;
end register;
deregisterプロシージャでは、wwpre_api_name.delete_nameをコールして、プリファレンス・ストアを削除する必要があります。
procedure deregister
(
p_portlet_instance in wwpro_api_provider.portlet_instance_record
)
is
begin
--
-- Delete the path used by the portlet instance. This will delete
-- all the names and all the values associated with the path.
--
wwpre_api_name.delete_path(
p_path => PORTLET_PATH || p_portlet_instance.reference_path
);
exception
when others then
raise;
end deregister;
また、ポートレットでは、wwpre_api_value.set_valueおよびwwpre_api_value.get_valueを使用し、プリファレンス・ストアに対して値の取得および設定を実行する必要があります。get_default_preferenceファンクションを探します。このファンクションがシステム・レベルのデフォルト値をプリファレンス・ストアからロードする方法に注意してください。デフォルトのプリファレンスは、インスタンスに関連付けられています。言語文字列は、データベースに設定されています。
function get_default_preference
...
begin
--
-- Try to find a previously entered portlet instance string preference,
-- if any.
-- A portlet instance string preference is stored in the preference
-- store and has a level of SYSTEM_LEVEL_TYPE.
--
p_path => PORTLET_PATH || p_reference_path,
l_prefs.string_id := to_char(wwpre_api_value.get_value_as_number(
p_name => PREFNAME_STRING,
p_level_type => wwpre_api_value.SYSTEM_LEVEL_TYPE
));
--
-- If the value returned above is null it is an indication that there
-- is no default string yet. Initialize the string id to 0 to indicate
-- this and load the default string value.
--
if (l_prefs.string_id is null or to_number(l_prefs.string_id) = 0) then
wwpre_api_value.set_value_as_number(
p_path => PORTLET_PATH || p_reference_path,
p_name => PREFNAME_STRING,
p_level_type => wwpre_api_value.SYSTEM_LEVEL_TYPE,
p_level_name => null,
p_value => 0
);
...
end get_default_preference;
showプロシージャを探します。ポートレットがデフォルト編集モードまたは編集モードであるときの動作に注意してください。また、ユーザーが「適用」、「取消」または「OK」をクリックしたときにp_actionに移入が行われる方法にも注意してください。フォームが送信されると、ポートレットのshowプロシージャが再度コールされます。p_actionパラメータがNULLでない場合は、save_prefsプロシージャをコールして、パーソナライズを保存し、関連ページにリダイレクトします。
procedure show
(
p_portlet_record wwpro_api_provider.portlet_runtime_record
)
is
l_str varchar2(32000);
l_pref_record preference_record;
l_action varchar2(10);
l_names owa.vc_arr;
l_values owa.vc_arr;
begin
...
elsif (p_portlet_record.exec_mode =
wwpro_api_provider.MODE_SHOW_EDIT)
or (p_portlet_record.exec_mode =
wwpro_api_provider.MODE_SHOW_EDIT_DEFAULTS)
then
wwpro_api_parameters.retrieve(l_names, l_values);
for i in 1..l_names.count loop
if (upper(l_names(i)) = upper('p_string')) then
l_pref_record.string := l_values(i);
elsif l_names(i) = 'p_title' then
l_pref_record.title_string := l_values(i);
elsif l_names(i) = 'p_action' then
l_action := l_values(i);
end if;
end loop;
if (l_action in (ACTION_OK,ACTION_APPLY,ACTION_CANCEL)) then
if (p_portlet_record.exec_mode =
wwpro_api_provider.MODE_SHOW_EDIT) then
save_prefs(p_string => l_pref_record.string,
p_title => l_pref_record.title_string,
p_action => l_action,
p_level => wwpre_api_value.USER_LEVEL_TYPE,
p_portlet_record => p_portlet_record);
else
save_prefs(p_string => l_pref_record.string,
p_title => l_pref_record.title_string,
p_action => l_action,
p_level => wwpre_api_value.SYSTEM_LEVEL_TYPE,
p_portlet_record => p_portlet_record);
end if;
else
show_edit(p_portlet_record => p_portlet_record);
end if;
...
end show;
show_editプロシージャでは、編集モードまたはデフォルト編集モードのページがレンダリングされます。2つのテキスト・フィールドがレンダリングされ、ユーザーは、3つのボタン(「適用」、「OK」および「取消」)を使用してフォームでパーソナライズ可能な値を変更できます。このファンクションでは、wwpro_api_adapter.open_formを使用して、<FORM>タグに対する適切なアクション属性および適切な非表示フィールドが設定されたHTMLフォームを作成することに注意してください。重要なのは、リモートのOracle Portalインスタンスから連携されたPortalアダプタを利用してポートレットを使用する場合、このプロシージャを使用して<FORM>タグを作成することです。
procedure show_edit
(
p_portlet_record in wwpro_api_provider.portlet_runtime_record
)
is
l_prefs preference_record;
l_text_prompt_string varchar2(30);
l_title_prompt_string varchar2(30);
begin
...
htp.centeropen;
htp.tableOpen(cattributes => 'BORDER="1" WIDTH=90%');
htp.tableRowOpen;
htp.p('<TD>');
--
-- This procedure call creates the <FORM> tags with a set of
-- standard parameters. Using this procedure makes the
-- personalization page work through the pl/sql http adapter.
--
wwpro_api_adapter.open_form(p_formattr => 'NAME="services"',
p_prr => p_portlet_record);
htp.p('</TD>');
htp.tableRowClose;
htp.tableClose;
htp.centerclose;
htp.formclose;
end show_edit;
この例でプリファレンス・ストレージの実装に関連する、次のプロシージャおよびファンクションを確認します。
get_user_preference: ユーザーによってパーソナライズされたポートレットの文字列およびタイトルを取得します。
save_prefs: パーソナライズ変更後にユーザーが「OK」または「適用」をクリックすると、プリファレンスをプリファレンス・ストアに保存するために起動されます。
entered_text_is_valid: パーソナライズ可能なテキスト・フィールドに入力されたテキストが有効かどうかをチェックします。
このポートレットをページに表示するのに、ポートレット・リポジトリにまだ登録していない場合は、その追加方法について8.3.2項「プロバイダ・パッケージの実装」の手順を必要に応じて参照してください。
ポートレットがリポジトリに表示されたら、ページに追加してテストできます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。
PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\svcexにあるサービスの例に、セッション・ストアの実装方法を示します。この例の目的は、次の機能を実現することです。
ユーザーがこのポートレットを起動すると、「このポートレットは、このセッションでx回描画されています。」というテキストが表示されます(xはポートレットがレンダリングされた回数です)。
ユーザーがポートレットを起動するたびに、カウンタが1ずつ増えます。
ポートレットで「詳細」をクリックすると、ユーザーは「消去」を使用してカウンタをリセットできます。カウンタをクリアすると、カウンタは再度0(ゼロ)から始まります。
次に示すこの例を参照すると、セッション・ストアの作成方法、セッション・ストアに対する値の格納および取得方法がわかります。
エディタでservices_portlet.pkbファイルを開きます。
ポートレット定義の定数部で、セッション・オブジェクトのドメインおよびサブドメインの定義に別名を指定します。
DOMAIN constant varchar2(30) := 'provider'; SUBDOMAIN constant varchar2(32) := 'services'; PORTLET_PATH constant varchar2(256):= 'oracle.portal.pdk.servicesportlet'; PREFNAME_STRING constant varchar2(30) := 'services_string'; PREFNAME_TITLE constant varchar2(30) := 'services_title';
clear_countプロシージャを探します。clear_countは、カウンタをリセットするためにユーザーが「消去」をクリックすると、showプロシージャからコールされます。clear_countは、wwsto_api_session.load_sessionをコールしてセッション・オブジェクトをロードします。次に、wwsto_api_session.set_attributeをコールしてカウンタをゼロに設定します。最後に、save_sessionをコールしてセッション・オブジェクトを保存します。
procedure clear_count
(
p_action in varchar2,
p_back_url in varchar2,
p_reference_path in varchar2
)
is
ex_counter integer;
session_parms &&1..wwsto_api_session;
begin
--
-- Clear the display counter.
--
if (p_action = ACTION_CLEAR) then
--
-- Load the session object that contains the display counter
--
session_parms :=
&&1..wwsto_api_session.load_session (DOMAIN,SUBDOMAIN);
ex_counter :=
session_parms.get_attribute_as_number(
'ex_counter' || p_reference_path);
--
-- Reset the display counter.
--
ex_counter := 0;
session_parms.set_attribute(
'ex_counter' || p_reference_path, ex_counter);
--
-- Save the changes to the database immediately to avoid any
-- data consistency problems with the data stored in the
-- session object.
--
session_parms.save_session;
end if;
owa_util.redirect_url(curl=>p_back_url);
end clear_count;
show_contentsプロシージャを探します。show_contentsは、showプロシージャからコールされ、カウンタを取得して1のみ増やし、セッション・ストアにその値を保存します。セッション・オブジェクトが取得されることにより、ユーザーがポートレットをレンダリングした回数が表示されることに注意してください。また、get_attribute_as_numberでカウンタ値が取得された後、このプロシージャが呼び出されるたびにカウンタが増分されます。
procedure show_contents
(
p_portlet_record wwpro_api_provider.portlet_runtime_record
)
is
l_prefs preference_record;
session_parms &&1..wwsto_api_session;
ex_counter integer;
l_portlet wwpro_api_provider.portlet_record;
l_str varchar2(32000);
begin
--
-- In this mode a session counter is used to indicate
-- the number of invocations of this portlet during the
-- current session. The counter is stored in the session
-- store.
--
session_parms :=
&&1..wwsto_api_session.load_session(DOMAIN,SUBDOMAIN);
ex_counter :=
session_parms.get_attribute_as_number(
'ex_counter' || p_portlet_record.reference_path);
if (ex_counter is null) then -- first invocation
session_parms.set_attribute(
'ex_counter' || p_portlet_record.reference_path,1);
ex_counter := session_parms.get_attribute_as_number(
'ex_counter' || p_portlet_record.reference_path);
else -- on every invocation increase by 1
ex_counter := ex_counter + 1;
session_parms.set_attribute(
'ex_counter'
|| p_portlet_record.reference_path, ex_counter);
end if; session_parms.save_session;
...
end show_contents;
このポートレットをページに表示するのに、ポートレット・リポジトリにまだ登録していない場合は、その追加方法について8.3.2項「プロバイダ・パッケージの実装」の手順を必要に応じて参照してください。
ポートレットがリポジトリに表示されたら、ページに追加してテストできます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。
ポートレットの機能は、パラメータを利用して拡張できます。ポートレットによって実装されたビジネス・ロジックは、ページに渡されるパラメータによって異なるHTML出力を作成できます。ポートレット・パラメータを使用することで、現行ページを変更せずに共有画面モードでポートレット内をナビゲートできます。また、ポートレットはパラメータを使用して相互に通信することもできます。
ポートレット・パラメータの構造は、名前/値ペアです。これらのペアは、GET送信メソッドを使用してURLパラメータ引渡し形式に直接マップするか、POST送信メソッドを使用してHTTPメッセージ本文を使用できます。また、ポートレットは、Oracle Portalにパラメータを公開できます。ページに追加されると、これらのポートレットは、ページ設計者が作成したページ・パラメータの形式で値を受け入れることができます。
|
注意: ポートレット・パラメータ名は、アンダースコア(_)で始めないでください。アンダースコアで始まるパラメータは、Oracle Portalの内部で使用するために予約されており、ポートレットには渡されません。 |
ポートレットは、URL、HTTPメッセージ本文またはページ・パラメータに直接アクセスできません。パラメータ値を取得するには、wwpro_api_parametersパッケージで提供されるOracle PortalのPL/SQLパラメータAPIをポートレットでコールする必要があります。
Oracle Portalでは、次のタイプのパラメータを提供しています。
|
警告: ポートレットでは、パブリックおよびプライベートのパラメータを混ぜて使用することはできません。ポートレットでパブリック・パラメータを有効にするにはプライベート・パラメータを、逆にプライベート・パラメータを有効にするにはパブリック・パラメータを使用できなくする手順をとる必要があります。 |
プライベート・ポートレット・パラメータ: ポートレットに内部ナビゲーションを実装できます。
パブリック・ポートレット・パラメータ: ポートレットのデータ・フローの制御をページ設計者に渡すことができます。ページ設計者は、パブリック・ポートレット・パラメータをページ・パラメータにマップしてデフォルト値を指定し、ユーザーがその値をパーソナライズすることを許可できます。
ページ・パラメータ: ページ設計者によって単純なユーザー・インタフェースに定義されます。これらのページ・パラメータは、ページ設計者がパラメータ値をページからそのポートレットに渡すために、パブリック・ポートレット・パラメータにマップできます。
パラメータの詳細は、2.12項「パブリック・ポートレット・パラメータのサポート」および2.13項「プライベート・ポートレット・パラメータのサポート」を参照してください。
プライベート・ポートレット・パラメータを渡す際に、GETまたはPOSTのいずれかのHTML送信メソッドを使用できます。GETメソッドは、URLを使用してパラメータを渡すのに対し、POSTメソッドは、パラメータをHTTPメッセージ本文に挿入します。どちらのメソッドにおいても、ポータル・ページ上のポートレット・インスタンス、パラメータのコール方法およびパラメータの値を指定する必要があります。
プライベート・ポートレット・パラメータには、次の2種類があります。
修飾パラメータ: プライベート・ポートレット・パラメータがページ上の他のどのポートレットでも読み取られないことを保証します。参照パスは、ポートレットがページに追加されると割り当てられる、パラメータの一意の接頭辞です。たとえば、http://page_url?277_MAP_368673.region=Europeとなります。この修飾パラメータの参照パスは277_MAP_368673、名前はregion、値はEuropeです。プライベート・パラメータには、常に修飾パラメータを使用することをお薦めします。
非修飾パラメータ: ポートレット・インスタンスに関する情報を保持せず、ページ上のどのポートレットでも読み取ることができます。たとえば、 http://page_url?region=Europeとなります。この非修飾パラメータの名前はregion、値はEuropeです。プライベート・パラメータには、非修飾パラメータを使用しないことをお薦めします。
パブリック・ポートレット・パラメータは、ページ設計者がポートレットを複数のページで再利用できるようにすることで、ポートレットの柔軟性を高めます。その結果、ページ設計者は、異なるページにポートレットを追加する際に、ポートレット・コードの変更を開発者に依頼する必要がありません。パブリック・ポートレット・パラメータを使用することで、ページ上のポートレットは、ポートレット・パラメータ名に関係なく、マップされたページ・パラメータから値を簡単に受け取ることができます。
たとえば、dept_idというページ・パラメータがあるとします。3つのポートレットでこの値が必要ですが、1つのポートレットではdept、もう1つのポートレットではdeptno、さらにもう1つのポートレットではdepartment_idという名前です。ページ・パラメータをマップすることで、3つすべてのポートレットは、dept_idパラメータから値を受け取り、適切なポートレット・パラメータに設定することができます。さらに、ページ設計者は、デフォルト値(たとえば、department 20)を設定して、その値をユーザーがパーソナライズ(たとえばdepartment 30)し、3つすべてのポートレットに適用できます。
パブリック・パラメータおよびページ・パラメータを引き渡すための一般的なモデルは、次のとおりです。
pass_all_url_paramsをfalseに設定して、ポートレット・レコードでパブリック・パラメータを有効にします。この設定により、ポートレットには、そのポートレットを対象とするパラメータのみが渡されます。
パブリック・パラメータをプロバイダのdescribe_portlet_parametersファンクションで宣言します。プロバイダに属すポートレットごとに、このプロシージャは、ポートレットが受け入れるパラメータのリストを、次のタイプのレコードのPL/SQL表形式で戻します。
type portlet_parameter_table is table ofportlet_parameter_record index by binary_integer;
パラメータの説明的な情報をポートレットのdescribe_parametersファンクションに指定します。例:
function describe_parameters
(p_provider_id in integer, p_language in varchar2)
return wwpro_api_provider.portlet_parameter_table
is
l_params wwpro_api_provider.portlet_parameter_table;
begin
l_params(1).name := 'dept_id';
l_params(1).datatype := wwpro_api_provider.STRING_TYPE;
l_params(1).description := 'Defines a department ID';
l_params(1).display_name := 'Department ID';
return l_params;
end describe_parameters;
パブリック・パラメータに値を割り当てます。パブリック・パラメータは、通常、ページ・パラメータを使用して値を取得します。ページ・パラメータには、通常、ページ設計者がデフォルト値を割り当て、ユーザーが実行時にその値をパーソナライズできます。あるいは、ページ・パラメータ値はコール元のURLで割り当てることができます。ページ設計者によるページ・パラメータの使用方法は、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』を参照してください。
プライベート・パラメータまたはパブリック・パラメータを使用しているかどうかに関係なく、同じAPIを使用してその値を取得できます。ポートレットは、wwpro_api_parametersパッケージの次のPL/SQLパラメータAPIをコールして、パラメータを取得できます。
wwpro_api_parameters.get_value: 特定のパラメータ名によって指定されるパラメータ値を戻します。パラメータ名は大/小文字を区別しないのに対して、パラメータ値は大/小文字を区別します。例:
l_region := wwpro_api_parameters.get_value
(p_name => 'region',
p_reference_path => p_portlet_record.reference_path);
wwpro_api_parameters.get_values: パラメータ値の配列を戻します。このファンクションは、1つのパラメータ名に関連付けられているすべての値、または、まったく一致しない場合は空のリストを戻します。一部のビジネス・ロジックでは、同じパラメータ名を使用して複数の値がポートレットに渡される場合、複数の選択が必要です。ポートレットは、同じパラメータの1つまたは複数の値を受け取ることができます。例:
l_region_values owa.vc_arr;
...
l_region_values := wwpro_api_parameters.get_values
(p_name = 'region',
p_reference_path => p_portlet_record.reference_path);
wwpro_api_parameters.get_names: 参照パスで特定される指定のポートレットに渡されるパラメータの名前を戻します。戻されるリストは、次のように定義されるowa.vc_arタイプのPL/SQL表です。
type vc_arr is table of varchar2(32000) index by binary_integer;
|
注意: ポートレット・パラメータ名は、アンダースコア(_)で始めないでください。アンダースコアで始まるパラメータは、Oracle Portalの内部で使用するために予約されており、ポートレットには渡されません。 |
例:
l_names owa.vc_arr;
...
l_names := wwpro_api_parameters.get_names
(p_reference_path => p_portlet_record.reference_path);
wwpro_api_parameters.retrieve: ポートレットのすべてのパラメータについて名前および値を戻します。例:
procedure show_portlet
( p_portlet_record in out
wwpro_api_provider.portlet_runtime_record )
is
l_names owa.vc_arr;
l_values owa.vc_arr;
...
begin
...
wwpro_api_parameters.retrieve (l_names, l_values);
for i in 1..l_names.count loop
htp.p('Parameter Name: '||l_names(i));
htp.p('Parameter Value: '||l_values(i));
htp.br;
end loop;
...
end show_portlet;
ユーザーがOracle Portalのページにアクセスするたびに、パブリック・セッションが確立されます。ユーザーがOracle Portalにログインすると、パブリック・セッションは認証済セッションになります。このセッションには、ユーザー名、現行セッションID、IPアドレス、言語設定など、ユーザーに関する複数のコンテキスト情報が含まれます。また、現在使用されているOracle Portalスキーマなどのサポート情報も含まれます。
セッション・コンテキスト・サービスは、ユーザーのセッションに関する情報を戻し、wwctx_apiパッケージを介して使用できます。
セッション・コンテキストを使用するための一般的なモデルは次のとおりです。
機能に必要な情報を指定します。
wwctx_apiの適切なメソッドを使用して、その値を取得し、必要に応じて設定します。
表8-5に、様々なセッション情報の取得に使用されるファンクション・コールを示します。
|
注意: コンテキストAPIの詳細は、PL/SQL APIリファレンスを参照してください。APIリファレンスは、Portal Center( |
表8-5 コンテキスト情報のファンクション・コール
| セッション情報 | ファンクション・コール |
|---|---|
|
現行ユーザー |
|
|
ユーザーのログイン・ステータス |
|
|
ログイン時間 |
|
|
言語 |
|
|
現行セッションID |
|
|
ユーザー・クライアントのIPアドレス |
|
|
ユーザー・スキーマ |
|
|
Oracle Portalのスキーマ |
|
|
Oracle Portalのバージョン |
|
PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\svcexにあるサービスの例に、wwwctx_apiパッケージを使用したセッション情報の取得用法を示します。次に示すこの例を参照すると、ポートレットにファンクション・コールを実装する方法がわかります。
エディタでservices_portlet.pkbファイルを開きます。
get_portlet_infoファンクションを探します。
ユーザー情報を導出し、ポートレット情報レコードにその値を設定するためのwwctx_api.get_userの使用方法に注意してください。
...
l_portlet.timeout := null;
l_portlet.timeout_msg := null;
l_portlet.created_on := to_date('10/19/2000', 'MM/DD/YYYY');
l_portlet.created_by := wwctx_api.get_user;
l_portlet.last_updated_on := to_date('10/19/2000', 'MM/DD/YYYY');
l_portlet.last_updated_by := wwctx_api.get_user;
l_portlet.has_show_edit_defaults := true;
l_portlet.has_show_preview := true;
l_portlet.preference_store_path := PORTLET_PATH;
...
wwctx_api.get_userは、services_portlet.pkb全体にわたって様々な場所で同じように使用されています。wwctx_api.get_userが他にないかコードを検索します。
コンテキスト情報を取得する別の例が、is_runnableファンクションにあります。
function is_runnable
(
p_provider_id in integer
,p_reference_path in varchar2
)
return boolean
is
begin
--
-- Portlet security check. It allows the portlet to be visible
-- if the user is logged on, that is, the current session is not a
-- public session.
--
return wwctx_api.is_logged_on;
end is_runnable;
registerプロシージャでは、言語の取得にwwctx_api.get_nls_languageが使用されています。
--
-- Create the names to store the portlet preferences.
--
wwpre_api_name.create_name(
p_path => PORTLET_PATH
|| p_portlet_instance.reference_path,
p_name => PREFNAME_STRING,
p_description => 'Single custom row in '
|| 'Introductory Example portlet.',
p_type_name => 'NLSID',
p_language => wwctx_api.get_nls_language);
wwpre_api_name.create_name(
p_path => PORTLET_PATH
|| p_portlet_instance.reference_path,
p_name => PREFNAME_TITLE,
p_description => 'Single custom row in '
|| 'Introductory Example portlet.',
p_type_name => 'NLSID',
p_language => wwctx_api.get_nls_language);
services_portlet.pkbを閉じます。セッション・コンテキストは、独自の機能的な要件に基づく以外は同様の方法で実装できます。
このポートレットをページに表示するのに、ポートレット・リポジトリにまだ登録していない場合は、その追加方法について8.3.2項「プロバイダ・パッケージの実装」の手順を必要に応じて参照してください。
ポートレットがリポジトリに表示されたら、ページに追加してテストできます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。
ポートレットのセキュリティは、エンド・ユーザーによるアクセスを制御するためにポートレットで使用されるテクニックとメソッドに関係しています。ポートレットは、Oracle Portalに認証を任せ、リクエストに基づいてポータルがポートレットを適切な検証済ユーザーに戻すことを信頼しています。
Oracle Portalは、特定の権限をユーザーやグループに割り当てて、情報およびアプリケーションへのアクセスを厳しく制御します。Portalのセキュリティ・サービスを使用すると、プログラムによりアクセス制御を指定し、実行時に適切な権限があるかどうかをチェックできます。ポートレットで使用されるセキュリティ・メカニズムにより、権限を持ったユーザーのみがこれらのポートレットにアクセスできるようになります。これらのセキュリティ・サービスは、wwsec_apiパッケージを介して使用できます。
ポートレットのセキュリティは、ポートレットがポータル・ページに表示されるとき、およびデータベース・プロバイダのget_portlet_listファンクションによってポートレットがポートレット・リストで戻されるときに起動されます。Portalフレームワークのセキュリティ・サービスには、次の主要な機能があります。
ポートレットの表示: ポートレットがページに表示される前に、プロバイダは、ポートレットのアクセス権限をチェックします。プロバイダで、is_portlet_runnableファンクションを定義する必要があります。このファンクションは、ポートレットのis_runnableファンクションをコールしてアクセス権限をチェックします。
ユーザー・グループ: wwsec_api.get_defaultgroupファンクションを使用して、ユーザーが属しているデフォルト・グループを検索できます。
権限のチェック: wwsec_api.has_privilegeファンクションを使用して、ポートレットをパーソナライズするために必要な権限をユーザーまたはグループが持っているかどうかがわかります。
最高の権限: wwsec_api.get_privilege_levelファンクションを使用して、すべてのグループでユーザーが使用できる最高の権限がわかります。
アクセス可能なオブジェクト: wwsec_api.accessible_objectsファンクションを使用して、指定された権限レベルでユーザーがアクセスできるすべてのオブジェクトがわかります。他の同様の関連するファンクションは、APIドキュメントを参照してください。APIリファレンスは、Portal Center(http://portalcenter.oracle.com)か、PDK-PL/SQL (pdkplsql.zip)をダウンロードしている場合は、..\pdkplsql\pdk\plsql\docにあります。
PL/SQLポートレットのセキュリティを実装するには、データベース・プロバイダによって実装されるファンクションis_portlet_runnableがポータルに必要です。このファンクションの実際の実装は、アプリケーションしだいです。つまり、現行ユーザーがポートレットにアクセスするために十分な権限を持っているかどうかを判断するセキュリティ方式は、個々のポートレットの実装で定義されます。また、ポータルには、現行ユーザーがアクセスできる一連のポートレットを戻す、データベース・プロバイダのファンクションget_portlet_listも必要です。
ポートレットのセキュリティ・メカニズムでは、コンテキストAPI、セキュリティ・サブシステムAPIおよびインフラストラクチャを使用できます。コンテキストAPIは、現行ユーザーに関する情報を取得するために使用できます。セキュリティ・サブシステムは、現行ユーザーの権限をチェックするために使用できます。
|
注意: コンテキストAPIとセキュリティ・サブシステムAPIの詳細は、PL/SQL APIのリファレンスを参照してください。APIリファレンスは、Portal Center( |
これらのAPIを使用する際は、次の事柄に注意してください。
権限を持ったユーザーのみ、「ポートレットの追加」ダイアログでポートレットを表示できる必要があります。この目的は、プロバイダにis_portlet_runnableファンクションを実装することで達成できます。また、ポートレットへのパブリック・アクセスを許可できます。
ポートレットがユーザーに対して自身をレンダリングしない場合、HTMLを戻さないか、ページ・エンジンが無視する例外を戻す必要があります。エラー・メッセージを戻す必要はありません。エラー・メッセージを戻すと、エラー・スタックに無駄に追加されます(エラー・スタックは無制限ではありません)。詳細は、8.9項「エラー処理の実装」を参照してください。
ポートレットのセキュリティにより、ポートレットでは、ランタイム・セキュリティ・チェックを実行して、現行ユーザーがポートレットにアクセスするために必要な認可を持っていることを保証できます。
ポートレットが表示モードでレンダリングされるとき、データベース・プロバイダのis_runnableファンクションをコールして、現在ログインしているユーザーにポートレットを表示するかどうかを判断できます。ポータルでは、このファンクションを直接コールすることができません。ただし、ポートレットがこのコールを実行することは必須ではありません。ポートレットのセキュリティを実装する場合のみ、ポートレットは、表示モードでこのコールを実行する必要があります。
is_runnableへのコールの結果により、ポートレットを実際に表示するかどうかが決まります。結果がtrueの場合、ポートレットは表示されます。それ以外の場合は表示されません。ポートレットは、ポータル・ページに表示されるときに、表示モードでレンダリングされます。
プロバイダのファンクションget_portlet_listへのコールにより、ポートレットがポートレット・リストで戻される場合、p_security_levelパラメータの値により、ファンクション・コールの目的が決まります。このコールが、プロバイダが実装するポートレットのマスター・リストを取得するためにポートレット・リポジトリのリフレッシュ操作から実行される場合、パラメータp_security_levelの値はfalseです。この設定は、ポートレットのセキュリティ・チェックを実行する必要はなく、プロバイダが実装するすべてのポートレットのマスター・リストを戻す必要があることをプロバイダに指示します。この場合に戻されるポートレットのマスター・リストは、そのプロバイダのポートレット・リポジトリに移入するために使用されます。
p_security_levelの値がtrueの場合、ポートレットのセキュリティを実行する必要があるかどうかを決定するのは、プロバイダの実装しだいです。ポートレットのセキュリティが実装されている場合、プロバイダは現行ユーザーによって異なるポートレットのリストを戻すことがあります。
ポートレット・リポジトリが表示されるとき、Oracle Portalは、ポートレット・リポジトリに存在するポートレットごとに、データベース・プロバイダのis_portlet_runnableファンクションをコールします。このステップは、現在ログインしているユーザーが参照の権限を持っているポートレットのみを表示するために実行されます。ポートレット・リポジトリが表示される場所の一例として、「ポートレットの追加」ダイアログ内があります。
PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\svcexにあるサービスの例に、セキュリティの実装方法を示します。次に示すこの例を参照すると、ポートレットにセキュリティ・ファンクションを実装する方法がわかります。
エディタでservices_provider.pkbファイルを開きます。
is_portlet_runnableファンクションを探します。このファンクションは、ポートレットのis_runnableファンクションを使用してセキュリティの実装をコールし、ポートレットのアクセス権限をチェックします。
function is_portlet_runnable
(
p_portlet_instance in wwpro_api_provider.portlet_instance_record
)
return boolean
is
begin
if (p_portlet_instance.portlet_id = SERVICES_PORTLET_ID) then
return services_portlet.is_runnable(
p_provider_id => p_portlet_instance.provider_id
,p_reference_path => p_portlet_instance.reference_path
);
else
raise wwpro_api_provider.PORTLET_NOT_FOUND_EXCEPTION;
end if;
end is_portlet_runnable;
get_portlet_listプロシージャを探します。get_portlet_listは、このプロバイダが実装するポートレットのリストに、ポートレットが含まれるようにします。get_portlet_listは、最初にセキュリティ・フラグ(p_security_level)をチェックし、セキュリティが有効かどうかを調べます。フラグがtrueに設定されている場合、get_portlet_listはis_runnableを使用してポートレットがアクセス可能かどうかをチェックします。p_security_levelパラメータの値は、ポートレットをリストで戻す前に、セキュリティ・チェックを実行するかどうかを示します。ポートレット・リポジトリのリフレッシュ操作で、プロバイダが実装するポートレットのマスター・リストを取得する場合、p_security_levelの値はfalseです。falseの値は、プロバイダはセキュリティ・チェックを実行する必要はなく、プロバイダが実装するすべてのポートレットのマスター・リストを戻す必要があることを意味します。戻されるポートレットのマスター・リストは、そのプロバイダのポートレット・リポジトリに移入するために使用されます。p_security_levelの値がtrueの場合、プロバイダの実装により、ポートレットのセキュリティ・チェックを実行するかどうかが決まります。ポートレットのセキュリティが実装されている場合、プロバイダは現在ログインしているユーザーによって異なるポートレットのリストを戻すことがあります。
function get_portlet_list
...
if (p_security_level = false) then
l_cnt := l_cnt + 1;
l_portlet_list(l_cnt) := get_portlet(
p_provider_id => p_provider_id
,p_portlet_id => SERVICES_PORTLET_ID
,p_language => p_language
);
else
if (services_portlet.is_runnable(
p_provider_id => p_provider_id
,p_reference_path => null)
) then
l_cnt := l_cnt + 1;
l_portlet_list(l_cnt) := get_portlet(
p_provider_id => p_provider_id
,p_portlet_id => SERVICES_PORTLET_ID
,p_language => p_language
); end if;
...
end get_portlet_list;
エディタでservices_portlet.pkbファイルを開きます。
showプロシージャを探します。ポートレットを表示する前に、showプロシージャは、セキュリティ・チェックを実行し、現行ユーザーがポートレットの参照を許可されているかどうかを判断します。
procedure show
...
-- Perform a security check
if (not is_runnable(
p_provider_id => p_portlet_record.provider_id
,p_reference_path => p_portlet_record.reference_path)
) then
wwerr_api_error.add(
DOMAIN, SUBDOMAIN,
'securityerr', 'services_portlet.show');
raise wwpro_api_provider.PORTLET_SECURITY_EXCEPTION; end if;
...
end show;
is_runnableファンクションを見つけます。is_runnableには、セキュリティ・チェックが実装されています。この例のセキュリティ・チェックは、きわめて単純です。ユーザーがログインしている(つまりパブリック・セッションではない)場合、ファンクションはtrueを戻し、ポートレットがユーザーに表示されます。独自の目的のために、さらに複雑なセキュリティ・チェックをis_runnableファンクションにコーディングすることもできます。
function is_runnable ( p_provider_id in integer ,p_reference_path in varchar2 ) return boolean is begin -- -- Portlet security check. It allows the portlet to be visible -- if the user is logged on, that is, the current session is not a -- public session. -- return wwctx_api.is_logged_on; end is_runnable;
このポートレットをページに表示するのに、ポートレット・リポジトリにまだ登録していない場合は、その追加方法について8.3.2項「プロバイダ・パッケージの実装」の手順を必要に応じて参照してください。
ポートレットがリポジトリに表示されたら、ページに追加してテストできます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。
Oracle Portalでは、PL/SQLポートレットのキャッシュを提供しています。この機能により、PL/SQLポートレットは、Webコンテンツを中間層でキャッシュできるようになります。コンテンツに対する後続のリクエストは、データベースからの有効化の有無に関係なく、キャッシュから取得できるため、データベースのワークロードは軽減されます。
Oracle Portalでは、次の3種類のPL/SQLポートレットのキャッシュを提供しています。
有効化ベースのキャッシュ: キー値を比較して、キャッシュのコンテンツがまだ有効かどうかをチェックします。キー値が変更されていない場合、キャッシュされたコンテンツが使用されます。それ以外の場合は、ポータルのノードに対してラウンド・トリップを実行し、ポートレットのコンテンツをフェッチします。
有効期限ベースのキャッシュ: ポートレットのレンダリング時に、キャッシュのコンテンツに対して、特定の有効期限を使用します。この形式のキャッシュは、めったに変更されない、またはきわめて定期的(たとえば、毎日業務終了時)に変更されるコンテンツに便利です。
無効化ベースのキャッシュ: 最も複雑ですが、最も柔軟性のあるキャッシュ形式です。Oracle Web Cache内のオブジェクトは、明示的に無効化されるまで有効とみなされます。また、無効化ベースのキャッシュを、有効期限ベースまたは有効化ベースのキャッシュのいずれかと組み合せることもできます。
Oracle Portalでは、ユーザーによるページおよびポートレットのパーソナライズがサポートされているため、ページの表示はユーザーによって異なることがあります。Oracle Portalのキャッシュは、URLがすべてのユーザーに対して同じでも、ユーザーごとに異なるコンテンツを使用できるように設計されています。そのため、ポータル・オブジェクトは、ユーザー・レベルまたはシステム・レベルでキャッシュできます。これらのキャッシュは、次のように説明できます。
ユーザー・レベルのキャッシュ: 特定のユーザーを対象としています。キャッシュ・エントリは、そのユーザー固有のものであり、他のユーザーはアクセスできません。
システム・レベルのキャッシュ: すべてのユーザーを対象としています。1つのキャッシュ・エントリを、すべてのユーザーが使用できます。システム・レベルのキャッシュに適したコンテンツの例として、ページ・バナーとニュース・ポートレットがあります。
データベース・プロバイダがポートレットに対するリクエストを発行すると、リクエストはポートレットのshowプロシージャに送信されます。このプロシージャは、portlet_runtime_recordをパラメータとして受け入れます。このレコード構造体には、キャッシュを有効にするためにポートレットで検査、設定できるフィールドが含まれます。このレコードのキャッシュ・コントロール・フィールドは次のとおりです。
caching_key: この値は、このリクエストのETAGヘッダーで伝達され、後続のリクエストでポートレット・プロバイダに戻されます。このフィールドを設定すると、有効化ベースのキャッシュが有効になります。
caching_period: このフィールドは、有効期限ベースのキャッシュを有効にします。値は、コンテンツがキャッシュに保持される時間(分)です。このモードは、有効化ベースのキャッシュに優先します。このフィールドに値が設定されている場合、caching_keyフィールドは無視されます。
caching_level: このフィールドは、コンテンツが汎用なのか、特定のユーザー用なのかを定義します。有効な値は、SYSTEMおよびUSERです。
ポートレットのキャッシュを使用するための一般的なモデルは、選択するキャッシュ・タイプによって変わります。選択するキャッシュ・タイプは、ポートレットのコンテンツに大きく左右されます。ポートレットのコンテンツが非常に定期的(たとえば、毎日業務終了時)に変わる場合、通常、有効期限ベースのキャッシュを使用することは理にかなっています。ポートレットのコンテンツが不定期に変わる場合、通常、有効化ベースまたは無効化ベースのキャッシュが最適です。
有効化ベースのキャッシュを選択した場合の一般的なモデルは次のとおりです。
portlet_runtime_recordパラメータのcaching_keyフィールドを設定します。現在のキー値とportlet_runtime_recordパラメータのcaching_keyフィールドの値を比較するチェックを追加します。showプロシージャの初回コール時、キーはNULLであるため、値を設定する必要があります。
システム・レベルまたはユーザー・レベルのキャッシュのどちらを使用するかを決定します。それに応じて、portlet_runtime_recordパラメータのcaching_levelフィールドを設定します。
有効期限ベースのキャッシュを選択した場合の一般的なモデルは次のとおりです。
portlet_runtime_recordパラメータのcaching_periodフィールドに希望するキャッシュ間隔(分)を設定します。
システム・レベルまたはユーザー・レベルのキャッシュのどちらを使用するかを決定します。それに応じて、portlet_runtime_recordパラメータのcaching_levelフィールドを設定します。
無効化ベースのキャッシュを選択した場合の一般的なモデルは次のとおりです。
wwpro_api_provider.USE_INVALIDATIONをコールして、Oracle Web Cache用に特別なヘッダーを生成する必要があることをOracle Portalに指示します。
システム・レベルまたはユーザー・レベルのキャッシュのどちらを使用するかを決定します。それに応じて、portlet_runtime_recordパラメータのcaching_levelフィールドを設定します。
必要に応じて、有効化ベースまたは有効期限ベースのキャッシュも設定します。
必要に応じて(たとえば、ポートレットがパーソナライズされたときに)ポートレットに無効化ロジックを追加し、wwpro_api_invalidationへの適切なコールを実行します。
キャッシュの構成方法と、パフォーマンスの監視およびチューニング方法は、『Oracle Fusion Middleware Oracle Portal管理者ガイド』を参照してください。
PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\cacheにあるキャッシュの例に、有効化ベースのキャッシュの実装方法を示します。次に示すこの例を参照すると、ポートレットに有効化ベースのファンクションを実装する方法がわかります。
エディタでvalidcache_portlet.pkbファイルを開きます。
ファイルの最上部にある、キャッシュ・レベルの定数に対する別名に注意してください。
CREATE OR REPLACE
package body VALIDCACHE_PORTLET
is
-- Caching Constants
CACHE_LEVEL_SYSTEM constant varchar2(10) := 'SYSTEM';
CACHE_LEVEL_USER constant varchar2(10) := 'USER';
showプロシージャを探します。p_portlet_recordが、このプロシージャの入出力パラメータであることに注意してください。
procedure show
(
p_portlet_record in out wwpro_api_provider.portlet_runtime_record
)
プロシージャのセキュリティ・チェックで、セキュリティ・チェックが失敗した場合、p_portlet_recordのキャッシュ・フィールドはNULLに設定されます。
begin
if (not is_runnable(
p_provider_id => p_portlet_record.provider_id
,p_reference_path => p_portlet_record.reference_path)
) then
-- Set it to null so that cache does not get used even if exists
p_portlet_record.caching_level := null;
p_portlet_record.caching_key := null;
raise wwpro_api_provider.PORTLET_SECURITY_EXCEPTION; end if;
その後に、プロシージャはget_cache_keyファンクションをコールして、キャッシュ・キーの値を取得し、一時値に割り当てます。
--
-- CACHE IS VALID?
--
l_cache_key := get_cache_key();
showプロシージャから参照されるget_cache_keyファンクションを探します。このファンクションは、ポートレット用のキーを生成します。ポートレットの要件に基づいて、独自のロジックをここに実装できます。
function get_cache_key
return varchar2
is
l_date date;
begin
select sysdate into l_date from dual;
return trim(substr(to_char(l_date, 'YYYY:MM:DD:HH:MI:SS'),1,18));
exception
when others then
null;
end get_cache_key;
showプロシージャに戻ります。コードで、caching_keyおよびcaching_levelの現在の値がportlet_runtime_recordパラメータに含まれていないかチェックする方法に注意します。この同じコードで、caching_keyの値を比較できます。
if p_portlet_record.caching_level = CACHE_LEVEL_SYSTEM then
if l_cache_key is not null then
-- Cache exists for the user, overwrite it
p_portlet_record.caching_level := CACHE_LEVEL_USER;
p_portlet_record.caching_key := l_cache_key;
else
return; -- System cache is still valid.
end if;
elsif p_portlet_record.caching_level = CACHE_LEVEL_USER then
if p_portlet_record.caching_key != l_cache_key then
-- cache has expired. reset it
p_portlet_record.caching_key := l_cache_key;
else
return; -- User cache is good as gold
end if;
elsif p_portlet_record.caching_level is null then
if p_portlet_record.caching_key is not null then
-- Cache does not exists for the user, create it
p_portlet_record.caching_level := CACHE_LEVEL_USER;
p_portlet_record.caching_key := l_cache_key;
else
-- Define a sytem cache. This can happen only once!
-- the first time the portlet is rendered.
p_portlet_record.caching_level := CACHE_LEVEL_SYSTEM;
p_portlet_record.caching_key := 'MY_INITIAL_CACHE_KEY';
end if;
else
p_portlet_record.caching_level := CACHE_LEVEL_SYSTEM;
p_portlet_record.caching_key := 'MY_INITIAL_CACHE_KEY';
end if;
このポートレットをページに表示するのに、ポートレット・リポジトリにまだ登録していない場合は、その追加方法について8.3.2項「プロバイダ・パッケージの実装」の手順を必要に応じて参照してください。
ポートレットがリポジトリに表示されたら、ページに追加してテストできます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。
PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\cacheにあるキャッシュの例に、有効期限ベースのキャッシュの実装方法を示します。次に示すこの例を参照すると、ポートレットに有効期限ベースのファンクションを実装する方法がわかります。
エディタでexpirycache_portlet.pkbファイルを開きます。
ファイルの最上部にある、キャッシュ・レベルの定数に対する別名に注意してください。
CREATE OR REPLACE
package body VALIDCACHE_PORTLET
is
-- Caching Constants
CACHE_LEVEL_SYSTEM constant varchar2(10) := 'SYSTEM';
CACHE_LEVEL_USER constant varchar2(10) := 'USER';
showプロシージャを探します。p_portlet_recordが、このプロシージャの入出力パラメータであることに注意してください。
procedure show
(
p_portlet_record in out wwpro_api_provider.portlet_runtime_record
)
プロシージャのセキュリティ・チェックで、セキュリティ・チェックが失敗した場合、p_portlet_recordのキャッシュ・フィールドはNULLに設定されます。
begin
if (not is_runnable(
p_provider_id => p_portlet_record.provider_id
,p_reference_path => p_portlet_record.reference_path)
) then
-- Set it to null so that cache does not get used even if exists
p_portlet_record.caching_level := null;
p_portlet_record.caching_key := null;
raise wwpro_api_provider.PORTLET_SECURITY_EXCEPTION; end if;
その後に、プロシージャは、次のように、キャッシュ期間の値(分)を一時変数で設定します。
-- Set the Caching Period to one minute
l_cache_period := 1;
次に、コードで、caching_periodの現在の値がyour portlet_runtime_recordパラメータに含まれていないかチェックし、それに応じてcaching_periodを設定する方法に注意します。この同じコードで、caching_periodの値を比較できます。
if p_portlet_record.caching_level = CACHE_LEVEL_SYSTEM then -- Cache does not exists for the user, create it p_portlet_record.caching_level := CACHE_LEVEL_USER; p_portlet_record.caching_period := l_cache_period; elsif p_portlet_record.caching_level = CACHE_LEVEL_USER then -- Cache exists for the user, overwrite it p_portlet_record.caching_period := l_cache_period; elsif p_portlet_record.caching_level is null then if p_portlet_record.caching_period is not null then -- Cache does not exists for the user, create it p_portlet_record.caching_level := CACHE_LEVEL_USER; p_portlet_record.caching_period := l_cache_period; else -- Define a sytem cache. This can happen only once! p_portlet_record.caching_level := CACHE_LEVEL_SYSTEM; p_portlet_record.caching_period := l_cache_period; end if; else -- p_portlet_record.caching_level value is messed up! p_portlet_record.caching_level := CACHE_LEVEL_SYSTEM; p_portlet_record.caching_period := l_cache_period; end if;
このポートレットをページに表示するのに、ポートレット・リポジトリにまだ登録していない場合は、その追加方法について8.3.2項「プロバイダ・パッケージの実装」の手順を必要に応じて参照してください。
ポートレットがリポジトリに表示されたら、ページに追加してテストできます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。
世界地図を表示するポートレット(map_portlet.pkbとmap_portlet.pks)があるとします。無効化ベースのファンクションをそのポートレットに追加する手順は次のとおりです。
showプロシージャで、wwpro_api_provider.use_invalidationへのコールを追加する必要があります。このコールは、ポートレットのコンテンツをOracle Web Cacheでキャッシュする必要があることをOracle Portalに指示します。コンテンツをユーザー・レベルでキャッシュすること、および有効期限ベースのキャッシュも使用する(つまり有効期限1分が設定されている)ことも指定していることに注意してください。
procedure show
...
if (p_portlet_record.exec_mode = wwpro_api_provider.MODE_SHOW) then
p_portlet_record.caching_invalidation :=
wwpro_api_provider.use_invalidation;
p_portlet_record.caching_level := 'USER';
p_portlet_record.caching_period := 1;
...
キャッシュを無効化するプロシージャをmap_portlet.pkbファイルに作成します。例:
procedure map_invalidation
(
p_provider_id in number,
p_portlet_id in number,
p_instance_id in varchar2,
p_page_url in varchar2
)
is
begin
wwpro_api_invalidation.invalidate_by_instance
(p_provider_id => p_provider_id,
p_portlet_id => p_portlet_id,
p_instance_id => p_instance_id,
p_user => wwctx_api.get_user);
owa_util.redirect_url(p_page_url);
end map_invalidation;
showプロシージャで、地図を描画するコードの前にポートレットをリフレッシュするためのリンクを追加します。例:
/* Draw the Refresh Me link */
htp.anchor(
curl => wwctx_api.get_user||
'.map_invalidation?p_provider_id='||p_portlet_record.provider_id||
'&p_portlet_id='||p_portlet_record.portlet_id||
'&p_instance_id='||p_portlet_record.reference_path||
'&p_page_url='||utl_url.escape(
url => p_portlet_record.page_url,
escape_reserved_chars => TRUE),
ctext => wwui_api_portlet.portlet_text(
p_string =>'Refresh Me',
p_level => 1)
);
このポートレットをページに表示するのに、ポートレット・リポジトリにまだ登録していない場合は、その追加方法について8.3.2項「プロバイダ・パッケージの実装」の手順を必要に応じて参照してください。
ポートレットがリポジトリに表示されたら、ページに追加してテストできます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。
Oracle Portalには、誤った入力をトラップし、重要なエラー・メッセージを戻すための機能があります。内部エラー・スタックは、発生した例外を追跡し、その情報を保持することで管理されます。また、Oracle Portalには、エラーを標準化された方法で提示する一連のAPIが付属しています。
エラー処理サービスは、wwerr_api_errorパッケージおよびwwerr_api_error_uiパッケージを介して使用できます。これらのエラー処理サービスには、次の主要な機能があります。
エラー・スタック。Oracle Portalでは、エラー・スタックを使用して、エラー・メッセージを管理します。エラーが発生すると、エラー・メッセージがエラー・スタックに送信されます。プロシージャまたはファンクションのコールがネストされるたびに、エラー・スタックですべてのエラー・メッセージを管理します。wwerr_api_error.get_topメソッドを使用すると、一番上のエラー(最新のエラー)のみを取得できます。あるいは、wwerr_api_error.get_errorsファンクションを使用すると、スタックのすべてのエラー・メッセージを取得できます。スタックでは、wwerr_api_error.is_emptyファンクションをコールしてエラーの存在をチェックすることもできます。
エラー・メッセージ。エラー処理サービスでは、重要なエラー・メッセージを定義する方法を提供しています。独自のエラー・メッセージを定義するには、ネームスペースを定義する必要があります。ネームスペースは次のもので構成されます。
名前: エラー名です。
ドメイン: エラーが発生した製品エリアです。
サブドメイン: エラーが発生したサブシステムです。
コンテキスト: エラーが発生したファンクション名です。
ネームスペースは、エラー・メッセージを一意に識別します。識別しない場合は、wwc-0000エラー・メッセージが生成されます。
デフォルト・ドメインには、ポータル(WWC)、アプリケーション(WWV)およびページ・グループ(WWS)があります。各ドメインは、オブジェクト・タイプを定義するサブドメインにさらに分類されます。ポータル・ドメインには、ポートレット、ページおよびドキュメントの各オブジェクト・タイプがあります。アプリケーション・ドメインには、フォーム、メニュー、レポート、チャートなどのオブジェクト・タイプがあります。ページ・グループ・ドメインには、ページ、アイテム、カテゴリ、パースペクティブなどのオブジェクト・タイプがあります。これらの分類に該当しないというエラーを定義する必要がある場合は、エラー用のサブドメインを使用して独自のドメインを定義できます。
メッセージ・パラメータ。エラー用に作成する他の言語の文字列では、メッセージ用の置換パラメータを使用できます。p1、p2、p3...といったパラメータを使用して置換パラメータをエラー・メッセージに渡すことができます。たとえば、次の文字列の場合を考えます。
(domain='yahoo', subdomain='provider', name='generalerror', string='Error: %1')
次のようにエラーを追加できます。
wwerr_api_error.add(p_domain=>'yahoo', p_sub_domain=>'provider', p_name=>'generalerror', p_context=>'yahoo.show', p1=> sqlerrm);
エラー表示。wwerr_api_error_uiパッケージは、Oracele Portalにエラーを表示するための標準的なユーザー・インタフェースを生成するための手段を提供しています。エラー・メッセージは、次の2つの方法で表示できます。
全画面ユーザー・インタフェース: これらのエラー・メッセージが全画面モードで表示されます。システムで致命的なエラーや動作を停止させるエラーが発生した場合に、全画面エラーを表示します。
インライン・ユーザー・インタフェース: これらのエラー・メッセージは、現行のページ自体の内部に表示されます。重大ではないエラーや警告の場合に、インライン・エラーを使用します。
さらに、表示の出力形式(HTML、XMLまたはASCIIテキスト)を選択できます。
一般に、次のようにエラー処理を設定します。
エラーの検出時に、wwerr_api_error.addプロシージャを使用して、エラー・メッセージを適切なドメインとサブドメインを組み合せてスタックに追加します。
必要に応じて(たとえば、ルーチンの終了時)、wwerr_api_error_uiプロシージャを使用して、エラー・メッセージを公開します。全画面メッセージを表示するには、希望する出力タイプに応じて、プロシージャshow_html、show_xmlまたはshow_textを使用します。インライン・メッセージを表示するには、希望する出力タイプに応じて、プロシージャshow_inline_html、show_inline_xmlまたはshow_inline_textを使用します。
エラー処理を実装する際は、次の事柄に注意してください。
独自のエラー・メッセージを定義している場合、これらのメッセージには独自のエラー・ドメインを使用します。独自のエラー・メッセージには、WWC、WWVまたはWWSドメインを使用しないでください。これらのメッセージを他の言語の表にロードするには、小規模のローダー・スクリプトを作成する必要があります。
不必要なエラー・メッセージは避けます。ファンクションで何もしない場合は、エラーではなくnullを戻します。たとえば、プロバイダで他のポートレットすべてに対してcopy_portletプロシージャをコールするので、自分のポートレット用のcopy_portletプロシージャをコーディングしているとします。この特別なポートレット用のcopy_portletプロシージャで何もしない場合は、nullを戻します。エラーを戻すと、ポートレットの機能を不用意に妨害することになります。
最大10のエラー・メッセージをスタックに保持できます。10を超えて、wwerr_api_error.addがコールされると、メッセージは無視されます。
APIは、問題を発見するプログラム的な方法として使用します。このために、ユーザー・インタフェース以外の形式を使用できます。たとえば、プログラムを使用してプロバイダを登録するとき、例外ブロックでは、get_text_stackを使用して、エラー・メッセージを取得し、出力できます。この方法は、デバッグでパブリックAPIをコールする際に役立ちます。というのも、すべてのパブリックAPIが例外用のスタックにエラーを追加するためです。
独自のエラー・メッセージ用に他の言語の文字列を必ず生成してください。詳細は、8.11項「多言語ポートレットの作成」を参照してください。
エラー・メッセージの標準的なユーザー・インタフェースには、前ページに戻るナビゲーション・リンクが用意されています。また、特定のヘルプのURLに対する「ヘルプ」アイコンも含まれます。
PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\svcexにあるサービスの例に、エラー処理の実装方法を示します。次の例を参照すると、ポートレットにエラー処理ファンクションを実装する方法がわかります。
エディタでservices_portlet.pkbファイルを開きます。
ポートレット定義の定数部で、エラー・メッセージのドメインおよびサブドメインの定義に別名を指定します。
DOMAIN constant varchar2(30) := 'provider'; SUBDOMAIN constant varchar2(32) := 'services'; PORTLET_PATH constant varchar2(256):= 'oracle.portal.pdk.servicesportlet'; PREFNAME_STRING constant varchar2(30) := 'services_string'; PREFNAME_TITLE constant varchar2(30) := 'services_title';
showプロシージャを探します。このプロシージャは、セキュリティ・チェックを実行し、エラーが発生すると、wwerr_api_error.addをコールしてsecurityerrエラー・メッセージをスタックに送信します。
procedure show
(
p_portlet_record wwpro_api_provider.portlet_runtime_record
)
is
...
begin
-- Perform a security check
if (not is_runnable(
p_provider_id => p_portlet_record.provider_id
,p_reference_path => p_portlet_record.reference_path)
) then
wwerr_api_error.add(
DOMAIN, SUBDOMAIN,
'securityerr', 'services_portlet.show');
raise wwpro_api_provider.PORTLET_SECURITY_EXCEPTION;
end if;
showプロシージャでは、他の種類の実行モードについてもチェックし、無効な表示モードについて適切なエラー・メッセージを生成します。
if (p_portlet_record.exec_mode = wwpro_api_provider.MODE_SHOW) then ... elsif (p_portlet_record.exec_mode = wwpro_api_provider.MODE_SHOW_EDIT) ... else wwerr_api_error.add(DOMAIN, SUBDOMAIN, 'invaliddispmode', 'services_portlet.show'); raise wwpro_api_provider.PORTLET_EXECUTION_EXCEPTION; end if;
最後に、showプロシージャは、汎用エラー・メッセージを例外ハンドラに実装し、前の条件ではトラップされなかったエラーを捕捉します。
exception
when others then
wwerr_api_error.add(
DOMAIN, SUBDOMAIN,
'generalerr', 'services_portlet.show');
raise wwpro_api_provider.PORTLET_EXECUTION_EXCEPTION;
end show;
エラー処理は、save_prefsプロシージャおよびsave_default_prefsプロシージャにも実装されます。これらのプロシージャはエラー・スタックが空かどうかをチェックし、空でない場合は、ポートレットでwwerr_api_error.show_htmlをコールして全画面モードでエラーを表示します。
exception
when INVALID_TEXT_EXCEPTION then
l_information := l_user||'%'||l_time
||'%INVALID_TEXT_EXCEPTION%'||p_string;
l_action := LOG_FAILED;
wwlog_api.log (p_domain => DOMAIN,
p_subdomain => SUBDOMAIN,
p_name => l_user,
p_action => l_action,
p_information => l_information,
p_url => l_url,
p_row_count => 0,
p_elapsed_time=> l_elapsed_time);
wwerr_api_error.add(DOMAIN, SUBDOMAIN,
'invalid_text', 'services_portlet.save_prefs');
if (not wwerr_api_error.is_empty) then
wwerr_api_error_ui.show_html;
end if;
end save_prefs;
このポートレットをページに表示するのに、ポートレット・リポジトリにまだ登録していない場合は、その追加方法について8.3.2項「プロバイダ・パッケージの実装」の手順を必要に応じて参照してください。
ポートレットがリポジトリに表示されたら、ページに追加してテストできます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。
Oracle Portalは、トランザクション時に発生したイベントをオブジェクトとともにログに記録できます。これらのログはデータベースに格納されるため、標準的なSQLコールおよびレポート作成ツールを介して使用できます。
ログに記録するイベントや、ユーザー定義のドメインおよびサブドメインに基づいて全面的に編成するイベントを選択できます。ログに記録されたイベントについては、イベント、イベントの開始/停止時間、リモート・ユーザーのホストまたはIPアドレス、ブラウザ・タイプおよび言語に関する情報を表示できます。
イベント・ロギング・サービスは、wwlog_apiパッケージおよびwwlog_api_adminパッケージを介して使用できます。これらのサービスには、次の主要な機能があります。
イベント・ログは、ポータルの特定の使用を追跡するのに便利です。このような情報を追跡するには、ログ・イベントを作成します。ログ・イベントには、次のもので構成されるネームスペースが必要です。
名前: イベント名です。
ドメイン: イベントが発生した製品エリアです。
サブドメイン: イベントを生成したサブシステムです。
デフォルト・ドメインには、ポータル(WWC)、アプリケーション(WWV)およびページ・グループ(WWS)があります。各ドメインは、オブジェクト・タイプを定義するサブドメインにさらに分類されます。ポータル・ドメインには、ポートレット、ページおよびドキュメントの各オブジェクト・タイプがあります。アプリケーション・ドメインには、フォーム、メニュー、レポート、チャートなどのオブジェクト・タイプがあります。ページ・グループ・ドメインには、フォルダ、アイテム、カテゴリ、パースペクティブなどのオブジェクト・タイプがあります。イベント自体には、追加、削除、パーソナライズ、非表示、コピー、実行、エクスポートなどのタイプがあります。これらの分類に該当しないというイベントを定義する必要がある場合は、イベント用のサブドメインを使用して独自のドメインを定義できます。
ログでは、次の2つの方法で情報を追跡できます。
間隔ロギング: 実行されたアクションの経過時間(たとえば、ポートレットのレンダリングにかかる時間)を計算します。
イベント・ロギング: 関心がある単一ステップ・イベントの発生を(たとえば、ユーザーがポートレットをパーソナライズするたび)ログに記録します。
ログ切替えにより、既存のログ・レコードを保持する期間を定義する切替え間隔を設定できます。データベースに格納されるログ情報は、2つの異なる表を使用します。ログ・レコードは、「グローバル設定」(「管理」タブの「ポータル」サブタブの「サービス」ポートレットからアクセス可能)の「構成」タブの「動作ログ間隔」に入力された値に基づいて消去されます。ログ間隔(日)に達すると、ロギングはデータベースの2つのロギング表(たとえばAとB)で切り替わります。最初、ログはAに書き込まれます。初めてログ間隔に達すると、ログはBに書き込まれます。再びログ間隔に達すると、ログはまたAに書き込まれます。Aは、新しいログ・レコードを格納できるように空にされています。ログ間隔を14(デフォルト設定)に設定すると、ログは14日ごとに切り替わるため、どの時点でも、過去14から28日間のレコードが保持されます。
一般に、イベント・ロギングは次のように設定できます。
wwlog_api_admin.add_log_eventを使用して、適切なドメインとサブドメインを組み合せてイベント・オブジェクトを追加します。イベントを追加することで、ユーザーがイベントを監視しているときに呼び出される値のリストや他のユーザー・インタフェースのコンポーネントのリストに、この新しいイベントが確実に表示されます。
wwlog_api_admin.add_log_registryを使用して、ログ・イベント・レコードを登録します。ログ・レジストリ・レコードは、ログに記録する予定のイベントを表し、ログに記録する必要があるイベントをフィルタ処理する手段を提供します。
コードでstart_logおよびstop_logを使用し、ログに記録するイベントをマークします。あるいは、単一ステップ・イベントのログ情報を入力する場合は、ログ・メソッドをコールしてそのイベントをマークします。
イベント・ロギングを実装する際は、次の事柄に注意してください。
パフォーマンスを向上させるために、本当に関心があることのみをログに記録します。不要なログ・メッセージが、システムにあふれないようにします。イベントが表示モードでログに記録される場合は、これらのポートレットの複数のインスタンスが、データベースに対して余計にヒットします。
ドメイン、サブドメインおよびログ・イベントを注意深く選択します。ログAPIを使用する際は、独自のログ・メッセージに、WWC、WWV、WWSなどのOracle Portalドメインを使用しないでください。ドメインおよびサブドメインを階層的に編成すると、ポートレット間で確実に一意になります。他のポートレットで同じドメインまたはサブドメインの使用が発生した場合、それらのログ・メッセージの間に独自のログ・メッセージが散らばって表示されます。
ログの監視時に値のポップアップ・リストに表示されるログ・イベントを作成します。また、特定のイベントを指定するか、ワイルド・カード(%)を指定した汎用フィルタを使用して、実際にログに記録されるイベントをフィルタ処理するログ・レジストリ・レコードが簡単に作成できます。ログ・レジストリ・レコードの作成とは別に、監視するイベントについてログ・イベントを作成することをお薦めします。この方法で、ユーザー・インタフェースの値のリストに、監視などの追加機能に対するこれらのレコードが表示されます。
ログの監視が必要なユーザーまたはユーザー・グループに必要な権限を付与します。ユーザーが作成したログは、そのユーザー、ポータル管理者、およびANY_LOGSオブジェクト・タイプに対して編集の権限を持つユーザーが表示できます。
PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\svcexにあるサービスの例に、イベント・ロギングの実装方法を示します。次に示すこの例を参照すると、ポートレットにイベント・ロギング・ファンクションを実装する方法がわかります。
エディタでservices_portlet.pkbファイルを開きます。
ポートレット定義の定数部で、ログ・メッセージのドメインおよびサブドメインの定義に別名を指定します。
DOMAIN constant varchar2(30) := 'provider'; SUBDOMAIN constant varchar2(32) := 'services'; PORTLET_PATH constant varchar2(256):= 'oracle.portal.pdk.servicesportlet'; PREFNAME_STRING constant varchar2(30) := 'services_string'; PREFNAME_TITLE constant varchar2(30) := 'services_title';
save_prefsプロシージャを探します。このプロシージャは、編集モードでテキストおよびポートレット・タイトルをパーソナライズできるパーソナライズ可能な機能を提供します。save_prefsは、これらのパーソナライズをデータベースに格納します。変更を保存する際には、ログにも記録することをお薦めします。したがって、このプロシージャは、ロギング・サービスを実装する理想的な例を示しています。単一ステップ・イベントは、wwlog_api.logを使用してログに記録します。wwlog_api.logの最初のインスタンスは、テキストのパーソナライズ・イベントをログに記録します。2番目のインスタンスは、ポートレット・タイトルのパーソナライズ・イベントをログに記録します。
procedure save_prefs
...
begin
...
if (l_prefs.string_id is null or to_number(l_prefs.string_id) = 0)
then
l_action := LOG_INSERT;
...
else -- string exists in at least one language so update it
l_action := LOG_UPDATE;
...
end if;
-- Log this transaction
l_information := l_user||'%'||l_time||'%completed%'||p_string;
wwlog_api.log (p_domain => DOMAIN,
p_subdomain => SUBDOMAIN,
p_name => l_user,
p_action => l_action,
p_information => l_information,
p_url => l_url,
p_row_count => l_row_count,
p_elapsed_time=> l_elapsed_time);
...
if (l_prefs.title_id is null or to_number(l_prefs.title_id) = 0)
then
l_action := LOG_INSERT;
...
else
l_action := LOG_UPDATE;
...
-- Log this transaction l_information := l_user||'%'||l_time||'%completed%'||p_title;
wwlog_api.log (p_domain => DOMAIN,
p_subdomain => SUBDOMAIN,
p_name => l_user,
p_action => l_action,
p_information => l_information,
p_url => l_url,
p_row_count => l_row_count,
p_elapsed_time=> l_elapsed_time);
...
end save_prefs;
save_prefsプロシージャでは、例外の発生時にもwwlog_api.logを使用してイベントをログに記録します。
exception
when INVALID_TEXT_EXCEPTION then
l_information := l_user||'%'||l_time
||'%INVALID_TEXT_EXCEPTION%'||p_string;
l_action := LOG_FAILED;
wwlog_api.log (p_domain => DOMAIN,
p_subdomain => SUBDOMAIN,
p_name => l_user,
p_action => l_action,
p_information => l_information,
p_url => l_url,
p_row_count => 0,
p_elapsed_time=> l_elapsed_time);
...
このポートレットをページに表示するのに、ポートレット・リポジトリにまだ登録していない場合は、その追加方法について8.3.2項「プロバイダ・パッケージの実装」の手順を必要に応じて参照してください。
ポートレットがリポジトリに表示されたら、ページに追加してテストできます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。
Oracle Portalには、Oracle Portalの多言語ストレージ機能とやり取りするための堅牢な一連のAPIがあります。このストレージ機能は、異なる言語で文字列を格納および取得するためのメカニズムを提供しています。これらのAPIは、ネイティブの多言語機能を抽出し、異なる言語環境をサポートするプロバイダを開発するために開発者に強力なストレージ・メカニズムを提供します。
多言語サービスは、wwnls_apiパッケージを介して使用できます。これらのサービスには、次の主要な機能があります。
多言語APIにより、プロバイダは、そのポートレットに表示される文字列について複数の翻訳をロードできます。文字列がロードされると、プロバイダは、必要に応じてAPIをコールして多言語の表から文字列を取得できます。
コンテキストAPIは、ユーザーの言語およびその言語の適切な翻訳を取得します。コンテキストAPIは、ユーザーの言語環境をブラウザの言語設定から判断します。リクエストされた翻訳が存在しない場合、APIは基本言語の翻訳を戻します。
たとえば、プロバイダのregisterプロシージャでポートレット・タイトルについて英語とフランス語の翻訳をロードしたとします。ポートレットがレンダリングされると、プロバイダの実装では、ポートレット・タイトルの文字列を表から取得し、次の結果が表示されます。
フランス語文字列のリクエストには、ポートレット・タイトルがフランス語で表示されます。
英語文字列のリクエストには、ポートレット・タイトルが英語で表示されます。
中国語文字列のリクエストには、中国語の翻訳はロードされていないため、ポートレット・タイトルは英語で表示されます。
一般に、多言語サポートは次のように設定できます。
使用する各言語に対応する文字列を使用して、文字列定義をデータベースにロードします。このために、ドメイン、サブドメイン、エラー・メッセージ名およびエラー・テキストの組合せを設定して、wwnls_api.add_stringまたはwwnls_api.set_stringをコールします。
希望する言語について、wwnls_api.get_stringを使用し、必要な文字列を取得します。
多言語サポートを追加する手順は、次のとおりです。
言語文字列は、プロバイダのインストールの一部であるスクリプトによってロードできます。このスクリプトは、add_stringおよびset_stringをコールして、異なる言語の対応する文字列を作成します。
Oracle Portalは、ドメイン、サブドメインおよび名前の組合せを使用して、言語文字列を一意に識別します。ドメインとサブドメインにより、文字列の分類方法が提供されます。ドメインとサブドメインは、APIの他のユーザーと競合しない程度に一意である必要があります。
ドメインは、製品の特定エリアです。ドメインの例には、プロバイダやページ・グループがあります。
サブドメインは、ドメインのサブシステムです。サブドメインの例には、プロバイダ名(HelloProviderなど)やサブページ名(HelloPageなど)があります。
PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\svcexにあるサービスの例に、多言語サポートの実装方法を示します。次に示すこの例を参照すると、多言語サポート用の文字列をロードする方法がわかります。
エディタでservices_seed.sqlファイルを開きます。
ドメイン名、サブドメイン名、文字列名、言語および実際の文字列テキストのパラメータを設定したadd_stringコールに注意してください。これは、言語文字列に対する文字列IDを戻します。他の言語で対応する文字列を設定するために、同じパラメータを設定したset_stringがコールされます。
set serveroutput on size 1000000
set define off
declare
l_string_id integer;
l_person_id integer;
l_group_id integer;
begin
...
-- strings for portlet record fields
l_string_id := wwnls_api.add_string(
'provider','services','ptldefname','us','DatabaseServicesPortlet');
wwnls_api.set_string(
'provider','services','ptldefname','d','DatenbankServicesPortlet-d');
l_string_id := wwnls_api.add_string(
'provider','services','ptldeftitle','us','Database Services Portlet');
wwnls_api.set_string(
'provider','services','ptldeftitle','d','Datenbank Services Portlet - d');
l_string_id := wwnls_api.add_string(
'provider','services','ptldefdesc','us','This is the database services
portlet implemented in PL/SQL. It displays 6 show modes.');
wwnls_api.set_string(
'provider','services','ptldefdesc','d','Dies ist das Datenbank Service
Portlet, erstellt in PL/SQL. Es stellt 6 Anzeigemodi dar. - d');
l_string_id := wwnls_api.add_string(
'provider','services','ptldevtmmsg','us','Web Services Portlet Timed
Out.');
wwnls_api.set_string(
'provider','services','ptldevtmmsg','d','Zeitüeberschreitung aufgetreten
in Web Services Portlet. -d');
PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\svcexにあるサービスの例に、多言語サポートの実装方法を示します。次に示すこの例を参照すると、多言語サポート用の文字列を取得する方法がわかります。
エディタでservices_portlet.pkbファイルを開きます。
ポートレット定義の定数部で、言語文字列のドメインおよびサブドメインの定義に別名を指定します。
DOMAIN constant varchar2(30) := 'provider'; SUBDOMAIN constant varchar2(32) := 'services'; PORTLET_PATH constant varchar2(256):= 'oracle.portal.pdk.servicesportlet'; PREFNAME_STRING constant varchar2(30) := 'services_string'; PREFNAME_TITLE constant varchar2(30) := 'services_title';
get_portlet_infoファンクションを探します。ポートレット・タイトル、名前および説明を移入するための、wwnls_api.get_stringへのコールに注意してください。
function get_portlet_info
(
p_provider_id in integer
,p_language in varchar2
)
return wwpro_api_provider.portlet_record
is
l_portlet wwpro_api_provider.portlet_record;
begin
l_portlet.id := services_provider.SERVICES_PORTLET_ID;
l_portlet.provider_id := p_provider_id;
l_portlet.language := p_language;
l_portlet.title :=
wwnls_api.get_string(
p_domain => DOMAIN
,p_sub_domain => SUBDOMAIN
,p_name => 'ptldeftitle'
,p_language => p_language
);
l_portlet.description :=
wwnls_api.get_string(
p_domain => DOMAIN
,p_sub_domain => SUBDOMAIN
,p_name => 'ptldefdesc'
,p_language => p_language
);
l_portlet.name :=
wwnls_api.get_string(
p_domain => DOMAIN
,p_sub_domain => SUBDOMAIN
,p_name => 'ptldefname'
,p_language => p_language
);
...
services_portlet.pkbファイルの残りの部分を参照し、別の場所でも使用されているwwnls_api.get_stringの他の使用例を調査します。
このポートレットをページに表示するのに、ポートレット・リポジトリにまだ登録していない場合は、その追加方法について8.3.2項「プロバイダ・パッケージの実装」の手順を必要に応じて参照してください。
ポートレットがリポジトリに表示されたら、ページに追加してテストできます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。
この項では、PDK-PL/SQLを使用してポートレットをモバイル機器用に拡張する手順を説明します。この項を読み進める前に、モバイル対応ポートレットの構築に関するガイドライン(8.1.3項「モバイル・ポートレットのガイドライン」)およびPDK-PL/SQLを使用してポートレットを構築する方法(8.2項「PL/SQLジェネレータを使用したPL/SQLポートレットの構築」および8.3項「手動によるPL/SQLポートレットの構築」)についてよく理解しておく必要があります。
モバイル機器のポートレットを正しく構築する手順は、次のとおりです。
ポートレット・レコード属性をモバイル出力可能に設定します。モバイル機器からモバイル・ゲートウェイを介して到着するリクエストには、OracleAS Wireless XMLでヘッダーにtext/vnd.oracle.mobilexmlコンテンツ・タイプを使用して応答する必要があります。モバイル対応ポートレットは、このタイプのリクエストを処理し、対応するモバイル・コンテンツを作成できるようにする必要があります。
表8-6に、モバイル・ポートレットに関連するポートレット・レコード属性をリストし、その指定方法について説明します。
表8-6 ポートレット・レコード属性
| 属性 | 説明 |
|---|---|
accept_content_type |
ポートレットが作成するコンテンツ・タイプのカンマ区切りのリストを指定します。ポートレットでHTMLおよびOracleAS Wireless XMLの両方のコンテンツを作成できる場合、リストの文字列には次のように指定します。 text/html, text/vnd.oracle.mobilexml ポートレットでOracleAS Wireless XMLのみを作成できる場合、リストの文字列には次のように指定します。 text/vnd.oracle.mobilexml |
mobile_only |
ポートレットがモバイル・ページでのみ使用可能かどうかを指定します。TRUEは、ポートレットがモバイル専用で、標準ページ用の「ポートレットの追加」ページには表示されないことを宣言します。FALSEは、ポートレットがモバイルおよび標準の両用で、標準ページとモバイル・ページの両方用として「ポートレットの追加」ページに表示されることを宣言します。ポートレットでOracleAS Wireless XMLのみが作成できる場合にこのフラグをFALSEに設定すると、OracleAS Wireless XMLは自動的にデスクトップ・デバイス(たとえば、普通のパーソナル・コンピュータのWebブラウザ)用のHTMLに変換されます。OracleAS Wireless XMLしか出力しないのに、モバイル・アクセス用のみでなくデスクトップ・アクセス用の標準ページにも表示できるポートレットを、この機能により開発できます。 |
short_title |
ポートレット・タイトルの短いバージョンを入力します。このタイトルは、小さな画面に収まりやすいことから、モバイル機器上で使用されます。短いタイトルを設定しないと、かわりにポートレット・タイトルが使用されます。 |
has_show_link_mode |
ポートレットに対してリンク・モードを実装しているかどうかを示します。すべてのモバイル・ポートレットでリンク・モードを有効にすることをお薦めします。リンク・モードを使用する根拠については、ステップ3で詳しく説明します。 |
ポートレットでは、HTMLとOracleAS Wireless XMLの両方を作成できるようにする場合、実行時に、リクエストがモバイル機器とデスクトップ・デバイスのどちら用であるかを判別できる必要があります。デスクトップ・リクエストの場合、ポートレットはHTML出力を作成する必要があります。モバイル・リクエストの場合は、OracleAS Wireless XML出力を作成する必要があります。リクエスト・タイプを判別するのに、wwctx_api.get_http_accept()が使用できます。これは、リクエスト・タイプを示すHTTP Acceptヘッダーをフェッチします。ポートレットのレスポンスでは、ポートレット・コンテンツを作成するために、MIMEヘッダーをHTTPヘッダーの該当値に設定する必要があります。設定しないと、結果のページがOracle Portalによって構築されたときに、ポートレットのレスポンスが拒否されます。wwctx_api.get_http_accept()を取得するコールが、text/vnd.oracle.mobilexmlで始まる文字列を戻した場合は、モバイル・リクエストであると想定できます。そうでない場合は、デスクトップ・リクエストです。モバイル・リクエストの場合は、MIMEヘッダーをtext/vnd.oracle.mobilexmlに設定する必要があります。デスクトップ・リクエストの場合は、MIMEヘッダーを明示的にtext/htmlに設定してもかまいませんが、これはデフォルト設定なので特にそのように設定する必要はありません。
デスクトップ・リクエストに対してHTMLを作成し、モバイル・リクエストに対してOracleAS Wireless XMLを作成するには、ポートレットのshowプロシージャを次のように実装する必要があります。
procedure show
(
p_portlet_record in out wwpro_api_provider.portlet_runtime_record
)
is
begin
--
-- Does the portal want us to render the portlet contents?
--
if (p_portlet_record.exec_mode = wwpro_api_provider.MODE_SHOW) then
--
-- Is this a mobile request?
--
if owa_util.get_cgi_env('HTTP_ACCEPT') like
wwpro_login.CONTENT_TYPE_MOBILEXML || '%' then
--
-- This is a mobile request for the portlet contents
-- call the mobile show contents procedure
--
render_mobile_show_contents(p_portlet_record);
else
--
-- This is a desktop request for the portlet contents,
-- call the desktop show contents procedure
--
render_desktop_show_contents(p_portlet_record);
end if;
elsif -- check for other show modes, and handle them
...
end show;
どのようなリクエストが来てもOracleAS Wireless XMLしか作成しないようにするには、ポートレットのshowプロシージャを次のように実装する必要があります。
procedure show
(
p_portlet_record in out wwpro_api_provider.portlet_runtime_record
)
is
begin
--
-- Does the portal want us to render the portlet contents?
--
if (p_portlet_record.exec_mode = wwpro_api_provider.MODE_SHOW) then
--
-- This is either a desktop or mobile request for the portlet
-- contents call the show contents procedure to render the
-- OracleAS Wireless XML output
--
render_show_contents(p_portlet_record);
elsif -- check for other modes
...
end show;
OracleAS Wireless XMLを生成するためには、render_show_contentsプロシージャまたはrender_show_mobile_contentsプロシージャに次のような内容を含める必要があります。
...
(
p_portlet_record in out wwpro_api_provider.portlet_runtime_record
)
is
begin
--
-- Set the MIME type to be Oracle9iAS Wireless XML
--
owa_util.mime_header('text/vnd.oracle.mobilexml');
--
-- Output the Oracle9iAS Wireless XML markup
--
htp.p('<SimpleText><SimpleTextItem>');
htp.p('Hello World!');
htp.p('</SimpleTextItem></SimpleText>');
...
|
注意: これはモバイル・リクエストなので、MIMEヘッダーは |
ポートレットでモバイル・レンダリング用にタイトルのパーソナライズを可能にするには、リンク・モードを実装する必要があります。リンク・モードは、モバイル・リクエストに対してのみコールされ、ポートレット・コンテンツへのリンクをレンダリングします。このリンクは、ユーザーが初めてページにナビゲートしたときに、そのページ・コンテンツのメニューに表示されます。ポートレットにリンク・モードが実装されていない場合は、Oracle Portalによって、ポートレット・レコード内の短いタイトルを使用して、デフォルトのリンク・モードがレンダリングされます。リンク・モードは、タイトル以外のものをレンダリングするのにも使用できます。たとえば、株式ポートレットでは、ユーザーのお気に入り株式の株価をレンダリングできます。このようにすれば、ドリルダウンしていかなくても最新の株価を表示できます。
リンク・モードをレンダリングするリンクはOracle Portalによって提供され、ポートレット・レコード内のpage_urlパラメータでポートレットに渡されます。ポートレットは、この動作を拡張することも完全に置き換えることもできます。このリンクがユーザーをOracle Portalから引き離す(Oracle Portalの中間層サーバーのサービスを受けない)ようなURLとして書きなおされた場合、ポートレットはshow_behaviour_styleフィールドをポートレット・レコード内のwwpro_api_provider.EXTERNAL_PORTLETに設定する必要があります。
次の例では、リンク・モードを含むようにshowプロシージャをコーディングする方法を示します。
procedure show
(
p_portlet_record in out wwpro_api_provider.portlet_runtime_record
)
is
begin
--
-- Does the portal want us to render the portlet contents?
--
if (p_portlet_record.exec_mode = wwpro_api_provider.MODE_SHOW) then
--
-- Is this a mobile request?
--
if owa_util.get_cgi_env('HTTP_ACCEPT') like
wwpro_login.CONTENT_TYPE_MOBILEXML || '%' then
--
-- This is a mobile request for the portlet contents,
-- call the mobile show contents procedure
--
render_mobile_show_contents(p_portlet_record);
else
--
-- This is a desktop request for the portlet contents,
-- call the desktop show contents procedure
--
render_desktop_show_contents(p_portlet_record);
end if;
--
-- Does the portal want us to render the LINK mode?
--
elsif (p_portlet_record.exec_mode = wwpro_api_provider.MODE_LINK) then
--
-- This is a mobile request for the portlet link mode,
-- call the mobile link procedure
--
render_mobile_link(p_portlet_record);
elsif -- check for other show modes, and handle them
...
end show;
次の例に、render_mobile_linkプロシージャにリンク・モード用に実装する必要がある内容を示します。特に、MIMEタイプの設定、get_custom_short_titleの使用方法およびOracleAS Wireless XML出力に注目してください。
procedure render_mobile_link
(
p_portlet_record in out wwpro_api_provider.portlet_runtime_record
)
is
l_short_title varchar2(80);
begin
--
-- Set the MIME type to be Oracle9iAS Wireless XML
--
owa_util.mime_header('text/vnd.oracle.mobilexml');
--
-- Get the personalized short title for this portlet instance
-- using the language and reference path held in the portlet
-- record
--
l_short_title := get_custom_short_title(p_portlet_record);
--
-- Output the OracleAS Wireless XML markup
--
if l_short_title is not null then
htp.p('<SimpleHref target="'
|| htf.escape_sc(p_portlet_record.page_url)
|| '">'
|| l_short_title
|| '</SimpleHref>');
else
htp.p('<SimpleHref target="'
|| htf.escape_sc(p_portlet_record.page_url)
|| '">'
|| get_custom_title(p_portlet_record)
|| '</SimpleHref>');
end if;
end render_mobile_link;
DeviceClassヘッダーへのアクセス
DeviceClassヘッダー内の情報を使用すると、モバイル対応ポートレットをさらに容易に作成できます。このヘッダーは、すべてのポートレットにowa_util.get_cgi_env('x-oracle-device.class')を介して送信されます。このヘッダーの値は、ポートレットのOracleAS Wireless XMLレンダリングの複雑度を決定するのに使用できます。たとえば、PDAでは、マイクロブラウザよりもさらに表現の豊かなコンテンツをレンダリングできます。音声レンダリングでは、ボイス・コマンド用の追加タグや音声ファイルへのリンクを対象とすることができます。これらは、テキスト読上げソフトを使用した場合と同様に再生されます。
表8-7に、このヘッダーに利用できる値を示します。
プロバイダを登録するには、ほとんどの場合、8.2.3.2項「データベース・プロバイダの登録」で説明したようにOracle Portalのユーザー・インタフェースを使用します。ただし、場合によっては、ユーザー・インタフェースを使用するのではなく、プログラムを使用してプロバイダを登録できます。この項では、次のようにwwpro_api_provider_registry.register_providerを使用してプロバイダを登録する方法を説明します。
wwpro_api_provider_registry.register_providerを使用してプログラムでプロバイダを登録するには、次の前提条件を満たしている必要があります。
最初に、8.2.3.1項「データベースへのパッケージのインストール」の説明に従ってプロバイダをインストールする必要があります。
wwpro_api_provider_registry.register_providerを実行するのに必要な権限を持っている必要があります。これはセキュアなAPIなので、セキュリティ・チェックによって呼出元のユーザーに必要な権限があるかどうかが判断されます。少なくとも、wwsec_api.ANYPROVIDER_PUBLISH権限を持っている必要があります。APIを実行する権限を持っている場合は、wwctx_api.set_contextを使用してOracle Portalセッションを設定する権限も十分に持っていることになります。
|
注意: SQL*Plusセッションのデータベース・ユーザーがOracle Portalスキーマの所有者である場合は、デフォルトで、このユーザーがOracle Portalスキーマの所有者になっています。( |
wwpro_api_provider_registry.register_provider APIは、入力としてprovider_recordを必要とします。provider_recordをregister_providerに渡すとき、フィールドのすべてが必要なわけではありません。表8-8に、Webプロバイダ用およびデータベース・プロバイダ用に必要とされるフィールドを示します。フィールドが特定タイプのプロバイダには適用されない場合は、NAと示されています。
表8-8 provider_recordの必須フィールド
| フィールド | データベース・プロバイダで必須 | Webプロバイダで必須 | コメント |
|---|---|---|---|
name |
はい。 |
はい。 |
なし。 |
implementation_style |
はい。 |
はい。 |
このフィールドは、PL/SQLポートレットの場合、常に次のようになります。 wwpro_api_provider_registry. DATABASE_IMPL; |
implementation_owner |
NA。 |
はい。 |
このフィールドは、プロバイダ/ポートレットが配置されるスキーマです。 |
implementation_name |
NA。 |
はい。 |
データベース・プロバイダを登録する際は、プロバイダの実装パッケージが有効でないと登録に失敗します。 |
login_frequency |
はい。 |
はい。 |
このフィールドは、セッション情報を取得する頻度を指定します。 |
http_app_type |
はい。 |
NA。 |
外部アプリケーションのWebプロバイダの場合: wwpro_api_provider_registry.HTTP_APP_TYPE_EXTERNAL 標準のWebプロバイダの場合: wwpro_api_provider_registry.HTTP_APP_TYPE_PORTAL |
http_url |
はい。 |
NA。 |
なし。 |
require_url |
はい。 |
NA。 |
なし。 |
encryption_key |
provider_keyがNULLではない場合は、はい。 provider_keyがNULLの場合は、いいえ。 |
provider_keyがNULLではない場合は、はい。 provider_keyがNULLの場合は、いいえ。 |
なし。 |
次のサンプルSQLスクリプトに、wwpro_api_provider_registry.register_providerの使用方法を示します。
set serveroutput on size 1000000
set define on
declare
l_prov_rec wwpro_api_provider_registry.provider_record;
l_prov_id integer;
begin
l_prov_rec.name := 'CacheProvider';
l_prov_rec.display_name := 'Cache Provider';
l_prov_rec.timeout := 10;
l_prov_rec.timeout_msg := 'The provider timed out';
l_prov_rec.implementation_style := wwpro_api_provider_registry.DATABASE_IMPL;
l_prov_rec.implementation_owner := '&&2';
l_prov_rec.implementation_name := 'cache_provider';
l_prov_rec.language := wwctx_api.get_nls_language;
l_prov_rec.enable_distribution := true;
l_prov_rec.login_frequency := wwpro_api_provider_registry.LOGIN_
FREQUENCY_NEVER;
l_prov_rec.created_on := sysdate;
l_prov_rec.created_by := '&&1';
l_prov_rec.last_updated_on := sysdate;
l_prov_rec.last_updated_by := '&&1';
l_prov_id := wwpro_api_provider_registry.register_provider(l_prov_rec);
commit;
dbms_output.put_line('Cache Provider successfully registered');
exception
when others then
dbms_output.put_line('ERROR: Could not register Cache Provider');
dbms_output.put_line('SQLERRM: ' || SQLERRM);
rollback;
end;
/
|
注意: プロバイダを登録したら、 |