KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jgroups > stack > ProtocolStack


1 // $Id: ProtocolStack.java,v 1.18 2005/04/26 20:08:40 belaban Exp $
2

3 package org.jgroups.stack;
4
5 import org.jgroups.*;
6 import org.jgroups.conf.ClassConfigurator;
7 import org.jgroups.util.Promise;
8 import org.jgroups.util.TimeScheduler;
9
10 import java.util.Iterator JavaDoc;
11 import java.util.Map JavaDoc;
12 import java.util.Properties JavaDoc;
13 import java.util.Vector JavaDoc;
14
15
16
17
18 /**
19  * A ProtocolStack manages a number of protocols layered above each other. It creates all
20  * protocol classes, initializes them and, when ready, starts all of them, beginning with the
21  * bottom most protocol. It also dispatches messages received from the stack to registered
22  * objects (e.g. channel, GMP) and sends messages sent by those objects down the stack.<p>
23  * The ProtocolStack makes use of the Configurator to setup and initialize stacks, and to
24  * destroy them again when not needed anymore
25  * @author Bela Ban
26  */

27 public class ProtocolStack extends Protocol implements Transport {
28     private Protocol top_prot=null;
29     private Protocol bottom_prot=null;
30     private final Configurator conf=new Configurator();
31     private final String JavaDoc setup_string;
32     private JChannel channel=null;
33     private boolean stopped=true;
34     public final TimeScheduler timer=new TimeScheduler(5000);
35     // final Promise ack_promise=new Promise();
36

37     /** Used to sync on START/START_OK events for start()*/
38     Promise start_promise=null;
39
40     /** used to sync on STOP/STOP_OK events for stop() */
41     Promise stop_promise=null;
42
43     public static final int ABOVE=1; // used by insertProtocol()
44
public static final int BELOW=2; // used by insertProtocol()
45

46
47
48     public ProtocolStack(JChannel channel, String JavaDoc setup_string) throws ChannelException {
49         this.setup_string=setup_string;
50         this.channel=channel;
51         ClassConfigurator.getInstance(true); // will create the singleton
52
}
53
54
55
56
57     /** Returns all protocols in a list, from top to bottom. <em>These are not copies of protocols,
58      so modifications will affect the actual instances !</em> */

59     public Vector JavaDoc getProtocols() {
60         Protocol p;
61         Vector JavaDoc v=new Vector JavaDoc();
62
63         p=top_prot;
64         while(p != null) {
65             v.addElement(p);
66             p=p.getDownProtocol();
67         }
68         return v;
69     }
70
71
72     /**
73      * Prints the names of the protocols, from the bottom to top. If include_properties is true,
74      * the properties for each protocol will also be printed.
75      */

76     public String JavaDoc printProtocolSpec(boolean include_properties) {
77         StringBuffer JavaDoc sb=new StringBuffer JavaDoc();
78         Protocol prot=top_prot;
79         Properties JavaDoc tmpProps;
80         String JavaDoc name;
81         Map.Entry JavaDoc entry;
82
83         while(prot != null) {
84             name=prot.getName();
85             if(name != null) {
86                 if("ProtocolStack".equals(name))
87                     break;
88                 sb.append(name);
89                 if(include_properties) {
90                     tmpProps=prot.getProperties();
91                     if(tmpProps != null) {
92                         sb.append('\n');
93                         for(Iterator JavaDoc it=tmpProps.entrySet().iterator(); it.hasNext();) {
94                             entry=(Map.Entry JavaDoc)it.next();
95                             sb.append(entry + "\n");
96                         }
97                     }
98                 }
99                 sb.append('\n');
100
101                 prot=prot.getDownProtocol();
102             }
103         }
104
105         return sb.toString();
106     }
107
108
109     public void setup() throws Exception JavaDoc {
110         if(top_prot == null) {
111             top_prot=conf.setupProtocolStack(setup_string, this);
112             if(top_prot == null)
113                 throw new Exception JavaDoc("ProtocolStack.setup(): couldn't create protocol stack");
114             top_prot.setUpProtocol(this);
115             bottom_prot=conf.getBottommostProtocol(top_prot);
116             conf.startProtocolStack(bottom_prot); // sets up queues and threads
117
}
118     }
119
120
121
122
123     /**
124      * Creates a new protocol given the protocol specification.
125      * @param prot_spec The specification of the protocol. Same convention as for specifying a protocol stack.
126      * An exception will be thrown if the class cannot be created. Example:
127      * <pre>"VERIFY_SUSPECT(timeout=1500)"</pre> Note that no colons (:) have to be
128      * specified
129      * @return Protocol The newly created protocol
130      * @exception Exception Will be thrown when the new protocol cannot be created
131      */

132     public Protocol createProtocol(String JavaDoc prot_spec) throws Exception JavaDoc {
133         return conf.createProtocol(prot_spec, this);
134     }
135
136
137
138
139
140
141     /**
142      * Inserts an already created (and initialized) protocol into the protocol list. Sets the links
143      * to the protocols above and below correctly and adjusts the linked list of protocols accordingly.
144      * Note that this method may change the value of top_prot or bottom_prot.
145      * @param prot The protocol to be inserted. Before insertion, a sanity check will ensure that none
146      * of the existing protocols have the same name as the new protocol.
147      * @param position Where to place the protocol with respect to the neighbor_prot (ABOVE, BELOW)
148      * @param neighbor_prot The name of the neighbor protocol. An exception will be thrown if this name
149      * is not found
150      * @exception Exception Will be thrown when the new protocol cannot be created, or inserted.
151      */

152     public void insertProtocol(Protocol prot, int position, String JavaDoc neighbor_prot) throws Exception JavaDoc {
153         conf.insertProtocol(prot, position, neighbor_prot, this);
154     }
155
156
157
158
159
160     /**
161      * Removes a protocol from the stack. Stops the protocol and readjusts the linked lists of
162      * protocols.
163      * @param prot_name The name of the protocol. Since all protocol names in a stack have to be unique
164      * (otherwise the stack won't be created), the name refers to just 1 protocol.
165      * @exception Exception Thrown if the protocol cannot be stopped correctly.
166      */

167     public void removeProtocol(String JavaDoc prot_name) throws Exception JavaDoc {
168         conf.removeProtocol(prot_name);
169     }
170
171
172     /** Returns a given protocol or null if not found */
173     public Protocol findProtocol(String JavaDoc name) {
174         Protocol tmp=top_prot;
175         String JavaDoc prot_name;
176         while(tmp != null) {
177             prot_name=tmp.getName();
178             if(prot_name != null && prot_name.equals(name))
179                 return tmp;
180             tmp=tmp.getDownProtocol();
181         }
182         return null;
183     }
184
185
186     public void destroy() {
187         if(top_prot != null) {
188             conf.stopProtocolStack(top_prot); // destroys msg queues and threads
189
top_prot=null;
190         }
191     }
192
193
194
195     /**
196      * Start all layers. The {@link Protocol#start()} method is called in each protocol,
197      * <em>from top to bottom</em>.
198      * Each layer can perform some initialization, e.g. create a multicast socket
199      */

200     public void startStack() throws Exception JavaDoc {
201         Object JavaDoc start_result=null;
202         if(stopped == false) return;
203
204         timer.start();
205
206         if(start_promise == null)
207             start_promise=new Promise();
208         else
209             start_promise.reset();
210
211         down(new Event(Event.START));
212         start_result=start_promise.getResult(0);
213         if(start_result != null && start_result instanceof Throwable JavaDoc) {
214             if(start_result instanceof Exception JavaDoc)
215                 throw (Exception JavaDoc)start_result;
216             else
217                 throw new Exception JavaDoc("ProtocolStack.start(): exception is " + start_result);
218         }
219
220         stopped=false;
221     }
222
223
224
225     public void startUpHandler() {
226         // DON'T REMOVE !!!! Avoids a superfluous thread
227
}
228
229     public void startDownHandler() {
230         // DON'T REMOVE !!!! Avoids a superfluous thread
231
}
232
233
234     /**
235      * Iterates through all the protocols <em>from top to bottom</em> and does the following:
236      * <ol>
237      * <li>Waits until all messages in the down queue have been flushed (ie., size is 0)
238      * <li>Calls stop() on the protocol
239      * </ol>
240      */

241     public void stopStack() {
242         if(timer != null) {
243             try {
244                 timer.stop();
245             }
246             catch(Exception JavaDoc ex) {
247             }
248         }
249
250         if(stopped) return;
251
252         if(stop_promise == null)
253             stop_promise=new Promise();
254         else
255             stop_promise.reset();
256
257         down(new Event(Event.STOP));
258         stop_promise.getResult(5000);
259         stopped=true;
260     }
261
262     /**
263      * Not needed anymore, just left in here for backwards compatibility with JBoss AS
264      * @deprecated
265      */

266     public void flushEvents() {
267
268     }
269
270     public void stopInternal() {
271         // do nothing, DON'T REMOVE !!!!
272
}
273
274
275
276     /*--------------------------- Transport interface ------------------------------*/
277
278     public void send(Message msg) throws Exception JavaDoc {
279         down(new Event(Event.MSG, msg));
280     }
281
282     public Object JavaDoc receive(long timeout) throws Exception JavaDoc {
283         throw new Exception JavaDoc("ProtocolStack.receive(): not implemented !");
284     }
285     /*------------------------- End of Transport interface ---------------------------*/
286
287
288
289
290
291     /*--------------------------- Protocol functionality ------------------------------*/
292     public String JavaDoc getName() {return "ProtocolStack";}
293
294
295
296
297     public void up(Event evt) {
298         switch(evt.getType()) {
299             case Event.START_OK:
300                 if(start_promise != null)
301                     start_promise.setResult(evt.getArg());
302                 return;
303             case Event.STOP_OK:
304                 if(stop_promise != null)
305                     stop_promise.setResult(evt.getArg());
306                 return;
307         }
308
309         if(channel != null)
310             channel.up(evt);
311     }
312
313
314
315
316     public void down(Event evt) {
317         if(top_prot != null)
318             top_prot.receiveDownEvent(evt);
319         else
320             log.error("no down protocol available !");
321     }
322
323
324
325     protected void receiveUpEvent(Event evt) {
326         up(evt);
327     }
328
329
330
331     /** Override with null functionality: we don't need any threads to be started ! */
332     public void startWork() {}
333
334     /** Override with null functionality: we don't need any threads to be started ! */
335     public void stopWork() {}
336
337
338     /*----------------------- End of Protocol functionality ---------------------------*/
339
340
341
342
343 }
344
Popular Tags