1 /*
   2  * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.io;
  27 
  28 import java.util.Objects;
  29 import java.util.Formatter;
  30 import java.util.Locale;
  31 import java.nio.charset.Charset;
  32 import java.nio.charset.IllegalCharsetNameException;
  33 import java.nio.charset.UnsupportedCharsetException;
  34 
  35 /**
  36  * Prints formatted representations of objects to a text-output stream.  This
  37  * class implements all of the <tt>print</tt> methods found in {@link
  38  * PrintStream}.  It does not contain methods for writing raw bytes, for which
  39  * a program should use unencoded byte streams.
  40  *
  41  * <p> Unlike the {@link PrintStream} class, if automatic flushing is enabled
  42  * it will be done only when one of the <tt>println</tt>, <tt>printf</tt>, or
  43  * <tt>format</tt> methods is invoked, rather than whenever a newline character
  44  * happens to be output.  These methods use the platform's own notion of line
  45  * separator rather than the newline character.
  46  *
  47  * <p> Methods in this class never throw I/O exceptions, although some of its
  48  * constructors may.  The client may inquire as to whether any errors have
  49  * occurred by invoking {@link #checkError checkError()}.
  50  *
  51  * @author      Frank Yellin
  52  * @author      Mark Reinhold
  53  * @since       JDK1.1
  54  */
  55 
  56 public class PrintWriter extends Writer {
  57 
  58     /**
  59      * The underlying character-output stream of this
  60      * <code>PrintWriter</code>.
  61      *
  62      * @since 1.2
  63      */
  64     protected Writer out;
  65 
  66     private final boolean autoFlush;
  67     private boolean trouble = false;
  68     private Formatter formatter;
  69     private PrintStream psOut = null;
  70 
  71     /**
  72      * Line separator string.  This is the value of the line.separator
  73      * property at the moment that the stream was created.
  74      */
  75     private final String lineSeparator;
  76 
  77     /**
  78      * Returns a charset object for the given charset name.
  79      * @throws NullPointerException          is csn is null
  80      * @throws UnsupportedEncodingException  if the charset is not supported
  81      */
  82     private static Charset toCharset(String csn)
  83         throws UnsupportedEncodingException
  84     {
  85         Objects.requireNonNull(csn, "charsetName");
  86         try {
  87             return Charset.forName(csn);
  88         } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
  89             // UnsupportedEncodingException should be thrown
  90             throw new UnsupportedEncodingException(csn);
  91         }
  92     }
  93 
  94     /**
  95      * Creates a new PrintWriter, without automatic line flushing.
  96      *
  97      * @param  out        A character-output stream
  98      */
  99     public PrintWriter (Writer out) {
 100         this(out, false);
 101     }
 102 
 103     /**
 104      * Creates a new PrintWriter.
 105      *
 106      * @param  out        A character-output stream
 107      * @param  autoFlush  A boolean; if true, the <tt>println</tt>,
 108      *                    <tt>printf</tt>, or <tt>format</tt> methods will
 109      *                    flush the output buffer
 110      */
 111     public PrintWriter(Writer out,
 112                        boolean autoFlush) {
 113         super(out);
 114         this.out = out;
 115         this.autoFlush = autoFlush;
 116         lineSeparator = java.security.AccessController.doPrivileged(
 117             new sun.security.action.GetPropertyAction("line.separator"));
 118     }
 119 
 120     /**
 121      * Creates a new PrintWriter, without automatic line flushing, from an
 122      * existing OutputStream.  This convenience constructor creates the
 123      * necessary intermediate OutputStreamWriter, which will convert characters
 124      * into bytes using the default character encoding.
 125      *
 126      * @param  out        An output stream
 127      *
 128      * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
 129      */
 130     public PrintWriter(OutputStream out) {
 131         this(out, false);
 132     }
 133 
 134     /**
 135      * Creates a new PrintWriter from an existing OutputStream.  This
 136      * convenience constructor creates the necessary intermediate
 137      * OutputStreamWriter, which will convert characters into bytes using the
 138      * default character encoding.
 139      *
 140      * @param  out        An output stream
 141      * @param  autoFlush  A boolean; if true, the <tt>println</tt>,
 142      *                    <tt>printf</tt>, or <tt>format</tt> methods will
 143      *                    flush the output buffer
 144      *
 145      * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
 146      */
 147     public PrintWriter(OutputStream out, boolean autoFlush) {
 148         this(new BufferedWriter(new OutputStreamWriter(out)), autoFlush);
 149 
 150         // save print stream for error propagation
 151         if (out instanceof java.io.PrintStream) {
 152             psOut = (PrintStream) out;
 153         }
 154     }
 155 
 156     /**
 157      * Creates a new PrintWriter, without automatic line flushing, with the
 158      * specified file name.  This convenience constructor creates the necessary
 159      * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter},
 160      * which will encode characters using the {@linkplain
 161      * java.nio.charset.Charset#defaultCharset() default charset} for this
 162      * instance of the Java virtual machine.
 163      *
 164      * @param  fileName
 165      *         The name of the file to use as the destination of this writer.
 166      *         If the file exists then it will be truncated to zero size;
 167      *         otherwise, a new file will be created.  The output will be
 168      *         written to the file and is buffered.
 169      *
 170      * @throws  FileNotFoundException
 171      *          If the given string does not denote an existing, writable
 172      *          regular file and a new regular file of that name cannot be
 173      *          created, or if some other error occurs while opening or
 174      *          creating the file
 175      *
 176      * @throws  SecurityException
 177      *          If a security manager is present and {@link
 178      *          SecurityManager#checkWrite checkWrite(fileName)} denies write
 179      *          access to the file
 180      *
 181      * @since  1.5
 182      */
 183     public PrintWriter(String fileName) throws FileNotFoundException {
 184         this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))),
 185              false);
 186     }
 187 
 188     /* Private constructor */
 189     private PrintWriter(Charset charset, File file)
 190         throws FileNotFoundException
 191     {
 192         this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), charset)),
 193              false);
 194     }
 195 
 196     /**
 197      * Creates a new PrintWriter, without automatic line flushing, with the
 198      * specified file name and charset.  This convenience constructor creates
 199      * the necessary intermediate {@link java.io.OutputStreamWriter
 200      * OutputStreamWriter}, which will encode characters using the provided
 201      * charset.
 202      *
 203      * @param  fileName
 204      *         The name of the file to use as the destination of this writer.
 205      *         If the file exists then it will be truncated to zero size;
 206      *         otherwise, a new file will be created.  The output will be
 207      *         written to the file and is buffered.
 208      *
 209      * @param  csn
 210      *         The name of a supported {@linkplain java.nio.charset.Charset
 211      *         charset}
 212      *
 213      * @throws  FileNotFoundException
 214      *          If the given string does not denote an existing, writable
 215      *          regular file and a new regular file of that name cannot be
 216      *          created, or if some other error occurs while opening or
 217      *          creating the file
 218      *
 219      * @throws  SecurityException
 220      *          If a security manager is present and {@link
 221      *          SecurityManager#checkWrite checkWrite(fileName)} denies write
 222      *          access to the file
 223      *
 224      * @throws  UnsupportedEncodingException
 225      *          If the named charset is not supported
 226      *
 227      * @since  1.5
 228      */
 229     public PrintWriter(String fileName, String csn)
 230         throws FileNotFoundException, UnsupportedEncodingException
 231     {
 232         this(toCharset(csn), new File(fileName));
 233     }
 234 
 235     /**
 236      * Creates a new PrintWriter, without automatic line flushing, with the
 237      * specified file.  This convenience constructor creates the necessary
 238      * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter},
 239      * which will encode characters using the {@linkplain
 240      * java.nio.charset.Charset#defaultCharset() default charset} for this
 241      * instance of the Java virtual machine.
 242      *
 243      * @param  file
 244      *         The file to use as the destination of this writer.  If the file
 245      *         exists then it will be truncated to zero size; otherwise, a new
 246      *         file will be created.  The output will be written to the file
 247      *         and is buffered.
 248      *
 249      * @throws  FileNotFoundException
 250      *          If the given file object does not denote an existing, writable
 251      *          regular file and a new regular file of that name cannot be
 252      *          created, or if some other error occurs while opening or
 253      *          creating the file
 254      *
 255      * @throws  SecurityException
 256      *          If a security manager is present and {@link
 257      *          SecurityManager#checkWrite checkWrite(file.getPath())}
 258      *          denies write access to the file
 259      *
 260      * @since  1.5
 261      */
 262     public PrintWriter(File file) throws FileNotFoundException {
 263         this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))),
 264              false);
 265     }
 266 
 267     /**
 268      * Creates a new PrintWriter, without automatic line flushing, with the
 269      * specified file and charset.  This convenience constructor creates the
 270      * necessary intermediate {@link java.io.OutputStreamWriter
 271      * OutputStreamWriter}, which will encode characters using the provided
 272      * charset.
 273      *
 274      * @param  file
 275      *         The file to use as the destination of this writer.  If the file
 276      *         exists then it will be truncated to zero size; otherwise, a new
 277      *         file will be created.  The output will be written to the file
 278      *         and is buffered.
 279      *
 280      * @param  csn
 281      *         The name of a supported {@linkplain java.nio.charset.Charset
 282      *         charset}
 283      *
 284      * @throws  FileNotFoundException
 285      *          If the given file object does not denote an existing, writable
 286      *          regular file and a new regular file of that name cannot be
 287      *          created, or if some other error occurs while opening or
 288      *          creating the file
 289      *
 290      * @throws  SecurityException
 291      *          If a security manager is present and {@link
 292      *          SecurityManager#checkWrite checkWrite(file.getPath())}
 293      *          denies write access to the file
 294      *
 295      * @throws  UnsupportedEncodingException
 296      *          If the named charset is not supported
 297      *
 298      * @since  1.5
 299      */
 300     public PrintWriter(File file, String csn)
 301         throws FileNotFoundException, UnsupportedEncodingException
 302     {
 303         this(toCharset(csn), file);
 304     }
 305 
 306     /** Checks to make sure that the stream has not been closed */
 307     private void ensureOpen() throws IOException {
 308         if (out == null)
 309             throw new IOException("Stream closed");
 310     }
 311 
 312     /**
 313      * Flushes the stream.
 314      * @see #checkError()
 315      */
 316     public void flush() {
 317         try {
 318             synchronized (lock) {
 319                 ensureOpen();
 320                 out.flush();
 321             }
 322         }
 323         catch (IOException x) {
 324             trouble = true;
 325         }
 326     }
 327 
 328     /**
 329      * Closes the stream and releases any system resources associated
 330      * with it. Closing a previously closed stream has no effect.
 331      *
 332      * @see #checkError()
 333      */
 334     public void close() {
 335         try {
 336             synchronized (lock) {
 337                 if (out == null)
 338                     return;
 339                 out.close();
 340                 out = null;
 341             }
 342         }
 343         catch (IOException x) {
 344             trouble = true;
 345         }
 346     }
 347 
 348     /**
 349      * Flushes the stream if it's not closed and checks its error state.
 350      *
 351      * @return <code>true</code> if the print stream has encountered an error,
 352      *          either on the underlying output stream or during a format
 353      *          conversion.
 354      */
 355     public boolean checkError() {
 356         if (out != null) {
 357             flush();
 358         }
 359         if (out instanceof java.io.PrintWriter) {
 360             PrintWriter pw = (PrintWriter) out;
 361             return pw.checkError();
 362         } else if (psOut != null) {
 363             return psOut.checkError();
 364         }
 365         return trouble;
 366     }
 367 
 368     /**
 369      * Indicates that an error has occurred.
 370      *
 371      * <p> This method will cause subsequent invocations of {@link
 372      * #checkError()} to return <tt>true</tt> until {@link
 373      * #clearError()} is invoked.
 374      */
 375     protected void setError() {
 376         trouble = true;
 377     }
 378 
 379     /**
 380      * Clears the error state of this stream.
 381      *
 382      * <p> This method will cause subsequent invocations of {@link
 383      * #checkError()} to return <tt>false</tt> until another write
 384      * operation fails and invokes {@link #setError()}.
 385      *
 386      * @since 1.6
 387      */
 388     protected void clearError() {
 389         trouble = false;
 390     }
 391 
 392     /*
 393      * Exception-catching, synchronized output operations,
 394      * which also implement the write() methods of Writer
 395      */
 396 
 397     /**
 398      * Writes a single character.
 399      * @param c int specifying a character to be written.
 400      */
 401     public void write(int c) {
 402         try {
 403             synchronized (lock) {
 404                 ensureOpen();
 405                 out.write(c);
 406             }
 407         }
 408         catch (InterruptedIOException x) {
 409             Thread.currentThread().interrupt();
 410         }
 411         catch (IOException x) {
 412             trouble = true;
 413         }
 414     }
 415 
 416     /**
 417      * Writes A Portion of an array of characters.
 418      * @param buf Array of characters
 419      * @param off Offset from which to start writing characters
 420      * @param len Number of characters to write
 421      */
 422     public void write(char buf[], int off, int len) {
 423         try {
 424             synchronized (lock) {
 425                 ensureOpen();
 426                 out.write(buf, off, len);
 427             }
 428         }
 429         catch (InterruptedIOException x) {
 430             Thread.currentThread().interrupt();
 431         }
 432         catch (IOException x) {
 433             trouble = true;
 434         }
 435     }
 436 
 437     /**
 438      * Writes an array of characters.  This method cannot be inherited from the
 439      * Writer class because it must suppress I/O exceptions.
 440      * @param buf Array of characters to be written
 441      */
 442     public void write(char buf[]) {
 443         write(buf, 0, buf.length);
 444     }
 445 
 446     /**
 447      * Writes a portion of a string.
 448      * @param s A String
 449      * @param off Offset from which to start writing characters
 450      * @param len Number of characters to write
 451      */
 452     public void write(String s, int off, int len) {
 453         try {
 454             synchronized (lock) {
 455                 ensureOpen();
 456                 out.write(s, off, len);
 457             }
 458         }
 459         catch (InterruptedIOException x) {
 460             Thread.currentThread().interrupt();
 461         }
 462         catch (IOException x) {
 463             trouble = true;
 464         }
 465     }
 466 
 467     /**
 468      * Writes a string.  This method cannot be inherited from the Writer class
 469      * because it must suppress I/O exceptions.
 470      * @param s String to be written
 471      */
 472     public void write(String s) {
 473         write(s, 0, s.length());
 474     }
 475 
 476     private void newLine() {
 477         try {
 478             synchronized (lock) {
 479                 ensureOpen();
 480                 out.write(lineSeparator);
 481                 if (autoFlush)
 482                     out.flush();
 483             }
 484         }
 485         catch (InterruptedIOException x) {
 486             Thread.currentThread().interrupt();
 487         }
 488         catch (IOException x) {
 489             trouble = true;
 490         }
 491     }
 492 
 493     /* Methods that do not terminate lines */
 494 
 495     /**
 496      * Prints a boolean value.  The string produced by <code>{@link
 497      * java.lang.String#valueOf(boolean)}</code> is translated into bytes
 498      * according to the platform's default character encoding, and these bytes
 499      * are written in exactly the manner of the <code>{@link
 500      * #write(int)}</code> method.
 501      *
 502      * @param      b   The <code>boolean</code> to be printed
 503      */
 504     public void print(boolean b) {
 505         write(b ? "true" : "false");
 506     }
 507 
 508     /**
 509      * Prints a character.  The character is translated into one or more bytes
 510      * according to the platform's default character encoding, and these bytes
 511      * are written in exactly the manner of the <code>{@link
 512      * #write(int)}</code> method.
 513      *
 514      * @param      c   The <code>char</code> to be printed
 515      */
 516     public void print(char c) {
 517         write(c);
 518     }
 519 
 520     /**
 521      * Prints an integer.  The string produced by <code>{@link
 522      * java.lang.String#valueOf(int)}</code> is translated into bytes according
 523      * to the platform's default character encoding, and these bytes are
 524      * written in exactly the manner of the <code>{@link #write(int)}</code>
 525      * method.
 526      *
 527      * @param      i   The <code>int</code> to be printed
 528      * @see        java.lang.Integer#toString(int)
 529      */
 530     public void print(int i) {
 531         write(String.valueOf(i));
 532     }
 533 
 534     /**
 535      * Prints a long integer.  The string produced by <code>{@link
 536      * java.lang.String#valueOf(long)}</code> is translated into bytes
 537      * according to the platform's default character encoding, and these bytes
 538      * are written in exactly the manner of the <code>{@link #write(int)}</code>
 539      * method.
 540      *
 541      * @param      l   The <code>long</code> to be printed
 542      * @see        java.lang.Long#toString(long)
 543      */
 544     public void print(long l) {
 545         write(String.valueOf(l));
 546     }
 547 
 548     /**
 549      * Prints a floating-point number.  The string produced by <code>{@link
 550      * java.lang.String#valueOf(float)}</code> is translated into bytes
 551      * according to the platform's default character encoding, and these bytes
 552      * are written in exactly the manner of the <code>{@link #write(int)}</code>
 553      * method.
 554      *
 555      * @param      f   The <code>float</code> to be printed
 556      * @see        java.lang.Float#toString(float)
 557      */
 558     public void print(float f) {
 559         write(String.valueOf(f));
 560     }
 561 
 562     /**
 563      * Prints a double-precision floating-point number.  The string produced by
 564      * <code>{@link java.lang.String#valueOf(double)}</code> is translated into
 565      * bytes according to the platform's default character encoding, and these
 566      * bytes are written in exactly the manner of the <code>{@link
 567      * #write(int)}</code> method.
 568      *
 569      * @param      d   The <code>double</code> to be printed
 570      * @see        java.lang.Double#toString(double)
 571      */
 572     public void print(double d) {
 573         write(String.valueOf(d));
 574     }
 575 
 576     /**
 577      * Prints an array of characters.  The characters are converted into bytes
 578      * according to the platform's default character encoding, and these bytes
 579      * are written in exactly the manner of the <code>{@link #write(int)}</code>
 580      * method.
 581      *
 582      * @param      s   The array of chars to be printed
 583      *
 584      * @throws  NullPointerException  If <code>s</code> is <code>null</code>
 585      */
 586     public void print(char s[]) {
 587         write(s);
 588     }
 589 
 590     /**
 591      * Prints a string.  If the argument is <code>null</code> then the string
 592      * <code>"null"</code> is printed.  Otherwise, the string's characters are
 593      * converted into bytes according to the platform's default character
 594      * encoding, and these bytes are written in exactly the manner of the
 595      * <code>{@link #write(int)}</code> method.
 596      *
 597      * @param      s   The <code>String</code> to be printed
 598      */
 599     public void print(String s) {
 600         if (s == null) {
 601             s = "null";
 602         }
 603         write(s);
 604     }
 605 
 606     /**
 607      * Prints an object.  The string produced by the <code>{@link
 608      * java.lang.String#valueOf(Object)}</code> method is translated into bytes
 609      * according to the platform's default character encoding, and these bytes
 610      * are written in exactly the manner of the <code>{@link #write(int)}</code>
 611      * method.
 612      *
 613      * @param      obj   The <code>Object</code> to be printed
 614      * @see        java.lang.Object#toString()
 615      */
 616     public void print(Object obj) {
 617         write(String.valueOf(obj));
 618     }
 619 
 620     /* Methods that do terminate lines */
 621 
 622     /**
 623      * Terminates the current line by writing the line separator string.  The
 624      * line separator string is defined by the system property
 625      * <code>line.separator</code>, and is not necessarily a single newline
 626      * character (<code>'\n'</code>).
 627      */
 628     public void println() {
 629         newLine();
 630     }
 631 
 632     /**
 633      * Prints a boolean value and then terminates the line.  This method behaves
 634      * as though it invokes <code>{@link #print(boolean)}</code> and then
 635      * <code>{@link #println()}</code>.
 636      *
 637      * @param x the <code>boolean</code> value to be printed
 638      */
 639     public void println(boolean x) {
 640         synchronized (lock) {
 641             print(x);
 642             println();
 643         }
 644     }
 645 
 646     /**
 647      * Prints a character and then terminates the line.  This method behaves as
 648      * though it invokes <code>{@link #print(char)}</code> and then <code>{@link
 649      * #println()}</code>.
 650      *
 651      * @param x the <code>char</code> value to be printed
 652      */
 653     public void println(char x) {
 654         synchronized (lock) {
 655             print(x);
 656             println();
 657         }
 658     }
 659 
 660     /**
 661      * Prints an integer and then terminates the line.  This method behaves as
 662      * though it invokes <code>{@link #print(int)}</code> and then <code>{@link
 663      * #println()}</code>.
 664      *
 665      * @param x the <code>int</code> value to be printed
 666      */
 667     public void println(int x) {
 668         synchronized (lock) {
 669             print(x);
 670             println();
 671         }
 672     }
 673 
 674     /**
 675      * Prints a long integer and then terminates the line.  This method behaves
 676      * as though it invokes <code>{@link #print(long)}</code> and then
 677      * <code>{@link #println()}</code>.
 678      *
 679      * @param x the <code>long</code> value to be printed
 680      */
 681     public void println(long x) {
 682         synchronized (lock) {
 683             print(x);
 684             println();
 685         }
 686     }
 687 
 688     /**
 689      * Prints a floating-point number and then terminates the line.  This method
 690      * behaves as though it invokes <code>{@link #print(float)}</code> and then
 691      * <code>{@link #println()}</code>.
 692      *
 693      * @param x the <code>float</code> value to be printed
 694      */
 695     public void println(float x) {
 696         synchronized (lock) {
 697             print(x);
 698             println();
 699         }
 700     }
 701 
 702     /**
 703      * Prints a double-precision floating-point number and then terminates the
 704      * line.  This method behaves as though it invokes <code>{@link
 705      * #print(double)}</code> and then <code>{@link #println()}</code>.
 706      *
 707      * @param x the <code>double</code> value to be printed
 708      */
 709     public void println(double x) {
 710         synchronized (lock) {
 711             print(x);
 712             println();
 713         }
 714     }
 715 
 716     /**
 717      * Prints an array of characters and then terminates the line.  This method
 718      * behaves as though it invokes <code>{@link #print(char[])}</code> and then
 719      * <code>{@link #println()}</code>.
 720      *
 721      * @param x the array of <code>char</code> values to be printed
 722      */
 723     public void println(char x[]) {
 724         synchronized (lock) {
 725             print(x);
 726             println();
 727         }
 728     }
 729 
 730     /**
 731      * Prints a String and then terminates the line.  This method behaves as
 732      * though it invokes <code>{@link #print(String)}</code> and then
 733      * <code>{@link #println()}</code>.
 734      *
 735      * @param x the <code>String</code> value to be printed
 736      */
 737     public void println(String x) {
 738         synchronized (lock) {
 739             print(x);
 740             println();
 741         }
 742     }
 743 
 744     /**
 745      * Prints an Object and then terminates the line.  This method calls
 746      * at first String.valueOf(x) to get the printed object's string value,
 747      * then behaves as
 748      * though it invokes <code>{@link #print(String)}</code> and then
 749      * <code>{@link #println()}</code>.
 750      *
 751      * @param x  The <code>Object</code> to be printed.
 752      */
 753     public void println(Object x) {
 754         String s = String.valueOf(x);
 755         synchronized (lock) {
 756             print(s);
 757             println();
 758         }
 759     }
 760 
 761     /**
 762      * A convenience method to write a formatted string to this writer using
 763      * the specified format string and arguments.  If automatic flushing is
 764      * enabled, calls to this method will flush the output buffer.
 765      *
 766      * <p> An invocation of this method of the form <tt>out.printf(format,
 767      * args)</tt> behaves in exactly the same way as the invocation
 768      *
 769      * <pre>
 770      *     out.format(format, args) </pre>
 771      *
 772      * @param  format
 773      *         A format string as described in <a
 774      *         href="../util/Formatter.html#syntax">Format string syntax</a>.
 775      *
 776      * @param  args
 777      *         Arguments referenced by the format specifiers in the format
 778      *         string.  If there are more arguments than format specifiers, the
 779      *         extra arguments are ignored.  The number of arguments is
 780      *         variable and may be zero.  The maximum number of arguments is
 781      *         limited by the maximum dimension of a Java array as defined by
 782      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
 783      *         The behaviour on a
 784      *         <tt>null</tt> argument depends on the <a
 785      *         href="../util/Formatter.html#syntax">conversion</a>.
 786      *
 787      * @throws  java.util.IllegalFormatException
 788      *          If a format string contains an illegal syntax, a format
 789      *          specifier that is incompatible with the given arguments,
 790      *          insufficient arguments given the format string, or other
 791      *          illegal conditions.  For specification of all possible
 792      *          formatting errors, see the <a
 793      *          href="../util/Formatter.html#detail">Details</a> section of the
 794      *          formatter class specification.
 795      *
 796      * @throws  NullPointerException
 797      *          If the <tt>format</tt> is <tt>null</tt>
 798      *
 799      * @return  This writer
 800      *
 801      * @since  1.5
 802      */
 803     public PrintWriter printf(String format, Object ... args) {
 804         return format(format, args);
 805     }
 806 
 807     /**
 808      * A convenience method to write a formatted string to this writer using
 809      * the specified format string and arguments.  If automatic flushing is
 810      * enabled, calls to this method will flush the output buffer.
 811      *
 812      * <p> An invocation of this method of the form <tt>out.printf(l, format,
 813      * args)</tt> behaves in exactly the same way as the invocation
 814      *
 815      * <pre>
 816      *     out.format(l, format, args) </pre>
 817      *
 818      * @param  l
 819      *         The {@linkplain java.util.Locale locale} to apply during
 820      *         formatting.  If <tt>l</tt> is <tt>null</tt> then no localization
 821      *         is applied.
 822      *
 823      * @param  format
 824      *         A format string as described in <a
 825      *         href="../util/Formatter.html#syntax">Format string syntax</a>.
 826      *
 827      * @param  args
 828      *         Arguments referenced by the format specifiers in the format
 829      *         string.  If there are more arguments than format specifiers, the
 830      *         extra arguments are ignored.  The number of arguments is
 831      *         variable and may be zero.  The maximum number of arguments is
 832      *         limited by the maximum dimension of a Java array as defined by
 833      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
 834      *         The behaviour on a
 835      *         <tt>null</tt> argument depends on the <a
 836      *         href="../util/Formatter.html#syntax">conversion</a>.
 837      *
 838      * @throws  java.util.IllegalFormatException
 839      *          If a format string contains an illegal syntax, a format
 840      *          specifier that is incompatible with the given arguments,
 841      *          insufficient arguments given the format string, or other
 842      *          illegal conditions.  For specification of all possible
 843      *          formatting errors, see the <a
 844      *          href="../util/Formatter.html#detail">Details</a> section of the
 845      *          formatter class specification.
 846      *
 847      * @throws  NullPointerException
 848      *          If the <tt>format</tt> is <tt>null</tt>
 849      *
 850      * @return  This writer
 851      *
 852      * @since  1.5
 853      */
 854     public PrintWriter printf(Locale l, String format, Object ... args) {
 855         return format(l, format, args);
 856     }
 857 
 858     /**
 859      * Writes a formatted string to this writer using the specified format
 860      * string and arguments.  If automatic flushing is enabled, calls to this
 861      * method will flush the output buffer.
 862      *
 863      * <p> The locale always used is the one returned by {@link
 864      * java.util.Locale#getDefault() Locale.getDefault()}, regardless of any
 865      * previous invocations of other formatting methods on this object.
 866      *
 867      * @param  format
 868      *         A format string as described in <a
 869      *         href="../util/Formatter.html#syntax">Format string syntax</a>.
 870      *
 871      * @param  args
 872      *         Arguments referenced by the format specifiers in the format
 873      *         string.  If there are more arguments than format specifiers, the
 874      *         extra arguments are ignored.  The number of arguments is
 875      *         variable and may be zero.  The maximum number of arguments is
 876      *         limited by the maximum dimension of a Java array as defined by
 877      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
 878      *         The behaviour on a
 879      *         <tt>null</tt> argument depends on the <a
 880      *         href="../util/Formatter.html#syntax">conversion</a>.
 881      *
 882      * @throws  java.util.IllegalFormatException
 883      *          If a format string contains an illegal syntax, a format
 884      *          specifier that is incompatible with the given arguments,
 885      *          insufficient arguments given the format string, or other
 886      *          illegal conditions.  For specification of all possible
 887      *          formatting errors, see the <a
 888      *          href="../util/Formatter.html#detail">Details</a> section of the
 889      *          Formatter class specification.
 890      *
 891      * @throws  NullPointerException
 892      *          If the <tt>format</tt> is <tt>null</tt>
 893      *
 894      * @return  This writer
 895      *
 896      * @since  1.5
 897      */
 898     public PrintWriter format(String format, Object ... args) {
 899         try {
 900             synchronized (lock) {
 901                 ensureOpen();
 902                 if ((formatter == null)
 903                     || (formatter.locale() != Locale.getDefault()))
 904                     formatter = new Formatter(this);
 905                 formatter.format(Locale.getDefault(), format, args);
 906                 if (autoFlush)
 907                     out.flush();
 908             }
 909         } catch (InterruptedIOException x) {
 910             Thread.currentThread().interrupt();
 911         } catch (IOException x) {
 912             trouble = true;
 913         }
 914         return this;
 915     }
 916 
 917     /**
 918      * Writes a formatted string to this writer using the specified format
 919      * string and arguments.  If automatic flushing is enabled, calls to this
 920      * method will flush the output buffer.
 921      *
 922      * @param  l
 923      *         The {@linkplain java.util.Locale locale} to apply during
 924      *         formatting.  If <tt>l</tt> is <tt>null</tt> then no localization
 925      *         is applied.
 926      *
 927      * @param  format
 928      *         A format string as described in <a
 929      *         href="../util/Formatter.html#syntax">Format string syntax</a>.
 930      *
 931      * @param  args
 932      *         Arguments referenced by the format specifiers in the format
 933      *         string.  If there are more arguments than format specifiers, the
 934      *         extra arguments are ignored.  The number of arguments is
 935      *         variable and may be zero.  The maximum number of arguments is
 936      *         limited by the maximum dimension of a Java array as defined by
 937      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
 938      *         The behaviour on a
 939      *         <tt>null</tt> argument depends on the <a
 940      *         href="../util/Formatter.html#syntax">conversion</a>.
 941      *
 942      * @throws  java.util.IllegalFormatException
 943      *          If a format string contains an illegal syntax, a format
 944      *          specifier that is incompatible with the given arguments,
 945      *          insufficient arguments given the format string, or other
 946      *          illegal conditions.  For specification of all possible
 947      *          formatting errors, see the <a
 948      *          href="../util/Formatter.html#detail">Details</a> section of the
 949      *          formatter class specification.
 950      *
 951      * @throws  NullPointerException
 952      *          If the <tt>format</tt> is <tt>null</tt>
 953      *
 954      * @return  This writer
 955      *
 956      * @since  1.5
 957      */
 958     public PrintWriter format(Locale l, String format, Object ... args) {
 959         try {
 960             synchronized (lock) {
 961                 ensureOpen();
 962                 if ((formatter == null) || (formatter.locale() != l))
 963                     formatter = new Formatter(this, l);
 964                 formatter.format(l, format, args);
 965                 if (autoFlush)
 966                     out.flush();
 967             }
 968         } catch (InterruptedIOException x) {
 969             Thread.currentThread().interrupt();
 970         } catch (IOException x) {
 971             trouble = true;
 972         }
 973         return this;
 974     }
 975 
 976     /**
 977      * Appends the specified character sequence to this writer.
 978      *
 979      * <p> An invocation of this method of the form <tt>out.append(csq)</tt>
 980      * behaves in exactly the same way as the invocation
 981      *
 982      * <pre>
 983      *     out.write(csq.toString()) </pre>
 984      *
 985      * <p> Depending on the specification of <tt>toString</tt> for the
 986      * character sequence <tt>csq</tt>, the entire sequence may not be
 987      * appended. For instance, invoking the <tt>toString</tt> method of a
 988      * character buffer will return a subsequence whose content depends upon
 989      * the buffer's position and limit.
 990      *
 991      * @param  csq
 992      *         The character sequence to append.  If <tt>csq</tt> is
 993      *         <tt>null</tt>, then the four characters <tt>"null"</tt> are
 994      *         appended to this writer.
 995      *
 996      * @return  This writer
 997      *
 998      * @since  1.5
 999      */
