View Javadoc

1   /**********************************************************************
2    * ChannelInputStream.java
3    * created on 17.03.2005 by netseeker
4    * $Source: /cvsroot/ejoe/EJOE/src/de/netseeker/ejoe/io/ChannelInputStream.java,v $
5    * $Date: 2007/03/22 21:01:31 $
6    * $Revision: 1.10 $
7    *
8    * ====================================================================
9    *
10   *  Copyright 2005-2006 netseeker aka Michael Manske
11   *
12   *  Licensed under the Apache License, Version 2.0 (the "License");
13   *  you may not use this file except in compliance with the License.
14   *  You may obtain a copy of the License at
15   *
16   *      http://www.apache.org/licenses/LICENSE-2.0
17   *
18   *  Unless required by applicable law or agreed to in writing, software
19   *  distributed under the License is distributed on an "AS IS" BASIS,
20   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21   *  See the License for the specific language governing permissions and
22   *  limitations under the License.
23   * ====================================================================
24   *
25   * This file is part of the ejoe framework.
26   * For more information on the author, please see
27   * <http://www.manskes.de/>.
28   *
29   *********************************************************************/
30  package de.netseeker.ejoe.io;
31  
32  import java.io.FilterInputStream;
33  import java.io.IOException;
34  import java.io.InputStream;
35  import java.nio.channels.NonReadableChannelException;
36  
37  /***
38   * This is a very ugly try to work around the following issue when using Channel.newInputStream(): If the client closes
39   * the connection and we are already reading from the blocking InputStream, that stream will simply throw an IOException
40   * to notify us of the connection close. Because channel.isOpen() as well as the corresponding socket methods will not
41   * immediately tell us that the socket is closed we have no chance to decide if the IOException was thrown because the
42   * socket was closed by client or if there occured an IOException in the reader of the InputStream. To avoid that
43   * annoying issue we use this FilterInputStream which just wraps all IOExceptions into a NonReadableChannelException to
44   * tell us that the socket is not readable anymore.
45   * 
46   * @author netseeker
47   * @since 0.3.2
48   */
49  public class ChannelInputStream extends FilterInputStream
50  {
51      /***
52       * @param in
53       */
54      public ChannelInputStream(InputStream in)
55      {
56          super( in );
57      }
58  
59      /*
60       * (non-Javadoc)
61       * 
62       * @see java.io.InputStream#read()
63       */
64      public int read() throws IOException
65      {
66          try
67          {
68              return super.read();
69          }
70          catch ( IOException e )
71          {
72              throw fillException( e );
73          }
74      }
75  
76      /*
77       * (non-Javadoc)
78       * 
79       * @see java.io.InputStream#read(byte[], int, int)
80       */
81      public int read( byte[] b, int off, int len ) throws IOException
82      {
83          try
84          {
85              return super.read( b, off, len );
86          }
87          catch ( IOException e )
88          {
89              throw fillException( e );
90          }
91      }
92  
93      /*
94       * (non-Javadoc)
95       * 
96       * @see java.io.InputStream#read(byte[])
97       */
98      public int read( byte[] b ) throws IOException
99      {
100         try
101         {
102             return super.read( b );
103         }
104         catch ( IOException e )
105         {
106             throw fillException( e );
107         }
108     }
109 
110     /***
111      * @param e
112      * @return
113      */
114     private NonReadableChannelException fillException( IOException e )
115     {
116         NonReadableChannelException ne = new NonReadableChannelException();
117         ne.setStackTrace( e.getStackTrace() );
118         ne.initCause( e.getCause() );
119         return ne;
120     }
121 }