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    *      https://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.Serializable;
20  import java.io.StringWriter;
21  import java.io.Writer;
22  
23  import org.apache.commons.io.IOUtils;
24  
25  /**
26   * {@link Writer} implementation that outputs to a {@link StringBuilder}.
27   * <p>
28   * <strong>NOTE:</strong> This implementation, as an alternative to {@link StringWriter}, provides an <em>un-synchronized</em> implementation for better
29   * performance for use in a single thread. For safe usage with multiple {@link Thread}s, a {@link StringWriter} should be used.
30   * </p>
31   * <h2>Deprecating Serialization</h2>
32   * <p>
33   * <em>Serialization is deprecated and will be removed in 3.0.</em>
34   * </p>
35   *
36   * @since 2.0
37   */
38  public class StringBuilderWriter extends Writer implements Serializable {
39  
40      private static final long serialVersionUID = -146927496096066153L;
41  
42      /** The append target. */
43      private final StringBuilder builder;
44  
45      /**
46       * Constructs a new {@link StringBuilder} instance with default capacity.
47       */
48      public StringBuilderWriter() {
49          this.builder = new StringBuilder();
50      }
51  
52      /**
53       * Constructs a new {@link StringBuilder} instance with the specified capacity.
54       *
55       * @param capacity The initial capacity of the underlying {@link StringBuilder}
56       */
57      public StringBuilderWriter(final int capacity) {
58          this.builder = new StringBuilder(capacity);
59      }
60  
61      /**
62       * Constructs a new instance with the specified {@link StringBuilder}.
63       *
64       * <p>If {@code builder} is null a new instance with default capacity will be created.</p>
65       *
66       * @param builder The String builder. May be null.
67       */
68      public StringBuilderWriter(final StringBuilder builder) {
69          this.builder = builder != null ? builder : new StringBuilder();
70      }
71  
72      /**
73       * Appends a single character to this Writer.
74       *
75       * @param value The character to append.
76       * @return This writer instance.
77       */
78      @Override
79      public Writer append(final char value) {
80          builder.append(value);
81          return this;
82      }
83  
84      /**
85       * Appends a character sequence to this Writer.
86       *
87       * @param value The character to append.
88       * @return This writer instance.
89       */
90      @Override
91      public Writer append(final CharSequence value) {
92          builder.append(value);
93          return this;
94      }
95  
96      /**
97       * Appends a portion of a character sequence to the {@link StringBuilder}.
98       *
99       * @param value The character to append.
100      * @param start The index of the first character.
101      * @param end The index of the last character + 1.
102      * @return This writer instance.
103      */
104     @Override
105     public Writer append(final CharSequence value, final int start, final int end) {
106         builder.append(value, start, end);
107         return this;
108     }
109 
110     /**
111      * Closing this writer has no effect.
112      */
113     @Override
114     public void close() {
115         // no-op
116     }
117 
118     /**
119      * Flushing this writer has no effect.
120      */
121     @Override
122     public void flush() {
123         // no-op
124     }
125 
126     /**
127      * Gets the underlying builder.
128      *
129      * @return The underlying builder.
130      */
131     public StringBuilder getBuilder() {
132         return builder;
133     }
134 
135     /**
136      * Returns {@link StringBuilder#toString()}.
137      *
138      * @return The contents of the String builder.
139      */
140     @Override
141     public String toString() {
142         return builder.toString();
143     }
144 
145     /**
146      * Writes a portion of a character array to the {@link StringBuilder}.
147      *
148      * @param value The value to write.
149      * @param offset The index of the first character.
150      * @param length The number of characters to write.
151      * @throws IndexOutOfBoundsException if {@code offset} or {@code length} are negative, or if {@code offset + length} is greater than {@code value.length}.
152      */
153     @Override
154     public void write(final char[] value, final int offset, final int length) {
155         if (value != null) {
156             IOUtils.checkFromIndexSize(value, offset, length);
157             builder.append(value, offset, length);
158         }
159     }
160 
161     /**
162      * Writes a String to the {@link StringBuilder}.
163      *
164      * @param value The value to write.
165      */
166     @Override
167     public void write(final String value) {
168         if (value != null) {
169             builder.append(value);
170         }
171     }
172 }