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 * https://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.StringWriter; 021import java.io.Writer; 022 023import org.apache.commons.io.IOUtils; 024 025/** 026 * {@link Writer} implementation that outputs to a {@link StringBuilder}. 027 * <p> 028 * <strong>NOTE:</strong> This implementation, as an alternative to {@link StringWriter}, provides an <em>un-synchronized</em> implementation for better 029 * performance for use in a single thread. For safe usage with multiple {@link Thread}s, a {@link StringWriter} should be used. 030 * </p> 031 * <h2>Deprecating Serialization</h2> 032 * <p> 033 * <em>Serialization is deprecated and will be removed in 3.0.</em> 034 * </p> 035 * 036 * @since 2.0 037 */ 038public class StringBuilderWriter extends Writer implements Serializable { 039 040 private static final long serialVersionUID = -146927496096066153L; 041 042 /** The append target. */ 043 private final StringBuilder builder; 044 045 /** 046 * Constructs a new {@link StringBuilder} instance with default capacity. 047 */ 048 public StringBuilderWriter() { 049 this.builder = new StringBuilder(); 050 } 051 052 /** 053 * Constructs a new {@link StringBuilder} instance with the specified capacity. 054 * 055 * @param capacity The initial capacity of the underlying {@link StringBuilder} 056 */ 057 public StringBuilderWriter(final int capacity) { 058 this.builder = new StringBuilder(capacity); 059 } 060 061 /** 062 * Constructs a new instance with the specified {@link StringBuilder}. 063 * 064 * <p>If {@code builder} is null a new instance with default capacity will be created.</p> 065 * 066 * @param builder The String builder. May be null. 067 */ 068 public StringBuilderWriter(final StringBuilder builder) { 069 this.builder = builder != null ? builder : new StringBuilder(); 070 } 071 072 /** 073 * Appends a single character to this Writer. 074 * 075 * @param value The character to append. 076 * @return This writer instance. 077 */ 078 @Override 079 public Writer append(final char value) { 080 builder.append(value); 081 return this; 082 } 083 084 /** 085 * Appends a character sequence to this Writer. 086 * 087 * @param value The character to append. 088 * @return This writer instance. 089 */ 090 @Override 091 public Writer append(final CharSequence value) { 092 builder.append(value); 093 return this; 094 } 095 096 /** 097 * Appends a portion of a character sequence to the {@link StringBuilder}. 098 * 099 * @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}