KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sapia > ubik > rmi > server > ServerTable


1 package org.sapia.ubik.rmi.server;
2
3 import java.rmi.RemoteException JavaDoc;
4 import java.util.Collections JavaDoc;
5 import java.util.HashMap JavaDoc;
6 import java.util.HashSet JavaDoc;
7 import java.util.Iterator JavaDoc;
8 import java.util.Map JavaDoc;
9 import java.util.Properties JavaDoc;
10 import java.util.Set JavaDoc;
11 import java.util.WeakHashMap JavaDoc;
12
13 import org.sapia.ubik.net.ServerAddress;
14 import org.sapia.ubik.rmi.Consts;
15 import org.sapia.ubik.rmi.server.transport.TransportManager;
16 import org.sapia.ubik.rmi.server.transport.socket.SocketTransportProvider;
17
18
19 /**
20  * This class is a singleton that implements the <code>Server</code> interface.
21  * It internally keeps a table of running servers, on a per-transport-type-to-server-instance
22  * basis. There can only be a single server instance per transport type.
23  * <p>
24  * This class holds methods pertaining to stub creations, etc. It and delegates the <code>Server</code> interface's
25  * methods to the internal <coce>Server</code> implementation(s).
26  * <p>
27  * For example, calling shutdown on this singleton will trigger the shutdown of all internal server instances.
28  *
29  * @author Yanick Duchesne
30  * <dl>
31  * <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>
32  * <dt><b>License:</b><dd>Read the license.txt file of the jar or visit the
33  * <a HREF="http://www.sapia-oss.org/license.html">license page</a> at the Sapia OSS web site</dd></dt>
34  * </dl>
35  */