1000     public PrintWriter append(CharSequence csq) {
1001         if (csq == null)
1002             write("null");
1003         else
1004             write(csq.toString());
1005         return this;
1006     }
1007 
1008     /**
1009      * Appends a subsequence of the specified character sequence to this writer.
1010      *
1011      * <p> An invocation of this method of the form <tt>out.append(csq, start,
1012      * end)</tt> when <tt>csq</tt> is not <tt>null</tt>, behaves in
1013      * exactly the same way as the invocation
1014      *
1015      * <pre>
1016      *     out.write(csq.subSequence(start, end).toString()) </pre>
1017      *
1018      * @param  csq
1019      *         The character sequence from which a subsequence will be
1020      *         appended.  If <tt>csq</tt> is <tt>null</tt>, then characters
1021      *         will be appended as if <tt>csq</tt> contained the four
1022      *         characters <tt>"null"</tt>.
1023      *
1024      * @param  start
1025      *         The index of the first character in the subsequence
1026      *
1027      * @param  end
1028      *         The index of the character following the last character in the
1029      *         subsequence
1030      *
1031      * @return  This writer
1032      *
1033      * @throws  IndexOutOfBoundsException
1034      *          If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
1035      *          is greater than <tt>end</tt>, or <tt>end</tt> is greater than
1036      *          <tt>csq.length()</tt>
1037      *
1038      * @since  1.5
1039      */
1040     public PrintWriter append(CharSequence csq, int start, int end) {
1041         CharSequence cs = (csq == null ? "null" : csq);
1042         write(cs.subSequence(start, end).toString());
1043         return this;
1044     }
1045 
1046     /**
1047      * Appends the specified character to this writer.
1048      *
1049      * <p> An invocation of this method of the form <tt>out.append(c)</tt>
1050      * behaves in exactly the same way as the invocation
1051      *
1052      * <pre>
1053      *     out.write(c) </pre>
1054      *
1055      * @param  c
1056      *         The 16-bit character to append
1057      *
1058      * @return  This writer
1059      *
1060      * @since 1.5
1061      */
1062     public PrintWriter append(char c) {
1063         write(c);
1064         return this;
1065     }
1066 }