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