0N/A/*
2362N/A * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/Apackage java.rmi;
0N/A
0N/Aimport java.rmi.registry.*;
0N/Aimport java.net.MalformedURLException;
0N/Aimport java.net.URI;
0N/Aimport java.net.URISyntaxException;
0N/A
0N/A/**
0N/A * The <code>Naming</code> class provides methods for storing and obtaining
0N/A * references to remote objects in a remote object registry. Each method of
0N/A * the <code>Naming</code> class takes as one of its arguments a name that
0N/A * is a <code>java.lang.String</code> in URL format (without the
0N/A * scheme component) of the form:
0N/A *
0N/A * <PRE>
0N/A * //host:port/name
0N/A * </PRE>
0N/A *
0N/A * <P>where <code>host</code> is the host (remote or local) where the registry
0N/A * is located, <code>port</code> is the port number on which the registry
0N/A * accepts calls, and where <code>name</code> is a simple string uninterpreted
0N/A * by the registry. Both <code>host</code> and <code>port</code> are optional.
0N/A * If <code>host</code> is omitted, the host defaults to the local host. If
0N/A * <code>port</code> is omitted, then the port defaults to 1099, the
0N/A * "well-known" port that RMI's registry, <code>rmiregistry</code>, uses.
0N/A *
0N/A * <P><em>Binding</em> a name for a remote object is associating or
0N/A * registering a name for a remote object that can be used at a later time to
0N/A * look up that remote object. A remote object can be associated with a name
0N/A * using the <code>Naming</code> class's <code>bind</code> or
0N/A * <code>rebind</code> methods.
0N/A *
0N/A * <P>Once a remote object is registered (bound) with the RMI registry on the
0N/A * local host, callers on a remote (or local) host can lookup the remote
0N/A * object by name, obtain its reference, and then invoke remote methods on the
0N/A * object. A registry may be shared by all servers running on a host or an
0N/A * individual server process may create and use its own registry if desired
0N/A * (see <code>java.rmi.registry.LocateRegistry.createRegistry</code> method
0N/A * for details).
0N/A *
0N/A * @author Ann Wollrath
0N/A * @author Roger Riggs
0N/A * @since JDK1.1
0N/A * @see java.rmi.registry.Registry
0N/A * @see java.rmi.registry.LocateRegistry
0N/A * @see java.rmi.registry.LocateRegistry#createRegistry(int)
0N/A */
0N/Apublic final class Naming {
0N/A /**
0N/A * Disallow anyone from creating one of these
0N/A */
0N/A private Naming() {}
0N/A
0N/A /**
0N/A * Returns a reference, a stub, for the remote object associated
0N/A * with the specified <code>name</code>.
0N/A *
0N/A * @param name a name in URL format (without the scheme component)
0N/A * @return a reference for a remote object
0N/A * @exception NotBoundException if name is not currently bound
0N/A * @exception RemoteException if registry could not be contacted
0N/A * @exception AccessException if this operation is not permitted
0N/A * @exception MalformedURLException if the name is not an appropriately
0N/A * formatted URL
0N/A * @since JDK1.1
0N/A */
0N/A public static Remote lookup(String name)
0N/A throws NotBoundException,
0N/A java.net.MalformedURLException,
0N/A RemoteException
0N/A {
0N/A ParsedNamingURL parsed = parseURL(name);
0N/A Registry registry = getRegistry(parsed);
0N/A
0N/A if (parsed.name == null)
0N/A return registry;
0N/A return registry.lookup(parsed.name);
0N/A }
0N/A
0N/A /**
0N/A * Binds the specified <code>name</code> to a remote object.
0N/A *
0N/A * @param name a name in URL format (without the scheme component)
0N/A * @param obj a reference for the remote object (usually a stub)
0N/A * @exception AlreadyBoundException if name is already bound
0N/A * @exception MalformedURLException if the name is not an appropriately
0N/A * formatted URL
0N/A * @exception RemoteException if registry could not be contacted
0N/A * @exception AccessException if this operation is not permitted (if
0N/A * originating from a non-local host, for example)
0N/A * @since JDK1.1
0N/A */
0N/A public static void bind(String name, Remote obj)
0N/A throws AlreadyBoundException,
0N/A java.net.MalformedURLException,
0N/A RemoteException
0N/A {
0N/A ParsedNamingURL parsed = parseURL(name);
0N/A Registry registry = getRegistry(parsed);
0N/A
0N/A if (obj == null)
0N/A throw new NullPointerException("cannot bind to null");
0N/A
0N/A registry.bind(parsed.name, obj);
0N/A }
0N/A
0N/A /**
0N/A * Destroys the binding for the specified name that is associated
0N/A * with a remote object.
0N/A *
0N/A * @param name a name in URL format (without the scheme component)
0N/A * @exception NotBoundException if name is not currently bound
0N/A * @exception MalformedURLException if the name is not an appropriately
0N/A * formatted URL
0N/A * @exception RemoteException if registry could not be contacted
0N/A * @exception AccessException if this operation is not permitted (if
0N/A * originating from a non-local host, for example)
0N/A * @since JDK1.1
0N/A */
0N/A public static void unbind(String name)
0N/A throws RemoteException,
0N/A NotBoundException,
0N/A java.net.MalformedURLException
0N/A {
0N/A ParsedNamingURL parsed = parseURL(name);
0N/A Registry registry = getRegistry(parsed);
0N/A
0N/A registry.unbind(parsed.name);
0N/A }
0N/A
0N/A /**
0N/A * Rebinds the specified name to a new remote object. Any existing
0N/A * binding for the name is replaced.
0N/A *
0N/A * @param name a name in URL format (without the scheme component)
0N/A * @param obj new remote object to associate with the name
0N/A * @exception MalformedURLException if the name is not an appropriately
0N/A * formatted URL
0N/A * @exception RemoteException if registry could not be contacted
0N/A * @exception AccessException if this operation is not permitted (if
0N/A * originating from a non-local host, for example)
0N/A * @since JDK1.1
0N/A */
0N/A public static void rebind(String name, Remote obj)
0N/A throws RemoteException, java.net.MalformedURLException
0N/A {
0N/A ParsedNamingURL parsed = parseURL(name);
0N/A Registry registry = getRegistry(parsed);
0N/A
0N/A if (obj == null)
0N/A throw new NullPointerException("cannot bind to null");
0N/A
0N/A registry.rebind(parsed.name, obj);
0N/A }
0N/A
0N/A /**
0N/A * Returns an array of the names bound in the registry. The names are
0N/A * URL-formatted (without the scheme component) strings. The array contains
0N/A * a snapshot of the names present in the registry at the time of the
0N/A * call.
0N/A *
0N/A * @param name a registry name in URL format (without the scheme
0N/A * component)
0N/A * @return an array of names (in the appropriate format) bound
0N/A * in the registry
0N/A * @exception MalformedURLException if the name is not an appropriately
0N/A * formatted URL
0N/A * @exception RemoteException if registry could not be contacted.
0N/A * @since JDK1.1
0N/A */
0N/A public static String[] list(String name)
0N/A throws RemoteException, java.net.MalformedURLException
0N/A {
0N/A ParsedNamingURL parsed = parseURL(name);
0N/A Registry registry = getRegistry(parsed);
0N/A
0N/A String prefix = "";
0N/A if (parsed.port > 0 || !parsed.host.equals(""))
0N/A prefix += "//" + parsed.host;
0N/A if (parsed.port > 0)
0N/A prefix += ":" + parsed.port;
0N/A prefix += "/";
0N/A
0N/A String[] names = registry.list();
0N/A for (int i = 0; i < names.length; i++) {
0N/A names[i] = prefix + names[i];
0N/A }
0N/A return names;
0N/A }
0N/A
0N/A /**
0N/A * Returns a registry reference obtained from information in the URL.
0N/A */
0N/A private static Registry getRegistry(ParsedNamingURL parsed)
0N/A throws RemoteException
0N/A {
0N/A return LocateRegistry.getRegistry(parsed.host, parsed.port);
0N/A }
0N/A
0N/A /**
0N/A * Dissect Naming URL strings to obtain referenced host, port and
0N/A * object name.
0N/A *
0N/A * @return an object which contains each of the above
0N/A * components.
0N/A *
0N/A * @exception MalformedURLException if given url string is malformed
0N/A */
0N/A private static ParsedNamingURL parseURL(String str)
0N/A throws MalformedURLException
0N/A {
0N/A try {
0N/A return intParseURL(str);
0N/A } catch (URISyntaxException ex) {
0N/A /* With RFC 3986 URI handling, 'rmi://:<port>' and
0N/A * '//:<port>' forms will result in a URI syntax exception
0N/A * Convert the authority to a localhost:<port> form
0N/A */
0N/A MalformedURLException mue = new MalformedURLException(
0N/A "invalid URL String: " + str);
0N/A mue.initCause(ex);
0N/A int indexSchemeEnd = str.indexOf(':');
0N/A int indexAuthorityBegin = str.indexOf("//:");
0N/A if (indexAuthorityBegin < 0) {
0N/A throw mue;
0N/A }
0N/A if ((indexAuthorityBegin == 0) ||
0N/A ((indexSchemeEnd > 0) &&
0N/A (indexAuthorityBegin == indexSchemeEnd + 1))) {
0N/A int indexHostBegin = indexAuthorityBegin + 2;
0N/A String newStr = str.substring(0, indexHostBegin) +
0N/A "localhost" +
0N/A str.substring(indexHostBegin);
0N/A try {
0N/A return intParseURL(newStr);
0N/A } catch (URISyntaxException inte) {
0N/A throw mue;
0N/A } catch (MalformedURLException inte) {
0N/A throw inte;
0N/A }
0N/A }
0N/A throw mue;
0N/A }
0N/A }
0N/A
0N/A private static ParsedNamingURL intParseURL(String str)
0N/A throws MalformedURLException, URISyntaxException
0N/A {
0N/A URI uri = new URI(str);
0N/A if (uri.isOpaque()) {
0N/A throw new MalformedURLException(
0N/A "not a hierarchical URL: " + str);
0N/A }
0N/A if (uri.getFragment() != null) {
0N/A throw new MalformedURLException(
0N/A "invalid character, '#', in URL name: " + str);
0N/A } else if (uri.getQuery() != null) {
0N/A throw new MalformedURLException(
0N/A "invalid character, '?', in URL name: " + str);
0N/A } else if (uri.getUserInfo() != null) {
0N/A throw new MalformedURLException(
0N/A "invalid character, '@', in URL host: " + str);
0N/A }
0N/A String scheme = uri.getScheme();
0N/A if (scheme != null && !scheme.equals("rmi")) {
0N/A throw new MalformedURLException("invalid URL scheme: " + str);
0N/A }
0N/A
0N/A String name = uri.getPath();
0N/A if (name != null) {
0N/A if (name.startsWith("/")) {
0N/A name = name.substring(1);
0N/A }
0N/A if (name.length() == 0) {
0N/A name = null;
0N/A }
0N/A }
0N/A
0N/A String host = uri.getHost();
0N/A if (host == null) {
0N/A host = "";
0N/A try {
0N/A /*
0N/A * With 2396 URI handling, forms such as 'rmi://host:bar'
0N/A * or 'rmi://:<port>' are parsed into a registry based
0N/A * authority. We only want to allow server based naming
0N/A * authorities.
0N/A */
0N/A uri.parseServerAuthority();
0N/A } catch (URISyntaxException use) {
0N/A // Check if the authority is of form ':<port>'
0N/A String authority = uri.getAuthority();
0N/A if (authority != null && authority.startsWith(":")) {
0N/A // Convert the authority to 'localhost:<port>' form
0N/A authority = "localhost" + authority;
0N/A try {
0N/A uri = new URI(null, authority, null, null, null);
0N/A // Make sure it now parses to a valid server based
0N/A // naming authority
0N/A uri.parseServerAuthority();
0N/A } catch (URISyntaxException use2) {
0N/A throw new
0N/A MalformedURLException("invalid authority: " + str);
0N/A }
0N/A } else {
0N/A throw new
0N/A MalformedURLException("invalid authority: " + str);
0N/A }
0N/A }
0N/A }
0N/A int port = uri.getPort();
0N/A if (port == -1) {
0N/A port = Registry.REGISTRY_PORT;
0N/A }
0N/A return new ParsedNamingURL(host, port, name);
0N/A }
0N/A
0N/A /**
0N/A * Simple class to enable multiple URL return values.
0N/A */
0N/A private static class ParsedNamingURL {
0N/A String host;
0N/A int port;
0N/A String name;
0N/A
0N/A ParsedNamingURL(String host, int port, String name) {
0N/A this.host = host;
0N/A this.port = port;
0N/A this.name = name;
0N/A }
0N/A }
0N/A}