KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sapia > ubik > rmi > naming > remote > EmbeddableJNDIServer


1 package org.sapia.ubik.rmi.naming.remote;
2
3 import javax.naming.Context JavaDoc;
4
5 import org.sapia.ubik.mcast.AsyncEventListener;
6 import org.sapia.ubik.mcast.EventChannel;
7 import org.sapia.ubik.mcast.RemoteEvent;
8 import org.sapia.ubik.net.TCPAddress;
9 import org.sapia.ubik.rmi.server.Hub;
10 import org.sapia.ubik.rmi.server.Log;
11 import org.sapia.ubik.util.Localhost;
12
13
14 /**
15  * This class implements an embeddable JNDI server.
16  * <p>
17  * Usage:
18  * <pre>
19  * EmbeddableJNDIServer jndi = new EmbeddableJNDIServer();
20  * jndi.start(true);
21  * // use it...
22  * jndi.stop();
23  * </pre>
24  *
25  * @author Yanick Duchesne
26  *
27  * <dl>
28  * <dt><b>Copyright:</b><dd>Copyright &#169; 2002-2004 <a HREF="http://www.sapia-oss.org">Sapia Open Source Software</a>. All Rights Reserved.</dd></dt>
29  * <dt><b>License:</b><dd>Read the license.txt file of the jar or visit the
30  * <a HREF="http://www.sapia-oss.org/license.html">license page</a> at the Sapia OSS web site</dd></dt>
31  * </dl>
32  */

33 public class EmbeddableJNDIServer implements Runnable JavaDoc, RemoteContextProvider, AsyncEventListener{
34   private String JavaDoc _domain;
35   private String JavaDoc _mcastAddr;
36   private int _port;
37   private int _mcastPort;
38   private Thread JavaDoc _serverThread;
39   private EventChannel _ec;
40   private Context JavaDoc _root;
41   private boolean _closed;
42   private boolean _started;
43   private Exception JavaDoc _startErr;
44
45   /**
46    * Creates an instance of this class that will listen on the default (1099) port,
47    * on the "default" domain. Also internally binds its multicast event channel to the
48    * default multicast address and port.
49    *
50    * @see Consts#DEFAULT_MCAST_ADDR
51    * @see Consts#DEFAULT_MCAST_PORT
52    */

53   public EmbeddableJNDIServer() {
54     this(JNDIServerHelper.DEFAULT_DOMAIN, JNDIServerHelper.DEFAULT_PORT,
55       org.sapia.ubik.rmi.Consts.DEFAULT_MCAST_ADDR,
56       org.sapia.ubik.rmi.Consts.DEFAULT_MCAST_PORT);
57   }
58
59   /**
60    * Creates an instance of this class that will listen on the given port and domain.
61    * Also internally binds its multicast event channel to the default multicast address and port.
62    *
63    * @see Consts#DEFAULT_MCAST_ADDR
64    * @see Consts#DEFAULT_MCAST_PORT
65    */

66   public EmbeddableJNDIServer(String JavaDoc domain, int port) {
67     this(domain, port, org.sapia.ubik.rmi.Consts.DEFAULT_MCAST_ADDR,
68       org.sapia.ubik.rmi.Consts.DEFAULT_MCAST_PORT);
69   }
70
71   /**
72    * Creates an instance of this class that will listen on the given port and domain.
73    * Also internally binds its multicast event channel to the given multicast address and port.
74    */

75   public EmbeddableJNDIServer(String JavaDoc domain, int port, String JavaDoc mcastAddress,
76     int mcastPort) {
77     _domain = domain;
78     _port = port;
79     _mcastAddr = mcastAddress;
80     _mcastPort = mcastPort;
81   }
82   
83   /**
84    * Returns the event channel that this instance uses to broacast events
85    * and subscribe to notifications.
86    *
87    * @return this instance's <code>EventChannel</code>.
88    */

89   public EventChannel getEventChannel() {
90     if (_ec == null) {
91       throw new IllegalStateException JavaDoc("Multicast event channel not initialized");
92     }
93
94     return _ec;
95   }
96   
97   public void onAsyncEvent(RemoteEvent evt) {
98     if(evt.getType().equals(Consts.JNDI_CLIENT_PUBLISH)){
99       try{
100         _ec.dispatch(Consts.JNDI_SERVER_DISCO,
101             new TCPAddress(Localhost.getLocalAddress().getHostAddress(), _port));
102       }catch(Exception JavaDoc e){
103         e.printStackTrace();
104       }
105     }
106     
107   }
108
109   /**
110    * @return this instance's root JNDI <code>Context</code>.
111    */

112   public Context JavaDoc getRootContext() {
113     if (_root == null) {
114       throw new IllegalStateException JavaDoc("Context not initialized");
115     }
116
117     return _root;
118   }
119   
120   public RemoteContext getRemoteContext(){
121     return (RemoteContext)_root;
122   }
123
124   /**
125    * Stops this instance (this internally closes the <code>EventChannel</code>
126    * that this instance holds).
127    */

128   public void stop() {
129     if (_serverThread != null) {
130       _serverThread.interrupt();
131       waitClosed();
132     } else {
133       if (_ec != null) {
134         _ec.close();
135       }
136     }
137   }
138
139   /**
140    * Starts this instance.
141    *
142    * @param daemon if <code>true</code>, this instance will be started
143    * as a daemon thread.
144    */

145   public void start(boolean daemon) throws Exception JavaDoc {
146     _serverThread = new Thread JavaDoc(this, "ubik.jndi:" + _domain + ":" + _port);
147     _serverThread.setDaemon(daemon);
148     _serverThread.start();
149     waitStarted();
150
151     if (_startErr != null) {
152       throw _startErr;
153     }
154   }
155
156   public final void run() {
157     try {
158       _ec = new EventChannel(_domain, _mcastAddr, _mcastPort);
159
160       _ec.start();
161       
162       _ec.registerAsyncListener(Consts.JNDI_CLIENT_PUBLISH, this);
163
164       _ec.dispatch(Consts.JNDI_SERVER_PUBLISH,
165         new TCPAddress(Localhost.getLocalAddress().getHostAddress(), _port));
166       
167       _ec.dispatch(Consts.JNDI_SERVER_DISCO,
168           new TCPAddress(Localhost.getLocalAddress().getHostAddress(), _port));
169       
170
171       _root = JNDIServerHelper.newRootContext(_ec);
172
173       Hub.exportObject(this, _port);
174       
175       Log.warning(getClass(),
176         "Server started on port: " + _port + ", domain: " + _domain);
177
178       notifyStarted();
179
180       while (true) {
181         Thread.sleep(10000);
182       }
183     } catch (InterruptedException JavaDoc e) {
184       Log.warning(getClass(),
185         "Shutting down JNDI server: " + _port + ", " + _domain);
186       _ec.close();
187       notifyClosed();
188     } catch (Exception JavaDoc e) {
189       _startErr = e;
190       notifyStarted();
191     }
192   }
193
194   private synchronized void notifyClosed() {
195     _closed = true;
196     notify();
197   }
198
199   private synchronized void notifyStarted() {
200     _started = true;
201     notify();
202   }
203
204   private synchronized void waitClosed() {
205     try {
206       while (!_closed) {
207         wait();
208       }
209     } catch (InterruptedException JavaDoc e) {
210       _ec.close();
211     }
212   }
213
214   private synchronized void waitStarted() {
215     try {
216       while (!_started) {
217         wait();
218       }
219     } catch (InterruptedException JavaDoc e) {
220       return;
221     }
222   }
223 }
224
Popular Tags