KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > remoting > InvokerRegistry


1 /***************************************
2  * *
3  * JBoss: The OpenSource J2EE WebOS *
4  * *
5  * Distributable under LGPL license. *
6  * See terms of license at gnu.org. *
7  * *
8  ***************************************/

9 package org.jboss.remoting;
10
11
12 import java.lang.reflect.Constructor JavaDoc;
13 import java.util.Collection JavaDoc;
14 import java.util.HashMap JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.Map JavaDoc;
18 import java.util.Set JavaDoc;
19 import org.jboss.logging.Logger;
20 import org.jboss.remoting.transport.ClientInvoker;
21 import org.jboss.remoting.transport.http.HTTPClientInvoker;
22 import org.jboss.remoting.transport.http.HTTPServerInvoker;
23 import org.jboss.remoting.transport.http.ssl.HTTPSClientInvoker;
24 import org.jboss.remoting.transport.http.ssl.HTTPSServerInvoker;
25 import org.jboss.remoting.transport.local.LocalClientInvoker;
26 import org.jboss.remoting.transport.rmi.RMIClientInvoker;
27 import org.jboss.remoting.transport.rmi.RMIServerInvoker;
28 import org.jboss.remoting.transport.servlet.ServletServerInvoker;
29 import org.jboss.remoting.transport.socket.SocketClientInvoker;
30 import org.jboss.remoting.transport.socket.SocketServerInvoker;
31 import org.jboss.remoting.transport.socket.ssl.SSLSocketClientInvoker;
32 import org.jboss.remoting.transport.socket.ssl.SSLSocketServerInvoker;
33
34 /**
35  * InvokerRegistry is a simple registery for creating client and server side Invoker implementations,
36  * getting information about the invokers and register as a invoker creator for one or more specific
37  * transports.
38  *
39  * @author <a HREF="mailto:jhaynie@vocalocity.net">Jeff Haynie</a>
40  * @author <a HREF="mailto:telrod@e2technologies.net">Tom Elrod</a>
41  * @version $Revision: 1.9 $
42  */

