ヘッダーをスキップ
Oracle® Fusion Middleware Oracle Portal開発者ガイド
11gリリース1 (11.1.1)
B61384-04
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次
索引へ移動
索引

前
 
次
 

8 PL/SQLポートレットの作成


注意:

一般に、ポートレットの構築には、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ツールキットに精通している必要があります。

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

詳細はOTN

この章で参照される多数の例のソース・コードは、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

8.1 PL/SQLポートレットの作成のガイドライン

PL/SQLでポートレットを作成する際は、この項で説明するベスト・プラクティスに従う必要があります。

8.1.1 ポートレットの表示モード

Javaポートレットと同様に、PL/SQLポートレットでは、様々な表示モードが使用できます。表示モードは、ポートレットの機能の一部です。使用できる次の表示モードの詳細は、第6章「Javaポートレットの作成」を参照してください。

選択した表示モードを確認するために、wwpro_api_providerパッケージの定数を使用できます。表8-1に、これらの定数とそれに対応する表示モードを示します。

表8-1 wwpro_api_providerの表示モードの定数

表示モード 定数

共有画面

MODE_SHOW

編集

MODE_SHOW_EDIT

デフォルト編集

MODE_SHOW_EDIT_DEFAULTS

プレビュー

MODE_SHOW_PREVIEW

全画面

MODE_SHOW_DETAILS

ヘルプ

MODE_SHOW_HELP

情報

MODE_SHOW_ABOUT

リンク

MODE_SHOW_LINK

8.1.2 推奨されるポートレットのプロシージャおよびファンクション

ポートレット・コードの主な目的は、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

パブリック・ポートレット・パラメータのリストを戻します。


8.1.3 モバイル・ポートレットのガイドライン

Oracle Portalのページは、HTMLデバイスおよび非HTMLデバイス(モバイル機器)の両方に対してレンダリングできます。モバイル機器用ポートレットを設計するときは、いくつかの追加のガイドラインを考慮する必要があります。モバイル・ポートレットに関するガイドラインは、6.1.4項「モバイル・ポートレットのガイドライン」を参照してください。

モバイル対応ポートレットの構築方法は、8.12項「ポートレットのモバイル機器用拡張」を参照してください。

8.2 PL/SQLジェネレータを使用したPL/SQLポートレットの構築

データベース・プロバイダおよび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ジェネレータを使用するための一般的なモデルは次のとおりです。

  1. 構築するプロバイダおよびポートレットを定義するXMLファイルを作成します(8.2.1項「入力XMLファイルの作成」を参照)。

  2. 作成したXMLファイルを入力として使用し、PL/SQLジェネレータを実行します(8.2.2項「PL/SQLジェネレータの実行」を参照)。

  3. 生成されたPL/SQLポートレットを公開します。手順は次のとおりです。

8.2.1 入力XMLファイルの作成

ソースの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

ポートレット名を指定します。名前には空白を含めないでください。ジェネレータでは、nameタグで指定された情報をポートレット・パッケージ名に使用します。

文字列

title

ポートレットの表示名を指定します。

文字列

shortTitle

ポートレットの短い表示名を指定します。このタグは、モバイル・ポートレットに便利です。

文字列

description

ポートレットの説明を指定します。

文字列

defaultLocale

ポートレットがデフォルトでレンダリングする言語を指定します。この値は、2文字のISO言語コードと国コードで、language.countryと表現されます。

文字列

timeout

ポートレットのタイムアウト時間(秒数)を指定します。

数値

timeoutMsg

ポートレットがタイムアウトしたときに表示されるメッセージを指定します。

文字列

showEdit

ユーザーがポートレットのプロパティをパーソナライズできる編集モードを、ポートレットがサポートするかどうかを指定します。

ブール

showEditDefault

ポートレットのプロパティのデフォルト値をパーソナライズできるデフォルト編集モードを、ポートレットがサポートするかどうかを指定します。

ブール

showDetails

ポートレットが全画面モードで表示できるかどうかを指定します。このモードでは、ブラウザ・ウィンドウ全体がそのポートレットのみのものになります。全画面モードを使用すると、ポートレットは、他のポートレットとページを共有しているときよりも詳細な表示を行います。

ブール

showPreview

ポートレットがプレビュー・モードをサポートするかどうかを指定します。

ブール

hasHelp

ポートレットがヘルプ・モードをサポートするかどうかを指定します。

ブール

hasAbout

ポートレットが情報モードをサポートするかどうかを指定します。

ブール

language

ポートレットのデフォルト言語(たとえばen)を定義します。

文字列

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のバージョンを指定します。値は、wwpro_api_provider.API_VERSION_1となります。

文字列

callIsRunnable

ポートレットを表示する前に、OracleAS Portalでユーザーの資格証明をチェックする必要があるかどうかを指定します。デフォルト値はtrueです。

ブール

callGetPortlet

ポートレット・レコードのプロバイダに接続するかわりに、Portlet Metadata Repository (PMR)に格納されるポートレット・レコード・データをポータルで使用できるかどうかを指定します。プロバイダから戻されるポートレット・レコード(プロバイダのid、ポートレットのidおよびlanguageで指定)に変更がなければ、プロバイダはcall_get_portletの値をfalseに設定します。つまり、プロバイダのget_portletファンクションおよびget_portlet_listファンクションをコールするかわりに、PMRを使用するようにポータルに指示します。プロバイダがPMRのポートレット・メタデータをポータルに使用させない場合の例は、ポートレット・レコードの値が、ログインしているユーザーのものとは異なる場合です。デフォルト値はtrueです。

ブール

acceptContentType

ポートレットで作成できるコンテンツ・タイプのカンマ区切りのリストを指定します。たとえば、ポートレットでHTMLおよびMOBILEXMLの両タイプのコンテンツを作成できる場合は、タグの値は次のとおりです。

text/html,text/vnd.oracle.mobilexml

文字列

hasShowLinkMode

ポートレットがリンク・モードを実装するかどうかを指定します。値がfalseの場合、ポートレットは、短いタイトルまたはフル・タイトルを使用して、モバイル機器のポートレット・コンテンツを参照するリンク・ラベルを表示します。そうでない場合、パーソナライズされたリンクをポートレット・コードで生成できます。デフォルト値はfalseです。

ブール

mobileOnly

ポートレットはモバイル機器でのみ使用可能かどうかを指定します。デフォルト値はfalseです。

ブール

preferenceStorePath

プロバイダがポートレットのパーソナライズ情報を格納した場所へのベース・プリファレンス・ストア・パスを指定します。このパスは、ポートレットのエクスポート時に使用されます。

文字列

createdOn

ポートレットの作成日を定義します。デフォルト値はsysdateです。

日付

createdBy

ポートレット・レコードを作成したユーザーを指定します。

文字列

lastUpdatedOn

