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

前
 
次
 

63 Oracle WebCenter Portalのページレット・プロデューサを使用したページレットの作成

ページレットは、再使用可能なユーザー・インタフェース・コンポーネントです。任意のHTMLフラグメントをページレットにできますが、ページレット開発者は、パラメータ化された構成可能なページレットを記述し、その他のページレットと動的にやりとりし、ユーザー入力に応答するようにすることもできます。ページレットは、ポートレットに似ていますが、ポートレットがポータル専用に設計されていることに対して、ページレットは、ポータルやその他のWebアプリケーションを含め、あらゆるWebページで実行できます。ページレットを使用すれば、他のWeb環境でプラットフォーム固有のポートレットを公開できます。

Oracle WebCenter Portalのページレット・プロデューサ(旧Oracle WebCenter Ensemble)は、動的なページレット開発を容易にする有用なツールと機能のコレクションを提供します。この章では、ページレット・プロデューサを使用したページレットの開発および構成の詳細について説明します。

63.1 サーバー通信とプロキシの概要

ページレット・プロデューサはプロキシ・サーバーとして動作し、クライアント・コンピュータと外部リソース間のトランザクションを仲介(ブローカ)します。

外部リソースのサービスは、HTTP経由でページレット・プロデューサと通信します。たとえば、ブラウザがページをリクエストすると、ページレット・プロデューサが各外部リソースに対する同時リクエストを作成し、ページからページレット・コンテンツを取得します。外部リソースは、現在のユーザーのプリファレンスをページレット・プロデューサから送信されたHTTPヘッダーから読取り、適切なHTMLを戻します。ページレット・プロデューサはHTMLをページ・マークアップに挿入します。イメージ・サービスに格納されたイメージは、ブラウザによって取得、表示されます。

63.1.1 ページレット・プロデューサのプロキシ

プロキシ・サーバーは仲介サーバーとして機能し、クライアント・コンピュータと別のサーバー間のトランザクションを仲介(ブローカ)します。この構成は、通常、本来は外部リソースにアクセスできないクライアントにコンテンツを提供するために使用されます。ただし、これを使用して、ポリシーの使用などのセキュリティ制限をクライアントに対して追加で課すことができます。プロキシは外部リソースを隠すため、エンド・ユーザーには、コンテンツがプロキシ・サーバーから直接提供されているように見えます。

このアーキテクチャにより、ページレット・プロデューサはコンテンツの単一アクセス・ポイントとなり、外部リソースがプライベート・ネットワークやファイアウォールの内側に存在できるようになります。ページレット・プロデューサが外部リソースに接続できるかぎり、ユーザーはコンテンツに直接アクセスできない場合でも、そのコンテンツを表示できます。ブラウザにとっては、ページレット・プロデューサは外部リソースのコンテンツのソースであるように見えます。

ユーザーがサービスとやりとりすると、プロキシ内でURLに対して作成されたリクエストが、ページレット・プロデューサを通じて自動的にリルートされます。ユーザーには、コンテンツはページレット・プロデューサからもたらされたように見えます。外部リソースは未知のバックエンド・システムです。

この構成には多くのメリットがあります。サービスに最も役に立つメリットは次のとおりです。

  • 動的な機能とパーソナライズ: ページレット・プロデューサは、ページレットからリクエストをインターセプトします。これにより、MDSに格納されている情報をHTTPリクエストとレスポンスに組み込むことができます。

  • セキュリティ: サービスを使用すると、ユーザーはパブリックに使用できないコンテンツにアクセスできます。特定のURLをプロキシの構成に含めることにより、保護されたサーバーに格納されているファイルが使用可能になります。注意: プロキシは強力な機能であるため、構成が正しくないと、セキュリティが侵害される可能性があります。非保護のプライベート接続をホストする外部リソースへの直接アクセスを許可すると、危険なセキュリティ・ホールが生じる可能性があります。

  • パフォーマンス: ページレット・プロデューサはプロキシ・コンテンツをキャッシュし、エンド・ユーザーに対するレスポンス時間を短縮し、外部リソースのパフォーマンスを向上します。プロキシはHTMLなどのコンテンツに対しては効率的に機能しますが、静的イメージなどのバイナリ・データには通常は適していません。イメージは変換する必要がないため、大きなイメージをプロキシすると、パフォーマンスに悪影響を与える可能性があります。これが、イメージ・サービスを使用してプロキシ経由での静的イメージのルーティングを避ける必要がある1つの理由です。

サービス用にプロキシする必要があるURLのコレクションは、リソース・エディタで構成されます。リソース用に構成された内部URL接頭辞を使用する、またはプロキシされた別のCSPやWebリソースを指すすべてのURLは、「URL再書きこみの有効化」の選択を解除しないかぎり、プロキシされます。

プロキシを使用するサービスを実装する場合は、次の警告とベスト・プラクティスに留意してください。

  • URL変換: ページレット・プロデューサは、プロキシされるURLを正確に開くため、コードを変換する必要があります。ページレット・プロデューサは、レスポンスを送信する前に、HTMLを解析し、関連するプロデューサ・リソース用に構成された内部URL接頭辞を使用するURLを探します。ページレット・プロデューサは、レスポンスをクライアントに返す前に、プロキシするURLを変換します。関連するURLは、正しい場所を指すように変換されます。

  • スクリプト制限: URLを動的に作成するJavaScript構成は、コンテンツがすでに変換された後で実行されるため、問題を引き起こす可能性があります。VBScriptはプロキシによって変換されません。動的スクリプトとVBスクリプトは、コードがプロキシ対応しているかぎり引き続き使用できます。パーサーとWebインジェクタは、URLリライトに対するターゲットのコントロールを実装するために使用できます。パーサーとWebインジェクタの構成の詳細は、『Oracle Fusion Middleware Oracle WebCenter Portal管理者ガイド』「Oracle WebCenter Portalのページレット・プロデューサの管理」の章を参照してください。

  • URLのエンコーディング: 予期しない変換を防ぐためのベスト・プラクティスは、URLであるすべてのヘッダーをエンコードすることです。JSPでは、記述されているすべてのURLをエンコードします。ページのボディ内にコードでURLが記述されている場合(プリファレンス・ページへのリンクなど)は、エンコードする必要があります。標準のJavaサーブレット・コマンドであるresponse.encodeURL()が優先されるメソッドですが、URLEncoder.encode(url)も使用できます。.NET Frameworkでは、HttpUtility.URLEncodeクラスに必要な機能が備わっています。注意: .NETでは、リダイレクトURLをエンコードする必要はありません。これは、バック・エンドで自動的に処理されるからです。

63.1.1.1 ページレットとプロキシの概要

すべてのページレットは、他のページレットと一緒に表示されるように設計されています。前の項で説明したように、ページレット・プロデューサはプロキシとして機能し、複数のアプリケーションのページレットを処理して組み合せ、様々な機能を持つ単一の統合されたページを作成します。

ページレットが返したコードはページレット・プロデューサ・サーバーによって解析され、ページを構成するHTMLマークアップに挿入されます。同じバックエンド・アプリケーションのページレットは、ページ内で互いにやりとりできます。

63.1.2 HTTPとCSPについて

HTTPはWebページのコンテンツとXMLをサーバーとクライアント間で送信するためにもっぱら使用されるプロトコルです。CSPは、オープン標準であるHTTP 1.1に基づいたプラットフォームに依存しないプロトコルで、ページレット・プロデューサと外部CSPリソース間の通信構文を定義します。

63.1.2.1 HTTP

