ヘッダーをスキップ
Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド
11gリリース1(11.1.1)
B52029-02
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

30 カスタムADF Facesコンポーネントの作成

この章では、カスタムADF Facesリッチ・クライアント・コンポーネントの作成方法を説明します。

この章に含まれる項は次のとおりです。

30.1 カスタムADF Facesコンポーネントの概要

ADF Facesコンポーネント・ライブラリには、ユーザー要件の大部分をカバーするUIコンポーネントの包括的なセットが用意されています。ただし、アプリケーションに固有のカスタム・リッチ・コンポーネントを作成する必要がある場合があります。カスタム・リッチ・コンポーネントによって、カスタム動作が可能になり、アプリケーションのニーズに最適なアクションを実行できます。


注意:

カスタム標準JSFコンポーネントの作成については、多くの本、記事、WebサイトおよびJavaServer Facesの仕様で取り上げられているため、このガイドでは説明しません。この章では、ADF Facesコンポーネントの作成方法を説明します。

JSFテクノロジは、コンポーネントとその他のフレームワーク部分を自己登録できるように構築されています。コアJSFランタイムでは、Webアプリケーションの起動時にクラス・パスのすべてのJARファイルを検査することで、自己登録が行われます。/META-INF/faces-config.xmlファイルにJSFアーチファクトが含まれるすべてのJARファイルがロードされます。そのため、カスタムADF FacesコンポーネントをJARファイルにパッケージ化し、Webプロジェクトに簡単に追加できます。

各ADF Facesコンポーネントにはサーバー側コンポーネントがあり、クライアント側コンポーネントがある場合もあります。サーバーでは、レンダー・キットによって、マークアップ言語とJavaScriptの複雑な組合せを調整するためのベースが提供されます。サーバー側フレームワークではカスタム・ライフサイクルも追加され、部分ページ・コンポーネント・レンダリングのAPIフックを利用できます。クライアントでは、ADF Facesにより、様々な重要なタスクを処理する構造化されたJavaScriptフレームワークが提供されます。それらのタスクには、部分ページ・レンダリングを使用した状態の同期化が含まれます。ADF Facesアーキテクチャの詳細は、第3章「ADF Facesアーキテクチャの使用」を参照してください。

ADF Facesコンポーネントは、Apache MyFaces Trinidadコンポーネント・ライブラリから導出されます。このため、カスタムADF Facesコンポーネントを作成するときに拡張するクラスの多くは、実際にはMyFaces Trinidadのクラスとなります。ADF Facesの履歴(その発展を含む)の詳細は、第1章「ADF Facesリッチ・クライアントの概要」を参照してください。

JSPコンポーネントとJSFコンポーネントの間にApplicationクラスがあります。タグ・ライブラリでは、applicationオブジェクトに対してファクトリ・メソッドが使用され、componentTypeと呼ばれるニーモニックを使用して具体的なコンポーネント・インスタンスがインスタンス化されます。

コンポーネントでは独自のマークアップをレンダリングできますが、それがベスト・プラクティスであるとは考えられていません。プレゼンテーションのレンダリングの方法に焦点を当てたレンダー・キットを定義する方法をお薦めします。コンポーネントは、レンダー・キットに対してファクトリ・メソッドを使用して、特定のコンポーネントに関連付けられているレンダラを取得します。

作成するすべてのカスタム・コンポーネントでは、機能面に加え、その他のADF Facesコンポーネントで正しく表示されるようにするために、ADF Facesスキンを使用する必要があります。スキンを使用するには、コンポーネントのスキニング・キーとプロパティを作成して登録する必要があります。この章では、カスタム・コンポーネントのスキンの作成方法および登録方法のみ説明します。一般的なスキンの使用方法および作成方法の詳細は、第20章「スタイルおよびスキンを使用した外観のカスタマイズ」を参照してください。


ヒント:

ADF Facesコンポーネントを使用するには、カスタム・コンポーネントでは、簡単なスキンから継承したblafplus-richおよびblafplus-mediumスキンとして、少なくとも簡単なADF Facesスキンを使用する必要があります。また、コンポーネントをOracle WebCenterアプリケーションで使用する可能性がある場合は、使用するスキンはsimple.portletスキンにも登録する必要があります。

30.1.1 JDeveloperを使用したカスタム・コンポーネントの開発

ADF Facesコンポーネントは、クライアント側リソースとサーバー側リソースの両方で構成されています。クライアント側には、クライアント・コンポーネント、コンポーネント・ピア(コンポーネント・プレゼンタ)、およびクライアント・コンポーネントに関連付けられているすべてのイベントがあります。

サーバー側には、サーバー・コンポーネント、サーバー・コンポーネント・イベントおよびイベント・リスナーがあります。また、コンポーネント・レンダラ、コンポーネントJSPタグ、コンポジット・リソース・ローダー、JavaScriptリソース・ローダーおよびリソース・バンドルもあります。

コンポーネントには複数の構成ファイルとサポート・ファイルもあります。それらのクラス、JavaScriptsおよび構成ファイルが1つのJARファイルにすべてパッケージ化されています。そのJARファイルは、ライブラリとしてアプリケーションにインポートし、その他のコンポーネントと同様に使用できます。

JDeveloperを使用して、カスタム・コンポーネントを開発するアプリケーション・ワークスペースおよびプロジェクトを設定できます。ワークスペースおよびプロジェクトを作成したら、カスタム・コンポーネントを構成する必須のクラス、JavaScriptファイルおよび構成ファイルに対して、基礎作業ファイルを追加します。開発時には、カスタム・コンポーネントに固有のそれらのファイルをそれぞれ編集し、ファイルにコードを追加します。

開発プロセスは次のとおりです。

  1. 開発の環境として、アプリケーション、ワークスペースおよびプロジェクトを作成します。これには、ライブラリ依存性の追加、XMLスキーマの登録が含まれます。コンポーネントは、そのコンポーネントを使用する予定があるアプリケーションには作成しないでください。

  2. JARファイルにコンポーネントをパッケージ化するためのデプロイメント・プロファイルを作成します。

  3. 次の基礎構成ファイルとサポート・ファイルを作成します。

    • faces-config.xml: コンポーネントで使用される多くのアーチファクトを登録するために使用します。

    • trinidad-skins.xml: コンポーネントが使用するスキンを登録するために使用します。

    • Cascading Style Sheet: スキンのスタイル・プロパティを定義するために使用します。

    • レンダー・キット・リソース・ローダー: コンポーネントで必要とされるすべてのリソースをアプリケーションでロードできるようにします。

    • adf-js-features.xml: コンポーネントをJavaScriptパーティションの一部にできます。パーティションの詳細は、1.2.1.2項「JavaScriptライブラリのパーティション化」を参照してください。

    • JSPタグ・ライブラリ・ディスクリプタ(TLD): JSFページで使用するタグを定義します。

  4. 次のクライアント側JavaScriptファイルを作成します。

    • クライアント・コンポーネント: クライアントのコンポーネントとその属性を表します。

    • クライアント・ピア: コンポーネントのDocument Object Model(DOM)を管理します。

    • クライアント・イベント: クライアントでの処理を起動し、オプションでサーバーに処理を伝播します。

  5. 次のサーバー側Javaファイルを作成します。

    • サーバー・コンポーネント・クラス: サーバーのコンポーネントを表します。

    • サーバー・イベント・リスナー・クラス: イベントをリスニングして、応答します。

    • サーバー・イベント・クラス: サーバーのイベントを起動します。

    • サーバー・レンダラ・クラス: コンポーネントの表示を決定します。

    • リソース・バンドル・クラス: コンポーネントで使用されるテキスト文字列を定義します。

  6. JavaScriptおよびJavaコードをテストおよびデバッグして、コンポーネントの開発をさらに進めます。JDeveloperデバッガを使用して、ブレークポイントを設定し、コードを段階的に開発できます。Javaロギング機能を使用して、コンポーネントの実行をトレースすることもできます。

  7. JARファイルにコンポーネントをデプロイします。

  8. コンポーネントをアプリケーションに追加してテストします。

表30-1には、カスタム・コンポーネントのクライアント側およびサーバー側コンポーネントのアーチファクトがリストされています。この表には構成ファイルおよびサポート・ファイルは含まれていません。

表30-1 カスタム・コンポーネントのクライアント側およびサーバー側アーチファクト

クライアント サーバー

コンポーネント・クラス:

oracle.component_package.js.component.prefixComponent_name.js

拡張:

oracle.adf.view.js.component. AdfUIObject.js

コンポーネント:

oracle.<component_package>.faces.component.<Component_name>.java

拡張:

org.apache.myfaces.trinidad.component.UIXObject.java

イベント:

oracle.<component_package>.js.event.<prefix><Event_name>.js

拡張:

oracle.adf.view.js.component.AdfComponentEvent.js

イベント:

oracle.<component_package>.faces.event.<Event_name>.java

拡張:

javax.faces.event.FacesEvent.java


イベント・リスナー:

oracle.<component_package>.faces.event<Listener_name>

拡張:

com.faces.event.FacesListener

コンポーネント・ピア:

com.<component_package>.js.component.<prefix><Peer_name>Peer.js

拡張:

oracle.adf.view.js.laf.rich. AdfRichUIPeer.js.js



コンポーネント・レンダラ:

com.<component_package>.faces.render.<Renderer_name>.java

拡張:

oracle.adf.view.rich.render.RichRenderer.java


コンポーネントJSPタグ:

com.<component_package>.faces.taglib.<Tagname_name>Tag.java

拡張:

javax.faces.webapp.UIComponentELTag.java


コンポジット・リソース・ローダー:

com.<component_package>.faces.resource.<Loader_name>ResourceLoader.java

拡張:

org.myfaces.trinidad.resource.RegxResourceLoader.java


JavaScriptリソース・ローダー:

com.<component_package>.faces.resource.<Script_Loader_name>ResourceLoader.java

拡張:

org.myfaces.trinidad.resource.AggregateingResourceLoader.java


リソース・バンドル:

com.<component_package>.faces.resource.<Bundle_name>Bundle.java

拡張:

java.util.ListResouceBundle.java


30.1.2 カスタム・コンポーネントの例

カスタム・コンポーネントの作成について説明するために、手順全体でtagPaneという名前のカスタム・コンポーネントを例として使用します。tagPaneカスタム・コンポーネントは、再利用の目的で作成されます。tagPaneのプレゼンテーションは、既存の様々なコンポーネントを使用して実装可能ですが、単一のカスタム・コンポーネントを作成するとページ開発者の作業が単純化されます。この場合、コンポーネント開発者とページ開発者間の生産性においてトレードオフが生じることがあります。この特定のビューを複数回作成する必要がある場合、開発チームはコード行を減らし、ビジネス・プロセスの自動化タスクを単純化することで、コストを削減できます。

tagPaneコンポーネントは、ファイル・セットに対する一連のタグとその出現の重み付けを表示します。最も頻繁に使用されるタグは最大フォント・サイズで表示され、最も使用されないタグは最小フォント・サイズで表示されます。各タグはイベントをトリガーするリンクでもあり、トリガーされたイベントはサーバーに伝播されます。サーバーでは、そのタグを含むすべてのファイルが表に表示されます。図30-1に、tagPaneコンポーネントがFile Explorerアプリケーションの「検索」ペインの下に追加された場合にどのように表示されるかを示します。

図30-1 カスタムtagPaneコンポーネント

最も一般的なリンクを表示するために使用されるカスタム・コンポーネント

tagPaneコンポーネントは、Java Mapコレクションのタグのコレクションを受け取ります。マップのキーはタグ名です。値はタグに割り当てられた重みです。File Explorerアプリケーションでは、重みはタグの出現回数であり、多くの場合、タグに関連付けられているファイル数です。タグ名はリンクのボディ・テキストに表示され、名前の表示に使用されるフォント・サイズが重みを表します。各タグのフォント・サイズは、ファイル・セット内のすべてのタグに割り当てられている重みの最大と最小に基づき、最大フォント・サイズと最小フォント・サイズ内で相対的に計算されます。これらの機能を実行するには、tagPaneカスタム・コンポーネントにクライアント側とサーバー側の両方の動作を設定する必要があります。

サーバー側では、コンポーネントはHTMLハイパーリンクをレンダリングすることでタグのマップを表示します。基本的なマークアップ・レンダリングはサーバー側で実行されます。コンポーネントには、ユーザーによるリンクのクリックを処理し、関連ファイルを表示するためのカスタム・イベントを定義します。これらのサーバー側の動作は、値式およびメソッド式を使用して定義します。

