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 javax.servlet.jsp;
019:
020: import java.io.IOException;
021:
022: /**
023: * <p>
024: * The actions and template data in a JSP page is written using the
025: * JspWriter object that is referenced by the implicit variable out which
026: * is initialized automatically using methods in the PageContext object.
027: *<p>
028: * This abstract class emulates some of the functionality found in the
029: * java.io.BufferedWriter and java.io.PrintWriter classes,
030: * however it differs in that it throws java.io.IOException from the print
031: * methods while PrintWriter does not.
032: * <p><B>Buffering</B>
033: * <p>
034: * The initial JspWriter object is associated with the PrintWriter object
035: * of the ServletResponse in a way that depends on whether the page is or
036: * is not buffered. If the page is not buffered, output written to this
037: * JspWriter object will be written through to the PrintWriter directly,
038: * which will be created if necessary by invoking the getWriter() method
039: * on the response object. But if the page is buffered, the PrintWriter
040: * object will not be created until the buffer is flushed and
041: * operations like setContentType() are legal. Since this flexibility
042: * simplifies programming substantially, buffering is the default for JSP
043: * pages.
044: * <p>
045: * Buffering raises the issue of what to do when the buffer is
046: * exceeded. Two approaches can be taken:
047: * <ul>
048: * <li>
049: * Exceeding the buffer is not a fatal error; when the buffer is
050: * exceeded, just flush the output.
051: * <li>
052: * Exceeding the buffer is a fatal error; when the buffer is exceeded,
053: * raise an exception.
054: * </ul>
055: * <p>
056: * Both approaches are valid, and thus both are supported in the JSP
057: * technology. The behavior of a page is controlled by the autoFlush
058: * attribute, which defaults to true. In general, JSP pages that need to
059: * be sure that correct and complete data has been sent to their client
060: * may want to set autoFlush to false, with a typical case being that
061: * where the client is an application itself. On the other hand, JSP
062: * pages that send data that is meaningful even when partially
063: * constructed may want to set autoFlush to true; such as when the
064: * data is sent for immediate display through a browser. Each application
065: * will need to consider their specific needs.
066: * <p>
067: * An alternative considered was to make the buffer size unbounded; but,
068: * this had the disadvantage that runaway computations would consume an
069: * unbounded amount of resources.
070: * <p>
071: * The "out" implicit variable of a JSP implementation class is of this type.
072: * If the page directive selects autoflush="true" then all the I/O operations
073: * on this class shall automatically flush the contents of the buffer if an
074: * overflow condition would result if the current operation were performed
075: * without a flush. If autoflush="false" then all the I/O operations on this
076: * class shall throw an IOException if performing the current operation would
077: * result in a buffer overflow condition.
078: *
079: * @see java.io.Writer
080: * @see java.io.BufferedWriter
081: * @see java.io.PrintWriter
082: */
083:
084: abstract public class JspWriter extends java.io.Writer {
085:
086: /**
087: * Constant indicating that the Writer is not buffering output.
088: */
089:
090: public static final int NO_BUFFER = 0;
091:
092: /**
093: * Constant indicating that the Writer is buffered and is using the
094: * implementation default buffer size.
095: */
096:
097: public static final int DEFAULT_BUFFER = -1;
098:
099: /**
100: * Constant indicating that the Writer is buffered and is unbounded; this
101: * is used in BodyContent.
102: */
103:
104: public static final int UNBOUNDED_BUFFER = -2;
105:
106: /**
107: * Protected constructor.
108: *
109: * @param bufferSize the size of the buffer to be used by the JspWriter
110: * @param autoFlush whether the JspWriter should be autoflushing
111: */
112:
113: protected JspWriter(int bufferSize, boolean autoFlush) {
114: this .bufferSize = bufferSize;
115: this .autoFlush = autoFlush;
116: }
117:
118: /**
119: * Write a line separator. The line separator string is defined by the
120: * system property <tt>line.separator</tt>, and is not necessarily a single
121: * newline ('\n') character.
122: *
123: * @exception IOException If an I/O error occurs
124: */
125:
126: abstract public void newLine() throws IOException;
127:
128: /**
129: * Print a boolean value. The string produced by <code>{@link
130: * java.lang.String#valueOf(boolean)}</code> is written to the
131: * JspWriter's buffer or, if no buffer is used, directly to the
132: * underlying writer.
133: *
134: * @param b The <code>boolean</code> to be printed
135: * @throws java.io.IOException If an error occured while writing
136: */
137:
138: abstract public void print(boolean b) throws IOException;
139:
140: /**
141: * Print a character. The character is written to the
142: * JspWriter's buffer or, if no buffer is used, directly to the
143: * underlying writer.
144: *
145: * @param c The <code>char</code> to be printed
146: * @throws java.io.IOException If an error occured while writing
147: */
148:
149: abstract public void print(char c) throws IOException;
150:
151: /**
152: * Print an integer. The string produced by <code>{@link
153: * java.lang.String#valueOf(int)}</code> is written to the
154: * JspWriter's buffer or, if no buffer is used, directly to the
155: * underlying writer.
156: *
157: * @param i The <code>int</code> to be printed
158: * @see java.lang.Integer#toString(int)
159: * @throws java.io.IOException If an error occured while writing
160: */
161:
162: abstract public void print(int i) throws IOException;
163:
164: /**
165: * Print a long integer. The string produced by <code>{@link
166: * java.lang.String#valueOf(long)}</code> is written to the
167: * JspWriter's buffer or, if no buffer is used, directly to the
168: * underlying writer.
169: *
170: * @param l The <code>long</code> to be printed
171: * @see java.lang.Long#toString(long)
172: * @throws java.io.IOException If an error occured while writing
173: */
174:
175: abstract public void print(long l) throws IOException;
176:
177: /**
178: * Print a floating-point number. The string produced by <code>{@link
179: * java.lang.String#valueOf(float)}</code> is written to the
180: * JspWriter's buffer or, if no buffer is used, directly to the
181: * underlying writer.
182: *
183: * @param f The <code>float</code> to be printed
184: * @see java.lang.Float#toString(float)
185: * @throws java.io.IOException If an error occured while writing
186: */
187:
188: abstract public void print(float f) throws IOException;
189:
190: /**
191: * Print a double-precision floating-point number. The string produced by
192: * <code>{@link java.lang.String#valueOf(double)}</code> is written to
193: * the JspWriter's buffer or, if no buffer is used, directly to the
194: * underlying writer.
195: *
196: * @param d The <code>double</code> to be printed
197: * @see java.lang.Double#toString(double)
198: * @throws java.io.IOException If an error occured while writing
199: */
200:
201: abstract public void print(double d) throws IOException;
202:
203: /**
204: * Print an array of characters. The characters are written to the
205: * JspWriter's buffer or, if no buffer is used, directly to the
206: * underlying writer.
207: *
208: * @param s The array of chars to be printed
209: *
210: * @throws NullPointerException If <code>s</code> is <code>null</code>
211: * @throws java.io.IOException If an error occured while writing
212: */
213:
214: abstract public void print(char s[]) throws IOException;
215:
216: /**
217: * Print a string. If the argument is <code>null</code> then the string
218: * <code>"null"</code> is printed. Otherwise, the string's characters are
219: * written to the JspWriter's buffer or, if no buffer is used, directly
220: * to the underlying writer.
221: *
222: * @param s The <code>String</code> to be printed
223: * @throws java.io.IOException If an error occured while writing
224: */
225:
226: abstract public void print(String s) throws IOException;
227:
228: /**
229: * Print an object. The string produced by the <code>{@link
230: * java.lang.String#valueOf(Object)}</code> method is written to the
231: * JspWriter's buffer or, if no buffer is used, directly to the
232: * underlying writer.
233: *
234: * @param obj The <code>Object</code> to be printed
235: * @see java.lang.Object#toString()
236: * @throws java.io.IOException If an error occured while writing
237: */
238:
239: abstract public void print(Object obj) throws IOException;
240:
241: /**
242: * Terminate the current line by writing the line separator string. The
243: * line separator string is defined by the system property
244: * <code>line.separator</code>, and is not necessarily a single newline
245: * character (<code>'\n'</code>).
246: * @throws java.io.IOException If an error occured while writing
247: */
248:
249: abstract public void println() throws IOException;
250:
251: /**
252: * Print a boolean value and then terminate the line. This method behaves
253: * as though it invokes <code>{@link #print(boolean)}</code> and then
254: * <code>{@link #println()}</code>.
255: *
256: * @param x the boolean to write
257: * @throws java.io.IOException If an error occured while writing
258: */
259:
260: abstract public void println(boolean x) throws IOException;
261:
262: /**
263: * Print a character and then terminate the line. This method behaves as
264: * though it invokes <code>{@link #print(char)}</code> and then <code>{@link
265: * #println()}</code>.
266: *
267: * @param x the char to write
268: * @throws java.io.IOException If an error occured while writing
269: */
270:
271: abstract public void println(char x) throws IOException;
272:
273: /**
274: * Print an integer and then terminate the line. This method behaves as
275: * though it invokes <code>{@link #print(int)}</code> and then <code>{@link
276: * #println()}</code>.
277: *
278: * @param x the int to write
279: * @throws java.io.IOException If an error occured while writing
280: */
281:
282: abstract public void println(int x) throws IOException;
283:
284: /**
285: * Print a long integer and then terminate the line. This method behaves
286: * as though it invokes <code>{@link #print(long)}</code> and then
287: * <code>{@link #println()}</code>.
288: *
289: * @param x the long to write
290: * @throws java.io.IOException If an error occured while writing
291: */
292:
293: abstract public void println(long x) throws IOException;
294:
295: /**
296: * Print a floating-point number and then terminate the line. This method
297: * behaves as though it invokes <code>{@link #print(float)}</code> and then
298: * <code>{@link #println()}</code>.
299: *
300: * @param x the float to write
301: * @throws java.io.IOException If an error occured while writing
302: */
303:
304: abstract public void println(float x) throws IOException;
305:
306: /**
307: * Print a double-precision floating-point number and then terminate the
308: * line. This method behaves as though it invokes <code>{@link
309: * #print(double)}</code> and then <code>{@link #println()}</code>.
310: *
311: * @param x the double to write
312: * @throws java.io.IOException If an error occured while writing
313: */
314:
315: abstract public void println(double x) throws IOException;
316:
317: /**
318: * Print an array of characters and then terminate the line. This method
319: * behaves as though it invokes <code>print(char[])</code> and then
320: * <code>println()</code>.
321: *
322: * @param x the char[] to write
323: * @throws java.io.IOException If an error occured while writing
324: */
325:
326: abstract public void println(char x[]) throws IOException;
327:
328: /**
329: * Print a String and then terminate the line. This method behaves as
330: * though it invokes <code>{@link #print(String)}</code> and then
331: * <code>{@link #println()}</code>.
332: *
333: * @param x the String to write
334: * @throws java.io.IOException If an error occured while writing
335: */
336:
337: abstract public void println(String x) throws IOException;
338:
339: /**
340: * Print an Object and then terminate the line. This method behaves as
341: * though it invokes <code>{@link #print(Object)}</code> and then
342: * <code>{@link #println()}</code>.
343: *
344: * @param x the Object to write
345: * @throws java.io.IOException If an error occured while writing
346: */
347:
348: abstract public void println(Object x) throws IOException;
349:
350: /**
351: * Clear the contents of the buffer. If the buffer has been already
352: * been flushed then the clear operation shall throw an IOException
353: * to signal the fact that some data has already been irrevocably
354: * written to the client response stream.
355: *
356: * @throws IOException If an I/O error occurs
357: */
358:
359: abstract public void clear() throws IOException;
360:
361: /**
362: * Clears the current contents of the buffer. Unlike clear(), this
363: * method will not throw an IOException if the buffer has already been
364: * flushed. It merely clears the current content of the buffer and
365: * returns.
366: *
367: * @throws IOException If an I/O error occurs
368: */
369:
370: abstract public void clearBuffer() throws IOException;
371:
372: /**
373: * Flush the stream. If the stream has saved any characters from the
374: * various write() methods in a buffer, write them immediately to their
375: * intended destination. Then, if that destination is another character or
376: * byte stream, flush it. Thus one flush() invocation will flush all the
377: * buffers in a chain of Writers and OutputStreams.
378: * <p>
379: * The method may be invoked indirectly if the buffer size is exceeded.
380: * <p>
381: * Once a stream has been closed,
382: * further write() or flush() invocations will cause an IOException to be
383: * thrown.
384: *
385: * @exception IOException If an I/O error occurs
386: */
387:
388: abstract public void flush() throws IOException;
389:
390: /**
391: * Close the stream, flushing it first.
392: * <p>
393: * This method needs not be invoked explicitly for the initial JspWriter
394: * as the code generated by the JSP container will automatically
395: * include a call to close().
396: * <p>
397: * Closing a previously-closed stream, unlike flush(), has no effect.
398: *
399: * @exception IOException If an I/O error occurs
400: */
401:
402: abstract public void close() throws IOException;
403:
404: /**
405: * This method returns the size of the buffer used by the JspWriter.
406: *
407: * @return the size of the buffer in bytes, or 0 is unbuffered.
408: */
409:
410: public int getBufferSize() {
411: return bufferSize;
412: }
413:
414: /**
415: * This method returns the number of unused bytes in the buffer.
416: *
417: * @return the number of bytes unused in the buffer
418: */
419:
420: abstract public int getRemaining();
421:
422: /**
423: * This method indicates whether the JspWriter is autoFlushing.
424: *
425: * @return if this JspWriter is auto flushing or throwing IOExceptions
426: * on buffer overflow conditions
427: */
428:
429: public boolean isAutoFlush() {
430: return autoFlush;
431: }
432:
433: /*
434: * fields
435: */
436:
437: /**
438: * The size of the buffer used by the JspWriter.
439: */
440: protected int bufferSize;
441:
442: /**
443: * Whether the JspWriter is autoflushing.
444: */
445: protected boolean autoFlush;
446: }
|