001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.io.output;
018
019 import java.io.FilterWriter;
020 import java.io.IOException;
021 import java.io.Writer;
022
023 /**
024 * A Proxy stream which acts as expected, that is it passes the method
025 * calls on to the proxied stream and doesn't change which methods are
026 * being called. It is an alternative base class to FilterWriter
027 * to increase reusability, because FilterWriter changes the
028 * methods being called, such as write(char[]) to write(char[], int, int)
029 * and write(String) to write(String, int, int).
030 *
031 * @author Stephen Colebourne
032 * @version $Id: ProxyWriter.java 1003647 2010-10-01 20:53:59Z niallp $
033 */
034 public class ProxyWriter extends FilterWriter {
035
036 /**
037 * Constructs a new ProxyWriter.
038 *
039 * @param proxy the Writer to delegate to
040 */
041 public ProxyWriter(Writer proxy) {
042 super(proxy);
043 // the proxy is stored in a protected superclass variable named 'out'
044 }
045
046 /**
047 * Invokes the delegate's <code>append(char)</code> method.
048 * @param c The character to write
049 * @return this writer
050 * @throws IOException if an I/O error occurs
051 * @since Commons IO 2.0
052 */
053 @Override
054 public Writer append(char c) throws IOException {
055 try {
056 beforeWrite(1);
057 out.append(c);
058 afterWrite(1);
059 } catch (IOException e) {
060 handleIOException(e);
061 }
062 return this;
063 }
064
065 /**
066 * Invokes the delegate's <code>append(CharSequence, int, int)</code> method.
067 * @param csq The character sequence to write
068 * @param start The index of the first character to write
069 * @param end The index of the first character to write (exclusive)
070 * @return this writer
071 * @throws IOException if an I/O error occurs
072 * @since Commons IO 2.0
073 */
074 @Override
075 public Writer append(CharSequence csq, int start, int end) throws IOException {
076 try {
077 beforeWrite(end - start);
078 out.append(csq, start, end);
079 afterWrite(end - start);
080 } catch (IOException e) {
081 handleIOException(e);
082 }
083 return this;
084 }
085
086 /**
087 * Invokes the delegate's <code>append(CharSequence)</code> method.
088 * @param csq The character sequence to write
089 * @return this writer
090 * @throws IOException if an I/O error occurs
091 * @since Commons IO 2.0
092 */
093 @Override
094 public Writer append(CharSequence csq) throws IOException {
095 try {
096 int len = 0;
097 if (csq != null) {
098 len = csq.length();
099 }
100
101 beforeWrite(len);
102 out.append(csq);
103 afterWrite(len);
104 } catch (IOException e) {
105 handleIOException(e);
106 }
107 return this;
108 }
109
110 /**
111 * Invokes the delegate's <code>write(int)</code> method.
112 * @param idx the character to write
113 * @throws IOException if an I/O error occurs
114 */
115 @Override
116 public void write(int idx) throws IOException {
117 try {
118 beforeWrite(1);
119 out.write(idx);
120 afterWrite(1);
121 } catch (IOException e) {
122 handleIOException(e);
123 }
124 }
125
126 /**
127 * Invokes the delegate's <code>write(char[])</code> method.
128 * @param chr the characters to write
129 * @throws IOException if an I/O error occurs
130 */
131 @Override
132 public void write(char[] chr) throws IOException {
133 try {
134 int len = 0;
135 if (chr != null) {
136 len = chr.length;
137 }
138
139 beforeWrite(len);
140 out.write(chr);
141 afterWrite(len);
142 } catch (IOException e) {
143 handleIOException(e);
144 }
145 }
146
147 /**
148 * Invokes the delegate's <code>write(char[], int, int)</code> method.
149 * @param chr the characters to write
150 * @param st The start offset
151 * @param len The number of characters to write
152 * @throws IOException if an I/O error occurs
153 */
154 @Override
155 public void write(char[] chr, int st, int len) throws IOException {
156 try {
157 beforeWrite(len);
158 out.write(chr, st, len);
159 afterWrite(len);
160 } catch (IOException e) {
161 handleIOException(e);
162 }
163 }
164
165 /**
166 * Invokes the delegate's <code>write(String)</code> method.
167 * @param str the string to write
168 * @throws IOException if an I/O error occurs
169 */
170 @Override
171 public void write(String str) throws IOException {
172 try {
173 int len = 0;
174 if (str != null) {
175 len = str.length();
176 }
177
178 beforeWrite(len);
179 out.write(str);
180 afterWrite(len);
181 } catch (IOException e) {
182 handleIOException(e);
183 }
184 }
185
186 /**
187 * Invokes the delegate's <code>write(String)</code> method.
188 * @param str the string to write
189 * @param st The start offset
190 * @param len The number of characters to write
191 * @throws IOException if an I/O error occurs
192 */
193 @Override
194 public void write(String str, int st, int len) throws IOException {
195 try {
196 beforeWrite(len);
197 out.write(str, st, len);
198 afterWrite(len);
199 } catch (IOException e) {
200 handleIOException(e);
201 }
202 }
203
204 /**
205 * Invokes the delegate's <code>flush()</code> method.
206 * @throws IOException if an I/O error occurs
207 */
208 @Override
209 public void flush() throws IOException {
210 try {
211 out.flush();
212 } catch (IOException e) {
213 handleIOException(e);
214 }
215 }
216
217 /**
218 * Invokes the delegate's <code>close()</code> method.
219 * @throws IOException if an I/O error occurs
220 */
221 @Override
222 public void close() throws IOException {
223 try {
224 out.close();
225 } catch (IOException e) {
226 handleIOException(e);
227 }
228 }
229
230 /**
231 * Invoked by the write methods before the call is proxied. The number
232 * of chars to be written (1 for the {@link #write(int)} method, buffer
233 * length for {@link #write(char[])}, etc.) is given as an argument.
234 * <p>
235 * Subclasses can override this method to add common pre-processing
236 * functionality without having to override all the write methods.
237 * The default implementation does nothing.
238 *
239 * @since Commons IO 2.0
240 * @param n number of chars to be written
241 * @throws IOException if the pre-processing fails
242 */
243 protected void beforeWrite(int n) throws IOException {
244 }
245
246 /**
247 * Invoked by the write methods after the proxied call has returned
248 * successfully. The number of chars written (1 for the
249 * {@link #write(int)} method, buffer length for {@link #write(char[])},
250 * etc.) is given as an argument.
251 * <p>
252 * Subclasses can override this method to add common post-processing
253 * functionality without having to override all the write methods.
254 * The default implementation does nothing.
255 *
256 * @since Commons IO 2.0
257 * @param n number of chars written
258 * @throws IOException if the post-processing fails
259 */
260 protected void afterWrite(int n) throws IOException {
261 }
262
263 /**
264 * Handle any IOExceptions thrown.
265 * <p>
266 * This method provides a point to implement custom exception
267 * handling. The default behaviour is to re-throw the exception.
268 * @param e The IOException thrown
269 * @throws IOException if an I/O error occurs
270 * @since Commons IO 2.0
271 */
272 protected void handleIOException(IOException e) throws IOException {
273 throw e;
274 }
275
276 }