ポートレット・レコードが変更された最新の日付を定義します。デフォルト値はsysdateです。

日付

lastUpdatedBy

ポートレット・レコードを最近変更したユーザーを指定します。

文字列

passAllUrlParams

ポートレットでのパラメータの引渡し動作を指定します。タグの値がtrueの場合、Oracle Portalは、URLですべてのパラメータをポートレットに渡します。タグの値がfalseの場合、ポートレットは、そのポートレットを対象とするパラメータのみを受け取ります。デフォルト値はtrueです。

ブール

cacheLevel

ポートレットのキャッシュ・レベルを指定します。次のいずれかの値をとります。

wwpro_api_provider.CACHE_LEVEL_SYSTEM
wwpro_api_provider.CACHE_LEVEL_USER

文字列

rewriteUrls

ポートレット・レンダリング・リクエストからの出力で、URLリライティングを実行するかどうかを指定します。デフォルト値はfalseです。

ブール


次に、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>

8.2.2 PL/SQLジェネレータの実行

有効なXML入力ファイルを作成したら、次のようにPL/SQLジェネレータを実行して、プロバイダおよびポートレットのパッケージをSQLファイル形式で生成できます。

  1. PL/SQLジェネレータをインストールしていない場合は、一緒にダウンロードした手順に従って、PL/SQLジェネレータをインストールします。

  2. ブラウザから、PL/SQLジェネレータのURLに移動します。図8-1に示すようなページが表示されます。

    図8-1 PL/SQLジェネレータ・ページ

    図8-1の説明が続きます
    「図8-1 PL/SQLジェネレータ・ページ」の説明

  3. 「Source XML File」フィールドで、「Browse」をクリックしてソースのXMLファイルを選択します。XMLファイルの作成方法は、8.2.1項「入力XMLファイルの作成」を参照してください。

  4. 「Provider Name」フィールドに、プロバイダの名前を入力します。プロバイダ名には空白を含めないでください。ジェネレータでは、このフィールドに入力された値をプロバイダ・パッケージ名に使用します。

  5. 「Generate」をクリックして、プロバイダおよびポートレットのパッケージに関するインストール可能なPL/SQLコードを含むSQLファイルを生成します。ブラウザからファイルの保存またはオープンを要求された場合は、「Save」を選択します。

  6. 「Save」ダイアログ・ボックスで、ファイル拡張子を.sqlに変更し、希望するファイル名に変更します。

  7. ファイルを保存します。

8.2.3 生成されたPL/SQLポートレットの公開

PL/SQLジェネレータを実行してSQLファイルを取得した後に、Oracle Portalでプロバイダとポートレットを使用できるようにするには、次のタスクを実行する必要があります。

8.2.3.1 データベースへのパッケージのインストール

生成されたプロバイダおよびポートレットのパッケージを、Oracle Portalがインストールされたデータベースにインストールする手順は、次のとおりです。

  1. SQL*Plusセッションを開始し、PORTALスキーマにログインします。

  2. 新しいデータベース・スキーマのプロバイダ・スキーマを作成し、SQL*Plusで次のコマンドを入力して生成されたプロバイダおよびポートレットのパッケージを格納します。

    create user provider_schema identified by provider_schema_password;
    grant resource, connect to provider_schema;
    
  3. 次のようにprovsyns.sqlスクリプトを実行して、Oracle PortalのAPIに対するEXECUTE権限をプロバイダ・スキーマに付与します。このスクリプトは、ORACLE_HOME/portal/admin/plsql/wwcディレクトリにあります。

    @provsyns.sql provider_schema
    
  4. プロバイダ・スキーマにログインし、生成されたSQLファイルを実行します。プロバイダおよびポートレットのパッケージがデータベースに作成されます。

8.2.3.2 データベース・プロバイダの登録

プロバイダおよびポートレットのパッケージをデータベースに作成した後は、次の手順を実行して、PL/SQLポートレットをポータル・ページに追加する前にプロバイダをOracle Portalに登録する必要があります。

  1. Oracle Portalに管理者としてログインします。

  2. Portalビルダーで、「管理」タブ、次に「ポートレット」タブをクリックします。

  3. 「リモート・プロバイダ」ポートレットで、「プロバイダの登録」をクリックします。

  4. 必要に応じて、「名前」「表示名」「タイムアウト」および「タイムアウト・メッセージ」に入力します。

  5. 「実装スタイル」リストから「データベース」を選択します。

  6. 「次へ」をクリックして残りのウィザードを入力します。

  7. ウィザードへの入力が完了したら、「終了」をクリックします。

  8. 「ポートレット・リポジトリ」ポートレットで、「ポートレット・リポジトリの表示」をクリックします。

  9. リポジトリを参照し、登録したばかりのプロバイダを探します。通常、新規プロバイダはリポジトリの「ポートレット・ステージング領域」に表示されます。

  10. プロバイダが見つかったら、作成したポートレットがすべてプロバイダに含まれていることを確認します。プロバイダまたはそのポートレットが表示されない場合は、この項および前項(8.2.3.1項「データベースへのパッケージのインストール」8.2.1項「入力XMLファイルの作成」8.2.2項「PL/SQLジェネレータの実行」)の手順を見なおし、プロバイダおよびポートレットを正しく作成、登録したことを確認します。

8.2.3.3 ページへのポートレットの追加

プロバイダとそのポートレットがリポジトリに表示されたら、ページに追加できます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。

8.3 手動によるPL/SQLポートレットの構築

この項では、starterプロバイダ・サンプルに含まれるhello worldサンプルを使用して、基本的なPL/SQLポートレットの構築方法について説明します。starterプロバイダ・サンプルは、PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\starterにあり、次のファイルで構成されています。

PL/SQLポートレットを手動で構築するための一般的なモデルは、次のとおりです。

  1. hello worldポートレットのパッケージ仕様および本体を変更し、独自のポートレット・パッケージを作成します(8.3.1項「ポートレット・パッケージの実装」を参照)。

  2. starterプロバイダのパッケージ仕様および本体を変更し、新規作成したポートレットをプロバイダに追加します(8.3.2項「プロバイダ・パッケージの実装」を参照)。

  3. 新規作成したポートレットをページに追加します(8.3.3項「ページへのポートレットの追加」を参照)。

8.3.1 ポートレット・パッケージの実装

helloworld_portlet.pksおよびhelloworld_portlet.pkbを変更し、独自のポートレット・パッケージを作成する手順は、次のとおりです。

  1. パッケージ仕様helloworld_portlet.pksおよびパッケージ本体helloworld_portlet.pkbをコピーします。

  2. コピーの名前をmy_first_portlet.pksおよびmy_first_portlet.pkbにそれぞれ変更します。

  3. エディタでmy_first_portlet.pksを開き、次のようにパッケージ名をmy_first_portletに変更します。

    CREATE OR REPLACE
    package my_first_portlet
    is
    ...
    
    end my_first_portlet;
    
  4. エディタでmy_first_portlet.pkbを開き、前述の手順で行った変更を繰り返します。つまり、パッケージ名をmy_first_portletに変更します。

  5. 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';
        ...
    
  6. 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;
    ...
    
  7. my_first_portlet.pkbを保存します。

