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.IOException; 020import java.io.Writer; 021import java.util.Objects; 022 023/** 024 * Writer implementation that writes the data to an {@link Appendable} 025 * Object. 026 * <p> 027 * For example, can be used with a {@link StringBuilder} 028 * or {@link StringBuffer}. 029 * </p> 030 * 031 * @since 2.7 032 * @see Appendable 033 * @param <T> The type of the {@link Appendable} wrapped by this AppendableWriter. 034 */ 035public class AppendableWriter <T extends Appendable> extends Writer { 036 037 private final T appendable; 038 039 /** 040 * Constructs a new instance with the specified appendable. 041 * 042 * @param appendable the appendable to write to 043 */ 044 public AppendableWriter(final T appendable) { 045 this.appendable = appendable; 046 } 047 048 /** 049 * Appends the specified character to the underlying appendable. 050 * 051 * @param c the character to append 052 * @return this writer 053 * @throws IOException upon error 054 */ 055 @Override 056 public Writer append(final char c) throws IOException { 057 appendable.append(c); 058 return this; 059 } 060 061 /** 062 * Appends the specified character sequence to the underlying appendable. 063 * 064 * @param csq the character sequence to append 065 * @return this writer 066 * @throws IOException upon error 067 */ 068 @Override 069 public Writer append(final CharSequence csq) throws IOException { 070 appendable.append(csq); 071 return this; 072 } 073 074 /** 075 * Appends a subsequence of the specified character sequence to the underlying appendable. 076 * 077 * @param csq the character sequence from which a subsequence will be appended 078 * @param start the index of the first character in the subsequence 079 * @param end the index of the character following the last character in the subsequence 080 * @return this writer 081 * @throws IOException upon error 082 */ 083 @Override 084 public Writer append(final CharSequence csq, final int start, final int end) throws IOException { 085 appendable.append(csq, start, end); 086 return this; 087 } 088 089 /** 090 * Closes the stream. This implementation does nothing. 091 * 092 * @throws IOException upon error 093 */ 094 @Override 095 public void close() throws IOException { 096 // noop 097 } 098 099 /** 100 * Flushes the stream. This implementation does nothing. 101 * 102 * @throws IOException upon error 103 */ 104 @Override 105 public void flush() throws IOException { 106 // noop 107 } 108 109 /** 110 * Gets the target appendable. 111 * 112 * @return the target appendable 113 */ 114 public T getAppendable() { 115 return appendable; 116 } 117 118 /** 119 * Writes a portion of an array of characters to the underlying appendable. 120 * 121 * @param cbuf an array with the characters to write 122 * @param off offset from which to start writing characters 123 * @param len number of characters to write 124 * @throws IOException upon error 125 */ 126 @Override 127 public void write(final char[] cbuf, final int off, final int len) throws IOException { 128 Objects.requireNonNull(cbuf, "cbuf"); 129 if (len < 0 || off + len > cbuf.length) { 130 throw new IndexOutOfBoundsException("Array Size=" + cbuf.length + 131 ", offset=" + off + ", length=" + len); 132 } 133 for (int i = 0; i < len; i++) { 134 appendable.append(cbuf[off + i]); 135 } 136 } 137 138 /** 139 * Writes a character to the underlying appendable. 140 * 141 * @param c the character to write 142 * @throws IOException upon error 143 */ 144 @Override 145 public void write(final int c) throws IOException { 146 appendable.append((char) c); 147 } 148 149 /** 150 * Writes a portion of a String to the underlying appendable. 151 * 152 * @param str a string 153 * @param off offset from which to start writing characters 154 * @param len number of characters to write 155 * @throws IOException upon error 156 */ 157 @Override 158 public void write(final String str, final int off, final int len) throws IOException { 159 // appendable.append will add "null" for a null String; add an explicit null check 160 Objects.requireNonNull(str, "str"); 161 appendable.append(str, off, off + len); 162 } 163 164}