    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    }