たとえば、tagPaneコンポーネントには次のものが含まれます。

  • タグのMap<String, Number>コレクションを設定するtagプロパティ。

  • タグのリンクをクリックしたときにサーバーで起動されるtagSelectionListenerメソッド・バインディング・イベント。

  • 重みの降順で左から右に一連のタグを表示する、またはアルファベットの昇順にタグのリンクを表示するためのorderByプロパティ。

各タグをその重み(出現回数)に比例したフォント・サイズで表示するために、フォント・サイズはインライン・スタイルを使用して制御されます。ただし、各タグとコンポーネントのルート・マークアップ・ノードもスタイル・クラスを使用します。

例30-1に、tagPaneコンポーネントのJSFページでの使用方法を示します。

例30-1 JSFページのtagPaneカスタム・コンポーネント・タグ

<acme:tagPane id="tagPane" tags="#{explorer.navigatorManager.tagNavigator.tags}"
  tagSelectListener="#{explorer.navigatorManager.tagNavigator.onTagSelect}"
  orderBy="alpha"
  partialTriggers="tagCountLabel"/>

tagPaneコンポーネントは、他のADF Facesコンポーネントとともに使用される必要があるため、同じスキンを使用する必要があります。そのため、すべてのスタイル設定は、Cascading Style Sheet(CSS)および対応するスキン・セレクタを使用して実現されます。たとえば、tagPaneコンポーネントでは、ルート要素を指定し、リンクのコンテナのスタイルおよびハイパーリンクの表示方法を定義するために、スキン・セレクタが必要です。例30-2に、tagPaneコンポーネントのCSSファイル内のスタイル・セレクタのサンプル・セットを示します。

例30-2 サンプル・カスタム・コンポーネントのCSSスタイル・セレクタ

acme|tagPane     - root element
acme|tagPane::content - container for the links
acme|tagPane::tag - tag hyperlink

サーバー側のカスタム・コンポーネントに必要なHTMLコードを指定する必要がある場合もあります。

例30-3に、tagPaneコンポーネントで使用されるHTMLサーバー側のコードを示します。

例30-3 サーバー側のHTMLコード

<div class=" acme|tagPane">
  <span class=" acme|tagPane::content ">
    <a class=" acme|tagPane::tag" href="#" style="font-size:9px;">Tag1</a>
    <a class=" acme|tagPane::tag" href="#" style="font-size:10px;">Tag2</a>
  </span>
</div>

クライアント側のコンポーネントには、クライアント側の動作を定義する、対応するJavaScriptコンポーネントとコンポーネント・ピアが必要です。DOMとのすべての対話は、ピアを使用して行われます(詳細は、第3章「ADF Facesアーキテクチャの使用」を参照してください)。コンポーネント・ピアでは、タグ名を囲むハイパーリンクのクリックがリスニングされます。リンクがクリックされると、ピアによってクライアント側でカスタム・イベントが発生し、そのイベントがサーバー側に伝播されて、追加処理されます。

表30-2には、tagPaneコンポーネントのクライアント側とサーバー側のアーチファクトがリストされています。表30-1のネーミング規則を参照すると、component_packagecom.adfdemo.acmeprefixAcmeです。

表30-2 tagPaneカスタム・コンポーネントのクライアント側およびサーバー側アーチファクト

クライアント サーバー

コンポーネント:

com.adfdemo.acme.js.component.AcmeTagPane.js

拡張:

oracle.adf.view.js.component.AdfUIObject.java

コンポーネント

com.adfdemo.acme.faces.component.TagPane.java

拡張:

org.apache.myfaces.trinidad.component.UIXObject.java

イベント:

com.adfdemo.acme.js.event.AcmeTagSelectEvent.js

拡張:

oracle.adf.view.js.component.AdfComponentEvent.js

イベント:

com.adfdemo.acme.faces.event.TagSelectEvent.java

拡張:

javax.faces.event.FacesEvent.java


イベント・リスナー:

com.adfdemo.acme.faces.event.SelectListener

拡張:

com.faces.event.FacesListener

コンポーネント・ピア:

com.adfdemo.acme.js.component.AcmeTagPanePeer.js

拡張:

oracle.adf.view.js.laf.rich.AdfRichUIPeer.js



コンポーネント・レンダラ:

com.adfdemo.acme.faces.render.TagPaneRenderer.java

拡張:

oracle.adf.view.rich.render.RichRenderer.java


コンポーネントJSPタグ:

oracle.adfdemo.acme.faces.taglib.TagPaneTag.java

拡張:

javax.faces.webapp.UIComponentELTag.java


コンポジット・リソース・ローダー:

oracle.adfdemo.acme.faces.resource.AcmeResourceLoader.java

拡張:

org.myfaces.trinidad.resource.RegxResourceLoader.java


JavaScriptリソース・ローダー:

oracle.adfdemo.acme.faces.resource.ScriptsResourceLoader.java

拡張:

org.myfaces.trinidad.resource.AggregateingResourceLoader.java


リソース・バンドル:

oracle.adfdemo.acme.faces.resource.AcmeSimpleDesktopBundle.java

拡張:

java.util.ListResouceBundle.java


30.2 ワークスペースと基礎ファイルの設定

JDeveloperを使用して、カスタム・コンポーネントを開発するためのアプリケーションおよびプロジェクトを設定します。スケルトン・プロジェクトを作成すると、JARファイルにコンポーネントをパッケージ化するためのデプロイメント・プロファイルを追加できます。

開発の初期段階では、開発を可能にするための基礎構成ファイルとサポート・ファイルを作成します。これらのファイルはプロセス中に追加および編集することもできます。次の構成ファイルを作成します。

たとえば、tagPaneコンポーネントには次の構成ファイルが必要です。

JDeveloperでファイルを設定したら、ファイルにコンテンツを追加します。その後、クライアント側のファイルを作成します。30.3項「クライアント側の開発」を参照してください。サーバー側のファイルについては、30.4項「サーバー側の開発」を参照してください。

30.2.1 JDeveloperカスタム・コンポーネント環境の設定方法

この項以降では、ユーザーがJDeveloperの使用経験があり、アプリケーションの作成およびデプロイに伴う手順に精通していると仮定しています。JDeveloperを使用したアプリケーション作成の詳細は、第2章「ADF Faces概説」を参照してください。デプロイメントの詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』の「Fusion Webアプリケーションのデプロイ」を参照してください。

JDeveloperでカスタム・コンポーネントの開発環境を設定する手順:

  1. コンポーネントの開発コンテナとして機能するアプリケーションを作成します。JDeveloperを使用して、ワークスペースおよびプロジェクトを作成します。アプリケーションの作成手順は、2.2項「アプリケーション・ワークスペースの作成」を参照してください。アプリケーション・テンプレートを選択するときには、汎用アプリケーション・テンプレートを選択します。


    注意:

    他のアプリケーション・テンプレートを選択したり、他のテクノロジをアプリケーションに追加したりしないでください。カスタム・コンポーネントはJARファイルにパッケージ化されるため、Webアプリケーションに固有のテンプレートを使用するときまたはWebテクノロジを追加するときに、デフォルトでJDeveloperによって作成されるpublic_htmlのような不要なフォルダを作成する必要はありません。かわりに、XMLスキーマから基礎構成ファイルを作成します。

  2. 新しいデプロイメント・プロファイルを作成し、プロジェクトをJARファイルとしてデプロイできるようにします。

    1. プロジェクトを右クリックし、「新規」を選択して、「新規ギャラリ」を開きます。

    2. 「新規ギャラリ」の左ペインで「デプロイメント・プロファイル」を選択し、右ペインで「ADFライブラリのJARファイル」を選択して、「OK」をクリックします。

    3. 「デプロイメント・プロファイルの作成」ダイアログで、「デプロイメント・プロファイル名」に名前を入力します。たとえば、tagPaneコンポーネントの場合は、adf-richclient-demo-acmeを使用します。

    4. 「JARデプロイメント・プロファイルのプロパティの編集」ダイアログで、「OK」をクリックします。

  3. 「プロジェクト・プロパティ」ダイアログで、ライブラリ依存性を追加します。

    1. 左ペインで「ライブラリとクラスパス」を選択します。

    2. 「ライブラリの追加」をクリックします。

    3. 「ライブラリの追加」ダイアログで、ADF Faces Runtime 11JSF 1.2およびJSP Runtimeを選択して、「OK」をクリックします。

    4. 「OK」をクリックして、「プロジェクト・プロパティ」ダイアログを閉じます。

  4. XMLスキーマを登録します。

    カスタム・コンポーネントには、複数のXML構成ファイルが必要です。JDeveloperを使用して、それらの構成ファイルに関連付けられているXMLスキーマを登録できます。faces-config.xmltrinidad-skins.xmlおよびtrinidad-config.xmlの3つの構成ファイルのスキーマを追加する必要があります。これらのスキーマを事前登録することにより、マークアップ構造の詳細を理解できなくても、テンプレートXML構成ファイルを作成できます。スキーマの名前と場所は、JDeveloperのベース・インストールによって想定されます。

    1. 「ツール」「設定」を選択します。「設定」ダイアログの左ペインで「XMLスキーマ」を選択し、「追加」をクリックします。

    2. 表30-3に示すように、「スキーマの追加」ダイアログで「参照」をクリックして、JDeveloperビルドに含まれているXMLスキーマに移動します。


      注意:

      「スキーマの追加」ダイアログでは、「拡張子」.xmlに設定されていることを確認してください。拡張子をXSDに変更すると、後でXMLファイルを作成するときに、作成したXMLスキーマを使用できなくなります。

      表30-3 XMLスキーマの場所

      XML構成ファイル

      /META-INF/faces-config.xml

      JDeveloper_Home/jdeveloper/modules/oracle.jsf_1.2.9/glassfish.jsf_1.2.9jar!/com/sun/faces/web-facesconfig_1_2.xsd

      /META-INF/trinidad-skins.xml

      JDeveloper_Home/jdeveloper/modules/oralce.adf.view_11.1.1/trinidad-impl.jar!/org/apache/myfaces/trinidadinternal/ui/laf/xml/schemas/skin/trinidad-skins.xsd

      /META-INF/trinidad-config.xml

      JDeveloper_Home/jdeveloper/modules/oracle.adf.view_11.1.1/trinidad-api.jar!/trinidad-config.xsd

      /META-INF/adf-js-features.xml

      JDeveloper_Home/jdeveloper/modules/oracle.adf.view_11.1.1/adf-richclient-api-ll.jar!/adf-js-features.xsd


30.2.2 Faces構成ファイルの追加方法

カスタム・コンポーネントは使用アプリケーションのfaces-config.xmlファイルに登録されますが、開発中は、ワークスペースにfaces-config.xmlファイルが必要です。


注意:

JDeveloperの宣言ウィザードやダイアログを使用してfaces-config.xmlファイルを作成しないでください。これらの宣言メソッドは、Webアプリケーションの作成を前提としており、カスタム・コンポーネント・アプリケーションに不要なアーチファクトが追加されます。

カスタム・コンポーネントのfaces-config.xmlファイルを作成する手順:

  1. プロジェクトを右クリックし、「新規」を選択します。

  2. 「新規ギャラリ」ダイアログの左ペインで、「一般」「XML」を選択します。

  3. 右ペインで「XMLスキーマからXMLドキュメント」を選択し、「OK」をクリックします。

  4. XMLスキーマからXMLを作成ダイアログで、次のように設定します。

    • XMLファイル: faces-config.xmlと入力します。

    • ディレクトリ: ディレクトリ・エントリの最後に\src\META-INFを追加します。

    • 「登録済のスキーマを使用」を選択して、「次へ」をクリックします。

  5. 次の内容を入力します。

    • ターゲット・ネームスペース: http://java.sun.com/xml/ns/javaeeを選択します。

    • ルート要素: faces-configを選択します。

    他のフィールドはデフォルトのままにして、「終了」をクリックします。

    新しいファイルがXMLエディタで自動的に開きます。

  6. ファイルの最初の行の後に次のスキーマ情報を追加します。

    <?xml version="1.0" encoding="US-ASCII"?>
     <faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee">
    

    スキーマを追加することで、より多くのWYSIWYGツール・サポートを得られます。

30.2.3 MyFaces Trinidadスキン構成ファイルの追加方法

MyFaces Trinidadスキン・ファイルを追加して、コンポーネントのスタイルを定義するために使用するコンポーネントのCSSファイルを登録します。

