]> WPIA git - gigi.git/blob - lib/jetty/org/eclipse/jetty/io/UncheckedPrintWriter.java
6898ddfb93f6bee534d9be5a04f05672507e1648
[gigi.git] / lib / jetty / org / eclipse / jetty / io / UncheckedPrintWriter.java
1 //
2 //  ========================================================================
3 //  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4 //  ------------------------------------------------------------------------
5 //  All rights reserved. This program and the accompanying materials
6 //  are made available under the terms of the Eclipse Public License v1.0
7 //  and Apache License v2.0 which accompanies this distribution.
8 //
9 //      The Eclipse Public License is available at
10 //      http://www.eclipse.org/legal/epl-v10.html
11 //
12 //      The Apache License v2.0 is available at
13 //      http://www.opensource.org/licenses/apache2.0.php
14 //
15 //  You may elect to redistribute this code under either of these licenses.
16 //  ========================================================================
17 //
18
19 package org.eclipse.jetty.io;
20
21 import java.io.BufferedWriter;
22 import java.io.IOException;
23 import java.io.InterruptedIOException;
24 import java.io.OutputStream;
25 import java.io.OutputStreamWriter;
26 import java.io.PrintWriter;
27 import java.io.Writer;
28
29 import org.eclipse.jetty.util.log.Log;
30 import org.eclipse.jetty.util.log.Logger;
31
32 /* ------------------------------------------------------------ */
33 /**
34  * A wrapper for the {@link java.io.PrintWriter} that re-throws the instances of
35  * {@link java.io.IOException} thrown by the underlying implementation of
36  * {@link java.io.Writer} as {@link RuntimeIOException} instances.
37  */
38 public class UncheckedPrintWriter extends PrintWriter
39 {
40     private static final Logger LOG = Log.getLogger(UncheckedPrintWriter.class);
41
42     private boolean _autoFlush = false;
43     private IOException _ioException;
44     private boolean _isClosed = false;
45
46     /* ------------------------------------------------------------ */
47     /**
48      * Line separator string. This is the value of the line.separator property
49      * at the moment that the stream was created.
50      */
51     private String _lineSeparator;
52
53     public UncheckedPrintWriter(Writer out)
54     {
55         this(out,false);
56     }
57
58     /* ------------------------------------------------------------ */
59     /**
60      * Create a new PrintWriter.
61      * 
62      * @param out
63      *            A character-output stream
64      * @param autoFlush
65      *            A boolean; if true, the println() methods will flush the
66      *            output buffer
67      */
68     public UncheckedPrintWriter(Writer out, boolean autoFlush)
69     {
70         super(out,autoFlush);
71         this._autoFlush = autoFlush;
72         this._lineSeparator = System.getProperty("line.separator");
73     }
74
75     /* ------------------------------------------------------------ */
76     /**
77      * Create a new PrintWriter, without automatic line flushing, from an
78      * existing OutputStream. This convenience constructor creates the necessary
79      * intermediate OutputStreamWriter, which will convert characters into bytes
80      * using the default character encoding.
81      * 
82      * @param out
83      *            An output stream
84      * 
85      * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
86      */
87     public UncheckedPrintWriter(OutputStream out)
88     {
89         this(out,false);
90     }
91
92     /* ------------------------------------------------------------ */
93     /**
94      * Create a new PrintWriter from an existing OutputStream. This convenience
95      * constructor creates the necessary intermediate OutputStreamWriter, which
96      * will convert characters into bytes using the default character encoding.
97      * 
98      * @param out
99      *            An output stream
100      * @param autoFlush
101      *            A boolean; if true, the println() methods will flush the
102      *            output buffer
103      * 
104      * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
105      */
106     public UncheckedPrintWriter(OutputStream out, boolean autoFlush)
107     {
108         this(new BufferedWriter(new OutputStreamWriter(out)),autoFlush);
109     }
110     
111     
112     /* ------------------------------------------------------------ */
113     public boolean checkError()
114     {
115         return _ioException!=null || super.checkError();
116     }
117     
118     /* ------------------------------------------------------------ */
119     private void setError(Throwable th)
120     {
121       
122         super.setError();
123
124         if (th instanceof IOException)
125             _ioException=(IOException)th;
126         else
127         {
128             _ioException=new IOException(String.valueOf(th));
129             _ioException.initCause(th);
130         }
131
132         LOG.debug(th);
133     }
134
135
136     @Override
137     protected void setError()
138     {
139         setError(new IOException());
140     }
141
142     /* ------------------------------------------------------------ */
143     /** Check to make sure that the stream has not been closed */
144     private void isOpen() throws IOException
145     {       
146         if (_ioException!=null)
147             throw new RuntimeIOException(_ioException); 
148         
149         if (_isClosed)
150             throw new IOException("Stream closed");
151     }
152
153     /* ------------------------------------------------------------ */
154     /**
155      * Flush the stream.
156      */
157     @Override
158     public void flush()
159     {
160         try
161         {
162             synchronized (lock)
163             {
164                 isOpen();
165                 out.flush();
166             }
167         }
168         catch (IOException ex)
169         {
170             setError(ex);
171         }
172     }
173
174     /* ------------------------------------------------------------ */
175     /**
176      * Close the stream.
177      */
178     @Override
179     public void close()
180     {
181         try
182         {
183             synchronized (lock)
184             {
185                 out.close();
186                 _isClosed = true;
187             }
188         }
189         catch (IOException ex)
190         {
191             setError(ex);
192         }
193     }
194
195     /* ------------------------------------------------------------ */
196     /**
197      * Write a single character.
198      * 
199      * @param c
200      *            int specifying a character to be written.
201      */
202     @Override
203     public void write(int c)
204     {
205         try
206         {
207             synchronized (lock)
208             {
209                 isOpen();
210                 out.write(c);
211             }
212         }
213         catch (InterruptedIOException x)
214         {
215             Thread.currentThread().interrupt();
216         }
217         catch (IOException ex)
218         {
219             setError(ex);
220         }
221     }
222
223     /* ------------------------------------------------------------ */
224     /**
225      * Write a portion of an array of characters.
226      * 
227      * @param buf
228      *            Array of characters
229      * @param off
230      *            Offset from which to start writing characters
231      * @param len
232      *            Number of characters to write
233      */
234     @Override
235     public void write(char buf[], int off, int len)
236     {
237         try
238         {
239             synchronized (lock)
240             {
241                 isOpen();
242                 out.write(buf,off,len);
243             }
244         }
245         catch (InterruptedIOException x)
246         {
247             Thread.currentThread().interrupt();
248         }
249         catch (IOException ex)
250         {
251             setError(ex);
252         }
253     }
254
255     /* ------------------------------------------------------------ */
256     /**
257      * Write an array of characters. This method cannot be inherited from the
258      * Writer class because it must suppress I/O exceptions.
259      * 
260      * @param buf
261      *            Array of characters to be written
262      */
263     @Override
264     public void write(char buf[])
265     { 
266         this.write(buf,0,buf.length);
267     }
268
269     /* ------------------------------------------------------------ */
270     /**
271      * Write a portion of a string.
272      * 
273      * @param s
274      *            A String
275      * @param off
276      *            Offset from which to start writing characters
277      * @param len
278      *            Number of characters to write
279      */
280     @Override
281     public void write(String s, int off, int len)
282     {
283         try
284         {
285             synchronized (lock)
286             {
287                 isOpen();
288                 out.write(s,off,len);
289             }
290         }
291         catch (InterruptedIOException x)
292         {
293             Thread.currentThread().interrupt();
294         }
295         catch (IOException ex)
296         {
297             setError(ex);
298         }
299     }
300
301     /* ------------------------------------------------------------ */
302     /**
303      * Write a string. This method cannot be inherited from the Writer class
304      * because it must suppress I/O exceptions.
305      * 
306      * @param s
307      *            String to be written
308      */
309     @Override
310     public void write(String s)
311     {
312         this.write(s,0,s.length());
313     }
314
315     private void newLine()
316     {
317         try
318         {
319             synchronized (lock)
320             {
321                 isOpen();
322                 out.write(_lineSeparator);
323                 if (_autoFlush)
324                     out.flush();
325             }
326         }
327         catch (InterruptedIOException x)
328         {
329             Thread.currentThread().interrupt();
330         }
331         catch (IOException ex)
332         {
333             setError(ex);
334         }
335     }
336
337     /* ------------------------------------------------------------ */
338     /**
339      * Print a boolean value. The string produced by <code>{@link
340      * java.lang.String#valueOf(boolean)}</code> is translated into bytes
341      * according to the platform's default character encoding, and these bytes
342      * are written in exactly the manner of the <code>{@link
343      * #write(int)}</code> method.
344      * 
345      * @param b
346      *            The <code>boolean</code> to be printed
347      */
348     @Override
349     public void print(boolean b)
350     {
351         this.write(b?"true":"false");
352     }
353
354     /* ------------------------------------------------------------ */
355     /**
356      * Print a character. The character is translated into one or more bytes
357      * according to the platform's default character encoding, and these bytes
358      * are written in exactly the manner of the <code>{@link
359      * #write(int)}</code> method.
360      * 
361      * @param c
362      *            The <code>char</code> to be printed
363      */
364     @Override
365     public void print(char c)
366     {
367         this.write(c);
368     }
369
370     /* ------------------------------------------------------------ */
371     /**
372      * Print an integer. The string produced by <code>{@link
373      * java.lang.String#valueOf(int)}</code> is translated into bytes according
374      * to the platform's default character encoding, and these bytes are written
375      * in exactly the manner of the <code>{@link #write(int)}</code> method.
376      * 
377      * @param i
378      *            The <code>int</code> to be printed
379      * @see java.lang.Integer#toString(int)
380      */
381     @Override
382     public void print(int i)
383     {
384         this.write(String.valueOf(i));
385     }
386
387     /* ------------------------------------------------------------ */
388     /**
389      * Print a long integer. The string produced by <code>{@link
390      * java.lang.String#valueOf(long)}</code> is translated into bytes according
391      * to the platform's default character encoding, and these bytes are written
392      * in exactly the manner of the <code>{@link #write(int)}</code> method.
393      * 
394      * @param l
395      *            The <code>long</code> to be printed
396      * @see java.lang.Long#toString(long)
397      */
398     @Override
399     public void print(long l)
400     {
401         this.write(String.valueOf(l));
402     }
403
404     /* ------------------------------------------------------------ */
405     /**
406      * Print a floating-point number. The string produced by <code>{@link
407      * java.lang.String#valueOf(float)}</code> is translated into bytes
408      * according to the platform's default character encoding, and these bytes
409      * are written in exactly the manner of the <code>{@link #write(int)}</code>
410      * method.
411      * 
412      * @param f
413      *            The <code>float</code> to be printed
414      * @see java.lang.Float#toString(float)
415      */
416     @Override
417     public void print(float f)
418     {
419         this.write(String.valueOf(f));
420     }
421
422     /* ------------------------------------------------------------ */
423     /**
424      * Print a double-precision floating-point number. The string produced by
425      * <code>{@link java.lang.String#valueOf(double)}</code> is translated into
426      * bytes according to the platform's default character encoding, and these
427      * bytes are written in exactly the manner of the <code>{@link
428      * #write(int)}</code> method.
429      * 
430      * @param d
431      *            The <code>double</code> to be printed
432      * @see java.lang.Double#toString(double)
433      */
434     @Override
435     public void print(double d)
436     {
437         this.write(String.valueOf(d));
438     }
439
440     /* ------------------------------------------------------------ */
441     /**
442      * Print an array of characters. The characters are converted into bytes
443      * according to the platform's default character encoding, and these bytes
444      * are written in exactly the manner of the <code>{@link #write(int)}</code>
445      * method.
446      * 
447      * @param s
448      *            The array of chars to be printed
449      * 
450      * @throws NullPointerException
451      *             If <code>s</code> is <code>null</code>
452      */
453     @Override
454     public void print(char s[])
455     {
456         this.write(s);
457     }
458
459     /* ------------------------------------------------------------ */
460     /**
461      * Print a string. If the argument is <code>null</code> then the string
462      * <code>"null"</code> is printed. Otherwise, the string's characters are
463      * converted into bytes according to the platform's default character
464      * encoding, and these bytes are written in exactly the manner of the
465      * <code>{@link #write(int)}</code> method.
466      * 
467      * @param s
468      *            The <code>String</code> to be printed
469      */
470     @Override
471     public void print(String s)
472     {
473         if (s == null)
474         {
475             s = "null";
476         }
477         this.write(s);
478     }
479
480     /* ------------------------------------------------------------ */
481     /**
482      * Print an object. The string produced by the <code>{@link
483      * java.lang.String#valueOf(Object)}</code> method is translated into bytes
484      * according to the platform's default character encoding, and these bytes
485      * are written in exactly the manner of the <code>{@link #write(int)}</code>
486      * method.
487      * 
488      * @param obj
489      *            The <code>Object</code> to be printed
490      * @see java.lang.Object#toString()
491      */
492     @Override
493     public void print(Object obj)
494     {
495         this.write(String.valueOf(obj));
496     }
497
498     /* ------------------------------------------------------------ */
499     /**
500      * Terminate the current line by writing the line separator string. The line
501      * separator string is defined by the system property
502      * <code>line.separator</code>, and is not necessarily a single newline
503      * character (<code>'\n'</code>).
504      */
505     @Override
506     public void println()
507     {
508         this.newLine();
509     }
510
511     /* ------------------------------------------------------------ */
512     /**
513      * Print a boolean value and then terminate the line. This method behaves as
514      * though it invokes <code>{@link #print(boolean)}</code> and then
515      * <code>{@link #println()}</code>.
516      * 
517      * @param x
518      *            the <code>boolean</code> value to be printed
519      */
520     @Override
521     public void println(boolean x)
522     {
523         synchronized (lock)
524         {
525             this.print(x);
526             this.println();
527         }
528     }
529
530     /* ------------------------------------------------------------ */
531     /**
532      * Print a character and then terminate the line. This method behaves as
533      * though it invokes <code>{@link #print(char)}</code> and then <code>{@link
534      * #println()}</code>.
535      * 
536      * @param x
537      *            the <code>char</code> value to be printed
538      */
539     @Override
540     public void println(char x)
541     {
542         synchronized (lock)
543         {
544             this.print(x);
545             this.println();
546         }
547     }
548
549     /* ------------------------------------------------------------ */
550     /**
551      * Print an integer and then terminate the line. This method behaves as
552      * though it invokes <code>{@link #print(int)}</code> and then <code>{@link
553      * #println()}</code>.
554      * 
555      * @param x
556      *            the <code>int</code> value to be printed
557      */
558     @Override
559     public void println(int x)
560     {
561         synchronized (lock)
562         {
563             this.print(x);
564             this.println();
565         }
566     }
567
568     /* ------------------------------------------------------------ */
569     /**
570      * Print a long integer and then terminate the line. This method behaves as
571      * though it invokes <code>{@link #print(long)}</code> and then
572      * <code>{@link #println()}</code>.
573      * 
574      * @param x
575      *            the <code>long</code> value to be printed
576      */
577     @Override
578     public void println(long x)
579     {
580         synchronized (lock)
581         {
582             this.print(x);
583             this.println();
584         }
585     }
586
587     /* ------------------------------------------------------------ */
588     /**
589      * Print a floating-point number and then terminate the line. This method
590      * behaves as though it invokes <code>{@link #print(float)}</code> and then
591      * <code>{@link #println()}</code>.
592      * 
593      * @param x
594      *            the <code>float</code> value to be printed
595      */
596     @Override
597     public void println(float x)
598     {
599         synchronized (lock)
600         {
601             this.print(x);
602             this.println();
603         }
604     }
605
606     /* ------------------------------------------------------------ */
607     /**
608      * Print a double-precision floating-point number and then terminate the
609      * line. This method behaves as though it invokes <code>{@link
610      * #print(double)}</code> and then <code>{@link #println()}</code>.
611      * 
612      * @param x
613      *            the <code>double</code> value to be printed
614      */
615     /* ------------------------------------------------------------ */
616     @Override
617     public void println(double x)
618     {
619         synchronized (lock)
620         {
621             this.print(x);
622             this.println();
623         }
624     }
625
626     /* ------------------------------------------------------------ */
627     /**
628      * Print an array of characters and then terminate the line. This method
629      * behaves as though it invokes <code>{@link #print(char[])}</code> and then
630      * <code>{@link #println()}</code>.
631      * 
632      * @param x
633      *            the array of <code>char</code> values to be printed
634      */
635     @Override
636     public void println(char x[])
637     {
638         synchronized (lock)
639         {
640             this.print(x);
641             this.println();
642         }
643     }
644
645     /* ------------------------------------------------------------ */
646     /**
647      * Print a String and then terminate the line. This method behaves as though
648      * it invokes <code>{@link #print(String)}</code> and then
649      * <code>{@link #println()}</code>.
650      * 
651      * @param x
652      *            the <code>String</code> value to be printed
653      */
654     @Override
655     public void println(String x)
656     {
657         synchronized (lock)
658         {
659             this.print(x);
660             this.println();
661         }
662     }
663
664     /* ------------------------------------------------------------ */
665     /**
666      * Print an Object and then terminate the line. This method behaves as
667      * though it invokes <code>{@link #print(Object)}</code> and then
668      * <code>{@link #println()}</code>.
669      * 
670      * @param x
671      *            the <code>Object</code> value to be printed
672      */
673     @Override
674     public void println(Object x)
675     {
676         synchronized (lock)
677         {
678             this.print(x);
679             this.println();
680         }
681     }
682 }