8.3.2 プロバイダ・パッケージの実装

ポートレット・パッケージを実装した後は、ポートレットをプロバイダに追加する必要があります。starter_provider.pksおよびstarter_provider.pkbを変更して、新規ポートレットをプロバイダに追加する手順は、次のとおりです。

  1. パッケージ仕様starter_provider.pksおよびパッケージ本体starter_provider.pkbをコピーします。

  2. コピーの名前をstarter_provider2.pksおよびstarter_provider2.pkbにそれぞれ変更します。


    注意:

    新しい空のプロバイダを作成する場合、次の手順を実行する前に、hello worldポートレットおよびsnoopポートレットへのすべての参照をstarter_provider2.pksおよびstarter_provider2.pkbから削除します。


  3. エディタでstarter_provider2.pksを開きます。

  4. 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;
    
  5. starter_provider2.pksを保存します。

  6. エディタでstarter_provider2.pkbを開きます。

  7. starter_provider2.pkbで、新規ポートレットのget_portlet_infoファンクションに対するコールをプロバイダ・パッケージのget_portletファンクションに追加します。このためには、コールmy_first_portlet.get_portlet_infoget_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;
    
  8. 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;
    
  9. 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;
    
  10. 表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)
    

  11. starter_provider2.pkbを保存して閉じます。

  12. 通常どおり、Oracle Portalにログインします。

  13. Portalビルダーで、「管理」タブ、次に「ポートレット」タブをクリックします。

  14. 「ポートレット・リポジトリ」ポートレットで、「ポートレット・リポジトリの表示」をクリックします。

  15. リポジトリを参照し、starterプロバイダを探します(通常、リポジトリの「ポートレット・ステージング領域」に表示されます)。これには、元のポートレットhello worldおよびsnoopの2つが含まれています。

  16. コマンドラインのプロンプトからSQL*Plusを起動し、starterプロバイダ・スキーマの所有者として接続します。

  17. 新規および変更済のPL/SQLパッケージを次の順序でコンパイルします。

    • starter_provider2.pks

    • my_first_portlet.pks

    • starter_provider2.pkb

    • my_first_portlet.pkb

  18. コンパイル・エラーが発生した場合は、すべてのパッケージが正常にコンパイルされるまで、修正して再コンパイルします。

  19. 「ポートレット・リポジトリ」ポートレットで、「ポートレット・リポジトリの表示」をクリックします。

  20. リポジトリを参照し、starterプロバイダを再度探します。この時点で、これには、元のポートレットに加えて、新規ポートレットmy_first_portletが含まれています。


    注意:

    既存のプロバイダまたはポートレット・レコードに変更を加える場合、Oracle Portalインスタンスに反映された変更を表示するには、プロバイダをリフレッシュする必要があります。


8.3.3 ページへのポートレットの追加

これで、ポートレット・リポジトリ内のポートレットと同様に、ポートレットをページに追加できます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。

8.4 情報ストレージの実装

Oracle Portalには、個々のポートレット・プリファレンスを格納、取得するためのAPI、および現行セッション用の一時データを格納、操作するためのAPIが用意されています。情報ストレージの実装は次のもので構成されます。

8.4.1 プリファレンス・ストアの実装

Oracle Portalでは、固有のポートレット・インスタンスごとに個々のプリファレンスを永続的に格納、取得するための一連のAPIを提供しています。各プリファレンスに対する一意の識別子、ユーザーごとに自動的にマップされるプリファレンス・ストア、およびPL/SQLポートレットのパーソナライズ情報を格納、取得するためのアクセス・メカニズムを提供しています。

デフォルトでは、エンドユーザーのパーソナライズを有効にすると、ポートレットのタイトル・バーに「パーソナライズ」が表示されます。このリンクにより、ユーザーがそのポートレットに対する設定を選択できるフォームが表示されます。

エンド・ユーザーのパーソナライズ・オプションは、wwpre_api_nameパッケージおよびwwpre_api_valueパッケージを介して使用できます。

8.4.1.1 プリファレンス・ストアの使用

一般に、プリファレンス・ストレージは次のように設定できます。

  1. wwpre_api_name.create_pathを使用して、プリファレンス・パスを作成します。

  2. wwpre_api_name.create_nameを使用して、プリファレンスを作成します。

  3. プリファレンス名を指定し、値を設定するレベルを調べて、プリファレンス値を設定します。このために、wwpre_api_value.set_value_as_varchar2set_value_as_numberまたはset_value_as_dateを使用します。

  4. プリファレンス値を取得するときは常に、プリファレンスの名前およびパスを指定して、プリファレンス値を取得します。このために、wwpre_api_value.get_value_as_varchar2get_value_as_numberまたはget_value_as_dateを使用します。

8.4.1.2 プリファレンス・ストアの作成およびアクセス

PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\svcexにあるサービスの例に、プリファレンス・ストレージの実装方法を示します。この例の目的は、次の機能を実現することです。

  • 「パーソナライズ」をクリックすると、ユーザーは2つのフィールドにテキストを入力できます。

  • 1つ目のフィールドは、パーソナライズされたテキストの入力を要求します。2つ目のフィールドは、パーソナライズされたポートレットのタイトルの入力を要求します。

  • これら2つのフィールドに対してユーザーが入力した値は、プリファレンス・ストアに格納されます。

  • パーソナライズされたテキストおよびポートレットのタイトルは、ユーザーがポートレット・インスタンスを起動するたびに取得されます。

次に示すこの例を参照すると、プリファレンス・ストアの作成方法、プリファレンス・ストアに対する値の格納および取得方法がわかります。

  1. エディタで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';
    
  2. 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;
    
  3. 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;
    
  4. また、ポートレットでは、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;
    
  5. 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;
    
  6. 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;
    
  7. この例でプリファレンス・ストレージの実装に関連する、次のプロシージャおよびファンクションを確認します。

    • get_user_preference: ユーザーによってパーソナライズされたポートレットの文字列およびタイトルを取得します。

    • save_prefs: パーソナライズ変更後にユーザーが「OK」または「適用」をクリックすると、プリファレンスをプリファレンス・ストアに保存するために起動されます。

    • entered_text_is_valid: パーソナライズ可能なテキスト・フィールドに入力されたテキストが有効かどうかをチェックします。

  8. このポートレットをページに表示するのに、ポートレット・リポジトリにまだ登録していない場合は、その追加方法について8.3.2項「プロバイダ・パッケージの実装」の手順を必要に応じて参照してください。

  9. ポートレットがリポジトリに表示されたら、ページに追加してテストできます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。

