KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sapia > ubik > rmi > naming > ServiceLocator


1 package org.sapia.ubik.rmi.naming;
2
3 import org.sapia.ubik.net.Uri;
4 import org.sapia.ubik.net.UriSyntaxException;
5 import org.sapia.ubik.rmi.naming.remote.proxy.JNDIHandler;
6
7 import java.util.HashMap JavaDoc;
8 import java.util.Map JavaDoc;
9
10 import javax.naming.NameNotFoundException JavaDoc;
11 import javax.naming.NamingException JavaDoc;
12
13
14 /**
15  * This class implements the Service Locator pattern. It acts as a universal
16  * lookup "helper", in conjunction with pluggable <code>ServiceHandler</code>
17  * instances. The ServiceLocator encapsulates one to many service handlers;
18  * for a given lookup, the locator retrieves the appropriate locator and then
19  * delegates the lookup to the latter, returning the result to the caller.
20  * <p>
21  * Service handlers are plugged into the locator in one of the following ways:
22  * <ul>
23  * <li>By specifying service handlers as part of the system properties. This
24  * requires mapping a service handler uri scheme to the handler's class. The
25  * property name in this case must respect the following syntax:
26  * <code>ubik.rmi.naming.service.handler.uri_scheme</code> (where 'uri_scheme'
27  * is the scheme that is used to retreive a given object.
28  * <li>by calling this class' <code>registerHandler(...)</code> method.
29  * </ul>
30  * <p>
31  * For example, given the following service handler: <code>com.acme.MyServiceHandler</code>,
32  * the configuration could be created has follows:
33  * <pre>
34  * System.setProperty("ubik.rmi.naming.service.handler.acme", "com.acme.MyServiceHandler");
35  * </pre>
36  *
37  * Then, latter on, a lookup can be performed using this class:
38  * <pre>
39  * Object remote = ServiceLocator.lookup("acme://localhost:7070");
40  * </pre>
41  *
42  * As shown above, the "acme" uri that was used to register the handler is
43  * then used in the lookup. Using the scheme of the passed in URI, the
44  * <code>lookup(...)</code> method delegates the operation to the proper
45  * handler.
46  * <p>
47  * <b>IMPORTANT</b>: If service handlers are configured through system
48  * properties, it is important to do so before invoking the ServiceLocator
49  * class in any way: the latter retrieves the configured handlers in a
50  * static initializer, which would prevent the handlers from being discovered
51  * if configured after the ServiceLocator class' initialization.
52  *
53  * @author Yanick Duchesne
54  * <dl>
55  * <dt><b>Copyright:</b><dd>Copyright &#169; 2002-2003 <a HREF="http://www.sapia-oss.org">Sapia Open Source Software</a>. All Rights Reserved.</dd></dt>
56  * <dt><b>License:</b><dd>Read the license.txt file of the jar or visit the
57  * <a HREF="http://www.sapia-oss.org/license.html">license page</a> at the Sapia OSS web site</dd></dt>
58  * </dl>
59  */

60 public class ServiceLocator {
61   /**
62    * This constant identifies an unidentified port.
63    */

64   public static final int UNDEFINED_PORT = -1;
65
66   /**
67    * Corresponds to the prefix of properties specifying service handlers. The prefix
68    * is: 'ubik.rmi.naming.service.handler'.
69    */

70   public static final String JavaDoc HANDLER_PATTERN = "ubik.rmi.naming.service.handler";
71
72   /**
73    * The URI scheme for the default service handler: ubik.
74    *
75    * @see JNDIHandler
76    */

77   public static final String JavaDoc UBIK_SCHEME = "ubik";
78
79   /**
80    * The URI scheme for ubik's reliable jndi handler: ubik.reliable.jndi.
81    *
82    * @see JNDIHandler
83    */

84   private static Map JavaDoc _handlers = new HashMap JavaDoc();
85
86   static {
87     registerHandler(UBIK_SCHEME, new JNDIHandler());
88
89     ServiceHandler handler;
90     String JavaDoc[] propNames = (String JavaDoc[]) System.getProperties().keySet()
91                                                 .toArray(new String JavaDoc[System.getProperties()
92                                                                           .size()]);
93     String JavaDoc propName;
94     String JavaDoc className;
95     String JavaDoc scheme;
96
97     for (int i = 0; i < propNames.length; i++) {
98       propName = (String JavaDoc) propNames[i];
99
100       if (propName.startsWith(HANDLER_PATTERN)) {
101         scheme = propName.substring(HANDLER_PATTERN.length() + 1);
102
103         className = System.getProperty(propName);
104
105         if (className == null) {
106           throw new IllegalStateException JavaDoc(
107             "no class name defined for transport provider: " + propName);
108         }
109
110         try {
111           handler = (ServiceHandler) Class.forName(className).newInstance();
112           registerHandler(scheme, handler);
113         } catch (Throwable JavaDoc e) {
114           e.printStackTrace();
115           throw new IllegalStateException JavaDoc(
116             "could not instantiate transport provider: " + className);
117         }
118       }
119     }
120   }
121
122   /**
123    * Performs the lookup for the given path.
124    *
125    * @param url the url of the object to look up.
126    *
127    * @return an <code>Object</code>
128    * @throws NameNotFoundException if no object could be found for the
129    * given url.
130    * @throws NamingException if an error occurs while performing the lookup.
131
132    */

133   public static Object JavaDoc lookup(String JavaDoc url)
134     throws NameNotFoundException JavaDoc, NamingException JavaDoc {
135     Uri uri;
136
137     try {
138       uri = Uri.parse(url);
139     } catch (UriSyntaxException e) {
140       NamingException JavaDoc exc = new NamingException JavaDoc("could not look up " + url);
141       exc.setRootCause(e);
142       throw exc;
143     }
144
145     ServiceHandler handler = (ServiceHandler) _handlers.get(uri.getScheme());
146
147     if (handler == null) {
148       throw new NamingException JavaDoc("no handler found for: " + uri.getScheme());
149     }
150
151     return handler.handleLookup(uri.getHost(), uri.getPort(),
152       uri.getQueryString().getPath(), uri.getQueryString().getParameters());
153   }
154
155   /**
156    * Registers the given handler with the passed in scheme.
157    *
158    * @param scheme a URI scheme.
159    * @param handler a <code>ServiceHandler</code>.
160    * @throws IllegalStateException if a handler is already registered with the given scheme.
161    */

162   public static void registerHandler(String JavaDoc scheme, ServiceHandler handler)
163     throws IllegalStateException JavaDoc {
164     if (_handlers.get(scheme) != null) {
165       throw new IllegalStateException JavaDoc(
166         "service handler already registered for :" + scheme);
167     }
168
169     _handlers.put(scheme, handler);
170   }
171 }
172
Popular Tags