36 public class ServerTable implements Server {
37   static final String JavaDoc DEFAULT_TRANSPORT_TYPE = SocketTransportProvider.TRANSPORT_TYPE;
38
39   // A "cache" of class-to-interfaces mappings.
40
private static Map JavaDoc _interfaceCache = Collections.synchronizedMap(new WeakHashMap JavaDoc());
41   Map JavaDoc _serversByType = Collections.synchronizedMap(new HashMap JavaDoc());
42
43   /*////////////////////////////////////////////////////////////////////
44                       Server interface methods
45   ////////////////////////////////////////////////////////////////////*/

46
47   /**
48    * @see org.sapia.ubik.rmi.server.Server#start()
49    */

50   public void start() {
51     //noop
52
}
53
54   /**
55    * @see org.sapia.ubik.rmi.server.Server#close()
56    */

57   public void close() {
58     Iterator JavaDoc itr = _serversByType.values().iterator();
59     ServerRef ref;
60
61     while (itr.hasNext()) {
62       ref = (ServerRef) itr.next();
63       ref.server.close();
64     }
65   }
66
67   /**
68    * Returns the adress of the server corresponding to the default transport type.
69    *
70    * @see org.sapia.ubik.rmi.server.Server#getServerAddress()()
71    */

72   public ServerAddress getServerAddress() {
73     return getServerRef(DEFAULT_TRANSPORT_TYPE).server.getServerAddress();
74   }
75
76   public ServerAddress getServerAddress(String JavaDoc transportType) {
77     return getServerRef(transportType).server.getServerAddress();
78   }
79
80   /*////////////////////////////////////////////////////////////////////
81                           Decorator methods
82   ////////////////////////////////////////////////////////////////////*/

83
84   /**
85    * Returns the remote reference of this instance.
86    *
87    * @return a <code>RemoteRef</code>.
88    */

89   public RemoteRef getRemoteRef(String JavaDoc transportType) {
90     return getServerRef(transportType).ref;
91   }
92
93   /**
94    * Returns the unique object identifier of this instance.
95    *
96    * @return an <code>OID</code>.
97    */

98   public OID getOID(String JavaDoc transportType) {
99     return getServerRef(transportType).oid;
100   }
101
102   /*////////////////////////////////////////////////////////////////////
103                       Restricted Access Methods.
104   ////////////////////////////////////////////////////////////////////*/

105   boolean isInit(String JavaDoc transportType) {
106     return _serversByType.get(transportType) != null;
107   }
108
109   ServerAddress init(Object JavaDoc remote, String JavaDoc transportType)
110     throws RemoteException JavaDoc, IllegalStateException JavaDoc {
111     Server s = TransportManager.getProviderFor(transportType).newDefaultServer();
112     s.start();
113
114     // try {
115
// Thread.sleep(200);
116
// } catch (InterruptedException e) {
117
// throw new RemoteException(e.getMessage());
118
// }
119
return doInit(remote, s, transportType);
120   }
121
122   ServerAddress init(Object JavaDoc remote)
123     throws RemoteException JavaDoc, IllegalStateException JavaDoc {
124     return init(remote, 0);
125   }
126
127   ServerAddress init(Object JavaDoc remote, int port)
128     throws RemoteException JavaDoc, IllegalStateException JavaDoc {
129     return doInit(remote, port, ServerTable.DEFAULT_TRANSPORT_TYPE);
130   }
131
132   ServerAddress init(Object JavaDoc remote, String JavaDoc transportType, Properties JavaDoc props)
133     throws RemoteException JavaDoc, IllegalStateException JavaDoc {
134     
135     if(Log.isDebug()){
136       Log.debug(getClass(), "Getting server for transport : " + transportType +
137         ": properties: " + props);
138     }
139     Server s = TransportManager.getProviderFor(transportType).newServer(props);
140
141     s.start();
142
143     // try {
144
// Thread.sleep(200);
145
// } catch (InterruptedException e) {
146
// throw new RemoteException(e.getMessage());
147
// }
148
return doInit(remote, s, transportType);
149   }
150
151   private synchronized ServerAddress doInit(Object JavaDoc remote, int port,
152     String JavaDoc transportType) throws RemoteException JavaDoc, IllegalStateException JavaDoc {
153     if (_serversByType.get(transportType) != null) {
154       throw new IllegalStateException JavaDoc("server already created");
155     }
156
157     if (Log.isDebug()) {
158       Log.debug(ServerTable.class, "initializing server");
159     }
160
161     Server s;
162
163     try {
164       s = TransportManager.getDefaultProvider().newServer(port);
165     } catch (java.io.IOException JavaDoc e) {
166       throw new java.rmi.RemoteException JavaDoc("could not create singleton server", e);
167     }
168
169     s.start();
170
171     // try {
172
// Thread.sleep(200);
173
// } catch (InterruptedException e) {
174
// throw new RemoteException(e.getMessage());
175
// }
176
return doInit(remote, s, transportType);
177   }
178
179   private synchronized ServerAddress doInit(Object JavaDoc remote, Server s,
180     String JavaDoc transportType) throws RemoteException JavaDoc, IllegalStateException JavaDoc {
181     if (_serversByType.get(transportType) != null) {
182       throw new IllegalStateException JavaDoc("server already created");
183     }
184
185     ServerRef serverRef = new ServerRef();
186     serverRef.server = s;
187
188     if (Log.isDebug()) {
189       Log.debug(ServerTable.class,
190         "server listening on: " + serverRef.server.getServerAddress());
191     }
192
193     if (remote != null) {
194       serverRef.oid = generateOID();
195
196       // StubCreationEvent stubEvt = new StubCreationEvent(remote,
197
// server.getServerAddress(),
198
// oid);
199
// Hub.serverRuntime.dispatchEvent(stubEvt);
200
serverRef.ref = initRef(remote, serverRef.oid, serverRef);
201       serverRef.stub = (Stub) Hub.getStubFor(serverRef.ref, remote);
202     }
203
204     _serversByType.put(transportType, serverRef);
205
206     return serverRef.server.getServerAddress();
207   }
208
209   final RemoteRef initStub(Object JavaDoc remote, String JavaDoc transportType) {
210     return initRef(remote, generateOID(), getServerRef(transportType));
211   }
212
213   static Class JavaDoc[] getInterfacesFor(Class JavaDoc clazz) {
214     Class JavaDoc[] cachedInterfaces = (Class JavaDoc[]) _interfaceCache.get(clazz);
215
216     if (cachedInterfaces == null) {
217       HashSet JavaDoc set = new HashSet JavaDoc();
218       Class JavaDoc current = clazz;
219       appendInterfaces(current, set);
220       set.add(Stub.class);
221
222       cachedInterfaces = (Class JavaDoc[]) set.toArray(new Class JavaDoc[set.size()]);
223       _interfaceCache.put(clazz, cachedInterfaces);
224     }
225
226     return cachedInterfaces;
227   }
228
229   static void appendInterfaces(Class JavaDoc current, Set JavaDoc interfaces) {
230     Class JavaDoc[] ifs = current.getInterfaces();
231
232     for (int i = 0; i < ifs.length; i++) {
233       appendInterfaces(ifs[i], interfaces);
234       interfaces.add(ifs[i]);
235     }
236
237     current = current.getSuperclass();
238
239     if (current != null) {
240       appendInterfaces(current, interfaces);
241     }
242   }
243
244   ServerRef getServerRef(String JavaDoc transportType) throws IllegalArgumentException JavaDoc {
245     ServerRef ref = (ServerRef) _serversByType.get(transportType);
246
247     if (ref == null) {
248       throw new IllegalStateException JavaDoc("No server for type: " + transportType);
249     }
250
251     return ref;
252   }
253
254   static synchronized OID generateOID() {
255     return new OID(UIDGenerator.createdUID());
256   }
257
258   private final RemoteRef initRef(Object JavaDoc remote, OID oid, ServerRef serverRef) {
259     RemoteRefEx rmiHandler = new RemoteRefEx(oid,
260         serverRef.server.getServerAddress());
261
262     rmiHandler.setCallBack((System.getProperty(Consts.CALLBACK_ENABLED) != null) &&
263       System.getProperty(Consts.CALLBACK_ENABLED).equalsIgnoreCase("true"));
264
265     if (Log.isDebug()) {
266       Log.debug(ServerTable.class,
267         remote + " is call-back: " + rmiHandler.isCallBack());
268     }
269
270     // Object proxy = Hub.getStubFor(rmiHandler);
271
Hub.serverRuntime.objectTable.register(oid, remote);
272
273     return rmiHandler;
274   }
275 }
276
Popular Tags