SeamFramework.org Community Documentation

- 前のページ
- 次のページ

## 第34章 JBoss EL

Seam は 標準の Unified Expression Language (EL) に拡張を提供する JBoss EL を使用します。 JBoss EL は EL 式のパワーや表現力を増強させるいくつかの機能拡張を提供しています。

## 34.1. パラメータ化された式

標準 EL ではユーザー定義のパラメータでメソッドを使用することはできません。 当然、 JSF リスナーのメソッド (`valueChangeListener`) は JSF 提供のパラメータをとることになります。

JBoss EL ではこの制約が取り除かれます。 以下が例です。

    <h:commandButton action="#{hotelBooking.bookHotel(hotel)}" value="Book Hotel"/>

    @Name("hotelBooking")

    public class HotelBooking {

       public String bookHotel(Hotel hotel) {

          // Book the hotel

       }

    }

### 34.1.1. 使い方

ちょうど Java から メソッドへのコールと同じように、 パラメータは括弧で囲まれコンマで区切られます。

    <h:commandButton action="#{hotelBooking.bookHotel(hotel, user)}" value="Book Hotel"/>

パラメータ `hotel` と `user` は値式として評価されコンポーネントの `bookHotel()` メソッドに渡されます。

パラメータには、以下のように、どのような値式も使う事ができます。

    <h:commandButton

       action="#{hotelBooking.bookHotel(hotel.id, user.username)}"

       value="Book Hotel"/>

こうした EL への拡張がどのように動作するのかを十分に理解しておくことが重要となります。 ページがレンダリングされるとパラメータの 名前 が保存され (例、 `hotel.id` と `user.username`)、 ページがサブミットされるときに(値式として)評価されます。 パラメータとしてオブジェクトを渡すことはできません。

ページがレンダリングされる場合だけでなくサブミットされる場合にもパラメータが使用できるようになっていることを確認する必要があります。 ページがサブミットされるときに引数が解決できないとアクションメソッドが `null` 引数を付けて呼び出されます。

一重引用符を用いて文字列リテラルを渡すこともできます。

    <h:commandLink action="#{printer.println('Hello world!')}" value="Hello"/>

Unified EL は値式にも対応し、 フィールドを支えている Bean にバインドするために使用されます。 値式は JavaBean の命名規則を使用し getter と setter の組み合わせを期待します。 JSF はしばしば、値の検索 (get) のみを必要とするような場合にも値式を期待します (`rendered` 属性)。 にもかかわらず、 多くのオブジェクトが適切な名前のプロパティアクセッサを持っていなかったり、 要求されたパラメータを持っていなかったりする場合があります。

JBoss EL はメソッド構文を使った値の検索を許可することで制約を取り除きます。 以下が例です。

    <h:outputText value="#{person.name}" rendered="#{person.name.length()

    > 5}" />

同様にして 1 集合のサイズにアクセスが可能です。

    #{searchResults.size()}

一般的には #{obj.property} 形式の表現は #{obj.getProperty()} 形式とまったく同一となります。

パラメータを使うこともできます。 次の例では文字列リテラルの引数を持つ `productsByColorMethod` を呼び出しています。

    #{controller.productsByColor('blue')}

### 34.1.2. 制約とヒント

JBoss EL を使用する際には次の点に留意してください。

- JSP 2.1 との非互換性 — JBoss EL は現在 JSP 2.1 との併用はできません。 コンパイラがパラメータ付きの式を拒否するためです。 JSF 1.2 でこの拡張を使用したい場合は Facelets を使用する必要があります。 この拡張は JSP 2.0 では正常に動作します。

- 反復コンポーネント内での使用 — `<c:forEach />` や `<ui:repeat />` といったコンポーネントは List またはアレイに渡って反復し一覧内の各アイテムをネストされるコンポーネントに公開します。 `<h:commandButton />` や `<h:commandLink />` を使った列を選択している場合に非常に便利です。

      @Factory("items")

      public List<Item

      > getItems() {

         return entityManager.createQuery("select ...").getResultList();

      }

      <h:dataTable value="#{items}" var="item">

         <h:column>

            <h:commandLink value="Select #{item.name}" action="#{itemSelector.select(item})" />

         </h:column>

      </h:dataTable

      >

  ただし、 `<s:link />` や `<s:button />` を使用したい場合はアイテムを `DataModel` として公開して `<dataTable />` (または `<rich:dataTable />` のようなコンポーネントセットからの同等) を使用 しなければなりません。 `<s:link />` あるいは `<s:button />` のいずれもフォームをサブミットしない (したがってリンクがブックマーク可能となる) ためアクションメソッドが呼び出された場合にそのアイテムを再度作成するためのマジックパラメータが必要となります。 `DataModel` で支えられるデータテーブルが使用されるとこのマジックパラメータのみが追加可能となります。

- Java コードから `MethodExpression` を呼び出す — 通常、 `MethodExpression` が作成されるとパラメータタイプが JSF によって渡されます。 メソッドのバインディングの場合、 JSF は渡すパラメータがないものとみなします。 この拡張では、 式が評価され終わってからでないとパラメータタイプを知ることができません。 これにより深刻ではありませんが 2 つの結果を招くことになります。

  - Javaコードで `MethodExpression` を呼び出したとき、 渡したパラメータが無視される可能性があります。 式中で定義されたパラメータが優先されます。

  - 通常、 `methodExpression.getMethodInfo().getParamTypes()` はいつでも安全に呼び出す事ができます。 パラメータを伴う式の場合、 まず `MethodExpression` を呼び出してから、 `getParamTypes()` を呼び出すようにしてください。

  上記のようなケースは非常に稀であり、 Java コードで `MethodExpression` を手作業で呼び出す必要が有る場合にのみ適用されます。

## 34.2. プロジェクション

JBoss EL は限られたプロジェクション構文に対応します。 プロジェクション式はサブとなる式を複数値 (リスト、 セットなど) の式全体にマッピングします。 以下が例です。

    #{company.departments}

この式は部署の一覧を返します。 部署名の一覧のみが必要な場合はその値を検索する一覧全体を反復させることが唯一のオプションとなります。 JBoss EL ではプロジェクション式を使うと行うことができます。

    #{company.departments.{d|d.name}}

サブとなる式は中括弧で囲みます。 この例では各部署ごとに `d.name` 式が評価され、 `d` を部署のオブジェクトへのエイリアスとして使っています。 この式の結果は文字列値の一覧となります。

式中に有効な式ならいずれの式でも使用できるため次の記述は完全に有効です。 ある会社の全部署の部署名の長さ (サイズ) を知りたい場合には次のように問い合わせることができます。

    #{company.departments.{d|d.size()}}

プロジェクションはネストさせることが可能です。 次の式は各部署内のそれぞれの社員のラストネームを返します。

    #{company.departments.{d|d.employees.{emp|emp.lastName}}}

ただしプロジェクションのネストは若干の注意が必要です。 次の式は全部署の全社員一覧を返すように見えます。

    #{company.departments.{d|d.employees}}

しかし実際には各個別部署ごとの社員一覧を含む一覧を返します。 値を結合させるにはもう少し長い式を使う必要があります。

    #{company.departments.{d|d.employees.{e|e}}}

この構文は Facelets や JSP では解析不能なため xhtml または JSP ファイルでは使用できない点に注意してください。 プロジェクション構文は JBoss EL の将来的なバージョンにおける変更が見込まれています。

- 前のページ第33章 Seam JSF コントロール
- 上に戻る
- ホーム
- 次のページ第35章 クラスタリングと EJB パッシベーション