KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sapia > ubik > net > nio > ChannelHandler


1 package org.sapia.ubik.net.nio;
2
3 /**
4  * An instance of this interface in fact implements an application-specific
5  * message protocol. The instance implements callbacks that are invoked at
6  * runtime. The callbacks correspond to the various states in a communication
7  * {@link Cycle}.
8  * <p>
9  * Instances of this class are created by a specific
10  * <code>ChannelHandlerFactory</code>. The created handlers are associated to
11  * a <code>Cycle</code> until that cycle completes.
12  * <p>
13  * The typical lifecycle of an instance of this class consists of some read or
14  * write operation, followed by some processing, followed by a read or write,
15  * and then possibly followed by a completion (meaning that the instance has
16  * "finished").
17  * <p>
18  * Note that the order of the reads and writes depends on this instance
19  * corresponding to a client or a server. In the cases of clients, write then
20  * read is normally done; in the case of servers, the opposite is of course
21  * true.
22  * <p>
23  * The read, write and process operations have been separated so that they
24  * eventually can be accomplished by different threads. A common strategy is to
25  * use RWP (read-write-process) thread pools that can be configured according to
26  * the specific application requirements.
27  * <p>
28  * Furthermore, instances of this interface are in charge of indicating the
29  * "next" state in the cycle. This is done in the <code>read()</code>,
30  * <code>write()</code> and <code>process()</code> methods. Indicating which
31  * state to execute next is done as follows:
32  *
33  * <pre>
34  * cycle.state(Cycle.STATE_PROCESS);
35  * </pre>
36  *
37  * <p>
38  * In addition, instances of this interface may signal an error by calling the
39  * <code>error()</code> method of the <code>Cycle</code> instance:
40  *
41  * <pre>
42  * try {
43  * // process...
44  * } catch(SomeException e) {
45  * cycle.error(e);
46  * return; //important in this case...
47  * }
48  * </pre>
49  *
50  * Signaling an error as above aborts the communication cycle. Therefore, errors
51  * that are part of the client-server messaging protocol should be dealt with as
52  * part of that protocol, not through the method demonstrated above - which
53  * should be reserved for low-level errors. In fact, this error handling
54  * mechanism has mainly been introduced so that the application-level handlers
55  * could be notified of such errors - see the <code>error()</code> method of this class.
56  *
57  * @see #error(Cycle)
58  *
59  * @author Yanick Duchesne
60  *
61  * @see Cycle
62  *
63  * <dl>
64  * <dt><b>Copyright: </b>
65  * <dd>Copyright &#169; 2002-2005 <a HREF="http://www.sapia-oss.org">Sapia Open
66  * Source Software </a>. All Rights Reserved.</dd>
67  * </dt>
68  * <dt><b>License: </b>
69  * <dd>Read the license.txt file of the jar or visit the <a
70  * HREF="http://www.sapia-oss.org/license.html">license page </a> at the Sapia
71  * OSS web site</dd>
72  * </dt>
73  * </dl>
74  */

75 public interface ChannelHandler {
76
77   /**
78    * Called when a read operation has been triggered (i.e.: when the current
79    * cycle is in read state). Implementations can have access to the data that
80    * has been read by calling <code>cycle.getByteBuffer()</code>
81    * <p>
82    * If the buffer does not hold all the data that is expected by this instance,
83    * then this method should return <code>false</code>. If all the data has
84    * been received, then this method should set the next state to execute and
85    * return <code>true</code>.
86    * <p>
87    * A pseudo-Java example:
88    *
89    * <pre>
90    * public boolean read(Cycle cycle) {
91    * ByteBuffer input = cycle.getByteBuffer();
92    * try {
93    * // here extract data...
94    * } catch(RuntimeException e) {
95    * cycle.error(e);
96    * }
97    * if(numReadBytes &gt;= expectedBytes) {
98    * cycle.state(Cycle.STATE_PROCESS);
99    * return true;
100    * }
101    * return false;
102    * }
103    *
104    *
105    * </pre>
106    *
107    * @see Cycle#getByteBuffer()
108    * @see Cycle#STATE_READ
109    *
110    * @param cycle
111    * the current <code>Cycle</code>
112    * @return <code>true</code> if <b>NO </b> more data is expected by this
113    * instance (i.e.: if the next specified state should be triggered).
114    */

115   public boolean read(Cycle cycle);
116
117   /**
118    * Called when a write operation has been triggered (i.e.: when the current
119    * cycle is in write state). Implementations write their that to the buffer
120    * that is made available through <code>cycle.getByteBuffer()</code>
121    * <p>
122    * If the buffer cannot contain all the data that is to be written, then this
123    * method should return <code>false</code>. Otherwise, if all the data has
124    * been written, this method should set the next state to execute and return
125    * <code>true</code>.
126    * <p>
127    * A pseudo-Java example:
128    *
129    * <pre>
130    * public boolean write(Cycle cycle) {
131    * ByteBuffer output = cycle.getByteBuffer();
132    * // here extract data...
133    * if(numWrittenBytes &gt;= expectedBytes) {
134    * cycle.state(Cycle.STATE_COMPLETE_CLOSE);
135    * return true;
136    * }
137    * return false;
138    * }
139    *
140    *
141    * </pre>
142    *
143    * @see Cycle#getByteBuffer()
144    * @see Cycle#STATE_WRITE
145    *
146    * @param cycle
147    * the current <code>Cycle</code>
148    * @return <code>true</code> if <b>NO</b> more data is to be written by
149    * this instance (i.e.: if the next specified state should be
150    * triggered).
151    */

152   public boolean write(Cycle cycle);
153
154   /**
155    * This method implements this instance's business logic.
156    *
157    * @see Cycle#STATE_PROCESS
158    *
159    * @param cycle
160    * the current <code>Cycle</code>.
161    */

162   public void process(Cycle cycle);
163
164   /**
165    * Called when the given cycle has completed.
166    *
167    * @see Cycle#STATE_COMPLETE
168    *
169    * @param cycle
170    * the current <code>Cycle</code>.
171    */

172   public void completed(Cycle cycle);
173
174   /**
175    * Callback that is invoked in an error is signaled. This method is called
176    * after a <code>cycle.error()</code> invocation as occured. Handlers can
177    * thus perform appropriate cleanup.
178    * <p>
179    * Note that if this method is called, the <code>completed()</code> method
180    * will not be called.
181    *
182    * @param cycle
183    * the current <code>Cycle</code>.
184    * @see #completed(Cycle)
185    */

186   public void error(Cycle cycle);
187
188 }
189
Popular Tags