View Javadoc

1   package de.netseeker.ejoe.io;
2   
3   import java.io.FilterOutputStream;
4   import java.io.IOException;
5   import java.io.OutputStream;
6   import java.nio.channels.ClosedChannelException;
7   
8   import de.netseeker.ejoe.EJConstants;
9   
10  /***
11   * Simple input stream wrapper which overwrites #close to prevent some and is used when output streams are handed over
12   * to serialize adapters to prevent some encoders, eg. Suns XmlEncoder, to close our socket output streams
13   * automatically.
14   * 
15   * @author netseeker
16   * @since 0.3.5
17   */
18  public class UncloseableOutputStream extends FilterOutputStream
19  {
20  
21      private boolean _customEOF;
22  
23      private boolean _isClosed  = false;
24  
25      private int     _written   = 0;
26  
27      private int     _lastFlush = 0;
28  
29      /***
30       * @param out
31       */
32      public UncloseableOutputStream(OutputStream out)
33      {
34          this( out, false );
35      }
36  
37      /***
38       * @param out
39       * @param customEOF
40       */
41      public UncloseableOutputStream(OutputStream out, boolean customEOF)
42      {
43          super( out );
44          _customEOF = customEOF;
45      }
46  
47      /*
48       * (non-Javadoc)
49       * 
50       * @see java.io.FilterOutputStream#write(byte[], int, int)
51       */
52      public void write( byte[] b, int off, int len ) throws IOException
53      {
54          if ( _customEOF && len > 0 && b[off + len - 1] == -1 )
55          {
56              len -= 1;
57          }
58  
59          super.write( b, off, len );
60          _written += len;
61      }
62  
63      /*
64       * (non-Javadoc)
65       * 
66       * @see java.io.FilterOutputStream#write(byte[])
67       */
68      public void write( byte[] b ) throws IOException
69      {
70          write( b, 0, b.length );
71      }
72  
73      /*
74       * (non-Javadoc)
75       * 
76       * @see java.io.FilterOutputStream#write(int)
77       */
78      public void write( int b ) throws IOException
79      {
80          super.write( b );
81          _written++;
82      }
83  
84      /*
85       * (non-Javadoc)
86       * 
87       * @see java.io.FilterOutputStream#flush()
88       */
89      public void flush() throws IOException
90      {
91          try
92          {
93              if ( _written > _lastFlush ) super.flush();
94          }
95          catch ( IOException e )
96          {
97              throw new ClosedChannelException();
98          }
99          finally
100         {
101             _lastFlush = _written;
102         }
103     }
104 
105     /*
106      * (non-Javadoc)
107      * 
108      * @see java.io.FilterOutputStream#close()
109      */
110     public void close() throws IOException
111     {
112         if ( !_isClosed )
113         {
114             try
115             {
116                 if ( _written > 0 )
117                 {
118                     if ( _customEOF )
119                     {
120                         super.write( EJConstants.EJOE_EOF );
121                     }
122 
123                     flush();
124                 }
125             }
126             catch ( IOException e )
127             {
128                 throw new ClosedChannelException();
129             }
130             finally
131             {
132                 _isClosed = true;
133                 _written = 0;
134             }
135         }
136     }
137 }