View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.io.output;
18  
19  import java.io.FilterOutputStream;
20  import java.io.IOException;
21  import java.io.OutputStream;
22  
23  /**
24   * A Proxy stream which acts as expected, that is it passes the method 
25   * calls on to the proxied stream and doesn't change which methods are 
26   * being called. It is an alternative base class to FilterOutputStream
27   * to increase reusability.
28   * <p>
29   * See the protected methods for ways in which a subclass can easily decorate
30   * a stream with custom pre-, post- or error processing functionality.
31   * 
32   * @version $Id: ProxyOutputStream.java 1415850 2012-11-30 20:51:39Z ggregory $
33   */
34  public class ProxyOutputStream extends FilterOutputStream {
35  
36      /**
37       * Constructs a new ProxyOutputStream.
38       * 
39       * @param proxy  the OutputStream to delegate to
40       */
41      public ProxyOutputStream(final OutputStream proxy) {
42          super(proxy);
43          // the proxy is stored in a protected superclass variable named 'out'
44      }
45  
46      /**
47       * Invokes the delegate's <code>write(int)</code> method.
48       * @param idx the byte to write
49       * @throws IOException if an I/O error occurs
50       */
51      @Override
52      public void write(final int idx) throws IOException {
53          try {
54              beforeWrite(1);
55              out.write(idx);
56              afterWrite(1);
57          } catch (final IOException e) {
58              handleIOException(e);
59          }
60      }
61  
62      /**
63       * Invokes the delegate's <code>write(byte[])</code> method.
64       * @param bts the bytes to write
65       * @throws IOException if an I/O error occurs
66       */
67      @Override
68      public void write(final byte[] bts) throws IOException {
69          try {
70              final int len = bts != null ? bts.length : 0;
71              beforeWrite(len);
72              out.write(bts);
73              afterWrite(len);
74          } catch (final IOException e) {
75              handleIOException(e);
76          }
77      }
78  
79      /**
80       * Invokes the delegate's <code>write(byte[])</code> method.
81       * @param bts the bytes to write
82       * @param st The start offset
83       * @param end The number of bytes to write
84       * @throws IOException if an I/O error occurs
85       */
86      @Override
87      public void write(final byte[] bts, final int st, final int end) throws IOException {
88          try {
89              beforeWrite(end);
90              out.write(bts, st, end);
91              afterWrite(end);
92          } catch (final IOException e) {
93              handleIOException(e);
94          }
95      }
96  
97      /**
98       * Invokes the delegate's <code>flush()</code> method.
99       * @throws IOException if an I/O error occurs
100      */
101     @Override
102     public void flush() throws IOException {
103         try {
104             out.flush();
105         } catch (final IOException e) {
106             handleIOException(e);
107         }
108     }
109 
110     /**
111      * Invokes the delegate's <code>close()</code> method.
112      * @throws IOException if an I/O error occurs
113      */
114     @Override
115     public void close() throws IOException {
116         try {
117             out.close();
118         } catch (final IOException e) {
119             handleIOException(e);
120         }
121     }
122 
123     /**
124      * Invoked by the write methods before the call is proxied. The number
125      * of bytes to be written (1 for the {@link #write(int)} method, buffer
126      * length for {@link #write(byte[])}, etc.) is given as an argument.
127      * <p>
128      * Subclasses can override this method to add common pre-processing
129      * functionality without having to override all the write methods.
130      * The default implementation does nothing.
131      *
132      * @since 2.0
133      * @param n number of bytes to be written
134      * @throws IOException if the pre-processing fails
135      */
136     protected void beforeWrite(final int n) throws IOException {
137     }
138 
139     /**
140      * Invoked by the write methods after the proxied call has returned
141      * successfully. The number of bytes written (1 for the
142      * {@link #write(int)} method, buffer length for {@link #write(byte[])},
143      * etc.) is given as an argument.
144      * <p>
145      * Subclasses can override this method to add common post-processing
146      * functionality without having to override all the write methods.
147      * The default implementation does nothing.
148      *
149      * @since 2.0
150      * @param n number of bytes written
151      * @throws IOException if the post-processing fails
152      */
153     protected void afterWrite(final int n) throws IOException {
154     }
155 
156     /**
157      * Handle any IOExceptions thrown.
158      * <p>
159      * This method provides a point to implement custom exception
160      * handling. The default behaviour is to re-throw the exception.
161      * @param e The IOException thrown
162      * @throws IOException if an I/O error occurs
163      * @since 2.0
164      */
165     protected void handleIOException(final IOException e) throws IOException {
166         throw e;
167     }
168 
169 }