/*
 * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/*
 * @test
 * @bug 5083594
 * @summary Ensure that Naming.java correctly parses host names with '_' in
 * them.
 * @author Vinod Johnson
 *
 * @library ../testlibrary
 * @build TestLibrary
 * @build UnderscoreHost UnderscoreHost_Stub
 * @run main/othervm UnderscoreHost
 */

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.net.Socket;
import java.rmi.Naming;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.RMISocketFactory;
import java.rmi.server.UnicastRemoteObject;

public class UnderscoreHost extends UnicastRemoteObject implements Remote {
    private static final String HOSTNAME = "foo_bar";
    private static final String NAME = "name";
    /*
     * The socket factory captures the host name of the parsed URL, and
     * then connects to the local host.
     */
    private static class HostVerifyingSocketFactory extends RMISocketFactory {
        String host;

        public synchronized Socket createSocket(String host, int port)
            throws IOException  {
            if (this.host == null) {
                // Only set it the first time, subsequent DGC dirty calls
                // will be local host
                this.host = host;
            }
            return new Socket("localhost", port);
        }
        public ServerSocket createServerSocket(int port) throws IOException {
            return new ServerSocket(port);
        }
    }

    public UnderscoreHost() throws RemoteException {};

    public static void main(String args[]) {
        UnderscoreHost t = null;
        try {
            HostVerifyingSocketFactory hvf = new HostVerifyingSocketFactory();
            RMISocketFactory.setSocketFactory(hvf);
            Registry r = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
            t = new UnderscoreHost();
            r.rebind(NAME, t);
            Naming.lookup("rmi://" + HOSTNAME +
                          ":" + Registry.REGISTRY_PORT + "/" + NAME);
            /*
             * This test is coded to pass whether java.net.URI obeys
             * RFC 2396 or RFC 3986 (see 5085902, 6394131, etc.).
             *
             * If java.net.URI obeys RFC 3986, so host names may
             * contain underscores, then the Naming.lookup invocation
             * should succeed-- but the host actually connected to
             * must equal HOSTNAME.
             */
            if (!hvf.host.equals(HOSTNAME)) {
                throw new RuntimeException(
                    "java.rmi.Naming Parsing error:" +
                    hvf.host + ":" + HOSTNAME);
            }
        } catch (MalformedURLException e) {
            /*
             * If java.net.URI obeys RFC 2396, so host names must not
             * contain underscores, then the Naming.lookup invocation
             * should throw MalformedURLException-- so this is OK.
             */
        } catch (IOException ioe) {
            TestLibrary.bomb(ioe);
        } catch (java.rmi.NotBoundException nbe) {
            TestLibrary.bomb(nbe);
        } finally {
            TestLibrary.unexport(t);
        }

    }
}