カスタム・コンポーネントのtrinidad-skins.xmlファイルを作成する手順:

  1. プロジェクトを右クリックし、「新規」を選択します。

  2. 「新規ギャラリ」ダイアログの左ペインで、「一般」「XML」を選択します。

  3. 右ペインで「XMLスキーマからXMLドキュメント」を選択し、「OK」をクリックします。

  4. XMLスキーマからXMLを作成ダイアログで、次のように設定します。

    • XMLファイル: trinidad-skins.xmlと入力します。

    • ディレクトリ: ディレクトリ・エントリの最後に\src\META-INFを追加します。

    • 「登録済のスキーマを使用」を選択して、「次へ」をクリックします。

  5. 次の内容を入力します。

    • ターゲット・ネームスペース: http://myfaces.apache.org/trinidad/skinを選択します。

    • ルート要素: skinsを選択します。

    • 「終了」をクリックします。新しいファイルがXMLエディタで自動的に開きます。

30.2.4 Cascading Style Sheetの追加方法

Cascading Style Sheetを追加して、コンポーネントのスタイルを定義します。

カスタム・コンポーネントのCascading Style Sheetを作成する手順:

  1. プロジェクトを右クリックし、「新規」を選択します。

  2. 「新規ギャラリ」ダイアログの左ペインで、「一般」「ファイル」を選択します。「OK」をクリックします。

  3. 「ファイルの作成」ダイアログで、次のように設定します。

    • ファイル名、たとえばacme-simple-desktop.cssを入力します。

    • ディレクトリ・エントリの最後に\src\META-INF\component_prefix\stylesを追加します。ここで、component_prefixは、コンポーネント・ライブラリで使用される接頭辞です。たとえばtagPaneコンポーネントの場合、acmeが接頭辞です。そのため、追加する文字列は\META-INF\acme\stylesとなります。

30.2.5 リソース・キット・ローダーの追加方法

空のファイルを作成し、カスタム・リソース・ローダーへの完全修飾クラスパスを追加します。

カスタム・コンポーネントのリソース・ローダーを作成する手順:

  1. プロジェクトを右クリックし、「新規」を選択します。

  2. 「新規ギャラリ」ダイアログの左ペインで、「一般」「ファイル」を選択します。「OK」をクリックします。

  3. 「ファイルの作成」ダイアログで、次のように設定します。

    • 「ファイル名」component_prefix.resourcesと入力します。ここでcomponent_prefixは、コンポーネント・ライブラリで使用される接頭辞です。たとえばtagPaneコンポーネントの場合、acmeが接頭辞です。そのため、入力する文字列はacme.resourcesとなります。

    • ディレクトリ・エントリの最後に\src\META-INF\sevlets\resources\を追加します。

30.2.6 JavaServer Pagesタグ・ライブラリ・ディスクリプタ・ファイルの追加方法

JSFページを使用するにはJSP TLDファイルが必要です。

カスタム・コンポーネントのJavaServer Pages TLDファイルを作成する手順:

  1. プロジェクトを右クリックし、「新規」を選択します。

  2. 「新規ギャラリ」ダイアログの左ペインで、「Web層」「JSP」を選択します。

  3. 右ペインで「JSPタグ・ライブラリ」を選択し、「OK」をクリックします。

  4. 「JavaServer Pageタグ・ライブラリ作成」ダイアログで「デプロイ可能」を選択し、「次へ」をクリックします。

  5. 次の内容を入力します。

    • タグ・ライブラリ・ディスクリプタのバージョン: 2.1を選択します。

    • 短縮名: 名前を入力します。たとえば、tagPaneコンポーネントの場合、acmeと入力します。

    • タグ・ライブラリURI: タグ・ライブラリのURIを入力します。たとえば、tagPaneコンポーネントの場合、http://oracle.adfdemo.acmeと入力します。

  6. 「次へ」をクリックし、オプションで追加のタグ・ライブラリ情報を入力して、「終了」をクリックします。

30.2.7 JavaScriptライブラリ機能構成ファイルの追加方法

機能ファイルを追加して、カスタム・コンポーネントに関連付けられているJavaScriptファイルを定義します。クライアント・コンポーネント、クライアント・ピアおよびクライアント・イベントのファイルが含まれます。

カスタム・コンポーネントのadf-js-features.xmlファイルを作成する手順:

  1. プロジェクトを右クリックし、「新規」を選択します。

  2. 「新規ギャラリ」ダイアログの左ペインで、「一般」「XML」を選択します。

  3. 右ペインで「XMLスキーマからXMLドキュメント」を選択し、「OK」をクリックします。

  4. XMLスキーマからXMLを作成ダイアログで、次のように設定します。

    • XMLファイル: adf-js-features.xmlと入力します。

    • ディレクトリ: ディレクトリ・エントリの最後に\src\META-INFを追加します。

    • 「登録済のスキーマを使用」を選択して、「次へ」をクリックします。

  5. 次のように設定します。

    • ターゲット・ネームスペース: http://xmlns.oracle.com/adf/faces/featureを選択します。

    • ルート要素: featuresを選択します。

    • 「終了」をクリックします。新しいファイルがXMLエディタで自動的に開きます。

30.3 クライアント側の開発

JDeveloperワークスペースおよび構成ファイルを作成すると、クライアント側のJavaScriptファイルを作成およびコーディングできます。クライアント側の開発が終了したら、30.4項「サーバー側の開発」で説明されているように、サーバー側のファイルを作成します。

JavaScriptライブラリにはネームスペースがないため、カスタム・コンポーネントのすべてのJavaScriptオブジェクト名は、同じ接頭辞を使用して作成するのがベスト・プラクティスです。サーバー側のJavaパッケージ名では名前の競合が回避されるため、サーバー側では同じ接頭辞を使用する必要はありません。たとえば、tagPaneコンポーネントの場合、クライアント側のJavaScriptオブジェクト名すべてに接頭辞acmeを付けます。

クライアント・コンポーネントは、対応するDOM要素内で定義されていないプロパティの状態を保持します。これらのプロパティは、clientIdを使用して関連するDOM要素にバインドされます。clientIdによって、ページを表すコンポーネント・ツリーにサーバー側コンポーネントが一意に定義されます。DOM要素では、Id属性内にclientIdが保持されます。


注意:

ベスト・プラクティスおよび一貫性の点から、各JavaScriptオブジェクトはそれぞれの独自のソース・ファイルに配置してください。

クライアント側コンポーネントの開発では、コンポーネント、ピアおよびコンポーネント・イベントのJavaScriptファイルを作成する必要があります。

クライアント・コンポーネントに加えて、クライアント側のイベントも定義する必要があります。tagPaneコンポーネントのクライアント側のイベントは、ユーザーが3つのファイル・タイプのいずれかをクリックすると起動して、サーバーに伝播されます。サーバーに渡されたクライアント・イベントは、ターゲット・サーバー側のコンポーネントが適切なアクションを実行できるようにキューイングされます。

さらに、カスタム・コンポーネントにはクライアント・ピアが必要です。ピアはコンポーネント・プレゼンタです。ピアは、クライアント・コンポーネントと関連するDOM要素間のリンクとして機能します。クライアント・ピアによってクライアントの動作が追加されます。ピアは、登録メソッドを使用してコンポーネントにバインドする必要があります。

クライアント・コンポーネントに関連付けられているピアは、コンポーネントのclientIdを使用してDOM要素にバインドされます。ピアには、ステートフルとステートレスの2つのタイプがあります。

