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 */
017package org.apache.commons.io.output;
018
019import java.io.Serializable;
020import java.io.Writer;
021
022/**
023 * {@link Writer} implementation that outputs to a {@link StringBuilder}.
024 * <p>
025 * <strong>NOTE:</strong> This implementation, as an alternative to
026 * {@code java.io.StringWriter}, provides an <i>un-synchronized</i>
027 * (i.e. for use in a single thread) implementation for better performance.
028 * For safe usage with multiple {@link Thread}s then
029 * {@code java.io.StringWriter} should be used.
030 * </p>
031 *
032 * @since 2.0
033 */
034public class StringBuilderWriter extends Writer implements Serializable {
035
036    private static final long serialVersionUID = -146927496096066153L;
037    private final StringBuilder builder;
038
039    /**
040     * Constructs a new {@link StringBuilder} instance with default capacity.
041     */
042    public StringBuilderWriter() {
043        this.builder = new StringBuilder();
044    }
045
046    /**
047     * Constructs a new {@link StringBuilder} instance with the specified capacity.
048     *
049     * @param capacity The initial capacity of the underlying {@link StringBuilder}
050     */
051    public StringBuilderWriter(final int capacity) {
052        this.builder = new StringBuilder(capacity);
053    }
054
055    /**
056     * Constructs a new instance with the specified {@link StringBuilder}.
057     *
058     * <p>If {@code builder} is null a new instance with default capacity will be created.</p>
059     *
060     * @param builder The String builder. May be null.
061     */
062    public StringBuilderWriter(final StringBuilder builder) {
063        this.builder = builder != null ? builder : new StringBuilder();
064    }
065
066    /**
067     * Appends a single character to this Writer.
068     *
069     * @param value The character to append
070     * @return This writer instance
071     */
072    @Override
073    public Writer append(final char value) {
074        builder.append(value);
075        return this;
076    }
077
078    /**
079     * Appends a character sequence to this Writer.
080     *
081     * @param value The character to append
082     * @return This writer instance
083     */
084    @Override
085    public Writer append(final CharSequence value) {
086        builder.append(value);
087        return this;
088    }
089
090    /**
091     * Appends a portion of a character sequence to the {@link StringBuilder}.
092     *
093     * @param value The character to append
094     * @param start The index of the first character
095     * @param end The index of the last character + 1
096     * @return This writer instance
097     */
098    @Override
099    public Writer append(final CharSequence value, final int start, final int end) {
100        builder.append(value, start, end);
101        return this;
102    }
103
104    /**
105     * Closing this writer has no effect.
106     */
107    @Override
108    public void close() {
109        // no-op
110    }
111
112    /**
113     * Flushing this writer has no effect.
114     */
115    @Override
116    public void flush() {
117        // no-op
118    }
119
120
121    /**
122     * Writes a String to the {@link StringBuilder}.
123     *
124     * @param value The value to write
125     */
126    @Override
127    public void write(final String value) {
128        if (value != null) {
129            builder.append(value);
130        }
131    }
132
133    /**
134     * Writes a portion of a character array to the {@link StringBuilder}.
135     *
136     * @param value The value to write
137     * @param offset The index of the first character
138     * @param length The number of characters to write
139     */
140    @Override
141    public void write(final char[] value, final int offset, final int length) {
142        if (value != null) {
143            builder.append(value, offset, length);
144        }
145    }
146
147    /**
148     * Returns the underlying builder.
149     *
150     * @return The underlying builder
151     */
152    public StringBuilder getBuilder() {
153        return builder;
154    }
155
156    /**
157     * Returns {@link StringBuilder#toString()}.
158     *
159     * @return The contents of the String builder.
160     */
161    @Override
162    public String toString() {
163        return builder.toString();
164    }
165}