8.4.2 セッション・ストアの実装

PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\svcexにあるサービスの例に、セッション・ストアの実装方法を示します。この例の目的は、次の機能を実現することです。

  • ユーザーがこのポートレットを起動すると、「このポートレットは、このセッションでx回描画されています。」というテキストが表示されます(xはポートレットがレンダリングされた回数です)。

  • ユーザーがポートレットを起動するたびに、カウンタが1ずつ増えます。

  • ポートレットで「詳細」をクリックすると、ユーザーは「消去」を使用してカウンタをリセットできます。カウンタをクリアすると、カウンタは再度0(ゼロ)から始まります。

セッション・ストアの作成およびアクセス

次に示すこの例を参照すると、セッション・ストアの作成方法、セッション・ストアに対する値の格納および取得方法がわかります。

  1. エディタで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';
    
  2. 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;
    
  3. 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;
    
  4. このポートレットをページに表示するのに、ポートレット・リポジトリにまだ登録していない場合は、その追加方法について8.3.2項「プロバイダ・パッケージの実装」の手順を必要に応じて参照してください。

  5. ポートレットがリポジトリに表示されたら、ページに追加してテストできます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。

8.5 パラメータの使用

ポートレットの機能は、パラメータを利用して拡張できます。ポートレットによって実装されたビジネス・ロジックは、ページに渡されるパラメータによって異なる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項「プライベート・ポートレット・パラメータのサポート」を参照してください。

8.5.1 プライベート・パラメータの引渡し

プライベート・ポートレット・パラメータを渡す際に、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です。プライベート・パラメータには、非修飾パラメータを使用しないことをお薦めします。

8.5.2 ページ・パラメータの引渡しとパブリック・ポートレット・パラメータのマッピング

パブリック・ポートレット・パラメータは、ページ設計者がポートレットを複数のページで再利用できるようにすることで、ポートレットの柔軟性を高めます。その結果、ページ設計者は、異なるページにポートレットを追加する際に、ポートレット・コードの変更を開発者に依頼する必要がありません。パブリック・ポートレット・パラメータを使用することで、ページ上のポートレットは、ポートレット・パラメータ名に関係なく、マップされたページ・パラメータから値を簡単に受け取ることができます。

たとえば、dept_idというページ・パラメータがあるとします。3つのポートレットでこの値が必要ですが、1つのポートレットではdept、もう1つのポートレットではdeptno、さらにもう1つのポートレットではdepartment_idという名前です。ページ・パラメータをマップすることで、3つすべてのポートレットは、dept_idパラメータから値を受け取り、適切なポートレット・パラメータに設定することができます。さらに、ページ設計者は、デフォルト値(たとえば、department 20)を設定して、その値をユーザーがパーソナライズ(たとえばdepartment 30)し、3つすべてのポートレットに適用できます。

パブリック・パラメータおよびページ・パラメータを引き渡すための一般的なモデルは、次のとおりです。

  1. pass_all_url_paramsfalseに設定して、ポートレット・レコードでパブリック・パラメータを有効にします。この設定により、ポートレットには、そのポートレットを対象とするパラメータのみが渡されます。

  2. パブリック・パラメータをプロバイダのdescribe_portlet_parametersファンクションで宣言します。プロバイダに属すポートレットごとに、このプロシージャは、ポートレットが受け入れるパラメータのリストを、次のタイプのレコードのPL/SQL表形式で戻します。

    type portlet_parameter_table is table ofportlet_parameter_record index by binary_integer;
    
  3. パラメータの説明的な情報をポートレットの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;
    
  4. パブリック・パラメータに値を割り当てます。パブリック・パラメータは、通常、ページ・パラメータを使用して値を取得します。ページ・パラメータには、通常、ページ設計者がデフォルト値を割り当て、ユーザーが実行時にその値をパーソナライズできます。あるいは、ページ・パラメータ値はコール元のURLで割り当てることができます。ページ設計者によるページ・パラメータの使用方法は、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』を参照してください。

8.5.3 パラメータ値の取得

プライベート・パラメータまたはパブリック・パラメータを使用しているかどうかに関係なく、同じ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;
    

8.6 コンテキスト情報へのアクセス

ユーザーがOracle Portalのページにアクセスするたびに、パブリック・セッションが確立されます。ユーザーがOracle Portalにログインすると、パブリック・セッションは認証済セッションになります。このセッションには、ユーザー名、現行セッションID、IPアドレス、言語設定など、ユーザーに関する複数のコンテキスト情報が含まれます。また、現在使用されているOracle Portalスキーマなどのサポート情報も含まれます。

セッション・コンテキスト・サービスは、ユーザーのセッションに関する情報を戻し、wwctx_apiパッケージを介して使用できます。

8.6.1 コンテキスト情報の使用

セッション・コンテキストを使用するための一般的なモデルは次のとおりです。

  1. 機能に必要な情報を指定します。

  2. wwctx_apiの適切なメソッドを使用して、その値を取得し、必要に応じて設定します。

表8-5に、様々なセッション情報の取得に使用されるファンクション・コールを示します。


注意:

コンテキストAPIの詳細は、PL/SQL APIリファレンスを参照してください。APIリファレンスは、Portal Center(http://portalcenter.oracle.com)か、PDK-PL/SQL (pdkplsql.zip)をダウンロードしている場合は、..\pdkplsql\pdk\plsql\docにあります。


表8-5 コンテキスト情報のファンクション・コール

セッション情報 ファンクション・コール

現行ユーザー

wwctx_api.get_user

ユーザーのログイン・ステータス

wwctx_api.is_logged_on

ログイン時間

wwctx_api.get_login_time

言語

wwctx_api.get_nls_language

現行セッションID

wwctx_api.get_sessionid

ユーザー・クライアントのIPアドレス

wwctx_api.get_ip_address

ユーザー・スキーマ

wwctx_api.get_db_user

Oracle Portalのスキーマ

wwctx_api.get_product_schema

Oracle Portalのバージョン

wwctx_api.get_product_version


8.6.2 コンテキスト情報を取得するためのwwctx_apiの使用

PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\svcexにあるサービスの例に、wwwctx_apiパッケージを使用したセッション情報の取得用法を示します。次に示すこの例を参照すると、ポートレットにファンクション・コールを実装する方法がわかります。

  1. エディタでservices_portlet.pkbファイルを開きます。

  2. get_portlet_infoファンクションを探します。

  3. ユーザー情報を導出し、ポートレット情報レコードにその値を設定するための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;
    ...
    
  4. wwctx_api.get_userは、services_portlet.pkb全体にわたって様々な場所で同じように使用されています。wwctx_api.get_userが他にないかコードを検索します。

  5. コンテキスト情報を取得する別の例が、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;
    
  6. 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);
    
  7. services_portlet.pkbを閉じます。セッション・コンテキストは、独自の機能的な要件に基づく以外は同様の方法で実装できます。

  8. このポートレットをページに表示するのに、ポートレット・リポジトリにまだ登録していない場合は、その追加方法について8.3.2項「プロバイダ・パッケージの実装」の手順を必要に応じて参照してください。

  9. ポートレットがリポジトリに表示されたら、ページに追加してテストできます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。

