KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sapia > ubik > rmi > naming > remote > discovery > DiscoveryHelper


1 package org.sapia.ubik.rmi.naming.remote.discovery;
2
3 import java.io.IOException JavaDoc;
4 import java.rmi.RemoteException JavaDoc;
5 import java.util.ArrayList JavaDoc;
6 import java.util.Collections JavaDoc;
7 import java.util.List JavaDoc;
8 import java.util.Properties JavaDoc;
9
10 import javax.naming.Context JavaDoc;
11 import javax.naming.NamingException JavaDoc;
12
13 import org.sapia.archie.Name;
14 import org.sapia.archie.impl.AttributeNameParser;
15 import org.sapia.archie.impl.AttributeNamePart;
16 import org.sapia.archie.impl.DefaultNameParser;
17 import org.sapia.ubik.mcast.AsyncEventListener;
18 import org.sapia.ubik.mcast.EventChannel;
19 import org.sapia.ubik.mcast.RemoteEvent;
20 import org.sapia.ubik.net.TCPAddress;
21 import org.sapia.ubik.rmi.naming.ServiceLocator;
22 import org.sapia.ubik.rmi.naming.remote.Consts;
23 import org.sapia.ubik.rmi.naming.remote.RemoteContext;
24 import org.sapia.ubik.rmi.naming.remote.archie.SyncPutEvent;
25 import org.sapia.ubik.rmi.naming.remote.proxy.ContextResolver;
26 import org.sapia.ubik.rmi.naming.remote.proxy.DefaultContextResolver;
27 import org.sapia.ubik.rmi.naming.remote.proxy.LocalContext;
28
29 /**
30  * An instance of this class can be used by applications to listen for the appearance of
31  * a) appearing JNDI servers; b) existing JNDI servers; and c) appearing service bindings.
32  *
33  * @author Yanick Duchesne
34  * <dl>
35  * <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>
36  * <dt><b>License:</b><dd>Read the license.txt file of the jar or visit the
37  * <a HREF="http://www.sapia-oss.org/license.html">license page</a> at the Sapia OSS web site</dd></dt>
38  * </dl>
39  */

