1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.mina.io.handler;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.OutputStream;
24 import java.net.SocketTimeoutException;
25
26 import org.apache.mina.common.ByteBuffer;
27 import org.apache.mina.common.IdleStatus;
28 import org.apache.mina.io.IoHandler;
29 import org.apache.mina.io.IoHandlerAdapter;
30 import org.apache.mina.io.IoSession;
31 import org.apache.mina.util.SessionLog;
32
33 /***
34 * A {@link IoHandler} that adapts asynchronous MINA events to stream I/O.
35 * <p>
36 * Please extend this class and implement
37 * {@link #processStreamIo(IoSession, InputStream, OutputStream)} to
38 * execute your stream I/O logic; <b>please note that you must forward
39 * the process request to other thread or thread pool.</b>
40 *
41 * @author The Apache Directory Project (dev@directory.apache.org)
42 * @version $Rev: 357871 $, $Date: 2005-12-20 10:56:40 +0900 (Tue, 20 Dec 2005) $
43 */
44 public abstract class StreamIoHandler extends IoHandlerAdapter
45 {
46 private static final String KEY_IN = StreamIoHandler.class.getName() + ".in";
47 private static final String KEY_OUT = StreamIoHandler.class.getName() + ".out";
48
49 private int readTimeout;
50 private int writeTimeout;
51
52 protected StreamIoHandler()
53 {
54 }
55
56 /***
57 * Implement this method to execute your stream I/O logic;
58 * <b>please note that you must forward the process request to other
59 * thread or thread pool.</b>
60 */
61 protected abstract void processStreamIo( IoSession session,
62 InputStream in, OutputStream out );
63
64 /***
65 * Returns read timeout in seconds.
66 * The default value is <tt>0</tt> (disabled).
67 */
68 public int getReadTimeout()
69 {
70 return readTimeout;
71 }
72
73 /***
74 * Sets read timeout in seconds.
75 * The default value is <tt>0</tt> (disabled).
76 */
77 public void setReadTimeout( int readTimeout )
78 {
79 this.readTimeout = readTimeout;
80 }
81
82 /***
83 * Returns write timeout in seconds.
84 * The default value is <tt>0</tt> (disabled).
85 */
86 public int getWriteTimeout()
87 {
88 return writeTimeout;
89 }
90
91 /***
92 * Sets write timeout in seconds.
93 * The default value is <tt>0</tt> (disabled).
94 */
95 public void setWriteTimeout( int writeTimeout )
96 {
97 this.writeTimeout = writeTimeout;
98 }
99
100 /***
101 * Initializes streams and timeout settings.
102 */
103 public void sessionOpened( IoSession session )
104 {
105
106 session.getConfig().setWriteTimeout( writeTimeout );
107 session.getConfig().setIdleTime( IdleStatus.READER_IDLE, readTimeout );
108
109
110 InputStream in = new IoSessionInputStream();
111 OutputStream out = new IoSessionOutputStream( session );
112 session.setAttribute( KEY_IN, in );
113 session.setAttribute( KEY_OUT, out );
114 processStreamIo( session, in, out );
115 }
116
117 /***
118 * Closes input stream.
119 */
120 public void sessionClosed( IoSession session )
121 {
122 IoSessionInputStream in = ( IoSessionInputStream ) session.getAttribute( KEY_IN );
123 IoSessionOutputStream out = ( IoSessionOutputStream ) session.getAttribute( KEY_OUT );
124 in.close();
125 out.close();
126 }
127
128 /***
129 * Forwards read data to input stream.
130 */
131 public void dataRead( IoSession session, ByteBuffer buf )
132 {
133 final IoSessionInputStream in = ( IoSessionInputStream ) session.getAttribute( KEY_IN );
134 in.write( buf );
135 }
136
137 /***
138 * Forwards caught exceptions to input stream.
139 */
140 public void exceptionCaught( IoSession session, Throwable cause )
141 {
142 final IoSessionInputStream in = ( IoSessionInputStream ) session.getAttribute( KEY_IN );
143
144 IOException e = null;
145 if( cause instanceof StreamIoException )
146 {
147 e = ( IOException ) cause.getCause();
148 }
149 else if( cause instanceof IOException )
150 {
151 e = ( IOException ) cause;
152 }
153
154 if( e != null && in != null )
155 {
156 in.throwException( e );
157 }
158 else
159 {
160 SessionLog.warn( session, "Unexpected exception.", cause );
161 session.close();
162 }
163 }
164
165 /***
166 * Handles read timeout.
167 */
168 public void sessionIdle( IoSession session, IdleStatus status )
169 {
170 if( status == IdleStatus.READER_IDLE )
171 {
172 throw new StreamIoException(
173 new SocketTimeoutException( "Read timeout" ) );
174 }
175 }
176
177 private static class StreamIoException extends RuntimeException
178 {
179 private static final long serialVersionUID = 3976736960742503222L;
180
181 public StreamIoException( IOException cause )
182 {
183 super(cause);
184 }
185 }
186 }