1. /*
  2. * @(#)Naming.java 1.16 00/02/02
  3. *
  4. * Copyright 1996-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package java.rmi;
  11. import java.rmi.registry.*;
  12. import java.net.MalformedURLException;
  13. /**
  14. * The <code>Naming</code> class provides methods for storing and obtaining
  15. * references to remote objects in the remote object registry. The
  16. * <code>Naming</code> class's methods take, as one of their arguments, a name
  17. * that is a URL formatted <code>java.lang.String</code> of the form:
  18. *
  19. * <PRE>
  20. * //host:port/name
  21. * </PRE>
  22. *
  23. * <P>where <code>host</code> is the host (remote or local) where the registry
  24. * is located, <code>port</code> is the port number on which the registry
  25. * accepts calls, and where <code>name</code> is a simple string uninterpreted
  26. * by the registry. Both <code>host</code> and <code>port</code> are optional.
  27. * If <code>host</code> is omitted, the host defaults to the local host. If
  28. * <code>port</code> is omitted, then the port defaults to 1099, the
  29. * "well-known" port that RMI's registry, <code>rmiregistry</code>, uses.
  30. *
  31. * <P><em>Binding</em> a name for a remote object is associating or
  32. * registering a name for a remote object that can be used at a later time to
  33. * look up that remote object. A remote object can be associated with a name
  34. * using the <code>Naming</code> class's <code>bind</code> or
  35. * <code>rebind</code> methods.
  36. *
  37. * <P>Once a remote object is registered (bound) with the RMI registry on the
  38. * local host, callers on a remote (or local) host can lookup the remote
  39. * object by name, obtain its reference, and then invoke remote methods on the
  40. * object. A registry may be shared by all servers running on a host or an
  41. * individual server process may create and use its own registry if desired
  42. * (see <code>java.rmi.registry.LocateRegistry.createRegistry</code> method
  43. * for details).
  44. *
  45. * @version 1.13, 09/05/99
  46. * @author Ann Wollrath
  47. * @author Roger Riggs
  48. * @since JDK1.1
  49. * @see java.rmi.registry.Registry
  50. * @see java.rmi.registry.LocateRegistry
  51. * @see java.rmi.registry.LocateRegistry#createRegistry(int)
  52. */
  53. public final class Naming {
  54. /**
  55. * Disallow anyone from creating one of these
  56. */
  57. private Naming() {}
  58. /**
  59. * Returns a reference, a stub, for the remote object associated
  60. * with the specified <code>name</code>.
  61. *
  62. * @param name a URL-formatted name for the remote object
  63. * @return a reference for a remote object
  64. * @exception NotBoundException if name is not currently bound
  65. * @exception RemoteException if registry could not be contacted
  66. * @exception AccessException if this operation is not permitted
  67. * @exception MalformedURLException if the name is not an appropriately
  68. * formatted URL
  69. * @since JDK1.1
  70. */
  71. public static Remote lookup(String name)
  72. throws NotBoundException,
  73. java.net.MalformedURLException,
  74. RemoteException
  75. {
  76. ParsedNamingURL parsed = parseURL(name);
  77. Registry registry = getRegistry(parsed);
  78. if (parsed.name == null)
  79. return registry;
  80. return registry.lookup(parsed.name);
  81. }
  82. /**
  83. * Binds the specified <code>name</code> to a remote object.
  84. *
  85. * @param name a URL-formatted name for the remote object
  86. * @param obj a reference for the remote object (usually a stub)
  87. * @exception AlreadyBoundException if name is already bound
  88. * @exception MalformedURLException if the name is not an appropriately
  89. * formatted URL
  90. * @exception RemoteException if registry could not be contacted
  91. * @exception AccessException if this operation is not permitted (if
  92. * originating from a non-local host, for example)
  93. * @since JDK1.1
  94. */
  95. public static void bind(String name, Remote obj)
  96. throws AlreadyBoundException,
  97. java.net.MalformedURLException,
  98. RemoteException
  99. {
  100. ParsedNamingURL parsed = parseURL(name);
  101. Registry registry = getRegistry(parsed);
  102. if (obj == null)
  103. throw new NullPointerException("cannot bind to null");
  104. registry.bind(parsed.name, obj);
  105. }
  106. /**
  107. * Destroys the binding for the specified name that is associated
  108. * with a remote object.
  109. *
  110. * @param name a URL-formatted name associated with a remote object
  111. * @exception NotBoundException if name is not currently bound
  112. * @exception MalformedURLException if the name is not an appropriately
  113. * formatted URL
  114. * @exception RemoteException if registry could not be contacted
  115. * @exception AccessException if this operation is not permitted (if
  116. * originating from a non-local host, for example)
  117. * @since JDK1.1
  118. */
  119. public static void unbind(String name)
  120. throws RemoteException,
  121. NotBoundException,
  122. java.net.MalformedURLException
  123. {
  124. ParsedNamingURL parsed = parseURL(name);
  125. Registry registry = getRegistry(parsed);
  126. registry.unbind(parsed.name);
  127. }
  128. /**
  129. * Rebinds the specified name to a new remote object. Any existing
  130. * binding for the name is replaced.
  131. *
  132. * @param name a URL-formatted name associated with the remote object
  133. * @param obj new remote object to associate with the name
  134. * @exception MalformedURLException if the name is not an appropriately
  135. * formatted URL
  136. * @exception RemoteException if registry could not be contacted
  137. * @exception AccessException if this operation is not permitted (if
  138. * originating from a non-local host, for example)
  139. * @since JDK1.1
  140. */
  141. public static void rebind(String name, Remote obj)
  142. throws RemoteException, java.net.MalformedURLException
  143. {
  144. ParsedNamingURL parsed = parseURL(name);
  145. Registry registry = getRegistry(parsed);
  146. if (obj == null)
  147. throw new NullPointerException("cannot bind to null");
  148. registry.rebind(parsed.name, obj);
  149. }
  150. /**
  151. * Returns an array of the names bound in the registry. The names are
  152. * URL-formatted strings. The array contains a snapshot of the names
  153. * present in the registry at the time of the call.
  154. *
  155. * @param name a URL-formatted name that specifies the remote registry
  156. * @return an array of names (in the appropriate URL format) bound
  157. * in the registry
  158. * @exception MalformedURLException if the name is not an appropriately
  159. * formatted URL
  160. * @exception RemoteException if registry could not be contacted.
  161. * @since JDK1.1
  162. */
  163. public static String[] list(String name)
  164. throws RemoteException, java.net.MalformedURLException
  165. {
  166. ParsedNamingURL parsed = parseURL(name);
  167. Registry registry = getRegistry(parsed);
  168. String prefix = "rmi:";
  169. if (parsed.port > 0 || !parsed.host.equals(""))
  170. prefix += "//" + parsed.host;
  171. if (parsed.port > 0)
  172. prefix += ":" + parsed.port;
  173. prefix += "/";
  174. String[] names = registry.list();
  175. for (int i = 0; i < names.length; i++) {
  176. names[i] = prefix + names[i];
  177. }
  178. return names;
  179. }
  180. /**
  181. * Returns a registry reference obtained from information in the URL.
  182. */
  183. private static Registry getRegistry(ParsedNamingURL parsed)
  184. throws RemoteException
  185. {
  186. return LocateRegistry.getRegistry(parsed.host, parsed.port);
  187. }
  188. /**
  189. * Fix for: 4251878 java.rmi.Naming shouldn't rely upon the
  190. * parsing functionality of java.net.URL
  191. *
  192. * Dissect Naming URL strings to obtain referenced host, port and
  193. * object name.
  194. *
  195. * @return an object which contains each of the above
  196. * components.
  197. *
  198. * @exception MalformedURLException if hostname in url contains '#' or
  199. * if incorrect protocol specified
  200. */
  201. private static ParsedNamingURL parseURL(String url)
  202. throws MalformedURLException
  203. {
  204. ParsedNamingURL parsed = new ParsedNamingURL();
  205. int startFile = -1;
  206. // remove the approved protocol
  207. if (url.startsWith("rmi:")) {
  208. url = url.substring(4);
  209. }
  210. // Anchors (i.e. '#') are meaningless in rmi URLs - disallow them
  211. if (url.indexOf('#') >= 0) {
  212. throw new MalformedURLException
  213. ("Invalid character, '#', in URL: " + url);
  214. }
  215. // No protocol must remain
  216. int checkProtocol = url.indexOf(':');
  217. if (checkProtocol >= 0 && (checkProtocol < url.indexOf('/')))
  218. throw new java.net.MalformedURLException("invalid protocol: " +
  219. url.substring(0, checkProtocol));
  220. if (url.startsWith("//")) {
  221. final int startHost = 2;
  222. int nextSlash = url.indexOf("/", startHost);
  223. if (nextSlash >= 0) {
  224. startFile = nextSlash + 1;
  225. } else {
  226. // no trailing slash implies no name
  227. nextSlash = url.length();
  228. startFile = nextSlash;
  229. }
  230. int colon = url.indexOf(":", startHost);
  231. if ((colon > 1) && (colon < nextSlash)) {
  232. // explicit port supplied
  233. try {
  234. parsed.port =
  235. Integer.parseInt(url.substring(colon + 1,
  236. nextSlash));
  237. } catch (NumberFormatException e) {
  238. throw new MalformedURLException(
  239. "invalid port number: " + url);
  240. }
  241. }
  242. // if have colon then endhost, else end with slash
  243. int endHost;
  244. if (colon >= startHost) {
  245. endHost = colon;
  246. } else {
  247. endHost = nextSlash;
  248. }
  249. parsed.host = url.substring(startHost, endHost);
  250. } else if (url.startsWith("/")) {
  251. startFile = 1;
  252. } else {
  253. startFile = 0;
  254. }
  255. // set the bind name
  256. parsed.name = url.substring(startFile);
  257. if (parsed.name.equals("") || parsed.name.equals("/")) {
  258. parsed.name = null;
  259. }
  260. return parsed;
  261. }
  262. /**
  263. * Simple class to enable multiple URL return values.
  264. */
  265. private static class ParsedNamingURL {
  266. String host = "";
  267. int port = Registry.REGISTRY_PORT;
  268. String name = null;
  269. }
  270. }