8.7 ポートレットのセキュリティの実装

ポートレットのセキュリティは、エンド・ユーザーによるアクセスを制御するためにポートレットで使用されるテクニックとメソッドに関係しています。ポートレットは、Oracle Portalに認証を任せ、リクエストに基づいてポータルがポートレットを適切な検証済ユーザーに戻すことを信頼しています。

Oracle Portalは、特定の権限をユーザーやグループに割り当てて、情報およびアプリケーションへのアクセスを厳しく制御します。Portalのセキュリティ・サービスを使用すると、プログラムによりアクセス制御を指定し、実行時に適切な権限があるかどうかをチェックできます。ポートレットで使用されるセキュリティ・メカニズムにより、権限を持ったユーザーのみがこれらのポートレットにアクセスできるようになります。これらのセキュリティ・サービスは、wwsec_apiパッケージを介して使用できます。

ポートレットのセキュリティは、ポートレットがポータル・ページに表示されるとき、およびデータベース・プロバイダのget_portlet_listファンクションによってポートレットがポートレット・リストで戻されるときに起動されます。Portalフレームワークのセキュリティ・サービスには、次の主要な機能があります。

8.7.1 セキュリティの使用

PL/SQLポートレットのセキュリティを実装するには、データベース・プロバイダによって実装されるファンクションis_portlet_runnableがポータルに必要です。このファンクションの実際の実装は、アプリケーションしだいです。つまり、現行ユーザーがポートレットにアクセスするために十分な権限を持っているかどうかを判断するセキュリティ方式は、個々のポートレットの実装で定義されます。また、ポータルには、現行ユーザーがアクセスできる一連のポートレットを戻す、データベース・プロバイダのファンクションget_portlet_listも必要です。

セキュリティAPIの使用のガイドライン

ポートレットのセキュリティ・メカニズムでは、コンテキストAPI、セキュリティ・サブシステムAPIおよびインフラストラクチャを使用できます。コンテキストAPIは、現行ユーザーに関する情報を取得するために使用できます。セキュリティ・サブシステムは、現行ユーザーの権限をチェックするために使用できます。


注意:

コンテキストAPIとセキュリティ・サブシステムAPIの詳細は、PL/SQL APIのリファレンスを参照してください。APIリファレンスは、Portal Center(http://portalcenter.oracle.com)か、PDK-PL/SQL (pdkplsql.zip)をダウンロードしている場合は、..\pdkplsql\pdk\plsql\docにあります。


これらの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ファンクションをコールします。このステップは、現在ログインしているユーザーが参照の権限を持っているポートレットのみを表示するために実行されます。ポートレット・リポジトリが表示される場所の一例として、「ポートレットの追加」ダイアログ内があります。

8.7.2 セキュリティのコーディング

PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\svcexにあるサービスの例に、セキュリティの実装方法を示します。次に示すこの例を参照すると、ポートレットにセキュリティ・ファンクションを実装する方法がわかります。

  1. エディタでservices_provider.pkbファイルを開きます。

  2. 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;
    
  3. get_portlet_listプロシージャを探します。get_portlet_listは、このプロバイダが実装するポートレットのリストに、ポートレットが含まれるようにします。get_portlet_listは、最初にセキュリティ・フラグ(p_security_level)をチェックし、セキュリティが有効かどうかを調べます。フラグがtrueに設定されている場合、get_portlet_listis_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;
    
  4. エディタでservices_portlet.pkbファイルを開きます。

  5. 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;
    
  6. 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;
    
  7. このポートレットをページに表示するのに、ポートレット・リポジトリにまだ登録していない場合は、その追加方法について8.3.2項「プロバイダ・パッケージの実装」の手順を必要に応じて参照してください。

  8. ポートレットがリポジトリに表示されたら、ページに追加してテストできます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。

8.8 キャッシュを使用したポートレットのパフォーマンスの向上

Oracle Portalでは、PL/SQLポートレットのキャッシュを提供しています。この機能により、PL/SQLポートレットは、Webコンテンツを中間層でキャッシュできるようになります。コンテンツに対する後続のリクエストは、データベースからの有効化の有無に関係なく、キャッシュから取得できるため、データベースのワークロードは軽減されます。

Oracle Portalでは、次の3種類のPL/SQLポートレットのキャッシュを提供しています。

Oracle Portalでは、ユーザーによるページおよびポートレットのパーソナライズがサポートされているため、ページの表示はユーザーによって異なることがあります。Oracle Portalのキャッシュは、URLがすべてのユーザーに対して同じでも、ユーザーごとに異なるコンテンツを使用できるように設計されています。そのため、ポータル・オブジェクトは、ユーザー・レベルまたはシステム・レベルでキャッシュできます。これらのキャッシュは、次のように説明できます。

データベース・プロバイダがポートレットに対するリクエストを発行すると、リクエストはポートレットのshowプロシージャに送信されます。このプロシージャは、portlet_runtime_recordをパラメータとして受け入れます。このレコード構造体には、キャッシュを有効にするためにポートレットで検査、設定できるフィールドが含まれます。このレコードのキャッシュ・コントロール・フィールドは次のとおりです。

8.8.1 キャッシュの使用

ポートレットのキャッシュを使用するための一般的なモデルは、選択するキャッシュ・タイプによって変わります。選択するキャッシュ・タイプは、ポートレットのコンテンツに大きく左右されます。ポートレットのコンテンツが非常に定期的(たとえば、毎日業務終了時)に変わる場合、通常、有効期限ベースのキャッシュを使用することは理にかなっています。ポートレットのコンテンツが不定期に変わる場合、通常、有効化ベースまたは無効化ベースのキャッシュが最適です。

8.8.1.1 有効化ベースのキャッシュ

有効化ベースのキャッシュを選択した場合の一般的なモデルは次のとおりです。

  1. portlet_runtime_recordパラメータのcaching_keyフィールドを設定します。現在のキー値とportlet_runtime_recordパラメータのcaching_keyフィールドの値を比較するチェックを追加します。showプロシージャの初回コール時、キーはNULLであるため、値を設定する必要があります。

  2. システム・レベルまたはユーザー・レベルのキャッシュのどちらを使用するかを決定します。それに応じて、portlet_runtime_recordパラメータのcaching_levelフィールドを設定します。

8.8.1.2 有効期限ベースのキャッシュ

有効期限ベースのキャッシュを選択した場合の一般的なモデルは次のとおりです。

  1. portlet_runtime_recordパラメータのcaching_periodフィールドに希望するキャッシュ間隔(分)を設定します。

  2. システム・レベルまたはユーザー・レベルのキャッシュのどちらを使用するかを決定します。それに応じて、portlet_runtime_recordパラメータのcaching_levelフィールドを設定します。

8.8.1.3 無効化ベースのキャッシュ

無効化ベースのキャッシュを選択した場合の一般的なモデルは次のとおりです。

  1. wwpro_api_provider.USE_INVALIDATIONをコールして、Oracle Web Cache用に特別なヘッダーを生成する必要があることをOracle Portalに指示します。

  2. システム・レベルまたはユーザー・レベルのキャッシュのどちらを使用するかを決定します。それに応じて、portlet_runtime_recordパラメータのcaching_levelフィールドを設定します。

  3. 必要に応じて、有効化ベースまたは有効期限ベースのキャッシュも設定します。

  4. 必要に応じて(たとえば、ポートレットがパーソナライズされたときに)ポートレットに無効化ロジックを追加し、wwpro_api_invalidationへの適切なコールを実行します。

8.8.2 キャッシュの構成と監視

キャッシュの構成方法と、パフォーマンスの監視およびチューニング方法は、『Oracle Fusion Middleware Oracle Portal管理者ガイド』を参照してください。

8.8.3 有効化ベースのキャッシュの実装

PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\cacheにあるキャッシュの例に、有効化ベースのキャッシュの実装方法を示します。次に示すこの例を参照すると、ポートレットに有効化ベースのファンクションを実装する方法がわかります。

  1. エディタでvalidcache_portlet.pkbファイルを開きます。

  2. ファイルの最上部にある、キャッシュ・レベルの定数に対する別名に注意してください。

    CREATE OR REPLACE
    package body VALIDCACHE_PORTLET
    is
        -- Caching Constants
        CACHE_LEVEL_SYSTEM constant varchar2(10) := 'SYSTEM';
        CACHE_LEVEL_USER   constant varchar2(10) := 'USER';
    
  3. showプロシージャを探します。p_portlet_recordが、このプロシージャの入出力パラメータであることに注意してください。

    procedure show
    (
        p_portlet_record   in out     wwpro_api_provider.portlet_runtime_record
    )
    
  4. プロシージャのセキュリティ・チェックで、セキュリティ・チェックが失敗した場合、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;
    
  5. その後に、プロシージャはget_cache_keyファンクションをコールして、キャッシュ・キーの値を取得し、一時値に割り当てます。

        --
        -- CACHE IS VALID?
        --
        l_cache_key := get_cache_key();
    
  6. 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;
    
  7. 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. このポートレットをページに表示するのに、ポートレット・リポジトリにまだ登録していない場合は、その追加方法について8.3.2項「プロバイダ・パッケージの実装」の手順を必要に応じて参照してください。

  9. ポートレットがリポジトリに表示されたら、ページに追加してテストできます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。

8.8.4 有効期限ベースのキャッシュの実装

PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\cacheにあるキャッシュの例に、有効期限ベースのキャッシュの実装方法を示します。次に示すこの例を参照すると、ポートレットに有効期限ベースのファンクションを実装する方法がわかります。

  1. エディタでexpirycache_portlet.pkbファイルを開きます。

  2. ファイルの最上部にある、キャッシュ・レベルの定数に対する別名に注意してください。

    CREATE OR REPLACE
    package body VALIDCACHE_PORTLET
    is
        -- Caching Constants
        CACHE_LEVEL_SYSTEM constant varchar2(10) := 'SYSTEM';
        CACHE_LEVEL_USER   constant varchar2(10) := 'USER';
    
  3. showプロシージャを探します。p_portlet_recordが、このプロシージャの入出力パラメータであることに注意してください。

    procedure show
    (
        p_portlet_record   in out     wwpro_api_provider.portlet_runtime_record
    )
    
  4. プロシージャのセキュリティ・チェックで、セキュリティ・チェックが失敗した場合、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;
    
  5. その後に、プロシージャは、次のように、キャッシュ期間の値(分)を一時変数で設定します。

       -- Set the Caching Period to one minute 
       l_cache_period := 1;
    
  6. 次に、コードで、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;
    
  7. このポートレットをページに表示するのに、ポートレット・リポジトリにまだ登録していない場合は、その追加方法について8.3.2項「プロバイダ・パッケージの実装」の手順を必要に応じて参照してください。

  8. ポートレットがリポジトリに表示されたら、ページに追加してテストできます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。

8.8.5 無効化ベースのキャッシュの実装

世界地図を表示するポートレット(map_portlet.pkbmap_portlet.pks)があるとします。無効化ベースのファンクションをそのポートレットに追加する手順は次のとおりです。

  1. 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;
    ...
    
  2. キャッシュを無効化するプロシージャを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;
    
  3. 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)
    );
    
  4. このポートレットをページに表示するのに、ポートレット・リポジトリにまだ登録していない場合は、その追加方法について8.3.2項「プロバイダ・パッケージの実装」の手順を必要に応じて参照してください。

  5. ポートレットがリポジトリに表示されたら、ページに追加してテストできます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。

8.9 エラー処理の実装

Oracle Portalには、誤った入力をトラップし、重要なエラー・メッセージを戻すための機能があります。内部エラー・スタックは、発生した例外を追跡し、その情報を保持することで管理されます。また、Oracle Portalには、エラーを標準化された方法で提示する一連のAPIが付属しています。

エラー処理サービスは、wwerr_api_errorパッケージおよびwwerr_api_error_uiパッケージを介して使用できます。これらのエラー処理サービスには、次の主要な機能があります。

8.9.1 エラー処理の使用

一般に、次のようにエラー処理を設定します。

  1. エラーの検出時に、wwerr_api_error.addプロシージャを使用して、エラー・メッセージを適切なドメインとサブドメインを組み合せてスタックに追加します。

  2. 必要に応じて(たとえば、ルーチンの終了時)、wwerr_api_error_uiプロシージャを使用して、エラー・メッセージを公開します。全画面メッセージを表示するには、希望する出力タイプに応じて、プロシージャshow_htmlshow_xmlまたはshow_textを使用します。インライン・メッセージを表示するには、希望する出力タイプに応じて、プロシージャshow_inline_htmlshow_inline_xmlまたはshow_inline_textを使用します。

エラー処理のガイドライン

