S2Remoting

むらたさんの日記から一連の「S2Remoting サンプル実装」を読ませて頂きました.なるほど〜,随分前からいろいろな構想があったのですね.さすがひがさん...
そんなわけで (どんなわけで?),さっそく採用させて頂こうかと思います.
S2Remoting では共通の Interceptor を提供し,Connector によって様々なプロトコルをサポートするということにしましょう.
そんなわけで (どんなわけで?),Interceptor はこんな感じでどうでしょうか?

package org.seasar.remoting.client;

import org.aopalliance.intercept.MethodInvocation;
import org.seasar.framework.aop.interceptors.AbstractInterceptor;
import org.seasar.framework.container.ComponentDef;
import org.seasar.framework.util.ClassUtil;

public class RemotingInterceptor extends AbstractInterceptor {
    protected Connector connector;
    protected String name;

    public void setConnector(final Connector connector) {
        this.connector = connector;
    }

    public void setName(final String name) {
        this.name = name;
    }

    public Object invoke(final MethodInvocation invocation) throws Throwable {
        return connector.invoke(getTargetName(invocation), invocation.getMethod(),
                invocation.getArguments());
    }

    protected String getTargetName(final MethodInvocation invocation) {
        if (name != null) {
            return name;
        }

        final ComponentDef componentDef = getComponentDef(invocation);
        final String componentName = componentDef.getComponentName();
        if (componentName != null) {
            return componentName;
        }

        final Class componentClass = componentDef.getComponentClass();
        if (componentClass != null) {
            return ClassUtil.getShortClassName(componentClass);
        }

        return ClassUtil.getShortClassName(invocation.getThis().getClass());
    }
}

ちょっと工夫したのはターゲットの名前を取ってくるところ.この意図は後で.
そして Connector

package org.seasar.remoting.client;

import java.lang.reflect.Method;

public interface Connector {
    Object invoke(String name, Method method, Object[] args) throws Throwable;
}

まぁ,どうということもなく.
そして URL を使う Connector のための抽象クラス.

package org.seasar.remoting.client;

import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.LinkedHashMap;
import java.util.Map;

public abstract class URLBasedConnector implements Connector {
    protected URL baseURL;

    public void setBaseURL(final URL baseURL) {
        this.baseURL = baseURL;
    }

    public Object invoke(final String name, final Method method, final Object[] args)
            throws Throwable {
        return invoke(getTargetURL(name), method, args);
    }

    protected URL getTargetURL(final String name)
            throws MalformedURLException {
        return new URL(baseURL, name);
    }

    protected abstract Object invoke(URL targetURL, Method method, Object[] args)
            throws Throwable;
}

ターゲット URL はキャッシュした方がいいかもしれませんが,それはまた後で.ひがさんの構想にあるような複数 URL をサポートする場合は ClusterableURLBasedConnector とか別途作るって事でそれはまた後で.それから,結局 setBaseUrl(URL) ではなく setBaseURL(URL) にしようかと思ってます.URL が複数になった時に Urls より URLs の方がカッコいいかなーって思ったので.
ともあれ (JW),このように URLBasedConnector はベースとなる URL を持ち,RemotingInterceptor から渡されるサービス (リモートオブジェクト) 名を付加してターゲットとなる URL を求めています.このため,複数のサービスを使う場合でも URL の指定を一カ所にまとめられたりします.そして RemotingInterceptorコンポーネント定義からターゲットの名前を取ってくるため,一つのインスタンスを複数のターゲットに適用できます.で,こんな感じ.

<component name="remoting" class="RemotingInterceptor"/>

<component class="AxisConnector">
    <property name="baseURL">new URL("http://localhost:8080/s2-axis-examples/services/")</property>
</component>

<component name="foo" class="Foo">
    <aspect>remoting</aspect>
</component>

<component name="bar" class="Bar">
    <aspect>remoting</aspect>
</component>

いい感じじゃない? (^^;


これ,S2Axis と S2Hessian は楽に対応できますが,S2XmlRpc はちょっと悩ましいかもしれませんね.ターゲット URL に対応する XmlRpcClient のキャッシュを持つとかしないといけない感じ.
とりあえず,ご意見あればお願いします.


リモーティング関連プロダクトのパッケージ名なんですが,次のように揃えた方がいいかなぁと考えています.

  • org.seasar.remoting.client  リモーティング共通 (クライアント)
  • org.seasar.remoting.server  リモーティング共通 (サーバ)
  • org.seasar.remoting.axis     Axis (SOAP)
  • org.seasar.remoting.caucho  Hessian / Burlap
  • org.seasar.remoting.rmi      RMI
  • org.seasar.remoting.xmlrpc  XmlRpc

なにげに S2XmlRpc はすでに上記のパッケージになっているので,S2Axis と S2Hessian が対応すればいいだけなんですが.
こちらもご意見あればお願いします.


そろそろ Sandbox 申請しようかな...