HTTP通信は、リクエストとレスポンスで構成されます。リクエストとレスポンスは、基本的にはヘッダー内のメタデータの名前/値ペアのリストで、オプションでボディが付いています。ボディは、送信されているデータ(HTMLページまたはXMLファイル)です。ヘッダー内のメタデータは、リクエストまたはレスポンス自体の情報(コンテンツを表示する言語、ブラウザがコンテンツをキャッシュする期間など)です。リクエストとレスポンスには、それぞれ、次に概説される固有の情報が含まれています。HTTPの詳細は、RFC 2616を参照してください(http://www.faqs.org/rfcs/rfc2616.html)。

クライアントはサーバーにHTTPリクエストを送信し、コンテンツを要求します。リクエスト・ボディは、POSTやPUTなど、サーバーにデータを送信するリクエストにのみ使用されます。

HTTPリクエストの形式:

[METHOD] [REQUEST-URI] HTTP/[VERSION]
[fieldname1]: [field-value1]
[fieldname2]: [field-value2]
[request body, if any]

HTTPリクエストの例:

GET /index.html HTTP/1.1 
Host: www.plumtree.com 
User-Agent: Mozilla/3.0 (compatible; Opera/3.0; Windows 95/NT4) 
Accept: */* 
Cookie: username=JoeSmith

サーバーは、ページ・コンテンツ、およびコンテンツのタイプ、ドキュメントの最終変更時期、サーバー・タイプなどの重要な詳細を含むHTTPレスポンスを返します。リクエストされたコンテンツが見つからない場合は、レスポンスにエラー・メッセージが含まれます。

HTTPレスポンスの形式:

HTTP/[VERSION] [CODE] [TEXT] 
[fieldname1]: [field-value1] 
[fieldname2]: [field-value2] 
[response body, if any (document content here)]

HTTPレスポンスの例:

HTTP/1.0 200 Found 
Last-modified: Thursday, 20-Nov-97 10:44:53 
Content-length: 6372 
Content-type: text/html 
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 3.2 Final// EN'><HTML> 
...followed by document content...

カスタムHTTPヘッダーを、特殊な情報を格納するように構成できます。


注意:

ヘッダー・サイズ制限は、コードをホストするサーバーによって制御されます。IIS/ASPの標準的な制限は60Kです。Javaアプリケーション・サーバーの場合は、2Kから10Kです。これらの制限は、通常構成可能です。詳細は、サーバーのドキュメントを参照してください。


サービスからも、Set-CookieヘッダーやHTTP 1.1 Basic認証ヘッダーなどの標準のHTTPヘッダーにアクセスできます。HTTPをさらに調べる場合は、ロギングを使用して、ブラウザとWebサーバー間でやりとりされるすべてのヘッダーを表示できます(第63.3.4項「ページレットのデバッグ」を参照)。HTTPは、SSLとともに使用され、セキュアなコンテンツを提供します。また、シングル・サインオン(SSO)でもBasic認証用のHTTPヘッダーが使用されます。

63.1.2.2 CSP

CSPはHTTPを拡張し、固有ヘッダーを定義してページレット・プロデューサと外部CSPリソース(つまり、Oracle WebCenter Interactionポートレット)間で設定を受け渡しします。CSPでは、これらのサービスがHTTPを使用して設定を通信および変更する方法の概略を記述します。最新バージョンの1.4は次の場所で入手できます: http://download.oracle.com/docs/cd/E13158_01/alui/wci/docs103/devguide/references/CSP1.4.pdf

システムとユーザー構成変数の通信に使用されるカスタムCSPヘッダーは、ページレットでも使用できます。

表63-1 ページレット・プロデューサのヘッダー

ヘッダー名 説明

ユーザーID

現在ログインしているユーザーのユーザーID。この値は、セッションが期限切れかどうかの判断に使用できます。UserID=2の場合は、デフォルトのGuestユーザーがログインしています。その他のユーザーのセッションは終了しています。

ユーザー名

ログインしているユーザーの名前。ユーザー名は、表示のパーソナライズやフォーム・フィールドの事前指定に使用できます。

イメージ・サービスのURL

ページレット・プロデューサのユーザー実装での、イメージ・サービスの仮想ルート・ディレクトリのURL。この場所は、サービスで使用されるすべての静的イメージに使用する必要があります。

スタイルシートのURL

現在のユーザーのスタイルシートのURL。ページレット・プロデューサの実装ごとに、UIはカスタマイズされます。一部のポータルでは、ユーザーはスタイルシートの中から選択できます。これらのスタイルを使用すると、ページレットが、現在のユーザーによるページレット・プロデューサの実装スタイルで表示されます。

ページレットID

現在のリソース(ページレット)のID、および現在のページレットのインスタンスID。この値は、HTMLフォームおよびクライアント側JavaScript機能の名前に追加し、ページ上のフォームや機能の一意の名前を確保して名前の競合を回避するために役立ちます。

ホスト・ページのURL

ページレットをホストするページのURL。設定の構成後にユーザーを正しいページに戻すために、プリファレンス・ページにはこのURLが必要です。この値を使用して、単一のページレットで様々なページに各種コンテンツを表示できるようにすることもできます。


63.2 Webアプリケーションでのページレットの使用

この項では、ページレットをJDeveloperのJSFページ、WebページまたはWebCenter Portal: Spacesのページに追加する方法について説明します。ページレットを任意のWebアプリケーションに追加する前に、『Oracle Fusion Middleware Oracle WebCenter Portal管理者ガイド』で説明されているように、ページレット・プロデューサでリソースとページレットをデプロイして構成する必要があります。

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

63.2.1 Oracle JDeveloperでのJSFページへのページレットの追加

Oracle JDeveloperを使用すると、JSFページにページレットをドラッグ・アンド・ドロップできます。この項では、ページレット・プロデューサをWebCenter Portal: Frameworkアプリケーションに登録し、ページレットをJSFページに追加し、ブラウザでページを表示してページレットをテストします。

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

63.2.1.1 WebCenter Portal: Frameworkアプリケーションへのページレット・プロデューサの登録

ページレットをJSFページに追加する前に、ページレット・プロデューサをアプリケーションに登録する必要があります。ページレット・プロデューサは次の2つの方法で登録できます。

  • 特定のアプリケーションにプロデューサを登録。デフォルトでは、「アプリケーション・リソース」パネル下に接続を作成する「新規Pagelet Producer」ダイアログで、「IDE接続」オプションが選択されています。

  • 「リソース・パレット」を使用してプロデューサを登録。このオプションを使用すると、プロデューサのページレットを複数のアプリケーションで使用できます。「リソース・パレット」で使用可能なページレットは、ページ上にドロップすることにより、任意のFrameworkアプリケーションに追加できます。「リソース・パレット」からページレットを追加する際、まだ登録されていない場合には、そのプロデューサはアプリケーションに登録されます。アプリケーション・ナビゲータの「アプリケーション・リソース」パネルに、「リソース・パレット」からプロデューサ接続全体をドラッグ・アンド・ドロップすることもできます。これにより、プロデューサがアプリケーションに登録されます。または、「リソース・パレット」でプロデューサを右クリックし、コンテキスト・メニューから「アプリケーションに追加」を選択してプロデューサを現在開いているアプリケーションに登録します。

Oracle JDeveloperを使用してページレット・プロデューサを登録する手順は次のとおりです。

  1. アプリケーション・ナビゲータの「アプリケーション・リソース」パネルで、「接続」を右クリックして「接続の作成」を選択し、「ページレット・プロデューサ」を選択します。

    「リソース・パレット」からの起動など、ウィザードを起動するその他の方法については、第1.6.2項「接続ウィザードにアクセスする方法」を参照してください。

  2. 「新規Pagelet Producer」ダイアログの「名前」フィールドに、意味のわかりやすいプロデューサ名を入力します。たとえば、myPageletProducerと入力します。

  3. 「URL」フィールドに、ページレット・プロデューサのURLをhttp://hostname:portnumber/pageletsの形式で入力します。

  4. 「OK」をクリックします。図63-1に示すように、ページレット・プロデューサは、「アプリケーション・リソース」パネルの「接続」ディレクトリの「ページレット・プロデューサ」ディレクトリの下に作成されます。

    図63-1 「アプリケーション・リソース」パネルのページレット・プロデューサ

    図63-1の説明が続きます
    「図63-1 「アプリケーション・リソース」パネルのページレット・プロデューサ」の説明

63.2.1.2 JSFページへのページレットの追加

ページレットをページに追加する手順は次のとおりです。

  1. JDeveloperで、JSFページがまだ開いていない場合は、そのページを「デザイン・ビュー」で開きます。

  2. 「アプリケーション・リソース」パネルまたは「リソース・パレット」の「IDEリソース」パネルに進みます。「ページレット・プロデューサ」で、プロデューサを開いてそのコンテンツを表示します。

  3. プロデューサのコンテンツから、JSFページにページレットをドロップします。

  4. このページレットでIFRAMEを有効化する場合は、「ページレットのページへの追加」ダイアログの「IFrameの使用」セクションで「はい」を選択します。

  5. 「IFrameの高さ」フィールドで、必要な高さをピクセルで指定するか、空白のままにします。また、高さをautoに指定して自動サイズ変更を使用することもできます。(このオプションを使用するには、IFrameサイズ変更ページをプロジェクトに追加する必要があります。詳細は、第63.2.2.3項「IFrameへの自動サイズ変更の使用」を参照してください。)「OK」をクリックします。

  6. 「タスク・フロー・バインディングの編集」ダイアログでは、入力パラメータがデフォルトで指定されています。必要に応じて任意のパラメータを変更し、「OK」をクリックします。

  7. ページを保存します。「構造」ウィンドウでは、ページは図63-2のように表示されます。

    図63-2 「構造」ウィンドウのページレット

    図63-2の説明が続きます
    「図63-2 「構造」ウィンドウのページレット」の説明

  8. アプリケーション・ナビゲータの「プロジェクト」で該当のJSFページを右クリックし、「実行」を選択します。

  9. ログイン・ページが表示される場合は、ユーザー名とパスワードを入力しページレットを表示できるようにします。図63-3に、ブラウザ・ウィンドウのサンプル・ページレットを示します。

    図63-3 サンプル・ページレット

    図63-3の説明が続きます
    「図63-3 サンプル・ページレット」の説明

63.2.1.3 ページレットの保護

ページレットの保護の詳細は、『Oracle Fusion Middleware Oracle WebCenter Portal管理者ガイド』のポリシーに関する項およびOracle Single Sign-On (OSSO)の構成に関する項を参照してください。

63.2.2 Webページへのページレットの追加

ページレットをデプロイすると、JavaScriptまたはRESTを使用してページレットをプロキシされたページやプロキシされていないページのどちらにも挿入できます。

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

63.2.2.1 JavaScriptを使用したページレットの挿入

簡単なJavaScript機能を使用して、ページレットをプロキシされていないページに挿入できます。

この機能をアクティブにするには、次のHTMLスニペットをページの<HEAD>セクションに追加します。

<script type="text/javascript" src="http://proxy:port/pagelets/inject/v2/csapi">
</script>

このスクリプトを実行すると、すべてのCSAPIおよびページレット注入関数がページレットを表示するページに注入されます。注入されたセクションの1つには、次の関数があります。

function injectpagelet(library, name, iframe_options, payload, params, context_id, element_id,  is_in_community, chrome, forward_params)
{
    ...
}

この関数は、ページレットをウィジェットとして親ページに注入します。メソッド・インタフェースでは、次のパラメータが使用されます。

  • library: 必須。注入するページレットのライブラリ名を表す文字列です。Unicode文字と数字のみ使用でき、スペースを含めることはできません。

  • name: 必須。注入するページレットの名前を表す文字列です。Unicode文字と数字のみ使用でき、スペースを含めることはできません。

  • iframe_options: ページレット・コンテンツの周囲にIFRAMEを使用するかどうかを指定します。IFRAMEオプションのサンプルは、iframe width=100% height=auto frameborder=0のようになります。省略または空白のままにすると、ページレット・コンテンツがインラインにレンダリングされます。

  • payload: ページレット・リクエストで送信するXMLペイロード。

  • params: 問合せ文字列形式のページレット・パラメータ。たとえば、'param1=value1&param2=value2&param3=value3'のようになります。

  • context_id: ページレット・インスタンスの外部識別子で、プリファレンスのスコープをページレット・プロデューサ・サーバーに設定するために使用されます。整数を指定する必要があります。

  • element_id: ページレット・コンテンツの注入先のHTML要素IDです。省略されたまたは空白のままの場合は、injectpageletコールが評価された場合に、document.write()を使用してページレット・コンテンツが注入されます。

  • is_in_community: このページレットがコミュニティまたはグループ・ページのいずれにあるのかを指定します。値がtrueに設定されている場合は、コミュニティIDヘッダーのcontext_idがページレットに送信されます。デフォルトはfalseです。

  • chrome: WSRP/JPDKページレット用に使用するChromeテンプレートの名前を指定します。Chromeが表示されないようにするには、値にnoneを指定します。

  • forward_params: 問合せ文字列引数を消費ページからバックエンド・サーバーに転送するかどうかを指定します。この機能を抑制するには、値falseを使用します。


注意:

これらの引数は前後関係に依存しているため、所定の順番で指定する必要があります。特定の引数を指定せずに後続の引数を指定するには、指定しない引数を空の値('')で渡す必要があります。libraryおよびnameを除くすべての引数はオプションです。


このスクリプトによって、injectpagelet関数への参照を含む、一意の名前を持つ新しい<div>も作成されます。次に例をいくつか示します。

<div>
    <script type="text/javascript">
        injectpagelet('library', 'name');
    </script>
</div>
<div>
    <script type="text/javascript">
    injectpagelet('library', 'name', 'iframe', 'payload', 'param1=value1&param2=value2&param3=value3');
    </script>
</div>
<div>
    <script type="text/javascript">
    injectpagelet('library', 'name', 'iframe width=100% height=200', 'payload');
    </script>
</div>
63.2.2.1.1 JavaScriptを使用したプリファレンス・エディタの追加

injecteditor関数を使用すると、ユーザーがこの機能をサポートするページレットに個人プリファレンスと共有プリファレンスを設定できるようにするプリファレンス・エディタを追加できます。この機能は、Oracle WebCenter Portalのパーソナライズ機能とカスタマイズ機能に似ています。

injecteditor(library, name, type, iframe_options, context_id, element_id, is_in_community, chrome)

これらの意味は、次のとおりです。

  • library: 必須。注入するページレットのライブラリ名です。Unicode文字と数字のみ使用でき、スペースを含めることはできません。

  • name: 必須。注入するページレットの名前です。Unicode文字と数字のみ使用でき、スペースを含めることはできません。

  • type: エディタのタイプ。この引数では、値admin、pagelet、communityをサポートします。community引数の場合は、context_idがコミュニティID CSPヘッダーのページレットに送信されます。

  • iframe_options: ページレット・エディタのコンテンツの周りにIFRAMEを使用するかどうかを指定します。IFRAMEオプションのサンプルは、iframe width=100% height=auto frameborder=0のようになります。省略または空白のままにすると、エディタ・コンテンツがインラインにレンダリングされます。

  • context_id: ページレット・インスタンスの外部識別子で、プリファレンスのスコープをページレット・プロデューサ・サーバーに設定するために使用されます。整数を指定する必要があります。

  • element_id: ページレット・コンテンツの注入先のHTML要素IDです。省略または空白のままにすると、 injecteditorコールが評価された場合に、document.write()を使用してページレット・コンテンツが注入されます。

  • is_in_community: このページレットがコミュニティまたはグループ・ページのいずれにあるのかを指定します。値がtrueに設定されている場合は、コミュニティIDヘッダーのcontext_idがページレットに送信されます。デフォルトはfalseです。

  • chrome: WSRP/JPDKページレット用に使用するChromeテンプレートの名前を指定します。Chromeが表示されないようにするには、値にnoneを指定します。


注意:

これらの引数は前後関係に依存しているため、所定の順番で指定する必要があります。特定の引数を指定せずに後続の引数を指定するには、指定しない引数を空の値('')で渡す必要があります。libraryおよびnameを除くすべての引数はオプションです。


63.2.2.2 RESTを使用したページレットへのアクセス

Representational State Transferを表すRESTは、HTTPを介してAPIを提供する簡単な手法です。RESTの基本原則は次のとおりです。

  • API URLは汎用的なメソッド・エンドポイントではなくリソースを指します。

  • リクエストでは、簡素化されたCRUDメソッドに標準のHTTP動詞を使用します。これは読取り専用APIで、GETリクエストのみを許可します。

  • すべてのリクエストは、取得したオブジェクト(ページレットまたはリソース)の完全表現を返します。

ページレット・プロデューサREST APIには、次の機能があります。

  • プロキシされていないページにページレットを注入します。これにより、ページレット・プロデューサは、Oracle WebCenter Interaction、Oracle WebLogic Portal、または他のサード・パーティ・ポータルのポートレット・プロバイダとして機能できます。詳細は、第63.2.2.2.1項「ページレット注入API」を参照してください。

  • リモートWebサービスで、リソースとページレットに関する情報をページレット・プロデューサから取得できます。詳細は、第63.2.2.2.2項「データ取得API」を参照してください。

63.2.2.2.1 ページレット注入API

ページレット注入URLは、リモート・ポートレットの場所を指定するためにポータルで使用できます(この方法でページレットをポートレットとして使用できます)。また、注入URLを、HTMLページでIFrameタグのsrc属性として使用することもできます。

URLは次の形式を使用する必要があります。

http://host:port/pagelets/inject/v2/pagelet/libraryname/pageletname?content-type=html

ここで、librarynameおよびpageletnameは、ページレット・プロデューサで構成されたライブラリとページレットを参照します。


注意:

ページレット注入APIをOracle WebCenter InteractionでポートレットWebサービスのURLとして使用する場合は、URLのpageletをportletに切り替える必要があります。たとえば、前述のURLは次のようになります。

http://host:port/pagelets/inject/v2/portlet/libraryname/pageletname?content-type=html


前述のコールに対する問合せ文字列引数は、ページレットが返される方法を定義します。次のパラメータが定義されます。

  • instanceid: オプション。ページレットのインスタンスIDで、ページ上のページレットを一意に識別し、ページレット間通信を容易にするために使用されます。ページに対して一意である必要があります。

  • context: オプション。ページレットのインスタンスの外部識別子で、ページレット・プロデューサ・サーバー上でのプリファレンスのスコーピングに使用されます。整数を指定する必要があります。

  • content-type: 戻り型。次の3つの型がサポートされています。

    • javascript: 注入可能なコードが返されます。

    • html: ページレット・マークアップがそれに関連付けられたPTPortletオブジェクトとともに返されます。

    • iframe: 元の注入APIを指すIFrameが返されます。ページに直接インラインするのではなく、ページレット・コンテンツはIFrameに格納されます。IFrameは、問合せ文字列パラメータのセットを提供することにより、スタイルを設定できます。

      パラメータ 説明 デフォルト

      ifwidth

      IFrameの幅を設定します。パーセント(%)またはピクセル(px)単位で指定できます(ifwidth=500pxなど)。autoに設定すると、コンテンツにあわせてIFrameを自動的にサイズ変更できます。詳細は、第63.2.2.3項「IFrameへの自動サイズ変更の使用」を参照してください。

      100%

      ifheight

      IFrameの高さを設定します。パーセント(%)またはピクセル(px)単位で指定できます(ifheight=500pxなど)。autoに設定すると、コンテンツにあわせてIFrameを自動的にサイズ変更できます。詳細は、第63.2.2.3項「IFrameへの自動サイズ変更の使用」を参照してください。

      デフォルトなし

      ifborder

      IFrameの境界を設定します。

      none

      ifalign

      IFrame内の位置あわせ規則を設定します(ifalign=centerなど)。

      デフォルトなし

      ifdesc

      IFrameの説明を設定します。

      デフォルトなし

      ifmarginheight

      マージンの高さを設定します。パーセント(%)またはピクセル(px)単位で指定できます(ifmarginheight=500pxなど)。

      デフォルトなし

      ifmarginwidth

      マージンの幅を設定します。 パーセント(%)またはピクセル(px)単位で指定できます(ifmarginwidth=500pxなど)。

      デフォルトなし

      ifscrolling

      IFrameのスクロールバーを設定します。許容される値は、yes、no、autoです。

      auto

      ifstyle

      IFrameのCSSスタイルを設定します。

      デフォルトなし

      ifclass

      IFrameのCSSクラスを設定します。

      デフォルトなし


  • csapi: オプション。CSAPIをページレット・レスポンスに含めるかどうかを設定します(trueまたはfalse)。CSAPIの組込みはオプションですが、レスポンスに含まれるページレットは、ページレットがレンダリングされるページ上に存在するCSAPIライブラリに依存します。csapi=falseの場合は、CSAPIライブラリは親ページ(通常はHEADセクション)に含まれる必要があります。

  • onhtttperror:: オプション。ページレット・リクエストの結果として403、404またはその他のエラー・コードが発生する場合は、ページレット・プロデューサは、ユーザーに表示するためにエラー・コードとエラー・ページ自体をブラウザに転送できます。onhttperrorパラメータは次の値を受け入れます。

    • comment (デフォルト): ページレット・プロデューサは失敗したページレットのかわりにHTMLコメントを生成します(失敗したページレットは単に表示されないだけです)。

    • inline: ページレット・エラーはサーバー・エラー・ページとともにインラインに表示されます。この場合、ページレットは通常、ページに表示されます。

    • fullpage: httpエラーはページ全体を消費します。このモードは、ページレット・プロデューサが親ページを制御する場合にのみ使用可能です。

たとえば、次のURLは、samplesライブラリのlinkspageletを指します。

http://host:port/pagelets/inject/v2/pagelet/samples/linkspagelet?content-type=iframe&csapi=true&ifheight=123px&ifclass=myclass

このURLは、次のコードに似たマークアップになります。


注意:

IFrameソースは元の注入APIを指しますが、今回、content-typeパラメータはhtmlに設定されます。この機能により、ページレットの取得で手順が追加されます。csapiパラメータは、後続のコールでtrueに設定され、IFrameコンテンツを取得して必須のCSAPIコンテンツがIFrameに格納されるようにします(これが当てはまらない場合は、ページレット・コードはIFrameの外に格納されているCSAPIスクリプトにアクセスできないため、JavaScript解決エラーが返されます)。


<html>
 <head>
 </head>
 <body>
  <iframe frameborder="none" class="myclass" width="100%" height="123px" scrolling="auto" src="http://proxy:port/inject/v2/pagelet/samples/linkspagelet?asdg=asdfgas&param=true&content-type=html&jswrap=false&csapi=true">
   <html>
    <head>
     <script src="http://proxy:loginserverport/loginserver/ensemblestatic/imageserver/plumtree/common/private/js/jsutil/LATEST/PTUtil.js" type="text/javascript"> </script>
     <script src="http://proxy:loginserverport/loginserver/ensemblestatic/imageserver/plumtree/common/private/js/jsutil/LATEST/PTDateFormats.js" type="text/javascript"></script>
     <script src="http://proxy:loginserverport/loginserver/ensemblestatic/imageserver/plumtree/common/private/js/jsxml/LATEST/PTXML.js" type="text/javascript"></script>
     <script src="http://proxy:loginserverport/loginserver/ensemblestatic/imageserver/plumtree/common/private/js/jsportlet/LATEST/PTPortletServices.js" type="text/javascript"></script>
    </head>
 
    <body>
     <div id="pt-pagelet-content-1" class="pagelet-container" style="display: inline;">
      <span xmlns:pt="http://www.plumtree.com/xmlschemas/ptui/">
      Pagelet links:
      <br/>
      <a href="http://proxy:port/inject/RP_PID393219_I1/headpagelet1.html">The first pagelet</a>
      <br/>
      <a href="http://proxy:port/inject/RP_PID393219_I1/headpagelet2.html">The second pagelet</a>
      <br/>
      <a href="http://proxy:port/inject/RP_PID393219_I1/csapipagelet.html">The csapi pagelet</a>
      <br/>
      <a href="http://proxy:port/inject/RP_PID393219_I1/linkspagelet.html">This pagelet</a>
      <br/>
      </span>
     </div>
    </body>
   </html>
  </iframe>
 </body>
</html>
63.2.2.2.2 データ取得API

ページレット・プロデューサからデータを取得するには、次の2つのREST APIが使用できます。

すべてのリクエストの基本のURLは、 http://host:port/pagelets/restservice/pageletproducer/です。

例63-1 すべてのページレット

http://host:port/pagelets/restservice/pageletproducer/pagelets/
http://host:port/pagelets/restservice/pageletproducer/pagelets/?format=xml

例63-2 ライブラリおよび名前別ページレット

http://host:port/pagelets/restservice/pageletproducer/pagelet/libraryname/pageletname/
http://host:port/pagelets/restservice/pageletproducer/pagelet/libraryname/pageletname/?format=xml

例63-3 すべてのリソース

http://host:port/pagelets/restservice/pageletproducer/resources/
http://host:port/pagelets/restservice/pageletproducer/resources/

例63-4 名前別リソース

http://host:port/pagelets/restservice/pageletproducer/resource/name
http://host:port/pagelets/restservice/pageletproducer/resource/name/?format=xml

63.2.2.3 IFrameへの自動サイズ変更の使用

ページレット・プロデューサ・ページレット注入APIは、ページレット・コンテンツをカプセル化するIFrameのサイズを自動的に変更できます。IFrameがストレッチして中のコンテンツに合うようにサイズ変更が行われます。この機能を使用するには、次の例に示すように、ifwidthおよびifheightパラメータをautoに設定する必要があります。

http://proxy:port/inject/v2/pagelet/samples/linkspagelet?content-type=iframe&csapi=true&ifheight=auto&ifwidth=auto&ifclass=myclass

さらに、この機能はコンシューマ・ページと同じドメイン上にある外部ページに依存します。このページは、内部非表示IFrameとしてページレットIFrameに格納されます。このページでは、サイズ設定情報を収集して親コンシューマ・ページに渡します。このページは、コンシューマ・ページと同じディレクトリにデプロイする必要があります。

次の例では、ロードの終了後に、ページレットIFrameのサイズが変更されます。初回ロード後に動的自動サイズ変更機能をユーザー対話型アクティビティに追加するには、マウスやキーボードのイベントについてイベント・リスナーをさらに追加するだけで済みます。

<html>
  <head>
    <title>Resizing Page</title>
    <script type="text/javascript">
  function onLoad() {
    var params = window.location.search.substring( 1 ).split( '&' );
    var height;
    var width;
    var iframe;
 
    for( var i = 0, l = params.length; i < l; ++i ) {
      var parts = params[i].split( '=' );
      switch( parts[0] ) {
        case 'height':
          height = parseInt( parts[1] );
          break;
        case 'width':
          width = parseInt( parts[1] );
          break;
        case 'iframe':
          iframe = parts[1];
          break;
      }
    }
  window.top.updateIFrame( iframe, height, width );
  }
 
  if (window.addEventListener) {
    window.addEventListener("load", onLoad, false)
  } else if (window.attachEvent) {
     window.detachEvent("onload", onLoad)
     window.attachEvent("onload", onLoad)
  } else {
    window.onload=onLoad
  }
  </script>
 </head>
<body>
</body>
</html>

63.2.3 WebCenter Portal: Spacesでのページへのページレットの追加

WebCenter Portal: Spacesでは、コンポーザを使用してページレットをページに追加できます。デフォルトでは、ページレットは「リソース・カタログ」の「マッシュアップ」フォルダに表示されます。ページレットをページに追加するには、「リソース・カタログ」のページレットに移動して選択します。

Spacesでリソースをページに追加する方法の詳細は、Oracle Fusion Middleware Oracle WebCenter Portal: Spacesユーザーズ・ガイドのページへのリソース・カタログのコンポーネントの追加に関する項を参照してください。

ページレットをページ内で構成するには、該当のページを編集モードで表示し、ページレットの編集ボタン(スパナ・アイコン)をクリックします。「コンポーネント・プロパティ」ダイアログの「ページレット・プロパティ」タブでは、ページレット・パラメータとIFrameオプションを定義できます。

図63-4 「コンポーネント・プロパティ」ダイアログ: 「ページレット・プロパティ」

図63-4の説明が続きます
「図63-4 「コンポーネント・プロパティ」ダイアログ: 「ページレット・プロパティ」」の説明

63.3 ページレット・プロデューサを使用したページレットの構築

この項では、ページレット・プロデューサを使用してページレットを構築するための情報について説明します。

63.3.1 アダプティブ・ページレットのスクリプティング・フレームワークの使用

アダプティブ・ページレットのスクリプティング・フレームワークは、サービスをCSPページレットとプロキシされたページに提供するクライアント側JavaScriptライブラリです。この項では、スクリプティング・フレームワークを使用して動的機能をページレットに実装する方法について説明します。

  • 第63.3.1.1項「構造化されたHTTPレスポンスの処理」: アダプティブ・ページレットのスクリプティング・フレームワークは、通常XMLとしてエンコードされる、構造化されたHTTPのクライアント側レスポンス・ハンドラとして使用できます。

  • 第63.3.1.2項「イベント通知の使用」: ページレットは、ページがロードされたり、ブラウザのフォーカスが変更された場合など特定のイベントが発生すると応答できます。

  • 第63.3.1.3項「インプレース更新の使用」: ページレットは、ページをリフレッシュすることなく、その内部コンテンツをリロードできます。

  • 第63.3.1.4項「セッション・プリファレンスの使用」: ブラウザレベルの変数が同一ページ上にない場合でも、その変数を格納してページレット間で共有できます。たとえば、1つのページレットにユーザーが入力した値は、別のユーザーが取得できます。スクリプティング・フレームワークは仲介として機能するため、すべてのページレットで共通セッションに格納されているすべての値にアクセスできます。

クラスとメソッドの完全リストについては、JSPortlet APIのドキュメントを参照してください。

アダプティブ・ページレットの追加情報は、第63.3.1.5項「アダプティブ・ページレットの開発のヒント」を参照してください。

63.3.1.1 構造化されたHTTPレスポンスの処理

ごく一部のユーザー・インタフェースのみを変更する必要がある場合、一部のHTTPリクエストに応じて大量のHTMLを返すのは多くの場合費用がかかり非効率的な可能性があります。これは、より複雑なユーザー・インタフェースに特に当てはまります。このような場合は、レスポンスをXMLでエンコードできます。クライアント側レスポンス・ハンドラはXMLを解析し、そのレスポンスに基づいてユーザー・インタフェースを更新(またはその他の処理を実行)できます。構造化されたレスポンス設計パターンを使用して、HTTPリクエストの作成後にユーザー・インタフェースの小領域を再描画するか、単純なHTTP/URIタイプのWebサービスにページレットからアクセスします。次のコード例 (structuredresponse_portlet.html) では、新しいサイトの選択からRSSフィードにアクセスします。

<!-- jsxml includes -->
<a id="imgServerHref" href="/images/plumtree" style="display:none"></a>
<script type="text/javascript"
src="/images/plumtree/common/private/js/PTLoader.js"></script>
<script type="text/javascript">
var oImgServer = new Object();
oImgServer.location = document.getElementById('imgServerHref').href;
var imageServerURL = document.getElementById('imgServerHref').href;
var imageServerConnectionURL = oImgServer.location;
new PTLoader(imageServerURL, imageServerConnectionURL).include('jsxml','en');
</script>

<!-- jscontrols includes -->
<link rel="stylesheet" type="text/css" href="/portal-remote-server/js/jscontrols/styles/css/PTMenu.css"/>
<link rel="stylesheet" type="text/css" href="/portal-remote-server/js/jscontrols/styles/css/PTRichTextEditor.css"/>
<script type="text/javascript" src="/portal-remote-server/js/jscontrols/strings/PTControls-en.js"></script>
<script type="text/javascript" src="/portal-remote-server/js/jscontrols/PTControls.js"></script>

<!-- Inline JS helper functions -->
-->

<script defer type="text/javascript" id="structured-response-portlet-A-script">
// Function that gets the RSS XML feed found at the specified url
getRSSFeed = function(url)
  {
  // First clear out any existing rows in the table
  channelTable.clearRows();

  // Force the transformer to fix up the url
  var oURL = new Object();
  oURL.location = url;

  // Do the http get
  var get = new PTHTTPGETRequest(oURL.location, handleRSSResponse);
  get.invoke();
  }

// Function that handles the RSS XML response and updates the table based on the RSS items
handleRSSResponse = function(response)
  {
  // Get the rss xml
  var xml = response.responseText;
  if (!xml || xml.indexOf('<?xml') == -1) { return; }

  // Parse into a dom, and get the channel node
  var xmlDOM = new PTXMLParser(xml);
  var rssNode = xmlDOM.selectSingleNode('rss');
  var channelNode = rssNode.selectSingleNode('channel');

  // Get the channel title and set the status bar text in the table
  var channelTitle = channelNode.selectSingleNode('title').getNodeValue();
  channelTable.statusBarText = '<b>Loaded Channel</b>: ' + channelTitle;

  // Get channel item nodes
  var itemNodes = channelNode.selectNodes('item');
  
  // Build table rows
  channelTable.rows = new Array();
  for (var i=0; i<itemNodes.length; i++)
    {
    var itemNode = itemNodes[i];

    // Get channel item properties
    var itemTitle = itemNode.selectSingleNode('title').getNodeValue();
    var itemLink = itemNode.selectSingleNode('link').getNodeValue();
    var itemDescription = itemNode.selectSingleNode('description').getNodeValue();
    if (itemNode.selectSingleNode('author'))
      var itemAuthor = itemNode.selectSingleNode('author').getNodeValue();
    if (itemNode.selectSingleNode('category'))
      var itemCategory = itemNode.selectSingleNode('category').getNodeValue();
    if (itemNode.selectSingleNode('pubDate'))
      var itemPubDate = itemNode.selectSingleNode('pubDate').getNodeValue();

    // Create a row and add it to the table
    var row = new PTRow();
    row.parent = channelTable;
    row.id = i;
    row.uid = i;
    row.previewText = itemDescription;
    row.link = itemLink;
    row.columnValues[0] = new PTTextColumnValue(itemTitle);
    row.columnValues[1] = new PTTextColumnValue(itemCategory);
    row.columnValues[2] = new PTTextColumnValue(itemAuthor);
    row.columnValues[3] = new PTTextColumnValue(itemPubDate);
    channelTable.rows[channelTable.rows.length] = row;
    }

  // Redraw the table
  channelTable.draw();
  }
</script>

<b>Select RSS Feed:</b>
<a href="#" onclick="getRSSFeed('http://www.wired.com/news/feeds/rss2/0,2610,,00.xml'); return false;">Wired News</a>
<a href="#" onclick="getRSSFeed('http://news.com.com/2547-1_3-0-5.xml'); return false;">CNET News.com</a>
<a href="#" onclick="getRSSFeed('http://partners.userland.com/nytRss/nytHomepage.xml'); return false;">NY Times</a>
<br><br>

<!-- Set up a table control to display channel items -->
<div id="channelTableContainer"></div>
<script defer type="text/javascript">
  var channelTable = new PTTableControl();
  channelTable.locale = 'en_US';
  channelTable.objName = 'channelTable';
  channelTable.container = 'channelTableContainer';
  channelTable.baseURL = '/imageserver/plumtree/common/private/portal-remote-server/js/jscontrols/1/';
  channelTable.statusBarText = 'No RSS Feed Selected';
  channelTable.rowDetailAction = new PTJavaScriptAction('window.open(\'${ROW.link}\');');
  channelTable.columns[0] = new PTColumn();
  channelTable.columns[0].name = 'Title';
  channelTable.columns[0].width = '40%';
  channelTable.columns[1] = new PTColumn();
  channelTable.columns[1].name = 'Category';
  channelTable.columns[1].width = '20%';
  channelTable.columns[2] = new PTColumn();
  channelTable.columns[2].name = 'Author';
  channelTable.columns[2].width = '20%';
  channelTable.columns[3] = new PTColumn();
  channelTable.columns[3].name = 'Publication Date';
  channelTable.columns[3].width = '20%';
  channelTable.areColumnsResizable = true;
  channelTable.clientSortEnabled = true;
  channelTable.scrollHeight = 250;
  channelTable.init();
  channelTable.draw();
</script>
</div>

63.3.1.2 イベント通知の使用

アダプティブ・ページレットのスクリプティング・フレームワークにより、ページレットでは、その他のページレットが生成したページレベルのイベントとカスタム・イベントの両方に応答できます。

スクリプティング・フレームワークのregisterForWindowEventメソッドおよびregisterOnceForWindowEventメソッドによって、ページレットでページレベルのイベントにアクセスできるようになります。完全なリストは、第63.3.1.2.1項「スクリプティング・フレームワークで使用するためのページレベルのイベント」を参照してください。これらのイベントの通知を登録するには、イベントの発生時にコールする必要があるイベント名とメソッド名を渡します。ページレベルのイベントが発生すると、JavaScriptイベント・オブジェクトが引数としてイベント・ハンドラに渡されます。スクリプティング・フレームワークによって、ページレットでは、raiseEventregisterForEventを使用してカスタム・イベントを生成したりカスタム・イベントに応答することもできます。ブロードキャスト/リスナー設計パターンは、セッション・プリファレンスを使用した通知サービスの重要な使用例を示しています。ユーザーはブロードキャスト・ページレットでアイテムを選択したり、その他の処理を実行できます。これにより、関連するその他のリスナー・ページレットのコンテンツが再描画されます。次の例では、ブロードキャスト・ページレットにテキスト・ボックスに数値を入力できるフォームが表示されています。

図63-5 ブロードキャスト・ポートレット

図63-5の説明が続きます
「図63-5 ブロードキャスト・ポートレット」の説明

ユーザーがテキスト・ボックスに数値を入力すると、リスナー・ページレットの値が変更されます。最初のリスナー・ページレットには、ブロードキャスト・ページレットに入力した数値の平方根が表示されます。

図63-6 リスナー -1 ポートレット

図63-6の説明が続きます
「図63-6 リスナー -1 ポートレット」の説明

2番目のリスナー・ページレットには、ブロードキャスト・ページレットに入力した数値の立方根が表示されます。

図63-7 リスナー -2 ポートレット

図63-7の説明が続きます
「図63-7 リスナー -2 ポートレット」の説明

次の手順では、ページレットがどのように機能するのかについてまとめています。

  • ロード時に、各リスナー・ページレットは固有のインスタンス・メソッド(registerForEvent)をコールし、onBroadcastUpdateタイプのイベントを登録します。

  • Enter numberテキスト・ボックスに発生するonkeyupイベントごとに、ブロードキャスト・ページレットはセッション・プリファレンスをこのテキスト・ボックスに入力された値に設定し、その固有のインスタンス・メソッド(raiseEvent)をコールしてonBroadcastUpdateタイプのイベントを生成します。

  • onBroadcastUpdateイベントが発生したり、ページが再ロードされた場合は、各リスナー・ページレットがブロードキャスト・ページレットによって設定されたセッション・プリファレンスを取得し、プリファレンスの値に基づいて表示する新しい値を計算します。

ブロードキャスト・ページレット

<div style="padding:10px;" align="center">
<p><b>Enter number:</b>
&nbsp;<input type="text" style="font-size:22px;font-weight:bold;text-align:center;"
id="broadcast_prefName" value="4" size="7" onkeyup="broadcast_setPrefs(this.value)"></p>
<br>
</div>

<script type="text/javascript">
function broadcast_setPrefs(val)
{
    var prefName = 'broadcastNumber';
    var prefValue = val;
    PTPortlet.setSessionPref(prefName,prefValue);
    var broadcastPortlet = PTPortlet.getPortletByGUID('{D9DFF3F4-EAE7-5478-0F4C-2DBD94444000}');

      if (!broadcastPortlet)
    {
        broadcast_debug('Could not locate PTPortlet object which corresponds to <b>Broadcast Portlet</b> on page.');
        return;
        }
      broadcast_debug('<b>Broadcast Portlet</b> raising onBroadcastUpdate event.');
    broadcastPortlet.raiseEvent('onBroadcastUpdate',false);
}
function broadcast_debug(str)
{
    if (window.PTDebugUtil) 
    { 
        PTDebugUtil.debug(str); 
    }
}
</script>

リスナー・ページレット#1

<div style="padding:10px;" align="center">
<p><b>Square root:</b>
<div style="height:21px;border:2px solid black;padding:2px;overflow:visible;font-size:14px;"id="listener1-swatch">
</div>
</div>

<script>
function listener1_update()
{
    var broadcastNumber = parseFloat(PTPortlet.getSessionPref('broadcastNumber'));
    if (isNaN(broadcastNumber))
    {
        listener1_error('<b>Listener-1 Portlet</b> cannot parse number from session pref broadcastNumber');
        return;
    }

      listener1_debug('<b>Listener-1 Portlet</b> computing square root of ' + broadcastNumber);
      var swatch = document.getElementById('listener1-swatch');
    swatch.innerHTML = Math.sqrt(broadcastNumber);
}

function listener1_debug(str)
{
    if (window.PTDebugUtil) 
    { 
        PTDebugUtil.debug(str); 
    }
}

function listener1_error(str)
{
    if (window.PTDebugUtil) 
    { 
        PTDebugUtil.error(str); 
    }
}

function listener1_getPortlet()
{
    var portletGUID = '{D9DFF3F4-EAE7-5478-0F4C-2DBDB4F4A000}';
    var listener1Portlet = PTPortlet.getPortletByGUID(portletGUID);
    return listener1Portlet;
}

var listener1Portlet = listener1_getPortlet();
if (listener1Portlet)
{
    listener1Portlet.registerForEvent('onBroadcastUpdate','listener1_update');
    listener1_debug('<b>Listener-1 Portlet</b> registered refreshOnEvent for event onBroadcastUpdate');
    listener1Portlet.registerForEvent('onload','listener1_update');
}

</script>

リスナー・ページレット#2

<div style="padding:10px;" align="center">
<p><b>Cube root:</b>
<div style="height:21px;border:2px solid black;padding:2px;overflow:visible;font-size:14px;"id="listener2-swatch">
</div>
</div>

<script>
var listener2_oneThird = (1/3);
function listener2_update()
{
    var broadcastNumber = parseFloat(PTPortlet.getSessionPref('broadcastNumber'));
    if (isNaN(broadcastNumber))
    {
        listener2_error('<b>Listener-2 Portlet</b> cannot parse number from session pref broadcastNumber');
        return;
    }

    listener2_debug('<b>Listener-2 Portlet</b> computing square root of ' + broadcastNumber);
    var swatch = document.getElementById('listener2-swatch');
    swatch.innerHTML = Math.pow(broadcastNumber,listener2_oneThird);
}

function listener2_debug(str)
{
    if (window.PTDebugUtil) 
    { 
        PTDebugUtil.debug(str); 
    }
}

function listener2_error(str)
{
    if (window.PTDebugUtil) 
    { 
        PTDebugUtil.error(str); 
    }
}

function listener2_getPortlet()
{
    var portletGUID = '{D9DFF3F4-EAE7-5478-0F4C-2DBDCA1C7000}';
    var listener2Portlet = PTPortlet.getPortletByGUID(portletGUID);
    return listener2Portlet;
}

var listener2Portlet = listener2_getPortlet();
if (listener2Portlet)
{
    listener2Portlet.registerForEvent('onBroadcastUpdate','listener2_update');
    listener2_debug('<b>Listener-2 Portlet</b> registered refreshOnEvent for event onBroadcastUpdate');
    listener2Portlet.registerForEvent('onload','listener2_update');
}

</script>
63.3.1.2.1 スクリプティング・フレームワークで使用するためのページレベルのイベント

スクリプティング・フレームワークでは、次のページレベルのイベントに自動的にアクセスできます。

表63-2 ページレベルのイベント

イベント トリガー時期:

onload

ブラウザがページをロードした直後

onbeforeunload

ページがアンロードされる(ブラウザ・ウィンドウが閉じるか別の場所に移動する)前

onunload

ページがアンロードされる(ブラウザ・ウィンドウが閉じるか別の場所に移動する)直前

onactivate

ページがアクティブ要素として設定された(フォーカスを取得した)とき

onbeforeactivate

ページがアクティブ要素として設定される(フォーカスを取得する)直前

ondeactivate

アクティブ要素が現在のページから親ドキュメントの別のページに変更されたとき

onfocus

ページがフォーカスを取得したとき

onblur

ページがフォーカスを喪失したとき

oncontrolselect

ユーザーがページのコントロールをまさに選択するとき

onresize

ページのサイズをまさに変更するとき

onresizestart

ユーザーがコントロールの選択でページ寸法の変更を開始したとき

onresizeend

ユーザーがコントロールの選択でページ寸法の変更を終了したとき

onhelp

ブラウザがアクティブ・ウィンドウになっている状態でユーザーが[F1]キーを押したとき

onerror

ページのロード中にエラーが発生したとき

onafterprint

関連するドキュメントが印刷されたまたは印刷プレビューされた直後


63.3.1.3 インプレース更新の使用

ページ上の他のコンテンツに影響を与えずに、ページレット・コンテンツをインプレースでリフレッシュするには、スクリプティング・フレームワークを使用してインプレース更新を実装します。

ページレットの多くは時間に影響を受けるデータを表示します。場合によっては、ユーザーはページの残りの部分を変更またはリフレッシュすることなく、ページレット内のリンク間を移動できる必要があります。ページレット・コンテンツは、コマンドを使用する、リフレッシュ・アクションをイベントに関連付ける (refreshOnEvent)、または設定した間隔でリフレッシュするようにページレットをプログラムする(setRefreshInterval)ことでリフレッシュできます。スクリプティング・フレームワークにはまた、ページレットを開閉するためのメソッドも用意されています。次の単純な例では、リフレッシュ・ページレットに「ポートレットのリフレッシュ」ボタンが表示されます。このボタンをクリックすると、ページレットに表示される日時が更新されます。

図63-8 「ポートレットのリフレッシュ」

図63-8の説明が続きます
「図63-8 「ポートレットのリフレッシュ」」の説明

インプレース更新は、ページレット・オブジェクト・インスタンスに対してrefresh()メソッドをコールすることにより、実行されます。リフレッシュ時には、新しいURLがページレット内に表示されるように設定することもできます。(タイトル・バーはリフレッシュ時に変更できません。)

<div style="padding:10px;" align="center">
<p><button onclick="refresh_portlet()">Refresh Portlet</button></p>
<p><b>Current time is:</b><br> <span id="refreshTimeSpan"></span></p>
</div>

<script type="text/javascript"> 
function refresh_portlet()
{
var refreshPortlet = PTPortlet.getPortletByID($PORTLET_ID$);
if (!refreshPortlet)
  {
  refresh_debug('Could not locate PTPortlet object which corresponds to <b>Refresh Portlet</b> on page.');
  return;
  }
refresh_debug('<b>Refresh Portlet</b> calling refresh() method.');
refreshPortlet.refresh();
}

function refresh_debug(str)
{
if (window.PTDebugUtil) 
  { 
  PTDebugUtil.debug(str); 
  }
}

var t = new Date();
document.getElementById('refreshTimeSpan').innerHTML = t;
</script>

63.3.1.4 セッション・プリファレンスの使用

クライアント・ブラウザ内に設定を保存して共有するには、セッション・プリファレンスを使用します。

ページレットはプリファレンスを使用して相互に通信できますが、プリファレンスへのアクセスには、通常、データベースへのラウンドトリップが必要となります。セッション・プリファレンスには、クライアント・ブラウザ内でユーザーのセッションに設定を保存および共有する方法が備わっています。マスター/ディテール設計パターンは、セッション・プリファレンスの最も基本的な使用法を示しています。この設計パターンでは、制御機能と表示機能が2つのページレットに分割されます。たとえば、マスター・ページレットにはデータをまとめてリスト形式で表示し、ディテール・ページレットにはユーザーの選択に応じて各データ項目の詳細を表示するという設計もできます。次の例では、フォームが表示されたマスター・ページレットを示しています。このフォームでは、テキスト・ボックスに色コードを入力できるようになっています。

ユーザーが色コードをテキスト・ボックスに入力すると、ディテール・ページレットに表示されている色が変更されます。

マスター・ページレットの「色の入力」テキスト・ボックスでonkeyupが発生するたびに、次の手順が実行されます。

  1. マスター・ページレットのテキスト・ボックスの現在値を使用してセッション・プリファレンスが設定されます。

  2. マスター・ページレットからディテール・ページレットの更新メソッドがコールされます。

  3. ディテール・ページレットにより、セッション・プリファレンスから色の値が取得されます。

  4. ディテール・ページレットの色見本領域が再描画され、新しい色の値が反映されます。


注意:

共有のセッション・プリファレンスは、ページレット・プロデューサ・コンソール内のページレットの「プリファレンス」ページから名前で指定する必要があります。指定しないと、プリファレンスはページレットに送信されません。


アダプティブ・ページレットのスクリプティング・フレームワークには、ページレット間の関係を解除し、共通のイベント・インタフェースを使用して通信するための簡単な方法が用意されています。


注意:

次の例は極度に簡略化されたもので、マスター・ページレットからディテール・ページレットのJavaScriptメソッドが直接コールされます。マスター・ページレットで、ディテール・ページレットが同一ページ上に実際に存在することを確認するためのなんらかの処置を講じないかぎり、マスターからディテールに対してコールすると、エラーが発生する可能性があります。


マスター・ページレット

<div style="padding:10px;" align="center">
<p><b>Enter color:</b> &nbsp;
<input type="text" style="font-size:22px;font-weight:bold;text-align:center;" id="master_prefName"
value="#FFFFFF" size="8" onkeyup="master_setPrefs(this.value)"></p><br>
</div>

<script type="text/javascript">
function master_setPrefs(val)
{
var prefName = 'masterColor';
var prefValue = val;
PTPortlet.setSessionPref(prefName,prefValue);

master_debug('<b>Master Portlet</b> called PTPortlet.setSessionPref(\'masterColor\',\'' + prefValue + '\').');

if (window.detail_update)
  {
  master_debug('<b>Master Portlet</b> calling detail_update().');
  detail_update();
  }
else
  {
  master_debug('Could not locate portlet <b>Detail Portlet</b> on page.');
  }
}
function master_debug(str)
{
if (window.PTDebugUtil) 
  { 
  PTDebugUtil.debug(str); 
  }
}
</script>

ディテール・ページレット

<div style="padding:10px;" align="center">
<p><b>Color swatch</b> &nbsp;
<div style="width:100px;height:100px;border:2px solid black;padding:2px;"id="detail-swatch"></div>
<script>
function detail_update()
{
var color = PTPortlet.getSessionPref('masterColor');
detail_debug('<b>Detail Portlet</b> received value="' + color + '" for PTPortlet.getSessionPref(\'masterColor\')');

var swatch = document.getElementById('detail-swatch');
if (swatch)
  {
  swatch.innerHTML = '<div style="background-color:' + color + ';width:100%;height:100%;"></div>';
  }
else
  {
  detail_debug('<b>Detail Portlet</b> cannot find \'detail-swatch\' DIV element.');
  }
}

function detail_debug(str)
{
if (window.PTDebugUtil) 
  { 
  PTDebugUtil.debug(str); 
  }
}
</script>

63.3.1.5 アダプティブ・ページレットの開発のヒント

次のヒントは、アダプティブ・ページレットのスクリプティング・フレームワークを使用するほとんどのページレットに当てはまります。

  • すべてのフォームと関数に一意の名前を使用します。 一意の名前と値の形成にページレットのGUIDを使用し、ページ上の他のコードと名前の衝突が発生しないようにします。

  • すべてのURLをプロキシします。 コール元のページと異なるホスト/ポートを持つURLに対するリクエストを作成することはできません。JavaScriptを通じてリクエストされるURLはすべてプロキシする必要があります。詳細は、第63.3項「ページレット・プロデューサを使用したページレットの構築」を参照してください。

  • アダプティブ・ページレットのスクリプティング・フレームワークを使用している場合は、サポートをチェックします。 コンポーネントが存在するかどうかを判断するコードを組み込むことをお薦めします。理想的には、ページレットでいずれの状況も処理できる必要があります。最も簡単な解決方法は、スクリプティング・フレームワークがサポートされていない場合にユーザーに警告を行うIf文を備えたコードを優先することです。

    <script>
    if (PTPortlet == null) 
      {
      if (document.PCC == null) 
        {
        alert("This pagelet only works in portals that support the JSPortlet API .
    The pagelet will be displayed with severely reduced
        functionality. Contact your Administrator.");
        }
      }
    else 
      {
      [scripting code here]
      }
    </script>
  • ウィンドウが閉じるときに、ページレットによって開かれたポップアップ・ウィンドウをすべて閉じます。 onunloadイベントを使用してポップアップ・ウィンドウを閉じる場合に、スクリプティング・フレームワークを使用できます。

  • 必要なすべてのJavaScriptを前もってページに追加しておきます。 innerHTMLプロパティを使用してページに追加されたスクリプト・ブロック/インクルードは、ブラウザで処理されない場合があります。

    • Microsoft Internet Explorer: スクリプト・タグにdefer(遅延)属性を追加します。

    • Netscape: RegExpを使用してレスポンスを解析し、スクリプトを見つけて評価します。

  • JavaScript HTTPとプロキシされたHTTPで同じ認証資格証明を使用する必要があります。 JavaScriptで仲介(ブローカ)されたHTTPリクエストからは、ゲートウェイ処理された正常なHTTPリクエストの作成時と同じ認証トークン(cookie)が送信されます。

63.3.2 ページレット・プロデューサの資格証明マッピングの使用

ページレット・プロデューサでは、関連するリソースに定義された設定に基づいて、プロキシされた各アプリケーションの認証を管理します。

ページレット・プロデューサは外部の資格証明ストアへのカスタム・マッピングを作成するAPIを提供しているため、カスタム資格証明ソースに対してユーザーを認証できます。

IVendorCredentialMapperインタフェースでは、アプリケーションで特定のユーザーのセカンダリ認証に必要な、適切な資格証明のセットを取得できるオブジェクトに対するページレット・プロデューサのインタフェースを定義します。このインタフェースを実装するには、次の手順に従います。

  1. com.plumtree.runner.credentialmapper.IVendorCredentialMapperインタフェースを実装するJavaクラスを作成します。

  2. このインタフェースのgetCredentialメソッドとsetCredentialメソッドを資格証明ボールトにマップします。 次の簡略化した例では、VConnectorという内部クラスを使用して、VConnector.getInstance(). getCredentialsForDomainをコールしています。注意: この手順はベンダー固有のものです。資格証明ストアは別のサーバーにあることが多いため、おそらくネットワーク・ホップが含まれます。マッパーには一意の名前を付け、必要に応じてローカライズします。すべての必要な名前については、IVendorCredentialMapper APIのドキュメントを参照してください。

  3. クラスをJARにコンパイルします。ビルド・プロセスは、ページレット・プロデューサの配布キットに付属するcommon.jarにリンクする必要があります。

  4. カスタム・ボールトをページレット・プロデューサにロードします。詳細は、『Oracle Fusion Middleware Oracle WebCenter Portal管理者ガイド』を参照してください。

  5. ページレット・プロデューサ・サーバー(異なるサーバー上にある場合はproxyとadminuiの両方)を再起動します。カスタムの資格証明ボールトが、リソース・エディタの「資格証明マッピング」ページの資格証明ソースのリストに表示されます。

次の例は、説明を目的としているために簡略化されています。

package com.oracle.credentialvault;
import com.oracle.connector.CredentialsSet;
import com.oracle.connector.VConnector;
import com.plumtree.runner.credentialmapper.Credential;
import com.plumtree.runner.credentialmapper.IVendorCredentialMapper;

public class OracleCredentialVault implements IVendorCredentialMapper {

  /*
  * Pagelet Producer will pass credential types as following:
  * Runner_*, where * is what the credential value type associated with this login
  * form in the adminui. For example, if the credential value type is
  *  'username' then "Runner_username" will be passed to the mapper.
  */
  public Credential getCredential(String initiator, String credType) 
{ System.out.println("OracleCredentialVault::getCredential, initiator: " + initiator + ", credType: " + credType); /* * Since this vault stores credentials per user and domain, we need to devise * a scheme to map Pagelet Producer's credential type to a domain. * One way to do this is to specify the credential type as something like: * "domain_type", which would translate to credTypes like: * Runner_domain.com_username and Runner_domain.com_password */ String username = initiator.toLowerCase(); // assume that the vault stores all usernames in lowercase String domain = "oracle.com"; //getDomain(credType); String type = credType; //getType(credType); CredentialsSet credSet = VConnector.getInstance().getCrededentialsForDomain(username, domain); if( credSet != null ) { System.out.println("OracleCredentialVault::getCredential, found vault set: " + credSet.toString() + ", returning type = " + type); return new Credential(credSet.getCredential(type)); } else { System.out.println("OracleCredentialVault::getCredential, found null vault set"); return null; } } public String getDescription(String userLocale) { return "Test mapper that mimics a mapper between Pagelet Producer and a credential vault that associates credentials with a username/domain relationship"; } public String getName() { return "OracleCredentialVault"; } public String getName(String userLocale) { return "OracleCredentialVault"; } public String getVendorName(String userLocale) { return "Oracle"; } public boolean setCredential(String initiator, Credential credential, String credType) { System.out.println("OracleCredentialVault::setCredential, initiator: " + initiator + ", credType: " + credType + ", Credential: " + credential.getCredentialValue()); String username = initiator.toLowerCase(); // assume that the vault stores all usernames in lowercase String domain = "oracle.com"; //getDomain(credType); String type = credType; //getType(credType); System.out.println("OracleCredentialVault::setCredential setting username: " + credential.getCredentialValue()); CredentialsSet userCredSet = VConnector.getInstance().getCrededentialsForDomain(username, domain); userCredSet.setCrededential(type, credential.getCredentialValue()); VConnector.getInstance().setCrededentialsForDomain(username, domain, userCredSet); return true; } public boolean supportsCredentialsEditing()
{ // We can set new credentials using this vault return true; } /* private String getDomain(String credType) { int dstart = credType.indexOf("_"); int dend = credType.indexOf("_", dstart+1); String domain = credType.substring(dstart+1, dend); System.out.println("TestMapper::getDomain, reading domain as: " + domain); return domain; } */ /* private String getType(String credType) { int dstart = credType.indexOf("_"); dstart = credType.indexOf("_", dstart+1); String type = credType.substring(dstart+1, credType.length()); System.out.println("TestMapper::getType, reading type as: " + type); return type; } */ /* private String doGetPropertyValue(String principal, String property) { return doGetPropertyValue(principal, property, ",", "="); } */ /* private String doGetPropertyValue(String principal, String property, String propDelim, String valueDelim) { int propertyindex = principal.toLowerCase().indexOf(property.toLowerCase()); String uname = null; if( propertyindex != -1) { // found a property occurence int beginIndex = propertyindex; int endIndex = principal.toLowerCase().indexOf(propDelim.toLowerCase(), beginIndex); String prop = null; if(endIndex != -1) { prop = principal.subSequence(beginIndex, endIndex).toString().trim(); } else { prop = principal.subSequence(beginIndex, principal.length()).toString().trim(); } if( prop != null ) { int valueIndex = prop.toLowerCase().indexOf(valueDelim); if(valueIndex != -1) { uname = prop.subSequence(valueIndex + valueDelim.length(), prop.length()).toString().trim(); } } } return uname; } */ }

資格証明マッピングを使用するためのリソースの構成の詳細は、『Oracle Fusion Middleware Oracle WebCenter Portal管理者ガイド』のページレット・プロデューサのリソースとページレットの作成に関する項を参照してください。

63.3.3 実行時のページレット機能の変更

ページレット・プロデューサを使用すると、カスタムのインジェクタおよびパーサーを使用してページレットの機能を実行時に変更できます。

63.3.3.1 Webインジェクタの作成

Webインジェクタは、プロキシされているリソース・ページの指定の場所にコンテンツを挿入します。コンテンツには、HTML、CSS、JavaScriptおよびページレット宣言などのテキストを指定できます。ページから不要なコンテンツを削除するために空のインジェクタを使用することもできます。インジェクタをOpenSocialリソース用に作成することはできません。単純なHTMLコンテンツの注入についてはユースケースが限られていますが、ページレットのHTMLマークアップを直接変更するJavaScriptを注入することもできます。

Webインジェクタを作成するには、使用するリソース下の「インジェクタ」セクションを選択し、ツールバーの「作成」アイコンをクリックします。

URLパターンを「URLフィルタ」フィールドに入力することにより、インジェクタをリソースのサブセットに適用できます。インジェクタは、「URLフィルタ」ボックスに指定されたテキストで始まるリソース内のURLにのみ適用されます。このボックスが空または/のみ指定されている場合は、インジェクタはリソース全体に適用されます。

インジェクタで特定の種類のコンテンツに制限するには、「MIMEフィルタ」ボックスにMIMEタイプのカンマ区切りリストを入力します。たとえば、text/htmlではインジェクタはHTMLコンテンツに制限され、一方、text/cssではCSSコンテンツにのみ制限されます。

リソースの出力のどこに注入するのかを定義します。

  • 「先頭」はコンテンツをページの最初に配置します。このオプションは、ページレット宣言の注入には使用しないでください。

  • 「最後」はページの最後にコンテンツを配置します。

  • 「次より前」/「次より後」/「置換」の各オプションは、表示されたフィールドに指定されている一意の文字列に関連するページに配置します。「大文字/小文字を区別しない」を選択することにより、文字列の大/小文字を区別しないようにできます。

    「囲みタグ」オプションは、一意の文字列を識別し、テキストと囲みタグの両方を次のページで指定されているコンテンツと置き換えます。

図63-11 ページレット・プロデューサ・コンソール:「インジェクタ」 - 「全般」ページ

図63-11の説明が続きます
「図63-11 ページレット・プロデューサ・コンソール:「インジェクタ」 - 「全般」ページ」の説明

「コンテンツ」ページで注入するコンテンツを入力します。このコンテンツには、HTML、CSS、JavaScriptおよびページレット宣言などのテキストを指定できます。

たとえば、次のコードはページ上部に注入できます。この例では、ハンドラ関数をページ・ロード・イベントに登録し、(ヘッダーやフッターを検索および非表示にすることにより)ハンドラを使用してページ・マークアップを変更します。

<script type="text/javascript">
if (window.addEventListener) {
  window.addEventListener('load', hideHeaderFooter, false);
} else if (document.attachEvent) {
  window.attachEvent('onload', hideHeaderFooter);
}
function hideHeaderFooter() {
  var header = null;
  // find the header table by class 
  if (document.getElementsByClassName) {
    header = document.getElementsByClassName('page_header')[0];
  } else {
    // for older versions of IE
    var tables = document.getElementsByTagName('table');
    for (var table in tables) {
      if (table.class == 'page_header') {
        header = table;
        break;
      }
    }
  }
  if (header != null) {
    header.style.display = 'none';
  }
  // now find and hide the footer (easier to find, since it has an id)
  var footer = document.getElementById('t23PageFooter');
  if (footer != null) {
    footer.style.display = 'none';
  }
}
</script>

63.3.3.2 カスタム・パーサーの作成

カスタム・パーサーを使用すると、コンテンツを解析し、URLを検索するための組込みのロジックを補足したり変更できます。組込みのパーサーがURLの識別やURLとしてリライトしてはいけないセクションの識別に失敗した場合は、カスタム・パーサーを使用してデフォルトの動作を変更できます。パーサーは、WSRPやOracle JPDKポートレット・プロデューサまたはOpenSocialガジェット・プロデューサ用に作成することはできません。

カスタム・パーサーを作成するには、使用するリソース下で「パーサー」セクションを選択し、ツールバーの「作成」をクリックします。

  • パーサーの名前を入力します。

  • 「URLフィルタ」ボックスにURLパターンを入力することにより、パーサーをリソースのサブセットに適用できます。パーサーは、「URLフィルタ」ボックスに指定されたテキストで始まるリソース内のURLにのみ適用されます。ボックスが空または/のみ指定されている場合は、パーサーはリソース全体に適用されます。

  • 新しい解析ルールを追加するには、「作成」をクリックして新しい行を「フラグメントの場所」セクションに追加します。

  • 「正規表現」欄に、変換するURLフラグメントを識別するための正規表現を入力します。最初のグループ化表現(かっこ内)はフラグメントを識別し、残りの表現はそれを検索するためのコンテキストを提供します。

  • 「フラグメント・タイプ」から選択し、選択した場所を解析する方法を定義します。

    • 「静的URL」はサーバー上で変換されます。

    • 「動的URL」は、クライアント上でJavaScriptを使用して変換されます。

    • 「HTMLフラグメント」および「JavaScriptフラグメント」タイプは、XMLなどの別のコンテンツ・タイプに埋め込まれるコンテンツに使用します。

    • 「リライトなし」では、URLを検索しない場所を指定します。このオプションは、URLとして間違って識別されたマークアップのリライトを避けるために使用します。

  • ナビゲータ・ツールバーの保存アイコンをクリックします。

図63-12 ページレット・プロデューサ・コンソール: 「パーサー」 - 「一般」ページ

図63-12の説明が続きます
「図63-12 ページレット・プロデューサ・コンソール: 「パーサー」 - 「一般」ページ」の説明

たとえば、正規表現XMLFile=(.*?)"は、タグ内に次のように定義されたXMLファイルへのURLを識別します。<embed src="/i/flashchart/anychart_5/swf/OracleAnyChart.swf?>XMLFile=http://apex.oracle.com/pls/apex/apex_util.flash?p=53557:1:74175370346201:FLOW_FLASH_CHART5_R45192463162785599619_en"

63.3.4 ページレットのデバッグ

ページレット・プロデューサには、ページレットのデバッグ用に拡張ロギング・トレースが組み込まれています。ロギングは、ページレット・プロデューサ・コンソールの「設定」セクションで構成され、ここで、ページレット・プロデューサの各コンポーネントについて様々なレベルのロギングを定義できます。(ページレット・プロデューサの構成設定の詳細は、『Oracle Fusion Middleware Oracle WebCenter Portal管理者ガイド』Oracle WebCenter Portalのページレット・プロデューサの管理に関する項を参照してください。)

図63-13 ページレット・プロデューサ・コンソール:「設定」 - 「ロギング」

図63-13の説明が続きます
「図63-13 ページレット・プロデューサ・コンソール:「設定」 - 「ロギング」」の説明

ページレット・プロデューサは、標準のOracle Diagnostic Loggingファシリティにメッセージのログを記録します。Oracle WebLogic Serverでは、ログはuser-projects/domains/ <domain>/servers/<server>/logs/<server>-diagnostic.logに格納されます。

63.3.4.1 HTTPトレース

ページレット・プロデューサによって送受信されたHTTPリクエストとレスポンスを表示するには、「ログ設定」ページで「HTTP」コンポーネントを「最も詳細」に設定します。次のトレースの例は、テスト環境から取得されたものです。

例63-5 ページレット・プロデューサによって受信されたHTTPリクエスト

URL: http://10.148.118.211:7001/pagelets/bidwiki/includes/js/ajax.js
METHOD: GET
SESSION ID: GdYGNJzMhxy1CJBMVTX8xTNq32GmLXYNY9VqFBcdprFnhcyQtzdp!1377086614!1305769149498
HEADERS: 
  Host: 10.148.118.211:7001
  Connection: keep-alive
  Referer: http://example.com:7001/pagelets/bidwiki/dashboard.action
  User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.205 Safari/534.16
  Accept: */*
  Accept-Encoding: gzip,deflate,sdch
  Accept-Language: en-US,en;q=0.8,ru;q=0.6,it;q=0.4
  Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
  If-None-Match: W/"736-1124953206000"
  If-Modified-Since: Thu, 25 Aug 2005 07:00:06 GMT
COOKIES: 
  JSESSIONID: GdYGNJzMhxy1CJBMVTX8xTNq32GmLXYNY9VqFBcdprFnhcyQtzdp!1377086614

例63-6 ページレット・プロデューサから送信されたHTTPレスポンス

URL: http://example.com:7001/pagelets/bidwiki/styles/main-action.css
Response Code: 200
Reason: 
HEADERS: 
  Date: Thu, 19 May 2011 01:39:14 GMT
  Content-Type: text/css;charset=UTF-8
  Server: Apache-Coyote/1.1
BODY: 
.sidebar {
    /*background-image: url(http://example.com:7001/pagelets/bidwiki/download/ resources/leftnav_bg.jpg);*/
    /*background-repeat: repeat-y;*/
    background-color: #F0F0F0;
    /*border-bottom:1px solid #F0F0F0;*/
} ...

例63-7 ページレット・プロデューサから送信されたHTTPリクエスト

URL: http://example.com/includes/js/ajax.js
METHOD: GET
HEADERS: 
  CSP-Ensemble-REST-API: http://example.com:7001/pagelets
  X-Client-IP: 10.148.118.211
  User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.205 Safari/534.16
  CSP-Session-Username: weblogic
  Accept-Language: en-US,en;q=0.8,ru;q=0.6,it;q=0.4
  CSP-Gateway-Type: Proxy
  PT-Proxy-Passes: 1
  If-Modified-Since: Thu, 25 Aug 2005 07:00:06 GMT
  CSP-Protocol-Version: 1.4
  Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
  Accept-Encoding: gzip,deflate,sdch
  Referer: http://example.com:7001/pagelets/bidwiki/dashboard.action
  If-None-Match: W/"736-1124953206000"
  Accept: */*
  CSP-Aggregation-Mode: Single
  PT-Proxy-instance0: {DECBB085-D891-72CF-2B75-005E7FE20000}
  CSP-Gateway-Specific-Config: PT-User-Name=weblogic,PT-Guest-User=0,...

例63-8 ページレット・プロデューサによって受信されたHTTPレスポンス

Original URI: http://example.com/styles/main-action.css
Effective URI: http://example.com/styles/main-action.css
Status Code: 200
Reason: OK
Version: HTTP/1.1
HEADERS: 
  Content-Type: text/css;charset=UTF-8
  Content-Length: 29178
  Server: Apache-Coyote/1.1
  Date: Thu, 19 May 2011 01:39:14 GMT
TRAILERS: 
BODY: 
body, p, td, table, tr, .bodytext, .stepfield {
  font-family: Verdana, arial, sans-serif;
  font-size: 11px;
  line-height: 16px;
  color: #000000;
  font-weight: normal;
}

63.3.4.2 変換トレース

変換の前後にページレット・プロデューサによってプロキシされているコンテンツを表示するには、「ログ設定」ページで「変換」コンポーネントを「最も詳細」に設定します。これらのトレースの目的は、レスポンスのコンテンツを変換の様々な段階でログに記録し、それらを比較して各種トランスフォーマの結果を表示できるようにすることです。次のトレース例はテスト環境から取得されたものです。

例63-9 未変換のマークアップ

Original request: URL: http://10.148.118.211:7001/pagelets/bidwiki/styles/main-action.css
METHOD: GET
SESSION ID: GdYGNJzMhxy1CJBMVTX8xTNq32GmLXYNY9VqFBcdprFnhcyQtzdp!1377086614!1305769149498
HEADERS: 
  Host: example.com:7001
  Connection: keep-alive
  Referer: http://example.com:7001/pagelets/bidwiki/dashboard.action
  User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.205 Safari/534.16
  Accept: text/css,*/*;q=0.1
  Accept-Encoding: gzip,deflate,sdch
  Accept-Language: en-US,en;q=0.8,ru;q=0.6,it;q=0.4
  Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
COOKIES: 
  JSESSIONID: GdYGNJzMhxy1CJBMVTX8xTNq32GmLXYNY9VqFBcdprFnhcyQtzdp!1377086614
 
Untransformed content: 
body, p, td, table, tr, .bodytext, .stepfield {
  font-family: Verdana, arial, sans-serif;
  font-size: 11px;
  line-height: 16px;
  color: #000000;
  font-weight: normal;
}

例63-10 変換済のマークアップ(トランスフォーマ・クラスによって変換)

Transformed by: class com.plumtree.server.impl.portlet.transformers.CSSTurboParser
  Original request: URL: http://example.com:7001/pagelets/bidwiki/styles/main-action.css
METHOD: GET
SESSION ID: GdYGNJzMhxy1CJBMVTX8xTNq32GmLXYNY9VqFBcdprFnhcyQtzdp!1377086614!1305769149498
HEADERS: 
  Host: example.com:7001
  Connection: keep-alive
  Referer: http://example.com:7001/pagelets/bidwiki/dashboard.action
  User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.205 Safari/534.16
  Accept: text/css,*/*;q=0.1
  Accept-Encoding: gzip,deflate,sdch
  Accept-Language: en-US,en;q=0.8,ru;q=0.6,it;q=0.4
  Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
COOKIES: 
  JSESSIONID: GdYGNJzMhxy1CJBMVTX8xTNq32GmLXYNY9VqFBcdprFnhcyQtzdp!1377086614
 
Transformed content: 
body, p, td, table, tr, .bodytext, .stepfield {
  font-family: Verdana, arial, sans-serif;
  font-size: 11px;
  line-height: 16px;
  color: #000000;
  font-weight: normal;
}

63.4 WSRPおよびOracle JPDKポートレットの使用

ページレット・プロデューサを使用すると、WSRPおよびOracle JPDKポートレットを表示して任意のWebアプリケーションで使用できるようになります。WSRPまたはOracle JPDKポートレット・プロデューサに接続するためのページレット・プロデューサの構成の詳細は、『Oracle Fusion Middleware Oracle WebCenter Portal管理者ガイド』Oracle WebCenter Portalのページレット・プロデューサの管理に関する項を参照してください。次の第63.4.1項「ページレット・クロムの使用」で説明されているように、ページレット・プロデューサは、実行時にポートレット・マークアップを変更することもできます。

63.4.1 ページレット・クロムの使用

ページレット・クロムを使用すると、WSRPまたはJPDKポートレット・プロデューサからインポートされたポートレットを使用して作成されたページレットで実行時にマークアップを変更できます。

ページレット・クロム・テンプレートは次の各方法を指定するHTMLファイルです。

  • ポートレット・マークアップのスタイル・レンダリング方法

  • ポートレット・タイトルの表示方法

  • モード切替えオプションのレンダリング方法

デフォルトのクロム・テンプレートには、ポートレット名とドロップダウン・メニューが表示され、ユーザーはこれを使用して各種モードに切り替えることができます。ドロップダウン・メニューには、基本のポートレットでサポートされている標準のモードがすべて動的に移入されます。テンプレートでは、次の予約済トークンを使用して主要なポートレット要素を識別します。この要素は、実行時にページレット・プロデューサによって置換されます。

表63-3 ページレット・クロム・テンプレートのトークン

トークン 説明
$$PORTLET TITLE$$

ポートレット・タイトル

$$REPEAT MENU ITEM$$

ナビゲーショナル・アイテムの繰返しセクションの始まりを示すために使用

$$END REPEAT MENU ITEM$$

ナビゲーショナル・アイテムの繰返しセクションの終わりを示すために使用

$$MENU ITEM URL$$

ナビゲーションURL (ポートレット・モードまたはウィンドウ状態の切替え用)

$$MENU ITEM$$ 

ナビゲーショナル・アイテムの名前(Customizeなど)の表示

$$TOKEN$$

ページ上のページレット・インスタンスの一意の識別子

$$PORTLET CONTENT$$

ポートレット・コンテンツ

pt://images

imageserverのURLを示すために使用されるタグ


次に、非常に単純なページレット・クロム・テンプレートの例を示します。

<script type="text/javascript">
function goto(url)
{
  document.location = url;
  return false;
}
</script>
<div style="border: 1px solid">
<span><b><!-- $$PORTLET TITLE$$ --></b></span>
<span style="align: right">
  Switch Mode:
  <select size="1" name="mode">
    <!-- $$REPEAT MENU ITEM$$ -->
    <option onclick="goto('$$MENU ITEM URL$$')"><!-- $$MENU ITEM$$ --></option>
    <!-- $$END REPEAT MENU ITEM$$ -->
  </select>
 
</span>
</div>
<!-- $$PORTLET CONTENT$$ -->

注意:

ページレット・クロム・テンプレート・ファイルは、ページレット・プロデューサWebアプリケーションのclasspathでホストする必要があります。

外部イメージ・サーバーを使用するようにページレット・プロデューサを構成した場合は、ensemblestatic.war/imageserver/yahooからイメージ・サーバーにファイルをコピーしてデフォルトのクロム・テンプレートが正しくレンダリングされるようにします。


クロム・テンプレートを実装するには、パラメータとしてページレット注入URLに追加します(RESTまたはJavaScript)。ページレット注入URLの詳細は、第63.2.2項「Webページへのページレットの追加」を参照してください。次に例を示します。

  • REST: /inject/v2/pagelet/pagelet_lib/pagelet_name?chrome=mychrome.html

  • JavaScript: injectpagelet(library, name, iframe_options, payload, params, context_id, element_id, is_in_community, chrome)

クロム・パラメータの値には、クロム・テンプレートを含むファイルの名前または特別に予約された値noneを指定できます。この予約された値はすべてのクロムを抑制してポートレット・マークアップのみを返します。クロム・パラメータを省略すると、デフォルトのクロムがポートレット・マークアップとともに返されます。デフォルトのクロム・テンプレートには、YUIメニュー・コントロールを使用してグラデーション・タイトル・バーやモード切替え用のDHTMLドロップダウン・メニューが表示されます。(ADFコンテンツが削除された場合は、デフォルトで別のクロム・テンプレートが使用されます。このテンプレートは、カスタム・テンプレートまたはchrome=chrometemplate.htmlと設定された標準のデフォルト・テンプレートでオーバーライドできます。)

63.5 OpenSocialガジェットの使用

ページレット・プロデューサ・サーバーからアクセス可能なOpenSocialガジェットは、ページレットとして登録して、ポータルなどのWebアプリケーションで使用できます。ページレット・プロデューサへのOpenSocialページレットの登録の詳細は、『Oracle Fusion Middleware Oracle WebCenter Portal管理者ガイド』Oracle WebCenter Portalのページレット・プロデューサの管理に関する項を参照してください。

ページレット・プロデューサでは、OAuthを除く、標準のOpenSocial APIのほとんどをサポートしています。OpenSocial APIリファレンスのドキュメント一式は、http://shindig.apache.org/shindig-1.1.x/shindig-features/jsdoc/index.htmlで入手できます。

ページレット・プロデューサでは、OpenSocial APIを使用した、ガジェットによるプリファレンスの保存、WebCenter Portalプロファイルと接続情報の取得およびユーザーのアクティビティ・ストリームへのアクセスが可能です。これらの機能の使用方法の詳細は、後続の項を参照してください。

63.5.1 認証の構成

ガジェットからユーザーレベルのデータ(プリファレンスやピープル・コネクション)をリクエストするには、エンド・ユーザーのIDを確立する必要があります。任意のOpenSocialガゼットがサーバーのユーザーレベルのデータにアクセスする必要がある場合は、ページレット・プロデューサ・コンソールで親のOpenSocialリソースのセキュリティ・ポリシーを構成する必要があります。ユーザーがOpenSocialガゼットに初めてアクセスすると、ログイン・ページが表示されます。初回ログイン後は、OpenSocialガゼットに対する後続のリクエストで確立されたユーザーIDが使用されます。

ページレット・プロデューサ・リソースのセキュリティ・ポリシーの構成の詳細は、『Oracle Fusion Middleware Oracle WebCenter Portal管理者ガイド』の「ページレットの管理」の章を参照してください。

63.5.2 ユーザー・プリファレンスの格納

OpenSocialガゼットでは、ユーザー・プリファレンスを使用してコンテナでデータを格納できます。ユーザー・プリファレンスは、特定のユーザーにスコープ設定されますが、オプションで、appIdにスコープ設定することもできます(ガゼットappIdはページレットのコンテキストIDです)。OpenSocial gadget.Prefs APIを使用する場合は、ユーザー・プリファレンスはユーザーとページレット・インスタンスにスコープ設定されます。または、opensocial.DataRequest APIを使用して、他のページレットと共有可能なプリファレンスをユーザー・レベルで管理することもできます。

ページレットとして登録した場合は、ガゼットのユーザー・プリファレンスはページレット・プリファレンスとして処理されます。WebCenter Portalでは、たとえば、隠されていないユーザー・プリファレンスを、「パーソナライズ」ボタンを使用してエンド・ユーザーが編集できます。さらに、ユーザー間で共有されたプリファレンスをシミュレートするために、ページレット・パラメータを介してユーザー・プリファレンスを渡すことができます。ページレット・プリファレンスが設定されている場合は、対応するページレット・パラメータが常にオーバーライドされます(つまり、パーソナライズはカスタマイズに優先します)。

WebCenter Portalの外では、ガジェットがサポートするページレットに、プリファレンス・エディタにアクセスし、ガジェットを最大/最小化するためのガジェット・タイトルとボタンを表示する簡単なクロムが提供されます。値noneをページレット注入APIのクロム・パラメータに渡すことにより、クロムを抑止できます。プリファレンス・エディタのUIでは、次の4種類のユーザー・プリファレンスをすべてサポートしています。

  • string: テキスト・フィールドとしてレンダリング

  • bool: チェック・ボックスとしてレンダリング

  • enum: ドロップダウン・リストとしてレンダリング

  • list: テキスト・フィールドとしてレンダリング(値はパイプ「|」文字で区切る必要があります)

63.5.3 WebCenter Portalプロファイル情報へのアクセス

OpenSocialガジェットでは、標準のOpenSocial APIを介して現在のユーザーのプロファイル・データとピープル・コネクションを問合せできます。この機能を使用するには、『Oracle Fusion Middleware Oracle WebCenter Portal管理者ガイド』Oracle WebCenter Portalのページレット・プロデューサの管理に関する項の説明に従って、WebCenterDSデータ・ソースのターゲットをWC_Portletサーバーに設定する必要があります。


注意:

OpenSocial APIをプロファイルや接続情報の更新に使用することはできません。


サポートされているユーザー・プロファイルのフィールドを次の表に示します。

表63-4 ユーザー・プロファイルのフィールド

OpenSocialフィールド タイプ 説明

aboutme

string

個人に関する一般的な説明。

addresses

Plural-Field <Address>

個人の物理メーリング・アドレス。

appData

Plural-Field <AppData>

AppDataのキーと値のコレクションで、プリファレンスに使用。

birthday

Date

個人の生年月日。値は有効な日付である必要があります。この個人の年齢がプライベートであるか、入力した年が使用不可能である場合は、年が0000に設定される場合があります。

emails

Plural-Field <string>

個人の電子メール・アドレス。

location

string

個人の物理的な住所。

name

Name

個人の実名のコンポーネントを分解して書式設定したバージョン。

organizations

Plural-Field <Organization>

個人の現在や過去の組織的な所属。

phoneNumbers

Plural-Field <string>

個人の電話番号。このタイプに正当な標準値に加え、このフィールドでは、モバイル、ファックスおよびページャなどの追加の値を定義します。

photos

Plural-Field <string>

個人の写真のURL。この値は、イメージを含むWebページではなく、実際のイメージ・ファイル(GIF、JPEGまたはPNGイメージ・ファイルなど)を指す必要があります。このフィールドは、このユーザーが撮影した任意の写真の送信には使用しないでください。具体的には、連絡先を説明する場合に表示するプロファイル写真を指定します。

preferredUsername

string

ユーザー名を要求するサイトでの、この個人の優先ユーザー名(jsmarrまたはdaveman692など)。

status

string

個人のステータス、ヘッドラインまたは挨拶。

thumbnailUrl

string

文字列として指定された、個人の写真のサムネイルのURL。これは完全修飾URLである必要があります。


63.5.4 ユーザーのアクティビティ・ストリームへのアクセス

OpenSocialガジェットは、OpenSocial APIを使用してユーザーのアクティビティ・ストリームを操作できます。次の操作がサポートされています。

  • アクティビティの取得

  • アクティビティの作成

次の操作はサポートされていません。

  • アクティビティの更新

  • アクティビティの削除

サポートされているアクティビティ・ストリームのフィールドを次の表に示します。

表63-5 アクティビティ・ストリームのフィールド

OpenSocialフィールド タイプ 説明

appId

Object-Id

アクティビティが関連付けられているアプリケーション。

body

string

アクティビティの拡張バージョン(オプション)。ボディには次のHTMLタグ、<b>、<i>、<a>、<span>のみが含まれている可能性があります。ただし、この書式設定は無視される場合があります。

externalId

Object-Id

投稿アプリケーションで生成されるオプションのID。

id

Object-Id

アクティビティに永続的に関連付けられているID。

postedTime

string

エポック以降にアクティビティが実行された時間(ミリ秒)。

priority

number

同じソースの別のアクティビティとの関連で、該当のアクティビティの相対優先順位を表す0から1までの数値。

title

string

アクティビティのプライマリ・テキスト。タイトルには、次のHTMLタグ、<b>、<i>、<a>、<span>のみが含まれている可能性があります。ただし、この書式設定は無視される場合があります。

userId

Object-Id

アクティビティの定義対象であるユーザーのID。


63.5.5 ガジェット・イベンティングの使用

ページレット・プロデューサでは、OpenSocial PubSubガジェット間イベント・モデルをサポートしています。ガジェットでは、JavaScriptで任意の数のチャネル(単純な文字列名で定義)を通じてイベントを公開できます。受信が終了すると、ガジェットは、再びJavaScriptで任意の数のチャネルを通じてイベントの受信をサブスクライブし、イベントに応じて適切な処理を実行できます。

function connSelected(element) {
  var connId = element.id;
  var connName = element.lastChild.textContent;
  gadgets.pubsub.publish(channel, {id: connId, name: connName});

サポートされているイベントAPIへのJavaScriptの完全参照は、http://shindig.apache.org/shindig-1.1.x/shindig-features/jsdoc/symbols/gadgets.pubsub.htmlを参照してください。

63.5.6 例: 外部OpenSocialガジェットの消費

次の例は説明のために簡略化されています。ページレット・プロデューサ・コンソールの設定の詳細は、『Oracle Fusion Middleware Oracle WebCenter Portal管理者ガイド』「Oracle WebCenter Portalのページレット・プロデューサの管理」を参照してください。

  1. ページレット・プロデューサ・コンソールを使用して新しいリソースを作成し、タイプに「OpenSocial」を選択します。必要に応じてURLおよびポリシーを定義します。新しいリソースを保存します。

  2. ページレット・プロデューサ・コンソールを使用して、新しいページレットを作成し、「ガジェットURL」フィールドにガジェットXMLスキーマの場所を入力します。

    • ガジェット名およびガジェットに定義されたすべてのプリファレンスをインポートするには、「ガジェット・メタデータのインポート」ボタンをクリックします。いずれかのプリファレンスが編集可能な場合、ページレット・プロデューサは、インポートされたプリファレンスを使用してプリファレンス・エディタを作成します。

    • 生成されたプリファレンス・エディタを構成またはカスタマイズするには、「ページレット・パラメータ」ページに移動します。

  3. 「ドキュメント」ページに移動し、JavaScriptまたはREST APIを使用してページレットおよびプリファレンス・エディタにアクセスするためのサンプル・コードを確認します。

  4. 新しいページレットを保存します。

63.5.7 例: ローカルOpenSocialガジェットの消費

次の例は説明のために簡略化されています。ページレット・プロデューサ・コンソールの設定の詳細は、『Oracle Fusion Middleware Oracle WebCenter Portal管理者ガイド』「Oracle WebCenter Portalのページレット・プロデューサの管理」を参照してください。

  1. ページレット・プロデューサ・コンソールを使用して新しいリソースを作成し、タイプに「OpenSocial」を選択します。必要に応じてURLおよびポリシーを定義します。新しいリソースを保存します。

  2. ガジェット・ファイルを作成またはアップロードします。


    注意:

    OpenSocialガジェットXMLファイルをホストする場合は、このファイルを匿名リソース(セキュリティ・ポリシーなし)の下に配置する必要があります。そこに配置しないと、ガジェットが正常に機能しません。


    1. 匿名リソースの下の「ファイル」セクションを選択し、ツールバーの「作成」アイコンをクリックします。

    2. 「一般」ページの「名前」フィールドに、ファイルの相対パスを入力します。先頭にスラッシュ(/)を使用しないでください。たとえば、gadgets/activities.xmlなどのように入力します。任意のパスと名前を使用できます。パスは、ページレット・プロデューサがファイルを処理するために使用する仮想URLになります。ナビゲータに視覚的に表示されるファイル・コレクションのディレクトリ構造は、ファイルのパスに適合するように更新されます。

    3. ガジェット・ファイルをアップロードまたは作成するには、「コンテンツ」ページに進みます。

      ガジェット・ファイルをアップロードするには、ファイルへのパスを入力するか「参照」ボタンをクリックしてファイルに移動し、「アップロード」ボタンをクリックし、ページレット・プロデューサ・サーバーにファイルをアップロードします。

      ガジェット・ファイルを作成するには、「コンテンツ」ページでエディタを使用してコンテンツを入力したり編集します。

    4. ナビゲータ・ツールバーの保存アイコンをクリックします。

  3. ガジェットで必要なその他のファイル(JavaScript、イメージなど)を、リソースの「ファイル」セクションで作成またはアップロードします。ガジェット・コードのパスに一致するファイルのパスを定義します。たとえば、ガジェットがjsというサブフォルダのJavaScriptファイルを使用する場合は、ファイル(gadgets/js/activities.jsなど)をアップロードする際に「名前」フィールドにディレクトリを指定します。

  4. ページレット・プロデューサ・コンソールを使用して、新しいページレットを作成し、「ガジェットURL」フィールドに(ステップ2で作成またはアップロードした)ガジェットのXMLスキーマの相対パスを入力します。ローカル・ファイルの場合は、これはファイル・オブジェクトの「名前」フィールドに定義されているパスと同じになります(gadgets/activities.xmlなど)。

    • ガジェット名およびガジェットに定義されたすべてのプリファレンスをインポートするには、「ガジェット・メタデータのインポート」ボタンをクリックします。いずれかのプリファレンスが編集可能な場合、ページレット・プロデューサは、インポートされたプリファレンスを使用してプリファレンス・エディタを作成します。

    • 生成されたプリファレンス・エディタを構成またはカスタマイズするには、「ページレット・パラメータ」ページに移動します。

  5. 「ドキュメント」ページに移動し、JavaScriptまたはREST APIを使用してページレットおよびプリファレンス・エディタにアクセスするためのサンプル・コードを確認します。

  6. 新しいページレットを保存します。