43 public class InvokerRegistry
44 {
45
46    private static final Logger log = Logger.getLogger(InvokerRegistry.class);
47
48    private static final Map JavaDoc clientInvokers = new HashMap JavaDoc();
49    private static final Map JavaDoc serverInvokers = new HashMap JavaDoc();
50    private static final Map JavaDoc clientLocators = new HashMap JavaDoc();
51    private static final Map JavaDoc serverLocators = new HashMap JavaDoc();
52    private static final Set JavaDoc registeredLocators = new HashSet JavaDoc();
53    private static final Object JavaDoc serverLock = new Object JavaDoc();
54    private static final Object JavaDoc clientLock = new Object JavaDoc();
55
56    static
57    {
58       // auto-register some standard invokers
59
registerInvoker("socket", SocketClientInvoker.class, SocketServerInvoker.class);
60       registerInvoker("sslsocket", SSLSocketClientInvoker.class, SSLSocketServerInvoker.class);
61       registerInvoker("rmi", RMIClientInvoker.class, RMIServerInvoker.class);
62       registerInvoker("http", HTTPClientInvoker.class, HTTPServerInvoker.class);
63       registerInvoker("https", HTTPSClientInvoker.class, HTTPSServerInvoker.class);
64       registerInvoker("servlet", HTTPSClientInvoker.class, ServletServerInvoker.class);
65
66    }
67
68    /**
69     * return an array of InvokerLocators that are local to this VM (server invokers)
70     *
71     * @return
72     */

73    public static synchronized final InvokerLocator[] getRegisteredServerLocators()
74    {
75       return (InvokerLocator[]) registeredLocators.toArray(new InvokerLocator[registeredLocators.size()]);
76    }
77
78    /**
79     * return a suitable local server invoker that can service the remote invoker locator based on
80     * a compatible transport
81     *
82     * @param remote
83     * @return
84     */

85    public static synchronized InvokerLocator getSuitableServerLocatorForRemote(InvokerLocator remote)
86    {
87       Iterator JavaDoc iter = registeredLocators.iterator();
88       while(iter.hasNext())
89       {
90          InvokerLocator l = (InvokerLocator) iter.next();
91          if(l.getProtocol().equals(remote.getProtocol()))
92          {
93             // we found a valid transport match
94
return l;
95          }
96       }
97       return null;
98    }
99
100    /**
101     * return an array of String of the registered transports
102     *
103     * @return
104     */

105    public static final String JavaDoc[] getRegisteredInvokerTransports()
106    {
107       synchronized(clientLock)
108       {
109          Set JavaDoc set = clientInvokers.keySet();
110          String JavaDoc transports[] = new String JavaDoc[set.size()];
111          return (String JavaDoc[]) set.toArray(transports);
112       }
113    }
114
115    /**
116     * return an array of ClientInvokers that are connected
117     *
118     * @return
119     */

120    public static final ClientInvoker[] getClientInvokers()
121    {
122       synchronized(clientLock)
123       {
124          if(clientLocators.isEmpty())
125          {
126             return new ClientInvoker[0];
127          }
128          Collection JavaDoc collection = clientLocators.values();
129          return (ClientInvoker[]) collection.toArray(new ClientInvoker[collection.size()]);
130       }
131    }
132
133    /**
134     * return an array of ServerInvokers that are connected
135     *
136     * @return
137     */

138    public static final ServerInvoker[] getServerInvokers()
139    {
140       synchronized(serverLock)
141       {
142          if(serverLocators.isEmpty())
143          {
144             return new ServerInvoker[0];
145          }
146          Collection JavaDoc collection = serverLocators.values();
147          return (ServerInvoker[]) collection.toArray(new ServerInvoker[collection.size()]);
148       }
149    }
150
151    /**
152     * register a client/server invoker Class pair for a given transport
153     *
154     * @param transport
155     * @param client
156     * @param server
157     */

158    public static synchronized void registerInvoker(String JavaDoc transport, Class JavaDoc client, Class JavaDoc server)
159    {
160       clientInvokers.put(transport, client);
161       serverInvokers.put(transport, server);
162    }
163
164    /**
165     * unregister a client/server invoker pair for the given transport
166     *
167     * @param transport
168     */

169    public static synchronized void unregisterInvoker(String JavaDoc transport)
170    {
171       clientInvokers.remove(transport);
172       serverInvokers.remove(transport);
173    }
174
175    public static synchronized void unregisterLocator(InvokerLocator locator)
176    {
177       serverLocators.remove(locator);
178       registeredLocators.remove(locator);
179    }
180
181    /**
182     * returns true if the client invoker is registered in the local JVM for a given locator
183     *
184     * @param locator
185     * @return
186     */

187    public static boolean isClientInvokerRegistered(InvokerLocator locator)
188    {
189       synchronized(clientLock)
190       {
191          return clientLocators.containsKey(locator);
192       }
193    }
194
195    /**
196     * called to destroy any cached RemoteClientInvoker copies inside the registry. this method
197     * must be called when it is determined that a remote server (via the locator) is no
198     * longer available.
199     *
200     * @param locator
201     */

202    public static void destroyClientInvoker(InvokerLocator locator)
203    {
204       ClientInvoker invoker = null;
205
206       synchronized(clientLock)
207       {
208          invoker = (ClientInvoker) clientLocators.remove(locator);
209       }
210
211       if(invoker != null)
212       {
213          log.debug("destroying client for locator: " + locator + ", invoker:" + invoker + ", remaining list:" + clientLocators);
214
215          invoker.disconnect();
216          invoker = null;
217       }
218
219    }
220
221    /**
222     * create a ClientInvoker instance, using the specific InvokerLocator, which is just a client-side
223     * invoker to a remote server
224     *
225     * @param locator
226     * @return
227     * @throws Exception
228     */

229    public static ClientInvoker createClientInvoker(InvokerLocator locator)
230          throws Exception JavaDoc
231    {
232       if(locator == null)
233       {
234          throw new NullPointerException JavaDoc("locator cannot be null");
235       }
236       synchronized(clientLock)
237       {
238          ClientInvoker invoker = (ClientInvoker) clientLocators.get(locator);
239          if(invoker != null)
240          {
241             return invoker;
242          }
243
244          boolean isPassByValue = false;
245          Map JavaDoc parameters = locator.getParameters();
246          if(parameters != null)
247          {
248             String JavaDoc value = (String JavaDoc) parameters.get(InvokerLocator.BYVALUE);
249             if(value != null && Boolean.valueOf(value).booleanValue())
250             {
251                isPassByValue = true;
252             }
253          }
254
255          // Check to see if server invoker is local
256
// If in server locators map, then created locally by this class
257
ServerInvoker svrInvoker = (ServerInvoker) serverLocators.get(locator);
258          if(svrInvoker != null && !isPassByValue)
259          {
260             LocalClientInvoker localInvoker = new LocalClientInvoker(locator);
261             // have to set reference to local server invoker so client in invoke directly
262
localInvoker.setServerInvoker(svrInvoker);
263             invoker = localInvoker;
264             InvokerLocator l = invoker.getLocator();
265             clientLocators.put(l, invoker);
266          }
267          else //not local
268
{
269             String JavaDoc protocol = locator.getProtocol();
270             if(protocol == null)
271             {
272                throw new NullPointerException JavaDoc("protocol cannot be null for the locator");
273             }
274             Class JavaDoc cl = (Class JavaDoc) clientInvokers.get(protocol);
275             if(cl == null)
276             {
277                throw new RuntimeException JavaDoc("Couldn't find valid client invoker class for transport '" + protocol + "'");
278             }
279             Constructor JavaDoc ctor = cl.getConstructor(new Class JavaDoc[]{InvokerLocator.class});
280             invoker = (ClientInvoker) ctor.newInstance(new Object JavaDoc[]{locator});
281             InvokerLocator l = invoker.getLocator();
282             clientLocators.put(l, invoker);
283          }
284          return invoker;
285       }
286    }
287
288    /**
289     * returns true if the server invoker is registered in the local JVM for a given locator/handler pair
290     *
291     * @param locator
292     * @return
293     */

294    public static boolean isServerInvokerRegistered(InvokerLocator locator)
295    {
296       synchronized(serverLock)
297       {
298          return serverLocators.containsKey(locator);
299       }
300    }
301
302    /**
303     * create a ServerInvoker instance, using the specific Invoker locator data and an implementation of the
304     * ServerInvocationHandler interface. Will use the default configuration values for the transport.
305     *
306     * @param locator
307     * @return
308     * @throws Exception
309     */

310    public static ServerInvoker createServerInvoker(InvokerLocator locator)
311          throws Exception JavaDoc
312    {
313       return createServerInvoker(locator, null);
314    }
315
316    /**
317     * create a ServerInvoker instance, using the specific Invoker locator data and an implementation of the
318     * ServerInvocationHandler interface along with
319     *
320     * @param locator
321     * @return
322     * @throws Exception
323     */

324    public static ServerInvoker createServerInvoker(InvokerLocator locator, Map JavaDoc configuration)
325          throws Exception JavaDoc
326    {
327
328       ServerInvoker invoker = null;
329       synchronized(serverLock)
330       {
331          invoker = (ServerInvoker) serverLocators.get(locator);
332          if(invoker != null)
333          {
334             throw new InvalidConfigurationException("The invoker for locator (" + locator + ") is already " +
335                                                     "in use by another Connector. Either change the locator or " +
336                                                     "add new handlers to existing Connector.");
337          }
338          Class JavaDoc cl = (Class JavaDoc) serverInvokers.get(locator.getProtocol());
339          if(cl == null)
340          {
341             throw new RuntimeException JavaDoc("Couldn't find valid server invoker class for transport '" + locator.getProtocol() + "'");
342          }
343          if(configuration != null)
344          {
345             Constructor JavaDoc ctor = cl.getConstructor(new Class JavaDoc[]{InvokerLocator.class, Map JavaDoc.class});
346             invoker = (ServerInvoker) ctor.newInstance(new Object JavaDoc[]{locator, configuration});
347          }
348          else
349          {
350             Constructor JavaDoc ctor = cl.getConstructor(new Class JavaDoc[]{InvokerLocator.class});
351             invoker = (ServerInvoker) ctor.newInstance(new Object JavaDoc[]{locator});
352          }
353          serverLocators.put(locator, invoker);
354          registeredLocators.add(invoker.getLocator());
355       }
356       return invoker;
357    }
358
359    public static void destroyServerInvoker(ServerInvoker invoker)
360    {
361       if(invoker != null)
362       {
363          serverLocators.remove(invoker.getLocator());
364       }
365    }
366
367    /**
368     * This is needed by the ServerInvoker since it may change the port being used (if port specified was <= 0) to
369     * next available port.
370     *
371     * @param locator
372     * @param newLocator
373     */

374    public static synchronized void updateServerInvokerLocator(InvokerLocator locator, InvokerLocator newLocator)
375    {
376       Object JavaDoc si = serverLocators.get(locator);
377       serverLocators.remove(locator);
378       registeredLocators.remove(locator);
379       serverLocators.put(newLocator, si);
380       registeredLocators.add(newLocator);
381    }
382 }
383
Popular Tags