40 public class DiscoveryHelper implements AsyncEventListener {
41   protected EventChannel _channel;
42   private List JavaDoc _svclisteners = Collections.synchronizedList(new ArrayList JavaDoc());
43   private List JavaDoc _jndiListeners = Collections.synchronizedList(new ArrayList JavaDoc());
44   private ContextResolver _resolver = new DefaultContextResolver();
45
46   /**
47    * Constructor for DiscoveryHelper.
48    */

49   public DiscoveryHelper(EventChannel ec) {
50     _channel = ec;
51     initChannel();
52   }
53
54   /**
55    * Creates an instance of this class that will listen for new JNDI servers and
56    * for the binding of new services on the given domain.
57    *
58    * @param domain the name of a domain.
59    */

60   public DiscoveryHelper(String JavaDoc domain) throws IOException JavaDoc {
61     _channel = new EventChannel(domain,
62         org.sapia.ubik.rmi.Consts.DEFAULT_MCAST_ADDR,
63         org.sapia.ubik.rmi.Consts.DEFAULT_MCAST_PORT);
64     _channel.start();
65     initChannel();
66   }
67   
68   /**
69    * Creates an instance of this class that will listen for new JNDI servers and
70    * for the binding of new services on the given domain.
71    *
72    * @param domain the name of a domain.
73    * @param mcastAddr the multicast address to use internally.
74    * @param mcastPort the multicast port on which to listen.
75    */

76   public DiscoveryHelper(String JavaDoc domain, String JavaDoc mcastAddr, int mcastPort)
77     throws IOException JavaDoc {
78     _channel = new EventChannel(domain,
79         mcastAddr, mcastPort);
80     _channel.start();
81     initChannel();
82   }
83
84   /**
85    * @param res the <code>ContextResolver</code> that this instance should use
86    * when notified about new JNDI servers.
87    */

88   public void setContextResolver(ContextResolver res){
89     _resolver = res;
90   }
91
92   /**
93    * Adds a service discovery listener to this instance.
94    *
95    * @param a <code>ServiceDiscoListener</code>.
96    */

97   public synchronized void addServiceDiscoListener(ServiceDiscoListener listener) {
98     if(!_svclisteners.contains(listener)){
99       _svclisteners.add(listener);
100     }
101   }
102   
103   /**
104    * Removes the given service discovery listener from this instance.
105    *
106    * @param a <code>ServiceDiscoListener</code>.
107    */

108   public synchronized void removeServiceDiscoListener(ServiceDiscoListener listener) {
109     List JavaDoc listeners = new ArrayList JavaDoc(_svclisteners);
110     listeners.remove(listener);
111     _svclisteners = listeners;
112   }
113
114   /**
115    * Adds a JNDI discovery listener to this instance.
116    *
117    * @param a <code>JndiDiscoListener</code>.
118    */

119   public synchronized void addJndiDiscoListener(JndiDiscoListener listener) {
120     if(!_jndiListeners.contains(listener)){
121       _jndiListeners.add(listener);
122       try{
123         _channel.dispatch(Consts.JNDI_CLIENT_PUBLISH, "");
124       }catch(IOException JavaDoc e){}
125     }
126   }
127   
128   /**
129    * Removes the given JNDI discovery listener from this instance.
130    *
131    * @param a <code>JndiDiscoListener</code>.
132    */

133   public synchronized void removeJndiDiscoListener(JndiDiscoListener listener) {
134     List JavaDoc listeners = new ArrayList JavaDoc(_jndiListeners);
135     listeners.remove(listener);
136     _jndiListeners = listeners;
137   }
138   
139   /**
140    * @see org.sapia.ubik.mcast.AsyncEventListener#onAsyncEvent(RemoteEvent)
141    */

142   public void onAsyncEvent(RemoteEvent evt) {
143     TCPAddress tcp;
144     
145     try {
146       if (evt.getType().equals(Consts.JNDI_SERVER_PUBLISH)
147           || evt.getType().equals(Consts.JNDI_SERVER_DISCO)) {
148         tcp = (TCPAddress) evt.getData();
149
150         Context JavaDoc remoteCtx = (Context JavaDoc) _resolver.resolve(tcp);
151
152         List JavaDoc listeners = new ArrayList JavaDoc(_jndiListeners);
153          
154         /*
155          * TODO: this code is a hack and a refactoring will
156          * be necessary
157          */

158         if(remoteCtx instanceof RemoteContext){
159           try{
160             remoteCtx = new LocalContext(getJndiURI(tcp), (RemoteContext)remoteCtx);
161           }catch(NamingException JavaDoc e){
162             e.printStackTrace();
163             return;
164           }
165         }
166         for (int i = 0; i < listeners.size(); i++) {
167           ((JndiDiscoListener) listeners.get(i)).onJndiDiscovered(remoteCtx);
168         }
169       } else if (evt.getType().equals(SyncPutEvent.class.getName())) {
170         SyncPutEvent bevt = (SyncPutEvent) evt.getData();
171         Object JavaDoc obj;
172
173         try {
174           ServiceDiscoListener listener;
175           Properties JavaDoc props;
176           String JavaDoc name;
177           Name nameObj = bevt.getNodePath().add(bevt.getName());
178
179           if (bevt.getName() instanceof AttributeNamePart) {
180             props = ((AttributeNamePart) bevt.getName()).getAttributes();
181             name = new AttributeNameParser().asString(nameObj);
182           } else {
183             props = new Properties JavaDoc();
184             name = new DefaultNameParser().asString(nameObj);
185           }
186
187           ServiceDiscoveryEvent sevt = new ServiceDiscoveryEvent(props, name,
188               bevt.getValue());
189
190           List JavaDoc listeners = new ArrayList JavaDoc(_svclisteners);
191           for (int i = 0; i < listeners.size(); i++) {
192             listener = (ServiceDiscoListener) listeners.get(i);
193             listener.onServiceDiscovered(sevt);
194           }
195         } catch (IOException JavaDoc e) {
196           e.printStackTrace();
197         } catch (ClassNotFoundException JavaDoc e) {
198           e.printStackTrace();
199         }
200       }
201     } catch (RemoteException JavaDoc e) {
202       e.printStackTrace();
203     } catch (IOException JavaDoc e) {
204       e.printStackTrace();
205     }
206   }
207
208   /**
209    * Closes this instance - should thereafter be discarded.
210    */

211   public synchronized void close() {
212     _channel.close();
213   }
214
215   /**
216    * Returns this instance's event channel.
217    */

218   public synchronized EventChannel getChannel() {
219     return _channel;
220   }
221   
222   void initChannel() {
223     _channel.registerAsyncListener(Consts.JNDI_SERVER_PUBLISH, this);
224     _channel.registerAsyncListener(Consts.JNDI_SERVER_DISCO, this);
225     _channel.registerAsyncListener(SyncPutEvent.class.getName(), this);
226   }
227   
228   
229   protected String JavaDoc getJndiURI(TCPAddress addr){
230     return new StringBuffer JavaDoc(ServiceLocator.UBIK_SCHEME)
231       .append("://")
232       .append(addr.getHost())
233       .append(":")
234       .append(addr.getPort()).toString();
235   }
236 }
237
Popular Tags