View Javadoc

1   /*
2    *   @(#) $Id: StreamIoHandler.java 357871 2005-12-20 01:56:40Z trustin $
3    *
4    *   Copyright 2004 The Apache Software Foundation
5    *
6    *   Licensed under the Apache License, Version 2.0 (the "License");
7    *   you may not use this file except in compliance with the License.
8    *   You may obtain a copy of the License at
9    *
10   *       http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *   Unless required by applicable law or agreed to in writing, software
13   *   distributed under the License is distributed on an "AS IS" BASIS,
14   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   *   See the License for the specific language governing permissions and
16   *   limitations under the License.
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         // Set timeouts
106         session.getConfig().setWriteTimeout( writeTimeout );
107         session.getConfig().setIdleTime( IdleStatus.READER_IDLE, readTimeout );
108 
109         // Create streams
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 }