Save This Page
Home » openjdk-7 » java » rmi » [javadoc | source]
    1   /*
    2    * Copyright 1996-2005 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   package java.rmi;
   26   
   27   import java.rmi.registry;
   28   import java.net.MalformedURLException;
   29   import java.net.URI;
   30   import java.net.URISyntaxException;
   31   
   32   /**
   33    * The <code>Naming</code> class provides methods for storing and obtaining
   34    * references to remote objects in a remote object registry.  Each method of
   35    * the <code>Naming</code> class takes as one of its arguments a name that
   36    * is a <code>java.lang.String</code> in URL format (without the
   37    * scheme component) of the form:
   38    *
   39    * <PRE>
   40    *    //host:port/name
   41    * </PRE>
   42    *
   43    * <P>where <code>host</code> is the host (remote or local) where the registry
   44    * is located, <code>port</code> is the port number on which the registry
   45    * accepts calls, and where <code>name</code> is a simple string uninterpreted
   46    * by the registry. Both <code>host</code> and <code>port</code> are optional.
   47    * If <code>host</code> is omitted, the host defaults to the local host. If
   48    * <code>port</code> is omitted, then the port defaults to 1099, the
   49    * "well-known" port that RMI's registry, <code>rmiregistry</code>, uses.
   50    *
   51    * <P><em>Binding</em> a name for a remote object is associating or
   52    * registering a name for a remote object that can be used at a later time to
   53    * look up that remote object.  A remote object can be associated with a name
   54    * using the <code>Naming</code> class's <code>bind</code> or
   55    * <code>rebind</code> methods.
   56    *
   57    * <P>Once a remote object is registered (bound) with the RMI registry on the
   58    * local host, callers on a remote (or local) host can lookup the remote
   59    * object by name, obtain its reference, and then invoke remote methods on the
   60    * object.  A registry may be shared by all servers running on a host or an
   61    * individual server process may create and use its own registry if desired
   62    * (see <code>java.rmi.registry.LocateRegistry.createRegistry</code> method
   63    * for details).
   64    *
   65    * @author  Ann Wollrath
   66    * @author  Roger Riggs
   67    * @since   JDK1.1
   68    * @see     java.rmi.registry.Registry
   69    * @see     java.rmi.registry.LocateRegistry
   70    * @see     java.rmi.registry.LocateRegistry#createRegistry(int)
   71    */
   72   public final class Naming {
   73       /**
   74        * Disallow anyone from creating one of these
   75        */
   76       private Naming() {}
   77   
   78       /**
   79        * Returns a reference, a stub, for the remote object associated
   80        * with the specified <code>name</code>.
   81        *
   82        * @param name a name in URL format (without the scheme component)
   83        * @return a reference for a remote object
   84        * @exception NotBoundException if name is not currently bound
   85        * @exception RemoteException if registry could not be contacted
   86        * @exception AccessException if this operation is not permitted
   87        * @exception MalformedURLException if the name is not an appropriately
   88        *  formatted URL
   89        * @since JDK1.1
   90        */
   91       public static Remote lookup(String name)
   92           throws NotBoundException,
   93               java.net.MalformedURLException,
   94               RemoteException
   95       {
   96           ParsedNamingURL parsed = parseURL(name);
   97           Registry registry = getRegistry(parsed);
   98   
   99           if (parsed.name == null)
  100               return registry;
  101           return registry.lookup(parsed.name);
  102       }
  103   
  104       /**
  105        * Binds the specified <code>name</code> to a remote object.
  106        *
  107        * @param name a name in URL format (without the scheme component)
  108        * @param obj a reference for the remote object (usually a stub)
  109        * @exception AlreadyBoundException if name is already bound
  110        * @exception MalformedURLException if the name is not an appropriately
  111        *  formatted URL
  112        * @exception RemoteException if registry could not be contacted
  113        * @exception AccessException if this operation is not permitted (if
  114        * originating from a non-local host, for example)
  115        * @since JDK1.1
  116        */
  117       public static void bind(String name, Remote obj)
  118           throws AlreadyBoundException,
  119               java.net.MalformedURLException,
  120               RemoteException
  121       {
  122           ParsedNamingURL parsed = parseURL(name);
  123           Registry registry = getRegistry(parsed);
  124   
  125           if (obj == null)
  126               throw new NullPointerException("cannot bind to null");
  127   
  128           registry.bind(parsed.name, obj);
  129       }
  130   
  131       /**
  132        * Destroys the binding for the specified name that is associated
  133        * with a remote object.
  134        *
  135        * @param name a name in URL format (without the scheme component)
  136        * @exception NotBoundException if name is not currently bound
  137        * @exception MalformedURLException if the name is not an appropriately
  138        *  formatted URL
  139        * @exception RemoteException if registry could not be contacted
  140        * @exception AccessException if this operation is not permitted (if
  141        * originating from a non-local host, for example)
  142        * @since JDK1.1
  143        */
  144       public static void unbind(String name)
  145           throws RemoteException,
  146               NotBoundException,
  147               java.net.MalformedURLException
  148       {
  149           ParsedNamingURL parsed = parseURL(name);
  150           Registry registry = getRegistry(parsed);
  151   
  152           registry.unbind(parsed.name);
  153       }
  154   
  155       /**
  156        * Rebinds the specified name to a new remote object. Any existing
  157        * binding for the name is replaced.
  158        *
  159        * @param name a name in URL format (without the scheme component)
  160        * @param obj new remote object to associate with the name
  161        * @exception MalformedURLException if the name is not an appropriately
  162        *  formatted URL
  163        * @exception RemoteException if registry could not be contacted
  164        * @exception AccessException if this operation is not permitted (if
  165        * originating from a non-local host, for example)
  166        * @since JDK1.1
  167        */
  168       public static void rebind(String name, Remote obj)
  169           throws RemoteException, java.net.MalformedURLException
  170       {
  171           ParsedNamingURL parsed = parseURL(name);
  172           Registry registry = getRegistry(parsed);
  173   
  174           if (obj == null)
  175               throw new NullPointerException("cannot bind to null");
  176   
  177           registry.rebind(parsed.name, obj);
  178       }
  179   
  180       /**
  181        * Returns an array of the names bound in the registry.  The names are
  182        * URL-formatted (without the scheme component) strings. The array contains
  183        * a snapshot of the names present in the registry at the time of the
  184        * call.
  185        *
  186        * @param   name a registry name in URL format (without the scheme
  187        *          component)
  188        * @return  an array of names (in the appropriate format) bound
  189        *          in the registry
  190        * @exception MalformedURLException if the name is not an appropriately
  191        *  formatted URL
  192        * @exception RemoteException if registry could not be contacted.
  193        * @since JDK1.1
  194        */
  195       public static String[] list(String name)
  196           throws RemoteException, java.net.MalformedURLException
  197       {
  198           ParsedNamingURL parsed = parseURL(name);
  199           Registry registry = getRegistry(parsed);
  200   
  201           String prefix = "";
  202           if (parsed.port > 0 || !parsed.host.equals(""))
  203               prefix += "//" + parsed.host;
  204           if (parsed.port > 0)
  205               prefix += ":" + parsed.port;
  206           prefix += "/";
  207   
  208           String[] names = registry.list();
  209           for (int i = 0; i < names.length; i++) {
  210               names[i] = prefix + names[i];
  211           }
  212           return names;
  213       }
  214   
  215       /**
  216        * Returns a registry reference obtained from information in the URL.
  217        */
  218       private static Registry getRegistry(ParsedNamingURL parsed)
  219           throws RemoteException
  220       {
  221           return LocateRegistry.getRegistry(parsed.host, parsed.port);
  222       }
  223   
  224       /**
  225        * Dissect Naming URL strings to obtain referenced host, port and
  226        * object name.
  227        *
  228        * @return an object which contains each of the above
  229        * components.
  230        *
  231        * @exception MalformedURLException if given url string is malformed
  232        */
  233       private static ParsedNamingURL parseURL(String str)
  234           throws MalformedURLException
  235       {
  236           try {
  237               return intParseURL(str);
  238           } catch (URISyntaxException ex) {
  239               /* With RFC 3986 URI handling, 'rmi://:<port>' and
  240                * '//:<port>' forms will result in a URI syntax exception
  241                * Convert the authority to a localhost:<port> form
  242                */
  243               MalformedURLException mue = new MalformedURLException(
  244                   "invalid URL String: " + str);
  245               mue.initCause(ex);
  246               int indexSchemeEnd = str.indexOf(':');
  247               int indexAuthorityBegin = str.indexOf("//:");
  248               if (indexAuthorityBegin < 0) {
  249                   throw mue;
  250               }
  251               if ((indexAuthorityBegin == 0) ||
  252                       ((indexSchemeEnd > 0) &&
  253                       (indexAuthorityBegin == indexSchemeEnd + 1))) {
  254                   int indexHostBegin = indexAuthorityBegin + 2;
  255                   String newStr = str.substring(0, indexHostBegin) +
  256                                   "localhost" +
  257                                   str.substring(indexHostBegin);
  258                   try {
  259                       return intParseURL(newStr);
  260                   } catch (URISyntaxException inte) {
  261                       throw mue;
  262                   } catch (MalformedURLException inte) {
  263                       throw inte;
  264                   }
  265               }
  266               throw mue;
  267           }
  268       }
  269   
  270       private static ParsedNamingURL intParseURL(String str)
  271           throws MalformedURLException, URISyntaxException
  272       {
  273           URI uri = new URI(str);
  274           if (uri.isOpaque()) {
  275               throw new MalformedURLException(
  276                   "not a hierarchical URL: " + str);
  277           }
  278           if (uri.getFragment() != null) {
  279               throw new MalformedURLException(
  280                   "invalid character, '#', in URL name: " + str);
  281           } else if (uri.getQuery() != null) {
  282               throw new MalformedURLException(
  283                   "invalid character, '?', in URL name: " + str);
  284           } else if (uri.getUserInfo() != null) {
  285               throw new MalformedURLException(
  286                   "invalid character, '@', in URL host: " + str);
  287           }
  288           String scheme = uri.getScheme();
  289           if (scheme != null && !scheme.equals("rmi")) {
  290               throw new MalformedURLException("invalid URL scheme: " + str);
  291           }
  292   
  293           String name = uri.getPath();
  294           if (name != null) {
  295               if (name.startsWith("/")) {
  296                   name = name.substring(1);
  297               }
  298               if (name.length() == 0) {
  299                   name = null;
  300               }
  301           }
  302   
  303           String host = uri.getHost();
  304           if (host == null) {
  305               host = "";
  306               try {
  307                   /*
  308                    * With 2396 URI handling, forms such as 'rmi://host:bar'
  309                    * or 'rmi://:<port>' are parsed into a registry based
  310                    * authority. We only want to allow server based naming
  311                    * authorities.
  312                    */
  313                   uri.parseServerAuthority();
  314               } catch (URISyntaxException use) {
  315                   // Check if the authority is of form ':<port>'
  316                   String authority = uri.getAuthority();
  317                   if (authority != null && authority.startsWith(":")) {
  318                       // Convert the authority to 'localhost:<port>' form
  319                       authority = "localhost" + authority;
  320                       try {
  321                           uri = new URI(null, authority, null, null, null);
  322                           // Make sure it now parses to a valid server based
  323                           // naming authority
  324                           uri.parseServerAuthority();
  325                       } catch (URISyntaxException use2) {
  326                           throw new
  327                               MalformedURLException("invalid authority: " + str);
  328                       }
  329                   } else {
  330                       throw new
  331                           MalformedURLException("invalid authority: " + str);
  332                   }
  333               }
  334           }
  335           int port = uri.getPort();
  336           if (port == -1) {
  337               port = Registry.REGISTRY_PORT;
  338           }
  339           return new ParsedNamingURL(host, port, name);
  340       }
  341   
  342       /**
  343        * Simple class to enable multiple URL return values.
  344        */
  345       private static class ParsedNamingURL {
  346           String host;
  347           int port;
  348           String name;
  349   
  350           ParsedNamingURL(String host, int port, String name) {
  351               this.host = host;
  352               this.port = port;
  353               this.name = name;
  354           }
  355       }
  356   }

Save This Page
Home » openjdk-7 » java » rmi » [javadoc | source]