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