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:
018: package java.io;
019:
020: /**
021: * Writer is an Abstract class for writing Character Streams. Subclasses of
022: * writer must implement the methods <code>write(char[], int, int)</code>,
023: * <code>close()</code> and <code>flush()</code>.
024: *
025: * @see Reader
026: */
027: public abstract class Writer implements Appendable, Closeable,
028: Flushable {
029:
030: static final String TOKEN_NULL = "null"; //$NON-NLS-1$
031:
032: /**
033: * The object used to synchronize access to the writer.
034: */
035: protected Object lock;
036:
037: /**
038: * Constructs a new character stream Writer using <code>this</code> as the
039: * Object to synchronize critical regions around.
040: */
041: protected Writer() {
042: super ();
043: lock = this ;
044: }
045:
046: /**
047: * Constructs a new character stream Writer using <code>lock</code> as the
048: * Object to synchronize critical regions around.
049: *
050: * @param lock
051: * the Object to synchronize critical regions around.
052: */
053: protected Writer(Object lock) {
054: if (lock == null) {
055: throw new NullPointerException();
056: }
057: this .lock = lock;
058: }
059:
060: /**
061: * Close this Writer. This must be implemented by any concrete subclasses.
062: * The implementation should free any resources associated with the Writer.
063: *
064: * @throws IOException
065: * If an error occurs attempting to close this Writer.
066: */
067: public abstract void close() throws IOException;
068:
069: /**
070: * Flush this Writer. This must be implemented by any concrete subclasses.
071: * The implementation should ensure all buffered characters are written out.
072: *
073: * @throws IOException
074: * If an error occurs attempting to flush this Writer.
075: */
076: public abstract void flush() throws IOException;
077:
078: /**
079: * Writes the entire character buffer <code>buf</code> to this Writer.
080: *
081: * @param buf
082: * the non-null array containing characters to write.
083: *
084: * @throws IOException
085: * If this Writer has already been closed or some other
086: * IOException occurs.
087: */
088: public void write(char buf[]) throws IOException {
089: write(buf, 0, buf.length);
090: }
091:
092: /**
093: * Writes <code>count</code> characters starting at <code>offset<code> in
094: * <code>buf</code> to this Writer. This abstract method must be implemented
095: * by concrete subclasses.
096: *
097: * @param buf the non-null array containing characters to write.
098: * @param offset offset in buf to retrieve characters
099: * @param count maximum number of characters to write
100: *
101: * @throws IOException If this Writer has already been closed or some other IOException occurs.
102: * @throws ArrayIndexOutOfBoundsException If offset or count are outside of bounds.
103: */
104: public abstract void write(char buf[], int offset, int count)
105: throws IOException;
106:
107: /**
108: * Writes the specified character <code>oneChar</code> to this Writer.
109: * This implementation writes the low order two bytes of
110: * <code>oneChar</code> to the Stream.
111: *
112: * @param oneChar
113: * The character to write
114: *
115: * @throws IOException
116: * If this Writer has already been closed or some other
117: * IOException occurs.
118: */
119: public void write(int oneChar) throws IOException {
120: synchronized (lock) {
121: char oneCharArray[] = new char[1];
122: oneCharArray[0] = (char) oneChar;
123: write(oneCharArray);
124: }
125: }
126:
127: /**
128: * Writes the characters from the String <code>str</code> to this Writer.
129: *
130: * @param str
131: * the non-null String containing the characters to write.
132: *
133: * @throws IOException
134: * If this Writer has already been closed or some other
135: * IOException occurs.
136: */
137: public void write(String str) throws IOException {
138: char buf[] = new char[str.length()];
139: str.getChars(0, buf.length, buf, 0);
140: synchronized (lock) {
141: write(buf);
142: }
143: }
144:
145: /**
146: * Writes <code>count</code> number of characters starting at
147: * <code>offset</code> from the String <code>str</code> to this Writer.
148: *
149: * @param str
150: * the non-null String containing the characters to write.
151: * @param offset
152: * the starting point to retrieve characters.
153: * @param count
154: * the number of characters to retrieve and write.
155: *
156: * @throws IOException
157: * If this Writer has already been closed or some other
158: * IOException occurs.
159: * @throws ArrayIndexOutOfBoundsException
160: * If offset or count are outside of bounds.
161: */
162: public void write(String str, int offset, int count)
163: throws IOException {
164: if (count < 0) { // other cases tested by getChars()
165: throw new StringIndexOutOfBoundsException();
166: }
167: char buf[] = new char[count];
168: str.getChars(offset, offset + count, buf, 0);
169:
170: synchronized (lock) {
171: write(buf);
172: }
173: }
174:
175: /**
176: * Append a char <code>c</code>to the Writer. The Writer.append(<code>c</code>)
177: * works the same as Writer.write(<code>c</code>).
178: *
179: * @param c
180: * The character appended to the Writer.
181: * @return The Writer.
182: * @throws IOException
183: * If any IOException raises during the procedure.
184: */
185: public Writer append(char c) throws IOException {
186: write(c);
187: return this ;
188: }
189:
190: /**
191: * Append a CharSequence <code>csq</code> to the Writer. The
192: * Writer.append(<code>csq</code>) works the same way as Writer.write(<code>csq</code>.toString()).
193: * If <code>csq</code> is null, then "null" will be substituted for
194: * <code>csq</code>.
195: *
196: * @param csq
197: * The CharSequence appended to the Writer.
198: * @return The Writer.
199: * @throws IOException
200: * If any IOException raises during the procedure.
201: */
202: public Writer append(CharSequence csq) throws IOException {
203: if (null == csq) {
204: write(TOKEN_NULL);
205: } else {
206: write(csq.toString());
207: }
208: return this ;
209: }
210:
211: /**
212: * Append a subsequence of a CharSequence <code>csq</code> to the Writer.
213: * The first char and the last char of the subsequnce is specified by the
214: * parameter <code>start</code> and <code>end</code>. The
215: * Writer.append(<code>csq</code>) works the same way as Writer.write (<code>csq</code>csq.subSequence(<code>start</code>,<code>end</code>).toString).
216: * If <code>csq</code> is null, then "null" will be substituted for
217: * <code>csq</code>.
218: *
219: * @param csq
220: * The CharSequence appended to the Writaer.
221: * @param start
222: * The index of the first char in the CharSequence appended to
223: * the Writer.
224: * @param end
225: * The index of the char after the last one in the CharSequence
226: * appended to the Writer.
227: * @return The Writer.
228: * @throws IndexOutOfBoundsException
229: * If start is less than end, end is greater than the length of
230: * the CharSequence, or start or end is negative.
231: * @throws IOException
232: * If any IOException raises during the procedure.
233: */
234: public Writer append(CharSequence csq, int start, int end)
235: throws IOException {
236: if (null == csq) {
237: write(TOKEN_NULL.substring(start, end));
238: } else {
239: write(csq.subSequence(start, end).toString());
240: }
241: return this;
242: }
243: }
|