001 /* Naming.java --
002 Copyright (c) 1996, 1997, 1998, 1999, 2004, 2006
003 Free Software Foundation, Inc.
004
005 This file is part of GNU Classpath.
006
007 GNU Classpath is free software; you can redistribute it and/or modify
008 it under the terms of the GNU General Public License as published by
009 the Free Software Foundation; either version 2, or (at your option)
010 any later version.
011
012 GNU Classpath is distributed in the hope that it will be useful, but
013 WITHOUT ANY WARRANTY; without even the implied warranty of
014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 General Public License for more details.
016
017 You should have received a copy of the GNU General Public License
018 along with GNU Classpath; see the file COPYING. If not, write to the
019 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
020 02110-1301 USA.
021
022 Linking this library statically or dynamically with other modules is
023 making a combined work based on this library. Thus, the terms and
024 conditions of the GNU General Public License cover the whole
025 combination.
026
027 As a special exception, the copyright holders of this library give you
028 permission to link this library with independent modules to produce an
029 executable, regardless of the license terms of these independent
030 modules, and to copy and distribute the resulting executable under
031 terms of your choice, provided that you also meet, for each linked
032 independent module, the terms and conditions of the license of that
033 module. An independent module is a module which is not derived from
034 or based on this library. If you modify this library, you may extend
035 this exception to your version of the library, but you are not
036 obligated to do so. If you do not wish to do so, delete this
037 exception statement from your version. */
038
039
040 package java.rmi;
041
042 import java.net.MalformedURLException;
043 import java.net.URI;
044 import java.net.URISyntaxException;
045 import java.net.URL;
046 import java.rmi.registry.LocateRegistry;
047 import java.rmi.registry.Registry;
048
049 /**
050 * <p>
051 * The <code>Naming</code> class handles interactions with RMI registries.
052 * Each method takes a URL in <code>String</code> form, which points to
053 * the RMI registry. The scheme of the URL is irrelevant. The relevant
054 * part is:
055 * </p>
056 * <p>
057 * <code>//host:port/name</code>
058 * </p>
059 * <p>
060 * which tells the method how to locate and access the registry. The host
061 * and port are both optional, and default to `localhost' and the standard
062 * RMI registry port (1099) respectively. The name is simply a string
063 * used to refer to a particular service hosted by the registry. The
064 * registry does not attempt to interpret this further.
065 * </p>
066 * <p>
067 * RMI services are registered using one of these names, and the same name
068 * is later used by the client to lookup the service and access its methods.
069 * Registries can be shared by multiple services, or a service can create
070 * its own registry using <code>createRegistry()</code>.
071 * </p>
072 *
073 * @author Original author unknown.
074 * @author Ingo Proetel (proetel@aicas.com)
075 * @author Guilhem Lavaux (guilhem@kaffe.org)
076 * @author Jeroen Frijters (jeroen@frijters.net)
077 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
078 * @since 1.1
079 */
080 public final class Naming
081 {
082 /**
083 * This class isn't intended to be instantiated.
084 */
085 private Naming()
086 {
087 }
088
089 /**
090 * Looks for the remote object that is associated with the named service.
091 * Name and location is given in form of a URL without a scheme:
092 *
093 * <pre>
094 * //host:port/service-name
095 * </pre>
096 *
097 * The port is optional.
098 *
099 * @param name the service name and location
100 * @return Remote-object that implements the named service
101 * @throws NotBoundException if no object implements the service
102 * @throws MalformedURLException
103 * @throws RemoteException
104 */
105 public static Remote lookup(String name) throws NotBoundException,
106 MalformedURLException, RemoteException
107 {
108 URL u = parseURL(name);
109 String serviceName = getName(u);
110 return (getRegistry(u).lookup(serviceName));
111 }
112
113 /**
114 * Try to bind the given object to the given service name.
115 *
116 * @param name
117 * @param obj
118 * @throws AlreadyBoundException
119 * @throws MalformedURLException
120 * @throws RemoteException
121 */
122 public static void bind(String name, Remote obj)
123 throws AlreadyBoundException, MalformedURLException, RemoteException
124 {
125 URL u = parseURL(name);
126 String serviceName = getName(u);
127 getRegistry(u).bind(serviceName, obj);
128 }
129
130 /**
131 * Remove a binding for a given service name.
132 *
133 * @param name
134 * @throws RemoteException
135 * @throws NotBoundException
136 * @throws MalformedURLException
137 */
138 public static void unbind(String name) throws RemoteException,
139 NotBoundException, MalformedURLException
140 {
141 URL u = parseURL(name);
142 String serviceName = getName(u);
143 getRegistry(u).unbind(serviceName);
144 }
145
146 /**
147 * Forces the binding between the given Remote-object and the given service
148 * name, even if there was already an object bound to this name.
149 *
150 * @param name
151 * @param obj
152 * @throws RemoteException
153 * @throws MalformedURLException
154 */
155 public static void rebind(String name, Remote obj) throws RemoteException,
156 MalformedURLException
157 {
158 URL u = parseURL(name);
159 String serviceName = getName(u);
160 getRegistry(u).rebind(serviceName, obj);
161 }
162
163 /**
164 * Lists all services at the named registry.
165 *
166 * @param name url that specifies the registry
167 * @return list of services at the name registry
168 * @throws RemoteException
169 * @throws MalformedURLException
170 */
171 public static String[] list(String name) throws RemoteException,
172 MalformedURLException
173 {
174 return (getRegistry(parseURL(name)).list());
175 }
176
177 private static Registry getRegistry(URL u) throws RemoteException
178 {
179 if (u.getPort() == - 1)
180 {
181 return (LocateRegistry.getRegistry(u.getHost()));
182 }
183 else
184 {
185 return (LocateRegistry.getRegistry(u.getHost(), u.getPort()));
186 }
187 }
188
189 /**
190 * Parses the supplied URL and converts it to use the HTTP protocol. From an
191 * RMI perspective, the scheme is irrelevant and we want to be able to create
192 * a URL for which a handler is available.
193 *
194 * @param name the URL in String form.
195 * @throws MalformedURLException if the URL is invalid.
196 */
197 private static URL parseURL(String name) throws MalformedURLException
198 {
199 try
200 {
201 URI uri = new URI(name);
202 String host = uri.getHost();
203 int port = uri.getPort();
204 String query = uri.getQuery();
205 String path = uri.getPath();
206 return new URL("http", (host == null ? "localhost" : host),
207 (port == - 1 ? 1099 : port), uri.getPath()
208 + (query == null ? "" : query));
209 }
210 catch (URISyntaxException e)
211 {
212 throw new MalformedURLException("The URL syntax was invalid: "
213 + e.getMessage());
214 }
215 }
216
217 /**
218 * Checks that the URL contains a name, and removes any leading slashes.
219 *
220 * @param url the URL to check.
221 * @throws MalformedURLException if no name is specified.
222 */
223 private static String getName(URL url) throws MalformedURLException
224 {
225 String filename = url.getFile();
226 if (filename.length() == 0)
227 throw new MalformedURLException("No path specified: " + url);
228 // If the filename begins with a slash we must cut it for
229 // name resolution.
230 if (filename.charAt(0) == '/')
231 return filename.substring(1);
232 return filename;
233 }
234 }