EMMA Coverage Report (generated Wed Jun 08 12:10:57 KST 2005)
[all classes][org.apache.mina.io.handler]

COVERAGE SUMMARY FOR SOURCE FILE [StreamIoHandler.java]

nameclass, %method, %block, %line, %
StreamIoHandler.java0%   (0/4)0%   (0/23)0%   (0/286)0%   (0/93)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class StreamIoHandler0%   (0/1)0%   (0/11)0%   (0/201)0%   (0/61)
StreamIoHandler (): void 0%   (0/1)0%   (0/3)0%   (0/2)
beginService (IoSession, StreamIoHandler$PipedInputStream): void 0%   (0/1)0%   (0/18)0%   (0/4)
dataRead (IoSession, ByteBuffer): void 0%   (0/1)0%   (0/65)0%   (0/17)
exceptionCaught (IoSession, Throwable): void 0%   (0/1)0%   (0/38)0%   (0/14)
getReadTimeout (): int 0%   (0/1)0%   (0/3)0%   (0/1)
getWriteTimeout (): int 0%   (0/1)0%   (0/3)0%   (0/1)
sessionClosed (IoSession): void 0%   (0/1)0%   (0/15)0%   (0/6)
sessionIdle (IoSession, IdleStatus): void 0%   (0/1)0%   (0/12)0%   (0/3)
sessionOpened (IoSession): void 0%   (0/1)0%   (0/36)0%   (0/9)
setReadTimeout (int): void 0%   (0/1)0%   (0/4)0%   (0/2)
setWriteTimeout (int): void 0%   (0/1)0%   (0/4)0%   (0/2)
     
class StreamIoHandler$PipedInputStream0%   (0/1)0%   (0/5)0%   (0/28)0%   (0/11)
StreamIoHandler$PipedInputStream (PipedOutputStream): void 0%   (0/1)0%   (0/4)0%   (0/2)
read (): int 0%   (0/1)0%   (0/5)0%   (0/2)
read (byte [], int, int): int 0%   (0/1)0%   (0/8)0%   (0/2)
setException (IOException): void 0%   (0/1)0%   (0/4)0%   (0/2)
throwException (): void 0%   (0/1)0%   (0/7)0%   (0/3)
     
class StreamIoHandler$ServiceOutputStream0%   (0/1)0%   (0/6)0%   (0/53)0%   (0/19)
StreamIoHandler$ServiceOutputStream (IoSession): void 0%   (0/1)0%   (0/6)0%   (0/3)
close (): void 0%   (0/1)0%   (0/5)0%   (0/2)
flush (): void 0%   (0/1)0%   (0/1)0%   (0/1)
write (byte []): void 0%   (0/1)0%   (0/11)0%   (0/4)
write (byte [], int, int): void 0%   (0/1)0%   (0/13)0%   (0/4)
write (int): void 0%   (0/1)0%   (0/17)0%   (0/5)
     
class StreamIoHandler$StreamIoException0%   (0/1)0%   (0/1)0%   (0/4)0%   (0/2)
StreamIoHandler$StreamIoException (IOException): void 0%   (0/1)0%   (0/4)0%   (0/2)