エラー処理を実装する際は、次の事柄に注意してください。

  • 独自のエラー・メッセージを定義している場合、これらのメッセージには独自のエラー・ドメインを使用します。独自のエラー・メッセージには、WWCWWVまたはWWSドメインを使用しないでください。これらのメッセージを他の言語の表にロードするには、小規模のローダー・スクリプトを作成する必要があります。

  • 不必要なエラー・メッセージは避けます。ファンクションで何もしない場合は、エラーではなくnullを戻します。たとえば、プロバイダで他のポートレットすべてに対してcopy_portletプロシージャをコールするので、自分のポートレット用のcopy_portletプロシージャをコーディングしているとします。この特別なポートレット用のcopy_portletプロシージャで何もしない場合は、nullを戻します。エラーを戻すと、ポートレットの機能を不用意に妨害することになります。

  • 最大10のエラー・メッセージをスタックに保持できます。10を超えて、wwerr_api_error.addがコールされると、メッセージは無視されます。

  • APIは、問題を発見するプログラム的な方法として使用します。このために、ユーザー・インタフェース以外の形式を使用できます。たとえば、プログラムを使用してプロバイダを登録するとき、例外ブロックでは、get_text_stackを使用して、エラー・メッセージを取得し、出力できます。この方法は、デバッグでパブリックAPIをコールする際に役立ちます。というのも、すべてのパブリックAPIが例外用のスタックにエラーを追加するためです。

  • 独自のエラー・メッセージ用に他の言語の文字列を必ず生成してください。詳細は、8.11項「多言語ポートレットの作成」を参照してください。

  • エラー・メッセージの標準的なユーザー・インタフェースには、前ページに戻るナビゲーション・リンクが用意されています。また、特定のヘルプのURLに対する「ヘルプ」アイコンも含まれます。

8.9.2 エラー処理の追加

PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\svcexにあるサービスの例に、エラー処理の実装方法を示します。次の例を参照すると、ポートレットにエラー処理ファンクションを実装する方法がわかります。

  1. エディタでservices_portlet.pkbファイルを開きます。

  2. ポートレット定義の定数部で、エラー・メッセージのドメインおよびサブドメインの定義に別名を指定します。

    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';
    
  3. 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;
    
  4. 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;
    
  5. 最後に、showプロシージャは、汎用エラー・メッセージを例外ハンドラに実装し、前の条件ではトラップされなかったエラーを捕捉します。

    exception
        when others then
            wwerr_api_error.add(
                DOMAIN, SUBDOMAIN,
                'generalerr', 'services_portlet.show');
            raise wwpro_api_provider.PORTLET_EXECUTION_EXCEPTION;
    end show;
    
  6. エラー処理は、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;
    
  7. このポートレットをページに表示するのに、ポートレット・リポジトリにまだ登録していない場合は、その追加方法について8.3.2項「プロバイダ・パッケージの実装」の手順を必要に応じて参照してください。

  8. ポートレットがリポジトリに表示されたら、ページに追加してテストできます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。

8.10 イベント・ロギングの実装

Oracle Portalは、トランザクション時に発生したイベントをオブジェクトとともにログに記録できます。これらのログはデータベースに格納されるため、標準的なSQLコールおよびレポート作成ツールを介して使用できます。

ログに記録するイベントや、ユーザー定義のドメインおよびサブドメインに基づいて全面的に編成するイベントを選択できます。ログに記録されたイベントについては、イベント、イベントの開始/停止時間、リモート・ユーザーのホストまたはIPアドレス、ブラウザ・タイプおよび言語に関する情報を表示できます。

イベント・ロギング・サービスは、wwlog_apiパッケージおよびwwlog_api_adminパッケージを介して使用できます。これらのサービスには、次の主要な機能があります。

8.10.1 イベント・ロギングの使用

一般に、イベント・ロギングは次のように設定できます。

  1. wwlog_api_admin.add_log_eventを使用して、適切なドメインとサブドメインを組み合せてイベント・オブジェクトを追加します。イベントを追加することで、ユーザーがイベントを監視しているときに呼び出される値のリストや他のユーザー・インタフェースのコンポーネントのリストに、この新しいイベントが確実に表示されます。

  2. wwlog_api_admin.add_log_registryを使用して、ログ・イベント・レコードを登録します。ログ・レジストリ・レコードは、ログに記録する予定のイベントを表し、ログに記録する必要があるイベントをフィルタ処理する手段を提供します。

  3. コードでstart_logおよびstop_logを使用し、ログに記録するイベントをマークします。あるいは、単一ステップ・イベントのログ情報を入力する場合は、ログ・メソッドをコールしてそのイベントをマークします。

イベント・ロギングのガイドライン

イベント・ロギングを実装する際は、次の事柄に注意してください。

  • パフォーマンスを向上させるために、本当に関心があることのみをログに記録します。不要なログ・メッセージが、システムにあふれないようにします。イベントが表示モードでログに記録される場合は、これらのポートレットの複数のインスタンスが、データベースに対して余計にヒットします。

  • ドメイン、サブドメインおよびログ・イベントを注意深く選択します。ログAPIを使用する際は、独自のログ・メッセージに、WWCWWVWWSなどのOracle Portalドメインを使用しないでください。ドメインおよびサブドメインを階層的に編成すると、ポートレット間で確実に一意になります。他のポートレットで同じドメインまたはサブドメインの使用が発生した場合、それらのログ・メッセージの間に独自のログ・メッセージが散らばって表示されます。

  • ログの監視時に値のポップアップ・リストに表示されるログ・イベントを作成します。また、特定のイベントを指定するか、ワイルド・カード(%)を指定した汎用フィルタを使用して、実際にログに記録されるイベントをフィルタ処理するログ・レジストリ・レコードが簡単に作成できます。ログ・レジストリ・レコードの作成とは別に、監視するイベントについてログ・イベントを作成することをお薦めします。この方法で、ユーザー・インタフェースの値のリストに、監視などの追加機能に対するこれらのレコードが表示されます。

  • ログの監視が必要なユーザーまたはユーザー・グループに必要な権限を付与します。ユーザーが作成したログは、そのユーザー、ポータル管理者、およびANY_LOGSオブジェクト・タイプに対して編集の権限を持つユーザーが表示できます。

8.10.2 イベント・ロギングの追加

PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\svcexにあるサービスの例に、イベント・ロギングの実装方法を示します。次に示すこの例を参照すると、ポートレットにイベント・ロギング・ファンクションを実装する方法がわかります。

  1. エディタで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';
    
  2. 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;
    
  3. 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);
    ...
    
  4. このポートレットをページに表示するのに、ポートレット・リポジトリにまだ登録していない場合は、その追加方法について8.3.2項「プロバイダ・パッケージの実装」の手順を必要に応じて参照してください。

  5. ポートレットがリポジトリに表示されたら、ページに追加してテストできます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。

8.11 多言語ポートレットの作成

Oracle Portalには、Oracle Portalの多言語ストレージ機能とやり取りするための堅牢な一連のAPIがあります。このストレージ機能は、異なる言語で文字列を格納および取得するためのメカニズムを提供しています。これらのAPIは、ネイティブの多言語機能を抽出し、異なる言語環境をサポートするプロバイダを開発するために開発者に強力なストレージ・メカニズムを提供します。

