Re:S2RemotingのRMI実装

早速、id:koichikさんのURLBasedConnectorを利用しようと思ったのですが、URLクラスはプロトコルrmiだと
java.net.MalformedURLException: unknown protocol: rmi
となり使えないようです。知りませんでした。

ぐはぁっ,そんな問題が...
そんなわけで (どんなわけで?),こんなの作ってみました.
まずは URLStreamHandlerHandlerレジストリ

package org.seasar.remoting.url;

import java.net.URL;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
import java.util.HashMap;
import java.util.Map;

public class URLStreamHandlerRegistry implements URLStreamHandlerFactory {
    protected static final Map registry = new HashMap();

    static {
        URL.setURLStreamHandlerFactory(new URLStreamHandlerRegistry());
    }

    private URLStreamHandlerRegistry() {
    }

    public URLStreamHandler createURLStreamHandler(final String protocol) {
        return (URLStreamHandler) registry.get(protocol);
    }

    public static void registerHandler(final String protocol, final URLStreamHandler handler) {
        registry.put(protocol, handler);
    }
}

そしてデフォルトのポート番号を持ち,openConnection() することのできない汎用の URLStreamHandler

package org.seasar.remoting.url;

import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;

public class UnopenableURLStreamHandler extends URLStreamHandler {
    protected final int defaultPort;

    public UnopenableURLStreamHandler(final int defaultPort) {
        this.defaultPort = defaultPort;
    }

    protected URLConnection openConnection(final URL url) throws IOException {
        throw new UnsupportedOperationException();
    }

    protected void setURL(final URL url, final String protocol, final String host, int port,
            final String authority, final String userInfo, final String path, final String query,
            final String ref) {
        if (port == -1) {
            port = defaultPort;
        }
        super.setURL(url, protocol, host, port, authority, userInfo, path, query, ref);
    }
}

軽くテスト.

package org.seasar.remoting.url;

import java.net.MalformedURLException;
import java.net.URL;

import junit.framework.TestCase;

public class UnopenableURLStreamHandlerTest extends TestCase {
    public UnopenableURLStreamHandlerTest() {
        super();
    }

    public UnopenableURLStreamHandlerTest(String name) {
        super(name);
    }

    public void test() throws MalformedURLException {
        URLStreamHandlerRegistry.registerHandler("rmi", new UnopenableURLStreamHandler(1099));
        
        URL url = new URL("rmi://localhost/test");
        assertEquals("rmi", url.getProtocol());
        assertEquals(1099, url.getPort());
        assertEquals("localhost", url.getHost());
        assertEquals("/test", url.getPath());
        
        new URL("http://host/test");
        try {
            new URL("foo://host/hoge");
            fail();
        }
        catch (MalformedURLException ignore) {
        }
    }
}

これで,RMIConnector (?) で

public class RMIConnector extends URLBasedConnector {
    static {
        URLStreamHandlerRegistry.registerHandler("rmi", new UnopenableURLStreamHandler(1099));
    }
    ・・・
}

と使うことが出来ます.
S2Remoting 0.0.3 に含めます.