1package org.apache.mina.io.handler;
2 
3import java.io.IOException;
4import java.io.InputStream;
5import java.io.OutputStream;
6import java.io.PipedOutputStream;
7import java.net.SocketTimeoutException;
8 
9import org.apache.mina.common.ByteBuffer;
10import org.apache.mina.common.IdleStatus;
11import org.apache.mina.io.IoHandler;
12import org.apache.mina.io.IoHandlerAdapter;
13import org.apache.mina.io.IoSession;
14 
15/**
16 * A {@link IoHandler} that adapts asynchronous MINA events to stream I/O.
17 * <p>
18 * Please extend this class and implement
19 * {@link #processStreamIo(IoSession, InputStream, OutputStream)} to
20 * execute your stream I/O logic; <b>please note that you must forward
21 * the process request to other thread or thread pool.</b>
22 * 
23 * @author The Apache Directory Project (dev@directory.apache.org)
24 * @author Trustin Lee (trustin@apache.org)
25 * @version $Rev: 164449 $, $Date: 2005-04-24 14:44:18 +0900 $
26 */
27public abstract class StreamIoHandler extends IoHandlerAdapter
28{
29    private static final String KEY_IN = "BlockingIoHandler.in";
30    private static final String KEY_OUT = "BlockingIoHandler.out";
31    private static final String KEY_STARTED = "BlockingIoHandler.started";
32    
33    private int readTimeout;
34    
35    private int writeTimeout;
36    
37    protected StreamIoHandler()
38    {
39    }
40    
41    /**
42     * Implement this method to execute your stream I/O logic;
43     * <b>please note that you must forward the process request to other
44     * thread or thread pool.</b>
45     */
46    protected abstract void processStreamIo( IoSession session,
47                                             InputStream in, OutputStream out );
48    
49    /**
50     * Returns read timeout in seconds.
51     * The default value is <tt>0</tt> (disabled).
52     */
53    public int getReadTimeout()
54    {
55        return readTimeout;
56    }
57    
58    /**
59     * Sets read timeout in seconds.
60     * The default value is <tt>0</tt> (disabled).
61     */
62    public void setReadTimeout( int readTimeout )
63    {
64        this.readTimeout = readTimeout;
65    }
66    
67    /**
68     * Returns write timeout in seconds.
69     * The default value is <tt>0</tt> (disabled).
70     */
71    public int getWriteTimeout()
72    {
73        return writeTimeout;
74    }
75    
76    /**
77     * Sets write timeout in seconds.
78     * The default value is <tt>0</tt> (disabled).
79     */
80    public void setWriteTimeout( int writeTimeout )
81    {
82        this.writeTimeout = writeTimeout;
83    }
84 
85    /**
86     * Initializes streams and timeout settings.
87     */
88    public void sessionOpened( IoSession session )
89    {
90        // Set timeouts
91        session.getConfig().setWriteTimeout( writeTimeout );
92        session.getConfig().setIdleTime( IdleStatus.READER_IDLE, readTimeout );
93 
94        // Create streams
95        PipedOutputStream out = new PipedOutputStream();
96        session.setAttribute( KEY_OUT, out );
97        try
98        {
99            session.setAttribute( KEY_IN, new PipedInputStream( out ) );
100        }
101        catch( IOException e )
102        {
103            throw new StreamIoException( e );
104        }
105    }
106    
107    /**
108     * Closes input stream.
109     */
110    public void sessionClosed( IoSession session )
111    {
112        final PipedOutputStream out = ( PipedOutputStream ) session.getAttribute( KEY_OUT );
113        try {
114            out.close();
115        }
116        catch( IOException e )
117        {
118            throw new StreamIoException( e );
119        }
120    }
121 
122    /**
123     * Forwards read data to input stream.
124     */
125    public void dataRead( IoSession session, ByteBuffer buf )
126    {
127        final PipedInputStream in = ( PipedInputStream ) session.getAttribute( KEY_IN );
128        final PipedOutputStream out = ( PipedOutputStream ) session.getAttribute( KEY_OUT );
129        
130        java.nio.ByteBuffer nioBuf = buf.buf();
131        int offset = nioBuf.position();
132        int length = nioBuf.limit() - offset;
133        if( !nioBuf.hasArray() )
134        {
135            ByteBuffer heapBuf = ByteBuffer.allocate( length, false );
136            heapBuf.put( buf );
137            heapBuf.flip();
138            nioBuf = heapBuf.buf();
139            offset = 0;
140        }
141        
142        try
143        {
144            out.write( nioBuf.array(), offset, length );
145        }
146        catch( IOException e )
147        {
148            throw new StreamIoException( e );
149        }
150        finally
151        {
152            beginService( session, in );
153        }
154    }
155 
156    /**
157     * Forwards caught exceptions to input stream.
158     */
159    public void exceptionCaught( IoSession session, Throwable cause )
160    {
161        final PipedInputStream in = ( PipedInputStream ) session.getAttribute( KEY_IN );
162        
163        IOException e = null;
164        if( cause instanceof StreamIoException )
165        {
166            e = ( IOException ) cause.getCause();
167        }
168        else if( cause instanceof IOException )
169        {
170            e = ( IOException ) cause;
171        }
172        
173        if( e != null && in != null )
174        {
175            in.setException( e );
176            beginService( session, in );
177        }
178        else
179        {
180            cause.printStackTrace();
181            session.close();
182        }
183    }
184 
185    /**
186     * Handles read timeout.
187     */
188    public void sessionIdle( IoSession session, IdleStatus status )
189    {
190        if( status == IdleStatus.READER_IDLE )
191        {
192            throw new StreamIoException(
193                    new SocketTimeoutException( "Read timeout" ) );
194        }
195    }
196 
197    private void beginService( IoSession session, PipedInputStream in )
198    {
199        if( session.getAttribute( KEY_STARTED ) == null )
200        {
201            session.setAttribute( KEY_STARTED, Boolean.TRUE );
202            processStreamIo( session, in, new ServiceOutputStream( session ) );
203        }
204    }
205 
206    private static class PipedInputStream extends java.io.PipedInputStream
207    {
208        private IOException exception;
209 
210        public PipedInputStream(PipedOutputStream src) throws IOException
211        {
212            super( src );
213        }
214        
215        public void setException( IOException e )
216        {
217            this.exception = e;
218        }
219 
220        public synchronized int read() throws IOException
221        {
222            throwException();
223            return super.read();
224        }
225 
226        public synchronized int read( byte[] b, int off, int len ) throws IOException
227        {
228            throwException();
229            return super.read( b, off, len );
230        }
231        
232        private void throwException() throws IOException
233        {
234            if( exception != null )
235            {
236                throw exception;
237            }
238        }
239    }
240 
241    private static class ServiceOutputStream extends OutputStream
242    {
243        private final IoSession session;
244        
245        public ServiceOutputStream( IoSession session )
246        {
247            this.session = session;
248        }
249 
250        public void close()
251        {
252            session.close( true );
253        }
254 
255        public void flush()
256        {
257        }
258 
259        public void write( byte[] b, int off, int len )
260        {
261            ByteBuffer buf = ByteBuffer.wrap( b, off, len );
262            buf.acquire(); // prevent from being pooled.
263            session.write( buf, null );
264        }
265 
266        public void write( byte[] b )
267        {
268            ByteBuffer buf = ByteBuffer.wrap( b );
269            buf.acquire(); // prevent from being pooled.
270            session.write( buf, null );
271        }
272 
273        public void write( int b )
274        {
275            ByteBuffer buf = ByteBuffer.allocate( 1 );
276            buf.put( ( byte ) b );
277            buf.flip();
278            session.write( buf, null );
279        }
280    }
281    
282    private static class StreamIoException extends RuntimeException
283    {
284        private static final long serialVersionUID = 3976736960742503222L;
285 
286        public StreamIoException( IOException cause )
287        {
288            super(cause);
289        }
290    }
291}

[all classes][org.apache.mina.io.handler]
EMMA 2.0.4217 (C) Vladimir Roubtsov