多言語サービスは、wwnls_apiパッケージを介して使用できます。これらのサービスには、次の主要な機能があります。

たとえば、プロバイダのregisterプロシージャでポートレット・タイトルについて英語とフランス語の翻訳をロードしたとします。ポートレットがレンダリングされると、プロバイダの実装では、ポートレット・タイトルの文字列を表から取得し、次の結果が表示されます。

8.11.1 多言語サポートの使用

一般に、多言語サポートは次のように設定できます。

  1. 使用する各言語に対応する文字列を使用して、文字列定義をデータベースにロードします。このために、ドメイン、サブドメイン、エラー・メッセージ名およびエラー・テキストの組合せを設定して、wwnls_api.add_stringまたはwwnls_api.set_stringをコールします。

  2. 希望する言語について、wwnls_api.get_stringを使用し、必要な文字列を取得します。

8.11.2 多言語サポートの追加

多言語サポートを追加する手順は、次のとおりです。

8.11.2.1 言語文字列のロード

言語文字列は、プロバイダのインストールの一部であるスクリプトによってロードできます。このスクリプトは、add_stringおよびset_stringをコールして、異なる言語の対応する文字列を作成します。

Oracle Portalは、ドメイン、サブドメインおよび名前の組合せを使用して、言語文字列を一意に識別します。ドメインとサブドメインにより、文字列の分類方法が提供されます。ドメインとサブドメインは、APIの他のユーザーと競合しない程度に一意である必要があります。

  • ドメインは、製品の特定エリアです。ドメインの例には、プロバイダやページ・グループがあります。

  • サブドメインは、ドメインのサブシステムです。サブドメインの例には、プロバイダ名(HelloProviderなど)やサブページ名(HelloPageなど)があります。

PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\svcexにあるサービスの例に、多言語サポートの実装方法を示します。次に示すこの例を参照すると、多言語サポート用の文字列をロードする方法がわかります。

  1. エディタでservices_seed.sqlファイルを開きます。

  2. ドメイン名、サブドメイン名、文字列名、言語および実際の文字列テキストのパラメータを設定した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');
    

8.11.2.2 言語文字列の取得

PDK-PL/SQL (pdkplsql.zip)の..\pdkplsql\pdk\plsql\svcexにあるサービスの例に、多言語サポートの実装方法を示します。次に示すこの例を参照すると、多言語サポート用の文字列を取得する方法がわかります。

  1. エディタでservices_portlet.pkbファイルを開きます。

  2. ポートレット定義の定数部で、言語文字列のドメインおよびサブドメインの定義に別名を指定します。

    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';
    
  3. 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
                );
    ...
    
  4. services_portlet.pkbファイルの残りの部分を参照し、別の場所でも使用されているwwnls_api.get_stringの他の使用例を調査します。

  5. このポートレットをページに表示するのに、ポートレット・リポジトリにまだ登録していない場合は、その追加方法について8.3.2項「プロバイダ・パッケージの実装」の手順を必要に応じて参照してください。

  6. ポートレットがリポジトリに表示されたら、ページに追加してテストできます。ポートレットをページに追加するには、『Oracle Fusion Middleware Oracle Portalユーザーズ・ガイド』の指示に従ってください。

8.12 ポートレットのモバイル機器用拡張

この項では、PDK-PL/SQLを使用してポートレットをモバイル機器用に拡張する手順を説明します。この項を読み進める前に、モバイル対応ポートレットの構築に関するガイドライン(8.1.3項「モバイル・ポートレットのガイドライン」)およびPDK-PL/SQLを使用してポートレットを構築する方法(8.2項「PL/SQLジェネレータを使用したPL/SQLポートレットの構築」および8.3項「手動によるPL/SQLポートレットの構築」)についてよく理解しておく必要があります。

モバイル機器のポートレットを正しく構築する手順は、次のとおりです。

  1. ポートレット・レコード属性をモバイル出力可能に設定します。モバイル機器からモバイル・ゲートウェイを介して到着するリクエストには、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で詳しく説明します。


  2. ポートレットでは、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ヘッダーはtext/vnd.oracle.mobilexmlに設定されています。OracleAS Wireless XMLマークアップでは、コンテンツをそのままレンダリングするのみで済みます。Oracle Portalにより、コンテンツが完全なOracleAS Wireless XMLドキュメントとして表示されます。<SimpleResult>タグまたは<SimpleContainer>タグは必要ありません。これらのタグは、Oracle Portalによって「戻る」のリンクとともにレンダリングされます。「戻る」のリンクは、モバイル機器上でボタンの1つにデフォルトで割り当てられます。


  3. ポートレットでモバイル・レンダリング用にタイトルのパーソナライズを可能にするには、リンク・モードを実装する必要があります。リンク・モードは、モバイル・リクエストに対してのみコールされ、ポートレット・コンテンツへのリンクをレンダリングします。このリンクは、ユーザーが初めてページにナビゲートしたときに、そのページ・コンテンツのメニューに表示されます。ポートレットにリンク・モードが実装されていない場合は、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-7 DeviceClassヘッダーの値

説明
voice

音声アクセス番号をコールする通常の電話など、音声専用デバイスを示します。

microbrowser

WAP電話など、マークアップ・ブラウザをサポートする小型サイズの表示デバイスを示します。

pdabrowser

PalmまたはPocketPCなど、中型サイズの表示デバイスを示します。

pcbrowser

デスクトップ・ブラウザを使用する大型サイズの表示デバイスを示します。


8.13 プログラムを使用したプロバイダの登録

プロバイダを登録するには、ほとんどの場合、8.2.3.2項「データベース・プロバイダの登録」で説明したようにOracle Portalのユーザー・インタフェースを使用します。ただし、場合によっては、ユーザー・インタフェースを使用するのではなく、プログラムを使用してプロバイダを登録できます。この項では、次のようにwwpro_api_provider_registry.register_providerを使用してプロバイダを登録する方法を説明します。

8.13.1 登録の前提条件

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スキーマの所有者になっています。(wwctx_api.set_contextが別のユーザーによって呼び出された場合を除く)。スキーマの所有者には、wwpro_api_provider_registry.register_providerの実行に必要な権限がすでに備わっています。


8.13.2 プロバイダ・レコードの入力

wwpro_api_provider_registry.register_provider APIは、入力としてprovider_recordを必要とします。provider_recordregister_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の場合は、いいえ。

なし。


8.13.3 登録の例

次のサンプル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;
/

注意:

プロバイダを登録したら、wwpro_api_provider_registry.refresh_portlet_repositoryまたはOracle Portalのユーザー・インタフェースを使用して、プログラム的にポートレット・リポジトリをリフレッシュすることもできます。