1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.velocity.tools.view.jsp.jspimpl;
19
20 import java.io.IOException;
21 import java.io.Writer;
22
23 import javax.servlet.jsp.JspWriter;
24
25 /**
26 * Copied and modified from Tomcat 6.0.x source.
27 *
28 * Write text to a character-output stream, buffering characters so as
29 * to provide for the efficient writing of single characters, arrays,
30 * and strings.
31 *
32 * Provide support for discarding for the output that has been
33 * buffered.
34 *
35 * This needs revisiting when the buffering problems in the JSP spec
36 * are fixed -akv
37 *
38 * @author Anil K. Vijendran
39 */
40 public class JspWriterImpl extends JspWriter {
41
42 private Writer out;
43
44 /**
45 * Create a buffered character-output stream that uses a default-sized
46 * output buffer.
47 *
48 * @param out The writer.
49 */
50 public JspWriterImpl(Writer out) {
51 super(0, true);
52 this.out = out;
53 }
54
55 /**
56 * Discard the output buffer.
57 */
58 public final void clear() throws IOException {
59 throw new IllegalStateException("Cannot clear after an unbuffered output");
60 }
61
62 public void clearBuffer() throws IOException {
63 throw new IllegalStateException("Cannot clear after an unbuffered output");
64 }
65
66 /**
67 * Flush the stream.
68 *
69 */
70 public void flush() throws IOException {
71 out.flush();
72 }
73
74 /**
75 * Close the stream.
76 *
77 */
78 public void close() throws IOException {
79 out.close();
80 }
81
82 /**
83 * @return the number of bytes unused in the buffer
84 */
85 public int getRemaining() {
86 return 0;
87 }
88
89
90 /**
91 * Write a single character.
92 */
93 public void write(int c) throws IOException {
94 out.write(c);
95 }
96
97 /**
98 * Write a portion of an array of characters.
99 *
100 * <p> Ordinarily this method stores characters from the given array into
101 * this stream's buffer, flushing the buffer to the underlying stream as
102 * needed. If the requested length is at least as large as the buffer,
103 * however, then this method will flush the buffer and write the characters
104 * directly to the underlying stream. Thus redundant
105 * <code>DiscardableBufferedWriter</code>s will not copy data unnecessarily.
106 *
107 * @param cbuf A character array
108 * @param off Offset from which to start reading characters
109 * @param len Number of characters to write
110 */
111 public void write(char cbuf[], int off, int len)
112 throws IOException
113 {
114 out.write(cbuf, off, len);
115 }
116
117 /**
118 * Write an array of characters. This method cannot be inherited from the
119 * Writer class because it must suppress I/O exceptions.
120 */
121 public void write(char buf[]) throws IOException {
122 write(buf, 0, buf.length);
123 }
124
125 /**
126 * Write a portion of a String.
127 *
128 * @param s String to be written
129 * @param off Offset from which to start reading characters
130 * @param len Number of characters to be written
131 */
132 public void write(String s, int off, int len) throws IOException {
133 out.write(s, off, len);
134 }
135
136 /**
137 * Write a string. This method cannot be inherited from the Writer class
138 * because it must suppress I/O exceptions.
139 */
140 public void write(String s) throws IOException {
141 // Simple fix for Bugzilla 35410
142 // Calling the other write function so as to init the buffer anyways
143 if(s == null) {
144 write(s, 0, 0);
145 } else {
146 write(s, 0, s.length());
147 }
148 }
149
150
151 static String lineSeparator = System.getProperty("line.separator");
152
153 /**
154 * Write a line separator. The line separator string is defined by the
155 * system property <tt>line.separator</tt>, and is not necessarily a single
156 * newline ('\n') character.
157 *
158 * @exception IOException If an I/O error occurs
159 */
160
161 public void newLine() throws IOException {
162 write(lineSeparator);
163 }
164
165
166 /* Methods that do not terminate lines */
167
168 /**
169 * Print a boolean value. The string produced by <code>{@link
170 * java.lang.String#valueOf(boolean)}</code> is translated into bytes
171 * according to the platform's default character encoding, and these bytes
172 * are written in exactly the manner of the <code>{@link
173 * #write(int)}</code> method.
174 *
175 * @param b The <code>boolean</code> to be printed
176 */
177 public void print(boolean b) throws IOException {
178 write(b ? "true" : "false");
179 }
180
181 /**
182 * Print a character. The character is translated into one or more bytes
183 * according to the platform's default character encoding, and these bytes
184 * are written in exactly the manner of the <code>{@link
185 * #write(int)}</code> method.
186 *
187 * @param c The <code>char</code> to be printed
188 */
189 public void print(char c) throws IOException {
190 write(String.valueOf(c));
191 }
192
193 /**
194 * Print an integer. The string produced by <code>{@link
195 * java.lang.String#valueOf(int)}</code> is translated into bytes according
196 * to the platform's default character encoding, and these bytes are
197 * written in exactly the manner of the <code>{@link #write(int)}</code>
198 * method.
199 *
200 * @param i The <code>int</code> to be printed
201 */
202 public void print(int i) throws IOException {
203 write(String.valueOf(i));
204 }
205
206 /**
207 * Print a long integer. The string produced by <code>{@link
208 * java.lang.String#valueOf(long)}</code> is translated into bytes
209 * according to the platform's default character encoding, and these bytes
210 * are written in exactly the manner of the <code>{@link #write(int)}</code>
211 * method.
212 *
213 * @param l The <code>long</code> to be printed
214 */
215 public void print(long l) throws IOException {
216 write(String.valueOf(l));
217 }
218
219 /**
220 * Print a floating-point number. The string produced by <code>{@link
221 * java.lang.String#valueOf(float)}</code> is translated into bytes
222 * according to the platform's default character encoding, and these bytes
223 * are written in exactly the manner of the <code>{@link #write(int)}</code>
224 * method.
225 *
226 * @param f The <code>float</code> to be printed
227 */
228 public void print(float f) throws IOException {
229 write(String.valueOf(f));
230 }
231
232 /**
233 * Print a double-precision floating-point number. The string produced by
234 * <code>{@link java.lang.String#valueOf(double)}</code> is translated into
235 * bytes according to the platform's default character encoding, and these
236 * bytes are written in exactly the manner of the <code>{@link
237 * #write(int)}</code> method.
238 *
239 * @param d The <code>double</code> to be printed
240 */
241 public void print(double d) throws IOException {
242 write(String.valueOf(d));
243 }
244
245 /**
246 * Print an array of characters. The characters are converted into bytes
247 * according to the platform's default character encoding, and these bytes
248 * are written in exactly the manner of the <code>{@link #write(int)}</code>
249 * method.
250 *
251 * @param s The array of chars to be printed
252 *
253 * @throws NullPointerException If <code>s</code> is <code>null</code>
254 */
255 public void print(char s[]) throws IOException {
256 write(s);
257 }
258
259 /**
260 * Print a string. If the argument is <code>null</code> then the string
261 * <code>"null"</code> is printed. Otherwise, the string's characters are
262 * converted into bytes according to the platform's default character
263 * encoding, and these bytes are written in exactly the manner of the
264 * <code>{@link #write(int)}</code> method.
265 *
266 * @param s The <code>String</code> to be printed
267 */
268 public void print(String s) throws IOException {
269 if (s == null) {
270 s = "null";
271 }
272 write(s);
273 }
274
275 /**
276 * Print an object. The string produced by the <code>{@link
277 * java.lang.String#valueOf(Object)}</code> method is translated into bytes
278 * according to the platform's default character encoding, and these bytes
279 * are written in exactly the manner of the <code>{@link #write(int)}</code>
280 * method.
281 *
282 * @param obj The <code>Object</code> to be printed
283 */
284 public void print(Object obj) throws IOException {
285 write(String.valueOf(obj));
286 }
287
288 /* Methods that do terminate lines */
289
290 /**
291 * Terminate the current line by writing the line separator string. The
292 * line separator string is defined by the system property
293 * <code>line.separator</code>, and is not necessarily a single newline
294 * character (<code>'\n'</code>).
295 *
296 * Need to change this from PrintWriter because the default
297 * println() writes to the sink directly instead of through the
298 * write method...
299 */
300 public void println() throws IOException {
301 newLine();
302 }
303
304 /**
305 * Print a boolean value and then terminate the line. This method behaves
306 * as though it invokes <code>{@link #print(boolean)}</code> and then
307 * <code>{@link #println()}</code>.
308 */
309 public void println(boolean x) throws IOException {
310 print(x);
311 println();
312 }
313
314 /**
315 * Print a character and then terminate the line. This method behaves as
316 * though it invokes <code>{@link #print(char)}</code> and then <code>{@link
317 * #println()}</code>.
318 */
319 public void println(char x) throws IOException {
320 print(x);
321 println();
322 }
323
324 /**
325 * Print an integer and then terminate the line. This method behaves as
326 * though it invokes <code>{@link #print(int)}</code> and then <code>{@link
327 * #println()}</code>.
328 */
329 public void println(int x) throws IOException {
330 print(x);
331 println();
332 }
333
334 /**
335 * Print a long integer and then terminate the line. This method behaves
336 * as though it invokes <code>{@link #print(long)}</code> and then
337 * <code>{@link #println()}</code>.
338 */
339 public void println(long x) throws IOException {
340 print(x);
341 println();
342 }
343
344 /**
345 * Print a floating-point number and then terminate the line. This method
346 * behaves as though it invokes <code>{@link #print(float)}</code> and then
347 * <code>{@link #println()}</code>.
348 */
349 public void println(float x) throws IOException {
350 print(x);
351 println();
352 }
353
354 /**
355 * Print a double-precision floating-point number and then terminate the
356 * line. This method behaves as though it invokes <code>{@link
357 * #print(double)}</code> and then <code>{@link #println()}</code>.
358 */
359 public void println(double x) throws IOException {
360 print(x);
361 println();
362 }
363
364 /**
365 * Print an array of characters and then terminate the line. This method
366 * behaves as though it invokes <code>{@link #print(char[])}</code> and then
367 * <code>{@link #println()}</code>.
368 */
369 public void println(char x[]) throws IOException {
370 print(x);
371 println();
372 }
373
374 /**
375 * Print a String and then terminate the line. This method behaves as
376 * though it invokes <code>{@link #print(String)}</code> and then
377 * <code>{@link #println()}</code>.
378 */
379 public void println(String x) throws IOException {
380 print(x);
381 println();
382 }
383
384 /**
385 * Print an Object and then terminate the line. This method behaves as
386 * though it invokes <code>{@link #print(Object)}</code> and then
387 * <code>{@link #println()}</code>.
388 */
389 public void println(Object x) throws IOException {
390 print(x);
391 println();
392 }
393
394 }