[Seasar-user:1983] Re: MayaとS2のバインディングについて

Masataka Kurihara kurihara
2005年 5月 19日 (木) 11:14:19 JST


栗原です。

> ・式言語からS2のコンポーネントを直接アクセスすること。

  まず、こちらから解説します。

たとえば、以下のようなテンプレートの記述があったとします。

<!--***HTMLテンプレート***-->
<span m:inject="c:out" c:value="${ message.greeting }">
  テンプレート上のダミーメッセージ
</span>

これは、c:outタグに、${ message.greeting } を設定する記述ですが、
この式中の、「message」をS2コンテナ管理とすると便利かと思います。

/***インターフェイス***/
public interface MessageDao {
  String getGreeting();
}

/***実装***/
public class MessageDaoImpl {
  public String getGreeting() {
    return "こんにちは";
  }
}

<!-- ***DICONファイル*** -->
<component name="message" class="MessageDaoImpl"/>

上記のアプリケーションが動くには、ExpressionResolverを実装する必要が
あります。これは式エンジンに組み込まれ、式のエンティティ(ドットで区切ら
れる式文字列中の要素)を解決するためのものです。
org.seasar.maya.impl.el.resolver.ImplicitObjectExpressionResolver
org.seasar.maya.impl.el.resolver.ScopedAttributeExpressionResolver
Maya実装中では上記二つの具体的なExpressionResolver実装があります。
これをごらんになっていただきたいのと共に、応用例として、S2にアクセス
するには。。。

public class SingletonS2ContainerExpressionResolver
        implements ExpressionResolver {
    private static S2Container _container;
    public Object getValue(PageContext context, Object base,
            Object property, ExpressionChain chain) {
        if(base == null) {
            if(_container == null) {
                SingletonS2ContainerFactory.setServletContext(
                        context.getServletContext());
                SingletonS2ContainerFactory.init();
                _container = SingletonS2ContainerFactory.getContainer();
            }
            try {
                return _container.getComponent(property);
            } catch (ComponentNotFoundRuntimeException e) {
            }
        }
        return chain.getValue(context, base, property);
    }

    public void setValue(PageContext context, Object base, Object property,
            Object value, ExpressionChain chain) {
        throw new UnsupportedOperationException();
    }
}

ま、例外処理が甘いですが、上記のような実装を作ります。getValue()メソッド
は、式エンジンより式の実行パース都度にイベント的に呼び出されます。
${ message.greeting } だと、まず、「message」を解釈すべく、
Object base = getValue(context, null, "message", chain);
と呼び出されます。messageが解決出来た後、${ message.greeting }
の「greeting」を解釈すべく、
getValue(context, base, "greeting", chain); が呼ばれ、その結果が
テンプレートに返ります。そのため、base=nullのチェックをgetValue()中では
まず行っています。
コンテナから該当コンポーネントが取れればそのまま返しますが、もし、
ComponentNotFoundRuntimeExceptionが発生したときは、S2のコン
ポーネントではないものを式で要求されているということですから、例外を
食いつぶして、chain.getValue(context, base, property);
を呼んでいます。このchainはレゾルバのリストの次のリゾルバに処理を渡す
ためのもので、サーブレットFilterのchainと概念は一緒です。

  そして、このSingletonS2ContainerExpressionResolverをMayaに組み
込みます。「本日時点の」CVSのバージョンでしたら、expression.lst という
テキストファイルがあるので、それに登録します。

#***expression.lst***
org.seasar.maya.impl.el.resolver.ImplicitObjectExpressionResolver
org.seasar.maya.component.el.resolver.AttributeExpressionResolver
SingletonS2ContainerExpressionResolver
org.seasar.maya.impl.el.resolver.ScopedAttributeExpressionResolver

このファイルを、WEB-INFの下に配置すればMayaに組み込まれます。
このexpression.lstは、記述順でリゾルバを並べますので、順番が大事です。
ScopedAttributeExpressionResolverより後にレゾルバを並べても、この
レゾルバがchainを呼んでないので、処理がわたりません。
式の解決は、以上です。

(ServiceProviderのS2コンテナ利用編に続く。。。)

--
株式会社グルージェント
栗原 傑享(くりはら まさたか)
渋谷区渋谷3-7-6 第6矢木ビル4F
TEL:03-5469-8869 FAX:03-5469-8879
URL:http://www.gluegent.com/
--





Seasar-user メーリングリストの案内