ピアでは、DOMイベントを動的に登録およびリスニングすることで、コンポーネントに動作が追加されます。概念的には、ピアの機能はマネージドBeanの役割と似ています。ただし、サーバー側コンポーネントはビュー・モデル(#{backingbean.callback})にバインドされますが、クライアント・コンポーネントはELを使用してピアにはバインドされません。ピアは、InitSubclass (AdfRichUIPeer.addComponentEventHandlers("click"))コールバック・メソッドでクライアント・コンポーネント・イベントに登録されます。コールバックでは、ネーミング規則(<Peer>.prototype.HandleComponent<Event>)を使用することが前提となっています。ピアでは、サーバー側コンポーネントがマネージドBeanへのELバインディングを使用してリンクを処理する、DOMイベント・コールバックが管理されます。クライアント側アーキテクチャ(ピアを含む)の詳細は、3.1項「ADF Facesアーキテクチャの使用の概要」を参照してください。

次の項では、カスタム・コンポーネント開発テンプレート環境がすでに設定されていると仮定しています。この開発環境には、アプリケーション・ワークスペース、プロジェクトおよびデプロイメント・プロファイルの設定、およびスキーマの登録が含まれます。まだ設定していない場合は、30.2項「ワークスペースと基礎ファイルの設定」を参照してください。

30.3.1 コンポーネントのJavaScriptファイルの作成方法

JDeveloperを使用して、コンポーネントのJavaScriptファイルを作成します。JavaScriptファイルに、コンポーネントのコンポーネント・タイプを定義します。

コンポーネントのJavaScriptファイルを作成する手順:

  1. プロジェクトを右クリックし、「新規」をクリックします。

  2. 「新規ギャラリ」ダイアログの左ペインで、「Web層」「HTML」を選択します。

  3. 右ペインで「JavaScriptファイル」を選択し、「OK」をクリックします。

  4. 「JavaScriptファイルの作成」ダイアログで、次のように設定します。

    • ファイル名: クライアント側コンポーネントの名前を入力します。たとえば、tagPaneコンポーネントの場合、AcmeTagPane.jsと入力します。


      ヒント:

      ネーミングの競合を回避するために、名前をコンポーネントの接頭辞で開始します。

    • ディレクトリ: srcディレクトリの下のサブディレクトリに、コンポーネントのディレクトリ・パスを入力します。たとえば、tagPaneコンポーネントの場合、adfrichclient-demo-acme\src\oracle\adfdemo\acme\js\componentと入力します。

  5. エディタでJavaScriptファイルを開き、コンポーネント・コードを追加して、コンポーネント・タイプを定義します。例30-4に、tagPaneコンポーネントで使用されるコードを示します。

    例30-4 tagPaneコンポーネントのJavaScript

    AdfUIComponents.createComponentClass(
     "AcmeTagPane",
     {
          componentType:"oracle.adfdemo.acme.TagPane",superclass:AdfUIObject
     }
    );
    

30.3.2 イベントのJavaScriptファイルの作成方法

JDeveloperを使用して、イベントのJavaScriptファイルを作成します。イベントが起動されたとき(マウス・クリックなど)に必要な機能を実行するためのコードをJavaScriptに追加します。

イベントのJavaScriptを作成する手順:

  1. プロジェクトを右クリックし、「新規」を選択します。

  2. 「新規ギャラリ」ダイアログの左ペインで、「Web層」「HTML」を選択します。

  3. 右ペインで「JavaScriptファイル」を選択し、「OK」をクリックします。

  4. 「JavaScriptファイルの作成」ダイアログで、次のように設定します。

    • ファイル名: クライアント側イベントの名前を入力します。たとえば、tagPaneコンポーネントの場合、AcmeTagSelectEvent.jsと入力します。


      ヒント:

      ネーミングの競合を回避するために、名前をコンポーネントの接頭辞で開始します。

    • ディレクトリ: srcディレクトリの下のサブディレクトリに、イベントのディレクトリ・パスを入力します。たとえば、tagPaneコンポーネントの場合、adf-richclient-demo-acme\src\oracle\adfdemo\acme\js\eventと入力します。

  5. エディタでJavaScriptファイルを開き、イベント・コードを追加します。例30-5に、tagPaneコンポーネントに追加されるイベント・コードを示します。

    例30-5 tagPaneイベントのJavaScript

    /**
     * Fires a select type event to the server for the source component
    * when a tag is clicked.
    */
    function AcmeTagSelectEvent(source, tag)
    {
     AdfAssert.assertPrototype(source, AdfUIComponent);
     AdfAssert.assertString(tag); this.Init(source, tag);
    }
    // make AcmeTagSelectEvent a subclass of AdfComponentEvent
    
    AdfObject.createSubclass(AcmeTagSelectEvent, AdfComponentEvent);
    /**
     * The event type
    */
    AcmeTagSelectEvent.SELECT_EVENT_TYPE = "tagSelect";
    /**
     * Event Object constructor
    */
    AcmeTagSelectEvent.prototype.Init = function(source, tag)
    {
      AdfAssert.assertPrototype(source, AdfUIComponent);
      AdfAssert.assertString(tag);
      this._tag = tag;
     AcmeTagSelectEvent.superclass.Init.call(this, source, AcmeTagSelectEvent.SELECT_EVENT_TYPE);}
    /**
     * Indicates this event should be sent to the server
    */
    AcmeTagSelectEvent.prototype.propagatesToServer = function()
    {
      return true;
    }
    /**
     * Override of AddMarshalledProperties to add parameters * sent server side.
    */
    AcmeTagSelectEvent.prototype.AddMarshalledProperties = function( properties)
    {
      properties.tag = this._tag;
    
    
     }
    /**
     * Convenient method for queue a AcmeTagSelectEvent.
     */
    AcmeTagSelectEvent.queue = function(component, tag)
    {
    AdfAssert.assertPrototype(component, AdfUIComponent);
     AdfAssert.assertString(tag);
     AdfLogger.LOGGER.logMessage(AdfLogger.FINEST,     "AcmeTagSelectEvent.queue(component, tag)");
     new AcmeTagSelectEvent(component, tag).queue(true);
    }
    /**
     * returns the selected file type
    */
    AcmeTagSelectEvent.prototype.getTag = function()
    {
      return this._tag;}
    /**
     * returns a debug string
    */
    AcmeTagSelectEvent.prototype.toDebugString = function()
    {
     var superString = AcmeTagSelectEvent.superclass.toDebugString.call(this);
     return superString.substring(0, superString.length - 1)
      +     ", tag="
      + this._tag     + "]";
    }
    /*
    *
    * Make sure that this event only invokes immediate validators
    * on the client.
    */
    AcmeTagSelectEvent.prototype.isImmediate = function()
    {
      return true;
    }
    

30.3.3 ピアのJavaScriptファイルの作成方法

JDeveloperを使用して、ピアのJavaScriptファイルを作成します。コードを追加してピアを登録し、コンポーネントにバインドします。

ピアのJavaScriptファイルを作成する手順:

  1. プロジェクトを右クリックし、「新規」を選択します。

  2. 「新規ギャラリ」ダイアログの左ペインで、「Web層」「HTML」を選択します。

  3. 右ペインで「JavaScriptファイル」を選択し、「OK」をクリックします。

  4. 「JavaScriptファイルの作成」ダイアログで、次のように設定します。

    • ファイル名: クライアント側ピアの名前を入力します。たとえば、tagPaneコンポーネントの場合、AcmeTagPanePeer.jsと入力します。


      ヒント:

      ネーミングの競合を回避するために、名前をコンポーネントの接頭辞で開始します。

    • ディレクトリ: srcディレクトリの下のサブディレクトリに、イベントのディレクトリ・パスを入力します。たとえば、tagPaneコンポーネントの場合、adf-richclient-demo-acme\src\oracle\adfdemo\acme\js\componentと入力します。

  5. エディタでJavaScriptファイルを開き、ピアのコードを追加します。このコードで、ピアを作成し、DOMに関するイベント処理を追加し、ピアをコンポーネントに登録する必要があります。例30-6に、tagPaneコンポーネントに追加されるコードを示します。

    例30-6 tagPaneのJavaScriptピア

    AdfRichUIPeer.createPeerClass(AdfRichUIPeer, "AcmeTagPanePeer", true);
    AcmeTagPanePeer.InitSubclass = function()
    {
    AdfLogger.LOGGER.logMessage(AdfLogger.FINEST,
     "AcmeTagPanePeer.InitSubclass()");
      AdfRichUIPeer.addComponentEventHandlers(this,
         AdfUIInputEvent.CLICK_EVENT_TYPE);
    }
    
    AcmeTagPanePeer.prototype.HandleComponentClick = function(componentEvent)
    {
    AdfLogger.LOGGER.logMessage(AdfLogger.FINEST, "AcmeTagPanePeer.HandleComponentClick(componentEvent)");
      // if the left mouse button was pressed
    if (componentEvent.isLeftButtonPressed())
     {
       // find component for the peer
      var component = this.getComponent();
      AdfAssert.assertPrototype(component, AcmeTagPane);
       // find the native dom element for the click event
    var target = componentEvent.getNativeEventTarget();
        if (target && target.tagName == "A")
       {
       AdfLogger.LOGGER.logMessage(AdfLogger.FINEST, "File type element (A)
     found: " + componentEvent.toString());
         var tag = target.firstChild.nodeValue;
       AdfAssert.assertString(tag);
    
    
       AdfLogger.LOGGER.logMessage(AdfLogger.FINEST, "tag :" + tag);
       // fire a select event
    AcmeTagSelectEvent.queue(component, tag);
       //cancel the native dom onclick to prevent browser actions based on the
       //'#' hyperlink. The event is of type AdfIEUIInputEvent. This event
       //will cancle the native dom event by calling
        //AdfAgent.AGENT.preventDefault(Event)
          componentEvent.cancel();
      }
    // event has dom node
      }
    }
    // Register the peer with the component. This bit of script must
    // be invoked after the AcmeTagPane and AcmeTagSelectEvent objects
    // are created. This is enforced by the ordering of the script files
    // in the
     oracle.asfdemo.acme.faces.resource.AcmeResourceLoader.
     AcmeScriptsResourceLoader.AdfPage.PAGE.getLookAndFeel()
    .registerPeerConstructor("oracle.adfdemo.acme.TagPane",
            "AcmeTagPanePeer");
    

30.3.4 JavaScriptライブラリ機能構成ファイルへのカスタム・コンポーネントの追加方法

コンポーネントのJavaScriptファイルの作成がすべて終了すると、作成したadf-js-features.xmlファイルにコンポーネントを追加できます。A.9.1項「JavaScript機能の作成方法」に説明されている手順に従います。XMLファイルの作成はすでに行っているため、その手順は省略します。例30-7に、tagPaneコンポーネントで使用されるadf-js-features.xmlファイルを示します。

例30-7 tagPaneコンポーネントのadf-js-features.xmlファイル

<?xml version="1.0" encoding="UTF-8" ?>
<features xmlns="http://xmlns.oracle.com/adf/faces/feature">
  <feature>
    <feature-name>AcmeTagPane</feature-name>
    <feature-class>
      oracle/adfdemo/acme/js/component/AcmeTagPane.js
    </feature-class>
    <feature-class>
      oracle/adfdemo/acme/js/event/AcmeTagSelectEvent.js
    </feature-class>
    <feature-class>
      oracle/adfdemo/acme/js/component/AcmeTagPanePeer.js
    </feature-class>
  </feature>
</features>

30.4 サーバー側の開発

サーバー側の開発には、次のものに対するJavaクラスの作成が含まれます。

これらのクラスを作成したら、コンポーネント・クラスおよびレンダラ・クラスをfaces-config.xmlファイルに追加します。その後、30.2項「ワークスペースと基礎ファイルの設定」で開始した構成ファイルを完了させます。

30.4.1 イベント・リスナーのクラスの作成方法

ADF FacesイベントAPIには、イベントを処理するためのイベント・リスナー・インタフェースが必要です。カスタム・コンポーネントにはイベントに対する依存性があり、イベントにはイベント・リスナー・インタフェースに対する依存性があります。Javaのimport文に、これらの依存性を反映させる必要があります。コンポーネントのcomponentTypeも定義する必要があります。

EventListenerクラスを作成する手順:

  1. プロジェクトを右クリックし、「新規」を選択します。

  2. 「新規ギャラリ」ダイアログの左ペインで、「一般」「Java」を選択します。

  3. 右ペインで「Javaインタフェース」を選択し、「OK」をクリックします。

  4. Javaインタフェース・ファイルの作成ダイアログで、次のように設定します。

    • 名前: リスナーの名前を入力します。たとえば、tagPaneコンポーネントの場合、TagSelectListenerと入力します。

    • パッケージ: パッケージの名前を入力します。たとえば、tagPaneコンポーネントの場合、oracle.adfdemo.acme.faces.eventと入力します。

  5. エディタでJavaファイルを開き、次の内容を追加します。

    • リスナーでjavax.faces.event.FacesListenerインタフェースを拡張します。

    • import文を追加して、FacesListenerクラス、およびイベントが依存するすべてのクラスをインポートします。

    • 新規イベントを処理するメソッド・シグネチャを追加します。実際のイベントを作成していない場合でも、ここで入力しておけば、後で入力する必要がなくなります。

    例30-8に、tagPaneイベント・リスナーのコードを示します。

    例30-8 tagPaneイベント・リスナーのJavaコード

    package oracle.adfdemo.acme.faces.event;
    
    import javax.faces.event.AbortProcessingException;
    import javax.faces.event.FacesListener;
    
    public interface TagSelectListener
     extends FacesListener
    {
     /**
      * <p>Process the {@link TagSelectEvent}.</p>
      * @param event fired on click of a tag link
      * @throws AbortProcessingException error processing {@link TagSelectEvent}
      */
     public void processTagSelect(TagSelectEvent event)
      throws AbortProcessingException;
    }
    

30.4.2 イベントのクラスの作成方法

30.3.2項「イベントのJavaScriptファイルの作成方法」で作成したJavaScriptイベントに対応するサーバー側のイベントを作成する必要があります。サーバー側のJSFイベントは、リクエスト値の適用ライフサイクル・フェーズ中にコンポーネントによってキューイングされます。イベントは、レスポンスのレンダリング・フェーズ以外のすべてのフェーズの後にUIViewRootクラスまで伝播されます。キューイングされたイベントは、関連付けられたコンポーネントにブロードキャストされます。

サーバー側のJavaコンポーネントでは、サーバー側のイベントを呼び出す必要があるため、最初にイベント・ソース・ファイルを作成して、コンパイル依存性を解決する必要があります。

サーバー側イベント・クラスを作成する手順:

  1. プロジェクトを右クリックし、「新規」を選択します。

  2. 「新規ギャラリ」ダイアログの左ペインで、「一般」「Java」を選択します。

  3. 右ペインで「Javaクラス」を選択し、「OK」をクリックします。

  4. Javaクラス・ファイルの作成ダイアログで、次のように設定します。

    • 名前: イベントの名前を入力します。たとえば、tagPaneコンポーネントの場合、TagSelectEventと入力します。

    • パッケージ: パッケージの名前を入力します。たとえば、tagPaneコンポーネントの場合、oracle.adfdemo.acme.faces.eventと入力します。

    • 拡張: イベント・クラスで拡張するクラスの名前を入力します。この名前は通常、javax.faces.event.FacesEventです。

    • 「オプション属性」セクションで、次のように選択します。

      • 「アクセス修飾子」セクションで、「public」を選択します。

      • 下部で、「スーパークラスからのコンストラクタ」および「抽象メソッドの実装」を選択します。

例30-9に、イベント・クラスのコードを示します。

例30-9 tagPaneイベントのJavaコード

package oracle.adfdemo.acme.faces.event;
import javax.faces.component.UIComponent;
import javax.faces.event.FacesEvent;
import javax.faces.event.FacesListener;

public class TagSelectEvent
 extends FacesEvent
{
 /**
  * <p>Tag selected on the client.</p>
  */
 private String tag = null;
 /**
  * <p>Overloade constructor passing the <code>source</code>
  * {@link oracle.adfdemo.acme.faces.component.TagPane} component and the
  * selected <code>tag</code>.
  * </p>
  * @param source component firing the event
  * @param tag selected tag link type
  */
 public TagSelectEvent(UIComponent source,
            String tag)
 {
  super(source);
  this.tag = tag;
 }

 /**
  * <p>Returns <code>true</code> if the <code>facesListener</code> is a
  * {@link TagSelectListener}.</p>
  *
  * @param facesListener listener to be evaluated
  * @return <code>true</code>
  * if <code>facesListener</code> instancof {@link TagSelectListener}
  */
 public boolean isAppropriateListener(FacesListener facesListener)
 {
  return (facesListener instanceof TagSelectListener);
 }
 /**
  * <p>Delegates to the <code>processTagSelect</code>
  * method of a <code>FacesListener</code>
  * implementing the {@link TagSelectListener} interface.
  *
  * @param facesListener target listener realizing {@link TagSelectListener}
  */
 public void processListener(FacesListener facesListener)
 {
  ((TagSelectListener) facesListener).processTagSelect(this);
 }
 /**
  * @return the tag that was selected triggering this event
  */
 public String getTag()
 {
  return tag;
 }
}

30.4.3 コンポーネントの作成

JSFコンポーネントは、プロパティの状態ホルダーであると言えます。それらのプロパティでは、レンダリングの動作、およびコンポーネントがユーザー・インタフェース・アクションにどのように応答するかを定義します。コンポーネント・クラスを開発する場合、必要なプロパティのタイプを識別する必要があります。また、MyFaces Trinidadフレームワークから拡張される基本コンポーネントも定義します。たとえば、tagPaneコンポーネントは、MyFaces TrinidadのUIXObjectを拡張します。

大部分のコンポーネントには、実装する必要があるプロパティが複数あります。ベース・クラスから継承されるプロパティもあれば、リッチ・クライアント・フレームワークに必須のプロパティもあります。他のプロパティはベスト・プラクティスであるため、必要となります。また、一部のプロパティは、カスタム・コンポーネントの機能に固有のものです。

たとえば、tagPaneコンポーネントには、表30-4に示されているプロパティがあります。

表30-4 tagPaneカスタム・コンポーネントのコンポーネント・プロパティ

プロパティ データ型 説明

継承

id

String.class

コンポーネントの識別子。

rendererType

String.class

コンポーネント・レンダラとして登録されている論理識別子。

rendered

Boolean.class

コンポーネントがレンダリングされているかどうかを判断するTrueまたはFalseのフラグ。

binding

ValueExpression.class

マネージドBeanにコンポーネント・インスタンスを格納するバインディング値式。

リッチ・クライアント・フレームワーク

clientComponent

Boolean.class

クライアント側コンポーネントが生成されるかどうかを判断するTrueまたはFalseのフラグ。

clientListeners

ClientListenerSet.class

コンポーネントのクライアント・リスナーを登録するバインディング式。

clientAttributes

Set.class

コンポーネントのclient属性。この属性は、サーバー側のJSFコンポーネントとクライアント側の対応するコンポーネントの両方に追加されます。

ベスト・プラクティス

inlineStyle

String.class

ルート・コンポーネントのclass属性に適用されるCSSスタイル。

styleClass

String.class

コンポーネントのclass属性に追加されるCSSスタイル。

visible

Boolean.class

コンポーネントの可視性が戻されるかどうかを示すTrueまたはFalseのフラグ。visibleプロパティは、renderedプロパティとは異なります。visible属性は、コンポーネントのCSSルートのCSSスタイルに影響します。

partialTriggers

String[].class

部分的なページの更新をトリガーする必要があるコンポーネントのID。

tagPaneに固有

tags

Map.class

重み付けされたタグのマップ。キーによって、タグ名と値が数値で表されます。Map<String.Number>


orderBy

String.class

タグがレンダリングされる順序。有効な列挙は、alphaおよびweightです。


tagSelectListener

MethodExpression.class

oracle.adfdemo.acme.faces.event.TagSelectEventタイプの単一のパラメータを指定するnewselectListenerメソッド・バインディング式。このバンディングは、タグの1つをクリックしたことでクライアント側のoracle.adfdemo.acme.js.event.AcmeTagSelectEvent.jsイベントがキューイングされると、実行されます。


ADF FacesおよびMyFaces Trinidadコンポーネント・ライブラリは、他のライブラリとは異なる定義がされます。JSFコンポーネントには、attributesと呼ばれるコレクションがあり、MAPインタフェースを介したコンポーネント・プロパティへのアクセスを提供します(JavaのシンプルなBean仕様を使用)。このコレクションは、コンポーネントのプロパティに対応しない値のペアも保持します。この概念は、属性の透過性と呼ばれます。JSFランタイム(MyFaces TrinidadおよびJSF参照実装の両方)では、JavaリフレクションAPIを使用してこの概念が実装されます。

My Faces Trinidadでは、JavaリフレクションAPIを使用しない独自の内部コレクションが定義されます。この違いは、ベース実装よりも効率的であることを意味します。MyFaces Trinidadのソリューションでは、コンポーネント・プロパティに関するより多くのメタデータが収集されます。このメタデータによって状態プロパティが宣言され、ベース・クラスによって、ベース・クラス内にStateHolderインタフェースを完全に実装できます。

My Faces Trinidadでは、org.apache.trinidad.component.UIXComponentクラスによってjavax.faces.component.UIComponentクラスが拡張され、その後に完全なコンポーネント階層が拡張されます。コード・メンテナンスを容易にするために、フレームワークには構成ファイルとテンプレートに基づいてコードを生成するストラテジが用意されています。

このコンポーネント・ストラテジは、開発の点におけるトレードオフとなります。プロパティを定義するには、より多くのコーディングが必要となりますが、コンポーネントごとにStateHolderインタフェースの2つのメソッド(saveStaterestoreState)をコーディングする必要はありません。


注意:

カスタム・コンポーネントを、ADF Facesの実装パッケージから拡張しないでください。これらの実装は固有のものであり、変更される可能性があります。

30.4.4 コンポーネントのクラスの作成方法

JDeveloperを使用して、コンポーネントのJavaファイルを作成します。プロパティ情報を保持するType Beanを作成し、各プロパティのPropertyKeyを定義します。次に、private属性のアクセッサを生成します。

コンポーネント・クラスを作成する手順:

  1. プロジェクトを右クリックし、「新規」を選択します。

  2. 「新規ギャラリ」ダイアログの左ペインで、「一般」「Java」を選択します。

  3. 右ペインで「Javaクラス」をクリックします。「OK」をクリックします。

  4. Javaクラス・ファイルの作成ダイアログで、次のように設定します。

    • 名前: コンポーネントの名前を入力します。たとえば、tagPaneコンポーネントの場合、TagPaneと入力します。

    • パッケージ: パッケージの名前を入力します。たとえば、tagPaneコンポーネントの場合、oracle.adfdemo.acme.faces.componentと入力します。

    • 拡張: コンポーネント・クラスで拡張するクラスの名前を入力します。たとえば、tagPaneコンポーネントの場合、org.apache.myfaces.trinidad.component.UIXObjectと入力します。

    • 「オプション属性」セクションで、次のように選択します。

      • 「アクセス修飾子」セクションで、「public」を選択します。

      • 下部で、「スーパークラスからのコンストラクタ」および「抽象メソッドの実装」を選択します。

  5. コード・エディタで、コンポーネント・プロパティ情報を含むType Beanを作成します。この静的クラス属性によって、スーパー・クラス内の同じ名前を持つ属性がシャドウされます。type属性は、コンポーネント・クラスごとに一度定義されます。Typeコンストラクタを介して、スーパー・クラスType Beanに参照が渡され、プロパティ情報がコピーされます。たとえば、tagPaneクラスには次のコンストラクタが含まれます。

    static public final FacesBean.Type TYPE = new FacesBean.Type(UIXObject.TYPE);
    
  6. プロパティごとに、プロパティ状態へのアクセスに使用される静的PropertyKeyを定義します。TYPE参照を使用して、新規属性を登録します。クラス参照を使用して、プロパティ・タイプを指定します。コンポーネントのデータ型は、コンポーネント・プロパティと対応している必要があります。状態情報を指定できるようにするregisterKeyメソッドの別のオーバーロードもあります。デフォルトでは、プロパティはpersistentであるとみなされます。例30-10に、tagPaneコンポーネントのPropertyKeyメソッドを示します。

    例30-10 PropertyKeyの定義

     /**
      * <p>Custom CSS applied to the style attribute of the root markup node.</p>
      */
     static public final PropertyKey INLINE_STYLE_KEY =
      TYPE.registerKey("inlineStyle", String.class);
     /**
      * <p>Custom CSS class to the class attribute of the root markup node.</p>
      */
     static public final PropertyKey STYLE_CLASS_KEY =
      TYPE.registerKey("styleClass", String.class);
    
  7. エディタ内で右クリックし、「アクセッサの生成」を選択します。「アクセッサの生成」ダイアログで「すべて選択」をクリックして、スコープがPublicに設定されていることを確認し、「OK」をクリックします。これで、JDeveloperでprivate属性のgetメソッドおよびsetメソッドを生成できます。

    その後、private属性を削除して、getProperty(PropertyKey)およびgetProperty(PropertyKey)へのコールで置き換えます。

    例30-11に、private属性を置き換えた後のコードを示します。

    例30-11 コンポーネントのプロパティ

     public void setInlineStyle(String newinlineStyle)
     {
      // inlineStyle = newinlineStyle;
      setProperty(INLINE_STYLE_KEY, newinlineStyle);
     }
     /**
      * <p>CSS value applied to the root component's style attribute.</p>
      *
      * @return newinlineStyle CSS custom style text
      */
     public String getInlineStyle()
     {
      // return inlineStyle;
      return (String) getProperty(INLINE_STYLE_KEY);
     }
    
  8. コンポーネントの特定の機能を実行するには、メソッドをオーバーライドする必要がある場合があります。たとえば、コンポーネントが部分ページ・レンダリング(PPR)に参加できるようにするには、例30-12に示すように、getBeanTypeメソッドをオーバーライドする必要があります。

    例30-12

    /**
     * <p>Exposes the <code>FacesBean.Type</code> for this class through a protected
     * method.  This method is called but the <code>UIComponentBase</code> super class
     * to setup the components <code>ValueMap</code> which is the container for the
     * <code>attributes</code> collection.</p>
     *
     * @return <code>TagPane.TYPE</code> static property
     */
    @Override
    protected FacesBean.Type getBeanType()
     {
       return TYPE;
     }
    

    コンポーネントで拡張するクラスおよびオーバーライドする必要があるメソッドの詳細は、ADF FacesのJavaDocを参照してください。

    tagPaneコンポーネントの場合、コンポーネントはクライアント・コンポーネントから起動されるイベントで動作する必要があります。ソース・コンポーネントへの参照は、パラメータとしてイベントのコンストラクタに渡されます。

    tagPaneコンポーネントの場合、仮パラメータを使用して渡されたイベントがTagSelectEventであるかどうかが、broadcastメソッドによって確認されます。そうである場合、broadcastメソッドによって、tagSelectListener属性に保持されているメソッド式が呼び出されます。

    大部分のイベントには、イベントを起動するライフサイクル・フェーズを指定するimmediateブール・プロパティがあります。immediate属性がtrueの場合、イベントは値の適用フェーズで処理され、falseの場合は、アプリケーションの起動フェーズで処理されます。詳細は、第4章「JSFおよびADF Facesのライフサイクルの理解」を参照してください。

    例30-13に、tagPaneコンポーネントのオーバーライドされるbroadcastメソッドを示します。

    例30-13 tagPaneコンポーネントのbroadcastメソッド

     /**
      * <p>
      * </p>
      *
      * @param facesEvent faces event
      * @throws AbortProcessingException exception during processing
      */
     @Override
     public void broadcast(FacesEvent facesEvent)
      throws AbortProcessingException
     {
      // notify the bound TagSelectListener
      if (facesEvent instanceof TagSelectEvent)
      {
       TagSelectEvent event = (TagSelectEvent) facesEvent;
       // utility method found in UIXComponentBase for invoking method event
       // expressions
       broadcastToMethodExpression(event, getTagSelectListener());
      }
      super.broadcast(facesEvent);
     }
    

30.4.5 faces-config.xmlファイルへのコンポーネントの追加方法

コンポーネント・クラスを作成したら、コンポーネントを/META-INF/faces-config.xmlファイルに追加して登録します。JARプロジェクトにパッケージされているFaces構成ファイルにコンポーネントを定義することで、Webアプリケーションの起動時に、JSFランタイムによってコンポーネントが自動的に認識されます。

コンポーネントを登録するには、コンポーネント・タイプを入力します。コンポーネント・タイプは、コンポーネントのインスタンスをインスタンス化するためにアプリケーション・ファクトリによって使用される論理名です。たとえば、tagPaneコンポーネントのタイプは、oracle.adfdemo.acme.TagPaneです。oracle.adfdemo.acme.faces.component.TagPaneのような、コンポーネントの完全修飾クラス・パスも追加する必要があります。

カスタム・コンポーネントを登録する手順:

  1. faces-config.xmlファイルをダブルクリックして、エディタ内で開きます。

  2. 「概要」タブをクリックして、「コンポーネント」を選択します。

  3. 「追加」アイコンをクリックして、コンポーネントのタイプとクラスを入力します。

  4. オプションで、任意の属性、プロパティまたはファセットを追加します。

例30-14に、faces-config.xmlファイルに定義されているtagPaneコンポーネントを示します。

例30-14 faces-config.xmlファイルに追加されたtagPaneコンポーネント

<?xml version="1.0" encoding="UTF-8" ?>
<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee">
 <application>
 </application>

 <component>
  <component-type>oracle.adfdemo.acme.TagPane</component-type>
  <component-class>oracle.adfdemo.acme.faces.component.TagPane
  </component-class>
 </component>

30.4.6 リソース・バンドルのクラスの作成方法

リソース・バンドルは、コンポーネントの情報(ラベルやメッセージのテキストなど)、およびアプリケーションでロケールの切替えが許可されている場合に使用される翻訳されたテキストを格納するために使用されます。スキンでも、コンポーネントのテキストを保持するためにリソース・バンドルが使用されます。カスタム・コンポーネントでは少なくとも簡単なスキンを使用する必要があるため、少なくともそのスキンのリソース・バンドルを作成する必要があります。カスタム・コンポーネントの場合は、リソース・バンドルのJavaファイルを作成します。リソース・バンドル・クラスの詳細は、20.3項「スキン・スタイル・プロパティの定義」を参照してください。


ヒント:

リソースのプロパティ・ファイルを使用することもできます。

リソース・バンドル・クラスを作成する手順:

  1. プロジェクトを右クリックし、「新規」を選択します。

  2. 「新規ギャラリ」ダイアログの左ペインで、「一般」「Java」を選択します。

  3. 右ペインで「Javaクラス」を選択し、「OK」をクリックします。

  4. Javaクラス・ファイルの作成ダイアログで、次のように設定します。

    • 名前: リソース・バンドルの名前を入力します。名前には、使用するスキンを反映させる必要があります。たとえば、サンプル・コンポーネントの場合、AcmeSimpleDesktopBundleと入力します。

    • パッケージ: パッケージの名前を入力します。たとえば、サンプル・コンポーネントの場合、oracle.adfdemo.acme.faces.resourceと入力します。

    • 拡張: リソース・バンドルの場合、java.util.ListResourceBundleと入力する必要があります

    • 「オプション属性」セクションで、次のように選択します。

      • 「アクセス修飾子」セクションで、「public」を選択します。

      • 下部で、「スーパークラスからのコンストラクタ」および「抽象メソッドの実装」を選択します。

  5. 必要に応じてキーを追加し、テキストを定義します。スキンのリソース・バンドルの作成の詳細は、20.3.1項「テキストへのスキンの適用方法」を参照してください。

    例30-15に、tagPaneコンポーネントのリソース・バンドル・コードを示します。

    例30-15 tagPaneのリソース・バンドルのJavaコード

    package oracle.adfdemo.acme.faces.resource;
    import java.util.ListResourceBundle;
    /**
     * <p>Holds properties used by the components bundled in the jar project.
     * This bundle is part of the trinidad component skin that is configured
     * in the "/META-INF/trinidad-skins.xml" file. Component Renderers
     * will use the <code>RenderingContext</code> to lookup a key by calling
     * the <code>getTranslatedString(key)</code> method.</p>
     */
    public class AcmeSimpleDesktopBundle
     extends ListResourceBundle
    {
     /**
      * <p>Returns a two dimensional object array that represents a resource bundle
    . * The first
      * element of each pair is the key and the second the value.</p>
      *
      * @return an array of value pairs
      */
     protected Object[][] getContents()
     {
      return new Object[][]
       {
        {"AcmeTagPane_tag_title","Tag Weight: {0}"}
       };
     }
    }
    
  6. 簡単なデスクトップ・スキンおよび他の必要なスキンのリソース・バンドルを登録するには、/META-INF/trinidad-skins.xmlファイルをダブルクリックして開き、次のように設定します。

    1. 構造ウィンドウで、skin-additionを選択します。

    2. プロパティ・インスペクタでスキンIDを入力します。簡単なスキンIDの場合、simple.desktopと入力します。

    3. 構造ウィンドウで、skin-additionを右クリックし、「skin-additionの中に挿入」bundle-nameを選択します。

    4. プロパティ・インスペクタで、作成したリソース・バンドルの完全修飾名を入力します。


    注意:

    JDeveloperでは、translation-source要素とbundle-name要素はコメントとして追加されます。前述のように別のbundle-name要素を宣言的に作成するかわりに、生成済の要素にbundle-name値を手動で入力してから、コメント・タグを削除することもできます。

    例30-16に、tagPaneリソース・バンドルを簡単なスキンに登録するためのコードを示します(この後の手順でstyle-sheet-name要素値を追加します)。

    例30-16 リソース・バンドルのスキンへの登録

    <skins xmlns="http://myfaces.apache.org/trinidad/skin">
     <skin-addition>
      <skin-id>simple.desktop</skin-id>
      <style-sheet-name></style-sheet-name>
      <bundle-name>
        oracle.adfdemo.acme.faces.resource.AcmeSimpleDesktopBundle
      </bundle-name>
     </skin-addition>
    </skins>
    

30.4.7 レンダラのクラスの作成方法

ADF Facesコンポーネントでは、コンポーネントの機能はコンポーネント・クラスに、コンポーネントの表示はレンダラに委任されます。デフォルトでは、ADF Facesのすべてのタグが、関連付けられたコンポーネント・クラスとHTMLレンダラを結合し、HTMLレンダー・キットの一部になっています。ADF Facesには、デスクトップおよびPDAデバイスの両方に表示できるように、HTMLレンダー・キットが含まれています。

レンダラは、ファミリとレンダラ・タイプによってレンダー・キットで修飾されます。ファミリはコンポーネントの一般カテゴリであり、スーパー・クラスに定義されているファミリと同じにする必要があります。コンポーネントは継承によってメソッドを取得するため、コンポーネント内のgetFamily()メソッドをオーバーライドする必要はありません。

レンダラ・クラスを作成する手順:

  1. プロジェクトを右クリックし、「新規」を選択します。

  2. 「新規ギャラリ」ダイアログの左ペインで、「一般」「Java」を選択します。

  3. 右ペインで「Javaクラス」を選択し、「OK」をクリックします。

  4. Javaクラス・ファイルの作成ダイアログで、次のように設定します。

    • 名前: レンダラの名前を入力します。たとえば、tagPaneコンポーネントの場合、TagPaneRendererと入力します。

    • パッケージ: パッケージの名前を入力します。たとえば、tagPaneコンポーネントの場合、oracle.adfdemo.acme.faces.renderと入力します。

    • 拡張: oracle.adf.view.rich.render.RichRendererと入力します。

    • 「オプション属性」セクションで、次のように選択します。

      • 「アクセス修飾子」セクションで、「public」を選択します。

      • 下部で、「スーパークラスからのコンストラクタ」および「抽象メソッドの実装」を選択します。

30.4.8 faces-config.xmlファイルへのレンダラの追加方法

レンダラを作成したら、faces-config.xml構成ファイルを使用して登録します。カスタム・コンポーネントを他のADF Facesコンポーネントと組み合せて機能させる場合、そのADF Facesコンポーネントが使用しているのと同じレンダー・キットIDを使用する必要があります。


ヒント:

JSFでレンダー・キットを定義できる最も高いレベルはビュー・ルートです。

レンダー・キットおよびレンダラを登録する手順:

  1. faces-config.xmlファイルをダブルクリックして、エディタ内で開きます。

  2. 「概要」タブを選択して、「レンダー・キット」を選択します。

  3. 「レンダー・キット」の「追加」アイコンをクリックして、レンダー・キットIDにoracle.adf.richと入力します。

  4. 「レンダラ」の「追加」アイコンをクリックしてレンダラを登録し、次のように設定します。

    • ファミリ: コンポーネントで拡張するクラスを入力します。たとえば、tagPaneコンポーネントの場合、org.apache.myfaces.trinidad.Objectと入力します。

    • Type: コンポーネントのタイプを入力します。たとえば、tagPaneコンポーネントの場合、oracle.adfdemo.acme.TagPaneと入力します。これは、レンダラ・タイプと一致している必要があります

    • Class: 30.4.7項「レンダラのクラスの作成方法」で作成したレンダラの完全修飾クラス・パスを入力します。たとえば、tagPaneコンポーネントの場合、oracle.adfdemo.acme.faces.render.TagPaneRendererと入力します。

例30-17に、tagPaneコンポーネントのレンダー・キットおよびレンダラの登録を示します。

例30-17 faces-config.xmlファイルに追加されたtagPaneのレンダラ

<render-kit>
  <render-kit-id>oracle.adf.rich</render-kit-id>
  <renderer>
    <component-family>org.apache.myfaces.trinidad.Object</component-family>
    <renderer-type>oracle.adfdemo.acme.TagPane</renderer-type>
    <renderer-class>oracle.adfdemo.acme.faces.render.TagPaneRenderer
    </renderer-class>
  </renderer>
</render-kit>

30.4.9 JSPタグ・プロパティの作成方法

ページでコンポーネントを使用するには、カスタム・コンポーネントをインスタンス化するカスタム・タグを作成します。JSPタグはレンダリングには関係しません。レンダリングを実際に実行するのはコンポーネント・レンダラです。JSF 1.1では、コンポーネントを作成してコンポーネント・ツリーに追加すると、JSPタグによりコンポーネントのレンダリングが起動されます。このため、JSF/JSP以外のタグが同じレスポンス・ライターに書き込まれるため、問題が発生します。インターリビングのタイミングは、自らの子コンポーネントをレンダリングしたコンポーネントに対しては機能しません。

JSF 1.2、Java EE 5(Servlet 2.5、JSP 2.1)のターゲットでは、JSPの問題の大部分は修正されています。JSF/JSPコンポーネントは、コンポーネントの作成のみを行うコンポーネント・ファクトリとして機能します。これは、レンダリング・レスポンス・フェーズが2つの手順に分割されていることを意味します。コンポーネント・ツリーの作成時にコンポーネントがレンダリングされるかわりに、まずコンポーネント・ツリーが作成されてからそのツリーがレンダリングされます。この機能は、ビュー全体がJSFコンポーネントによって表されるようにすることで可能になっています。JSF/JSP以外では、暗黙的にJSF Verbatimコンポーネントとなるマークアップが生成されます。

JSF 1.2におけるこのような仕組みの変更の結果として、カスタムJSPタグによってjavax.faces.webapp.UIComponentELTagクラスが拡張されます。JSPタグのencodeBeginencodeChildrenおよびencodeEndメソッドは非推奨となっています。これらのメソッドは、以前はコンポーネントへの対応するコールを行っていました。JSF 1.2ではビュー・ルートでレンダリングが行われるため、すべての機能はdoStartTagメソッドおよびdoEndTagメソッドで実行できます。MyFaces Trinidadには、使用できるこのベース・クラス独自のバージョンがあります。org.apache.myfaces.Trinidad.webapp.UIComponentELTagがコンポーネントのプロパティ・バッグにフックされ、JSPのコーディングが単純化されます。

タグ・クラスには、コンポーネントのプロパティの作成が含まれます。タグ・プロパティは慎重に選択する必要があります。一部のプロパティはタグの実装では無視できても、TLD属性として必要な場合があります。

次の3つの属性は、スーパー・クラスによって実装され、Java継承を介して多くのコンポーネントで共有されます。

  • id

  • binding

  • rendered

id属性はスーパー・クラスjavax.faces.webapp.UIComponentTagBaseによって実装されるため、id属性は実装しないでください。スーパー・クラスjavax.faces.webapp.UIComponentELTagによって、bindingrenderedという2つの属性が実装されます。そのため、この2つの属性をタグ・クラスに追加する必要はありません。

JSPタグを追加する手順:

  1. プロジェクトを右クリックし、「新規」を選択します。

  2. 「新規ギャラリ」ダイアログの左ペインで、「一般」「Java」を選択します。

  3. 右ペインで「Javaクラス」を選択し、「OK」をクリックします。

  4. Javaクラス・ファイルの作成ダイアログで、次のように設定します。

    • 名前: タグの名前を入力します。たとえば、tagPaneコンポーネントの場合、TagPaneTagと入力します。

    • パッケージ: パッケージの名前を入力します。たとえば、tagPaneコンポーネントの場合、oracle.adfdemo.acme.faces.taglibと入力します。

    • Class: org.apache.myfaces.trinidad.webapp.UIXComponentELTagと入力します。

    • 「オプション属性」セクションで、次のように選択します。

      • 「アクセス修飾子」セクションで、「public」を選択します。

      • 下部で、「スーパークラスからのコンストラクタ」および「抽象メソッドの実装」を選択します。

  5. コード・エディタで、すべての属性をファイルに追加します。

    例30-18に、TagPaneTagクラスの属性のコードを示します。

    例30-18 TagPaneTagクラスの属性

    public class TagPaneTag
     extends UIXComponentELTag
    {
     private ValueExpression _partialTriggers = null;
     private ValueExpression _visible = null;
     private ValueExpression _inlineStyle = null;
     private ValueExpression _styleClass = null;
     private ValueExpression _tags = null;
     private ValueExpression _orderBy = null;
     private MethodExpression _tagSelectListener = null;
    
  6. 属性のアクセッサ・メソッドを宣言的に生成するには、コード・エディタでファイルを右クリックして、「アクセッサの生成」を選択します。

  7. 「アクセッサの生成」ダイアログで「すべて選択」をクリックして、スコープpublicに設定し、「OK」をクリックします。

  8. レンダー・タイプとコンポーネント・タイプをクラスに追加します。コンポーネント・タイプは、アプリケーションのファクトリ・メソッド、createComponent(componentType)を使用してコンポーネントをインスタンス化するためにスーパー・クラスによって使用されます。

    例30-19に、コンポーネント・タイプとレンダー・タイプがいずれもoracle.adfdemo.acme.TagPaneであるTagPaneTagクラスのコードを示します。

    例30-19 TagPaneTagクラスのコンポーネント・タイプとレンダー・タイプ

     public String getComponentType()
     {
      return COMPONENT_TYPE;
     }
     public String getRendererType()
     {
      return RENDERER_TYPE;
     }
    
     /**
      * <p>This component's type, <code>oracle.adfdemo.acme.TagPane</code></p>
      */
     static public final String COMPONENT_TYPE =
      "oracle.adfdemo.acme.TagPane";
     /**
      * <p>Logical name given to the registered renderer for this component.</p>
      */
     static public final String RENDERER_TYPE = "oracle.adfdemo.acme.TagPane";
    
  9. 単一の仮パラメータのタイプFacesBeanを持つスーパー・クラスからsetPropertiesメソッドをオーバーライドします。これは、ベースUIComponentELTagのMyFaces Trinidadバージョンですが、コンポーネント参照のかわりにコンポーネントの状態ホルダーが渡されます。setPropertiesメソッドの役割は、JSPタグ属性値をコンポーネントにプッシュすることです。

    例30-20に、tagPaneTagクラスのオーバーライド・メソッドを示します。

    例30-20 TagPaneTagクラスのsetPropertiesメソッドのオーバーライド

      @Override
      protected void setProperties(FacesBean facesBean) {
        super.setProperties(facesBean);
    
        setStringArrayProperty(facesBean, TagPane.PARTIAL_TRIGGERS_KEY,
                    _partialTriggers);
        setProperty(facesBean, TagPane.VISIBLE_KEY, _visible);
        setProperty(facesBean, TagPane.INLINE_STYLE_KEY, _inlineStyle);
        setProperty(facesBean, TagPane.STYLE_CLASS_KEY, _styleClass);
        setProperty(facesBean, TagPane.TAGS_KEY, _tags);
        setProperty(facesBean, TagPane.ORDER_BY_KEY, _orderBy);
        facesBean.setProperty(TagPane.TAG_SELECT_LISTENER_KEY,
                   _tagSelectListener);
    
      }
    

30.4.10 タグ・ライブラリ・ディスクリプタの構成方法

タグ・ライブラリ・ディスクリプタ(TLD)は、Javaクラスの詳細をJSPコンパイル・エンジンとIDEツールに提供します。

最初のタスクは、ラグ・ライブラリをURIに関連付け、バージョンを割り当てて名前を付けることです。この手順は、30.2.6項「JavaServer Pagesタグ・ライブラリ・ディスクリプタ・ファイルの追加方法」でタグ・ライブラリ・スタブ・ファイルを作成したときに実行されている必要があります。コンポーネントのクラスを実装すると、TLDが完了します。

TLDを構成する手順:

  1. スケルトンTLDファイルを開きます。

  2. コンポーネント・パレットから、tag要素をドラッグ・アンド・ドロップします。

  3. 「タグの挿入」ダイアログで、次のように設定します。

    • name: コンポーネントの名前を入力します。たとえば、tagPaneコンポーネントの場合、tagPaneと入力します。

    • body-content: JSPと入力します。

    • tag-class: 省略ボタンをクリックして、コンポーネントのタグ・クラス・ファイルに移動します。

  4. 各属性を定義します。各属性に対して次のように設定します。

    1. 構造ウィンドウで、tag要素を右クリックして、「tagの中に挿入」「attribute」を選択します。

    2. 「属性の挿入」ダイアログで、名前の値を入力します。この名前はタグ・クラスで指定した名前と同一にする必要があります。

    3. 構造ウィンドウで属性を選択し、プロパティ・インスペクタで属性の値を設定します。

      各属性に定義する要素は3タイプあります。<id>要素は単純な文字列です。追加の属性は、deferred-value属性またはdeferred-method属性となります。これらにより、式を遅れて(deferred)評価できます。これで、JSPとJSFで同じELエンジンを共有するようになったため、コンパイル済のELをコンポーネントに直接渡すことができます。

    例30-21に、tagPaneコンポーネントのTLDを示します。

例30-21 tagPaneのacme.tldタグ・ライブラリ・ディスクリプタ・コード

<?xml version = '1.0' encoding = 'windows-1252'?>
<taglib xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
     http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
     version="2.1" xmlns="http://java.sun.com/xml/ns/javaee">
 <description>Acme Corporation JSF components</description>
 <display-name>acme</display-name>
 <tlib-version>1.0</tlib-version>
 <short-name>acme</short-name>
 <uri>http://oracle.adfdemo.acme</uri>
  <tag>
  <description>
  </description>
  <name>tagPane</name>
  <tag-class>oracle.adfdemo.acme.faces.taglib.TagPaneTag</tag-class>
  <body-content>JSP</body-content>
  <attribute>
   <name>id</name>
   <rtexprvalue>true</rtexprvalue>
  </attribute>
  <attribute>
   <name>rendered</name>
   <deferred-value>
    <type>boolean</type>
   </deferred-value>
  </attribute>
  <attribute>
   <name>tagSelectListener</name>
   <deferred-method>
    <method-signature>void
    </method-signature>
        myMethod(oracle.adfdemo.acme.faces.event.TagSelectEvent)
   </deferred-method>
  </attribute>
  <attribute>
   <name>visible</name>
   <deferred-value>
    <type>boolean</type>
   </deferred-value>
  </attribute>
  <attribute>
   <name>partialTriggers</name>
   <deferred-value>
   </deferred-value>
  </attribute>
  <attribute>
   <name>inlineStyle</name>
   <deferred-value/>
  </attribute>
  <attribute>
   <name>inlineClass</name>
   <deferred-value/>
  </attribute>
  <attribute>
   <name>tags</name>
   <deferred-value/>
  </attribute>
  <attribute>
   <name>binding</name>
   <deferred-value/>
  </attribute>
  <attribute>
   <name>orderBy</name>
   <deferred-value/>
  </attribute>
 </tag>
</taglib>

30.4.11 リソース・ローダーの作成方法

リソース・ローダーは、コンポーネントのスキニングに必要なイメージ・ファイルがカスタム・コンポーネントにある場合のみ必要です。イメージ・ファイルはJARプロジェクトにパッケージ化されるため、コンポーネント・ライブラリのコンシューマは、JARをそれぞれのWebプロジェクトのクラス・パスに含め、いくつかのエントリをそれぞれのWebデプロイメント・ディスクリプタ・ファイル(web.xml)に追加する必要があります。リッチ・クライアント・フレームワークでは、リソース・サーブレットを使用してイメージが配信されます。このサーブレットをweb.xmlファイルに登録してから、リソース・ローダー・クラスを作成する必要があります。コンポーネント・ライブラリには、リソース・サーブレットによって自動ロードされるリソース・ローダーが必要です。サーブレットのURLパターン・フォルダ・マッピングを作成します。これは、カスタム・コンポーネント・ライブラリ内のリソースを検索および識別するために使用されます。

リソース・ローダー・クラスを作成する手順:

  1. プロジェクトを右クリックし、「新規」を選択します。

  2. 「新規ギャラリ」ダイアログの左ペインで、「一般」「Java」を選択します。

  3. 右ペインで「Javaクラス」を選択し、「OK」をクリックします。

  4. Javaクラス・ファイルの作成ダイアログで、次のように設定します。

    • 名前: リソース・ローダーの名前を入力します。たとえば、tagPaneコンポーネントの場合、AcmeResourceLoaderと入力します。

    • パッケージ: パッケージの名前を入力します。たとえば、tagPaneコンポーネントの場合、oracle.adfdemo.acme.faces.resourcesと入力します。

    • 拡張: タグで拡張するクラスの名前を入力します。たとえば、tagPaneコンポーネントの場合、org.apache.myfaces.trinidad.resource.RegexResourceLoaderと入力します。

    • 「オプション属性」セクションで、次のように選択します。

      • 「アクセス修飾子」セクションで、「public」を選択します。

      • 下部で、「スーパークラスからのコンストラクタ」および「抽象メソッドの実装」を選択します。

  5. コード・エディタで、より具体的なリソース・ローダーにマップされる正規表現を登録します。たとえば、イメージ・ディレクトリの下にあるイメージ・リソースにマップする式を作成できます。

    例30-22に、カスタム・コンポーネントJARの/META-INFフォルダと相対的な場所にある/acme/images/ディレクトリにマップするtagPaneコンポーネントの式を示します。登録すると、カスタム・コンポーネントのイメージは/META-INF/acme/imagesの下に配置されます。

    例30-22 tagPaneコンポーネントのリソース・ローダー

    public class AcmeResourceLoader
     extends RegexResourceLoader
    {
     public AcmeResourceLoader()
     {
      // any resource in "/acme/" with the following suffixes will be
      // loaded from the base folder of "META-INF".
      // The servlet pattern match "/acme/*" should exist under "META-INF".
      // For example URL : context-root/acme/images/type1.gif
      //      map to: META-INF/acme/images/type1.gif
      register("(/.*\\.(jpg|gif|png|jpeg))",
           new ClassLoaderResourceLoader("META-INF"));
    
  6. /META-INF/servlet/resources/name.resourcesファイルを開いてライブラリ・リソース・ローダーを登録し、URIパターンにバインドされているリソース・ローダー・クラスの完全修飾名を追加します。

    MyFaces Trinidad ResourceServletでは、サーブレットのコンテキストを使用して、Webアプリケーションのクラス・パス内にあるすべてのJARファイルがスキャンされます。サーブレットは、Webデプロイメント・ディスクリプタ内の独自のURIマッピングを調べて、このリソース・ファイルの場所を明らかにします。このファイルには、URIパターンにバインドされているJavaクラスの完全修飾名が含まれている必要があります。起動時に、ResourceServletはこのファイルを検索して使用します。その方法は、FacesServletfaces-config.xmlファイルを検索して使用する方法と似ています。

    tagPaneコンポーネントの場合、acme.resourcesファイルには、コンポジット・リソース・ローダーのための次のエントリが含まれます。

    oracle.adfdemo.acme.faces.resource.AcmeResourceLoader
    

30.4.12 MyFaces Trinidad Cascading Style Sheetの作成方法

スキンはCSS 3.0構文に基づくスタイルシートで、アプリケーション全体用に1箇所で指定されます。各ページのスタイルシートを挿入するかわりに、アプリケーション全体に対して1つ以上のスキンを使用します。各コンポーネントでは、スキンに記述されているスタイルが自動的に使用されます。設計時にコードを変更する必要はありません。

Oracle ADF Facesには、アプリケーションで使用するスキンが3つ用意されています。

  • blafplus-rich : ADF Facesコンポーネントのデフォルトのスタイルを定義します。このスキンは、blafplus-mediumスキンを拡張します。

  • blafplus-medium : 適度な数のスタイル設定が提供されます。このスタイルは、simpleスキンを拡張します。

  • simple : 最低限の書式設定のみが含まれています。

スキンには、標準のCSSスタイルやレイアウトを設定するよりも多くのオプションがあります。スキンのCSSファイルは、スキン・フレームワークによって処理され、スキン・プロパティとアイコンが抽出されてSkinオブジェクトに登録されます。スタイルシート・ルールには、要素を識別するスタイル・セレクタ、およびコンポーネントの外観を説明する一連のスタイル・プロパティが含まれます。

ADF Facesコンポーネントはすべてスキンを使用します。デフォルトのスキンは簡単なスキンです。カスタム・コンポーネントは、他のADF Facesコンポーネントとともに使用されるため、既存のADF Facesスキンにスタイル・セレクタを追加します。リッチ・スキンとミディアム・スキンは、簡単なスキンからスタイルを継承するので、セレクタを簡単なスキンに追加するだけで、すべてのスキンでそのセレクタを使用できるようになります。ただし、スキンごとにセレクタのスタイルを変えたい場合があります。そのようなスタイルは、作成したCSSファイルに設定します。このファイルは、コンポーネントが使用されるアプリケーションの他のCSSスタイルとマージされます。

スキンで使用されるテキストは、リソース・バンドル内で定義されます。カスタム・リソース・バンドルを作成してテキストを作成し、表示するテキストを宣言します。カスタム・リソース・バンドルを作成した後、スキンにそれを登録します。リソース・バンドルとCSSを組み合せることで、コンポーネントで複数のロケールをサポートするためのメソッドが提供されます。

作成した/META-INF/trinidad-skins.xmlファイルは、CSSファイルおよびリソース・バンドルをADF Facesスキンに登録するために使用されます。

コンポーネントのスタイルを作成する手順:

  1. 30.2.4項「Cascading Style Sheetの追加方法」で作成したCSSファイルを開きます。

  2. コンポーネントのルート・スタイル・セレクタを定義します。このスタイルは、コンポーネントを確立する<DIV>要素と関連付けられます。

  3. 必要に応じてその他のスタイル・セレクタを追加します。例30-23に、tagPaneコンポーネントのCSSファイルを示します。

    例30-23 tagPaneコンポーネントのCSSファイル

    acme|tagPane          -  root element
    acme|tagPane::content -  container for the links
    acme|tagPane::tag - tag hyperlink
    

    スキンで使用される、コンポーネントのCSSの作成の詳細は、20.3項「スキン・スタイル・プロパティの定義」を参照してください。

  4. コンポーネントに必要なリソース・バンドルをすべて作成します。

  5. CSSをADF Facesスキンに登録するには、/META-INF/trinidad-skins.xmlファイルを開きます。

  6. 構造ウィンドウでskin-addition要素を選択し、プロパティ・インスペクタで次のように設定します。

    • skin-id: カスタム・コンポーネント・セレクタを追加するADF Facesスキンを入力します。セレクタとADF Facesコンポーネントとの互換性を得るには、少なくともsimple.desktopスキンにセレクタを登録する必要があります。


      注意:

      コンポーネントがOracle WebCenterアプリケーションで使用される可能性がある場合は、simple.portletスキンにもセレクタを登録する必要があります。スキンはPDA(simple.pdaなど)でも使用可能です。詳細は、第20章「スタイルおよびスキンを使用した外観のカスタマイズ」を参照してください。

    • style-sheet-name: ドロップダウン・リストを使用して「編集」を選択し、作成したCSSファイルに移動します。

  7. リソース・バンドルを作成している場合は、バンドルの完全修飾パスを<bundle-name>要素の値として追加します。

    例30-24に、tagPaneコンポーネントのコードを示します。

    例30-24 tagPaneのtrinidad-skins.xmlコード

    <?xml version="1.0" encoding="UTF-8" ?>
    <skins xmlns="http://myfaces.apache.org/trinidad/skin">
     <skin-addition>
      <skin-id>simple.desktop</skin-id>
      <style-sheet-name>acme/styles/acme-simple-desktop.css</style-sheet-name>
      <bundle-name>oracle.adfdemo.acme.faces.resource.AcmeSimpleDesktopBundle
      </bundle-name>
     </skin-addition>
    </skins>
    
  8. カスタム・コンポーネントで使用するイメージのイメージ・フォルダを追加します。このフォルダは、META-INFディレクトリの下にある必要があります。カスタム・コンポーネントで使用するすべてのイメージをこのフォルダに配置します。

    tagPaneの場合、イメージ・フォルダは/META-INF/acme/imagesです。

30.5 コンポーネント・ライブラリのデプロイ

カスタム・コンポーネント・ライブラリを作成したら、Webアプリケーションで使用できるデプロイ可能なアーチファクトを作成する必要があります。Javaアーカイブ(JAR)ファイルを作成できるようにするには、作成した多くのリソースを追加して、プロジェクトのデプロイメント・プロファイルを更新する必要があります。

デプロイメントのJARファイルを作成する手順:

  1. アプリケーション・ナビゲータで、プロジェクトをダブルクリックし、「プロジェクト・プロパティ」ダイアログを開きます。

  2. 左ペインで、「デプロイ」を選択します。

  3. 右側の「Deployment Profiles」で、「ADFライブラリのJARファイル」を選択して、「編集」をクリックします。

  4. 左ペインで、「JARオプション」を選択します。

  5. ADFライブラリのJARファイルを格納するためのデフォルトのディレクトリ・パスを確認するか、新規パスを入力します。「Manifestファイルを含める」が選択されていることを確認して、「OK」をクリックします。

  6. デプロイするには、プロジェクトを右クリックし、ポップアップ・メニューから「デプロイ」Project_nameを選択します。デフォルトでは、プロジェクト・ディレクトリ内のデプロイメント・ディレクトリにJARファイルがデプロイされます。

30.6 アプリケーションへのカスタム・コンポーネントの追加

コンポーネントを作成し、ADFライブラリを作成すると、そのコンポーネントを別のアプリケーションにインポートして使用できるようになります。ただし、開発中のアプリケーションでコンポーネントを使用する前には、テスト・アプリケーションで使用してコンポーネントが予想どおりに機能することを確認する必要があります。テストするには、カスタム・ライブラリをテスト・アプリケーションにインポートします。手順は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』のプロジェクトへのADFライブラリ・コンポーネントの追加に関する項を参照してください。

ライブラリを追加したら、Webデプロイメント・ディスクリプタを構成して、リソース・サーブレット・マッピングを追加します。コンポーネントを使用してテスト・アプリケーションを実行すると、コンポーネントのデバッグが必要であることがわかる場合があります。そのため、プロジェクトに対してロギングとアサーションを有効にしておくと役立ちます。


ヒント:

ライブラリをアプリケーションにインポートすると、JDeveloperのコンポーネント・パレットにカスタム・コンポーネントを表示できます。

30.6.1 Webデプロイメント・ディスクリプタの構成方法

コンポーネント・リソース・ローダーは、サーブレット・リソース・マッピングを前提とするように構成されています(たとえば、tagPaneコンポーネントの場合、マッピングはacmeです)。そのため、想定されるリソース・サーブレット・マッピングを使用アプリケーションのweb.xmlファイルに追加する必要があります。

デフォルトでは、MyFaces Trinidadのスキニングでは、CSS 3をCSS 2に正規化するときに、CSSクラスが圧縮されます。コンポーネントのデバッグ時にはこの圧縮を無効にします。本番のデプロイメントでは、この設定を無効に切り替えます。

web.xmlファイルを構成する手順:

  1. web.xmlファイルをダブルクリックして、コード・エディタ内で開きます。

  2. リソース・サーブレットを構成するには、「サーブレット」ページを選択し、「追加」アイコンをクリックして新規サーブレットを追加します。

  3. サーブレット表で次のように設定します。

    • 名前: resourcesと入力します。

    • サーブレット・クラス: org.apache.myfaces.trinidad.webapp.ResourceServletと入力します。

  4. 表の下にある「サーブレット・マッピング」タブをクリックして、「追加」アイコンをクリックします。

  5. URIの接頭辞を入力します。この接頭辞で始まるリソースは、サーブレットによって処理されます。たとえば、tagPaneコンポーネントの場合、接頭辞/acme/*と入力します。

  6. スタイルシートの圧縮を無効にする手順:

    1. 「アプリケーション」を選択します。

    2. 「コンテキスト初期化パラメータ」の「追加」アイコンをクリックします。

    3. 「名前」org.apache.myfaces.trinidad.DISABLE_CONTENT_COMPRESSIONと入力し、「値」trueと入力します。

30.6.2 JavaScriptロギングとアサーションを有効にする方法

JavaScriptデバッグは難しいタスクです。この動的言語の型確認なしでのデバッグをサポートするために、リッチ・クライアントJavaScriptライブラリには、Javaロギングに似たロギング・メカニズムが用意されています。クライアント・スクリプトをより型保証されたスクリプトにするアサーション・ストラテジもあります。これらの機能はいずれも、web.xmlファイルの構成パラメータを使用して有効にします。ロギング・ルーチンとアサーション・ルーチンはブラウザ固有です。クライアントJavaScriptライブラリでは、Gecko、Internet Explorer、OperaおよびSafariバージョンのブラウザ・エージェントがサポートされます。

ロギングとアサーションを有効にする手順:

  1. web.xmlファイルをダブルクリックします。

  2. 「アプリケーション」ページで、「コンテキスト初期化パラメータ」の「追加」アイコンをクリックします。

  3. 次のパラメータを追加して、デバッグを有効にします。

    • 名前: org.apache.myfaces.trinidad.resource.DEBUG

    • 値: true

    この設定により、MyFaces Trinidadで、JavaScriptのようなリソースに対してキャッシュ・ヘッダーが設定されなくなります。ブラウザでのリソースのキャッシングも行われなくなります。

  4. 次のパラメータを追加して、クライアント側JavaScriptのデバッグ・レベルを設定します。

    • 名前: oracle.adf.view.rich.LOGGER_LEVEL

    • 値: ALL

    有効な値は、OFFSEVEREWARNINGINFOCONFIGFINEFINERFINESTおよびALLです。デフォルトは、OFFです。

  5. 次のパラメータを追加して、クライアント側のスクリプト・アサーションを有効にします。

    • 名前: oracle.adf.view.rich.ASSERT_ENABLED

    • 値: true

    この設定はロギングと連携して機能します。このスイッチを有効に切り替えると、デバッグ情報がブラウザで使用可能になります。アサーションとロギングの表示は、ブラウザによって異なります。Internet Explorerの場合、子ブラウザ・ウィンドウがアクティブ・ウィンドウと並んで表示されます。FireFoxにFire Bugプラグインをインストールしている場合、デバッグ情報はFire Bugコンソールから使用できます。

30.6.3 JSFページへのカスタム・コンポーネントの追加方法

カスタム・コンポーネントをJSFページに追加する手順:

  1. コード・エディタでjspxページを開きます。

  2. TLDネームスペースをルート・タグに追加します。たとえば、tagPaneコンポーネントの場合、タグ・ライブラリのURIはhttp://adf-richclient-demo-acmeなので、次の内容を追加します。

    xmlns:acme="http://oracle.adfdemo.acme"
    
  3. コンポーネント・パレットを使用して、コンポーネントをページに追加します。プロパティ・インスペクタを使用して、属性を設定します。


    ヒント:

    JDeveloper以外でアプリケーションを開発している場合は、ページ上でTLDの短縮名とコンポーネント名を使用します。また、属性の任意の値を追加します。たとえば、tagPaneの場合、次の内容を追加します。
    <acme:tagPane>
      <visible="true">
      <orderBy="alpha">
      <tagSelectionListener=#(tagBean.onTagSelect)
    </tagPane>
    

30.6.4 tagPaneカスタム・コンポーネントの使用について

この章の説明に従ってtagPaneコンポーネントを作成し、アプリケーションで使用する場合、バッキングBeanを使用して、カスタム・コンポーネントをアプリケーション・コンポーネントにバインドする必要があります。

例30-25に、tagPaneコンポーネントをFile Explorerアプリケーションにバインドするために使用されるバッキングBeanのコードを示します。

例30-25 tagPaneカスタム・コンポーネントのバッキングBeanロジック

public Map<String, Number> getTags()
 {
  if (_tags == null)
  {
    _tags = new TreeMap<String, Number>();
    List<FileItem> nameToFileItems = feBean.getDataFactory().getFileItemList();
   _doDeepTagCollection(_tags, nameToFileItems);
  }
  return _tags;
 }
 public void onTagSelect(TagSelectEvent event)
 {
  _selectedTag = event.getTag();
  CriteriaFileItemFilter criteria = new CriteriaFileItemFilter(_selectedTag);
  List<FileItem> nameToFileItems =    _feBean.getDataFactory().getFileItemList();
    if (_selectedTagFileItemList == null) {
       _selectedTagFileItemList = new ArrayList<FileItem>();
    else {
      _selectedTagFileItemList.clear();
     }
    _doDeepTagSearch(criteria, _selectedTagFileItemList, nameToFileItems);
    _selectedTagResultsTableModel = new SortableModel(_selectedTagFileItemList);

 }