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 }