jdk/src/share/classes/java/util/Formatter.java
changeset 7966 a23e3f47c5a8
parent 7816 55a18147b4bf
child 8166 13423c0952ad
equal deleted inserted replaced
7817:0b2c3a61f004 7966:a23e3f47c5a8
     1 /*
     1 /*
     2  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    39 import java.math.BigDecimal;
    39 import java.math.BigDecimal;
    40 import java.math.BigInteger;
    40 import java.math.BigInteger;
    41 import java.math.MathContext;
    41 import java.math.MathContext;
    42 import java.math.RoundingMode;
    42 import java.math.RoundingMode;
    43 import java.nio.charset.Charset;
    43 import java.nio.charset.Charset;
       
    44 import java.nio.charset.IllegalCharsetNameException;
       
    45 import java.nio.charset.UnsupportedCharsetException;
    44 import java.text.DateFormatSymbols;
    46 import java.text.DateFormatSymbols;
    45 import java.text.DecimalFormat;
    47 import java.text.DecimalFormat;
    46 import java.text.DecimalFormatSymbols;
    48 import java.text.DecimalFormatSymbols;
    47 import java.text.NumberFormat;
    49 import java.text.NumberFormat;
    48 import java.util.Calendar;
    50 import java.util.Calendar;
  1836  * @author  Iris Clark
  1838  * @author  Iris Clark
  1837  * @since 1.5
  1839  * @since 1.5
  1838  */
  1840  */
  1839 public final class Formatter implements Closeable, Flushable {
  1841 public final class Formatter implements Closeable, Flushable {
  1840     private Appendable a;
  1842     private Appendable a;
  1841     private Locale l;
  1843     private final Locale l;
  1842 
  1844 
  1843     private IOException lastException;
  1845     private IOException lastException;
  1844 
  1846 
  1845     private char zero = '0';
  1847     private final char zero;
  1846     private static double scaleUp;
  1848     private static double scaleUp;
  1847 
  1849 
  1848     // 1 (sign) + 19 (max # sig digits) + 1 ('.') + 1 ('e') + 1 (sign)
  1850     // 1 (sign) + 19 (max # sig digits) + 1 ('.') + 1 ('e') + 1 (sign)
  1849     // + 3 (max # exp digits) + 4 (error) = 30
  1851     // + 3 (max # exp digits) + 4 (error) = 30
  1850     private static final int MAX_FD_CHARS = 30;
  1852     private static final int MAX_FD_CHARS = 30;
  1851 
  1853 
  1852     // Initialize internal data.
  1854     /**
  1853     private void init(Appendable a, Locale l) {
  1855      * Returns a charset object for the given charset name.
       
  1856      * @throws NullPointerException          is csn is null
       
  1857      * @throws UnsupportedEncodingException  if the charset is not supported
       
  1858      */
       
  1859     private static Charset toCharset(String csn)
       
  1860         throws UnsupportedEncodingException
       
  1861     {
       
  1862         Objects.nonNull(csn, "charsetName");
       
  1863         try {
       
  1864             return Charset.forName(csn);
       
  1865         } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
       
  1866             // UnsupportedEncodingException should be thrown
       
  1867             throw new UnsupportedEncodingException(csn);
       
  1868         }
       
  1869     }
       
  1870 
       
  1871     private static final Appendable nonNullAppendable(Appendable a) {
       
  1872         if (a == null)
       
  1873             return new StringBuilder();
       
  1874 
       
  1875         return a;
       
  1876     }
       
  1877 
       
  1878     /* Private constructors */
       
  1879     private Formatter(Locale l, Appendable a) {
  1854         this.a = a;
  1880         this.a = a;
  1855         this.l = l;
  1881         this.l = l;
  1856         setZero();
  1882         this.zero = getZero(l);
       
  1883     }
       
  1884 
       
  1885     private Formatter(Charset charset, Locale l, File file)
       
  1886         throws FileNotFoundException
       
  1887     {
       
  1888         this(l,
       
  1889              new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), charset)));
  1857     }
  1890     }
  1858 
  1891 
  1859     /**
  1892     /**
  1860      * Constructs a new formatter.
  1893      * Constructs a new formatter.
  1861      *
  1894      *
  1865      * #toString toString()}.  The locale used is the {@linkplain
  1898      * #toString toString()}.  The locale used is the {@linkplain
  1866      * Locale#getDefault() default locale} for this instance of the Java
  1899      * Locale#getDefault() default locale} for this instance of the Java
  1867      * virtual machine.
  1900      * virtual machine.
  1868      */
  1901      */
  1869     public Formatter() {
  1902     public Formatter() {
  1870         init(new StringBuilder(), Locale.getDefault(Locale.Category.FORMAT));
  1903         this(Locale.getDefault(Locale.Category.FORMAT), new StringBuilder());
  1871     }
  1904     }
  1872 
  1905 
  1873     /**
  1906     /**
  1874      * Constructs a new formatter with the specified destination.
  1907      * Constructs a new formatter with the specified destination.
  1875      *
  1908      *
  1879      * @param  a
  1912      * @param  a
  1880      *         Destination for the formatted output.  If {@code a} is
  1913      *         Destination for the formatted output.  If {@code a} is
  1881      *         {@code null} then a {@link StringBuilder} will be created.
  1914      *         {@code null} then a {@link StringBuilder} will be created.
  1882      */
  1915      */
  1883     public Formatter(Appendable a) {
  1916     public Formatter(Appendable a) {
  1884         if (a == null)
  1917         this(Locale.getDefault(Locale.Category.FORMAT), nonNullAppendable(a));
  1885             a = new StringBuilder();
       
  1886         init(a, Locale.getDefault(Locale.Category.FORMAT));
       
  1887     }
  1918     }
  1888 
  1919 
  1889     /**
  1920     /**
  1890      * Constructs a new formatter with the specified locale.
  1921      * Constructs a new formatter with the specified locale.
  1891      *
  1922      *
  1898      *         The {@linkplain java.util.Locale locale} to apply during
  1929      *         The {@linkplain java.util.Locale locale} to apply during
  1899      *         formatting.  If {@code l} is {@code null} then no localization
  1930      *         formatting.  If {@code l} is {@code null} then no localization
  1900      *         is applied.
  1931      *         is applied.
  1901      */
  1932      */
  1902     public Formatter(Locale l) {
  1933     public Formatter(Locale l) {
  1903         init(new StringBuilder(), l);
  1934         this(l, new StringBuilder());
  1904     }
  1935     }
  1905 
  1936 
  1906     /**
  1937     /**
  1907      * Constructs a new formatter with the specified destination and locale.
  1938      * Constructs a new formatter with the specified destination and locale.
  1908      *
  1939      *
  1914      *         The {@linkplain java.util.Locale locale} to apply during
  1945      *         The {@linkplain java.util.Locale locale} to apply during
  1915      *         formatting.  If {@code l} is {@code null} then no localization
  1946      *         formatting.  If {@code l} is {@code null} then no localization
  1916      *         is applied.
  1947      *         is applied.
  1917      */
  1948      */
  1918     public Formatter(Appendable a, Locale l) {
  1949     public Formatter(Appendable a, Locale l) {
  1919         if (a == null)
  1950         this(l, nonNullAppendable(a));
  1920             a = new StringBuilder();
       
  1921         init(a, l);
       
  1922     }
  1951     }
  1923 
  1952 
  1924     /**
  1953     /**
  1925      * Constructs a new formatter with the specified file name.
  1954      * Constructs a new formatter with the specified file name.
  1926      *
  1955      *
  1947      *          regular file and a new regular file of that name cannot be
  1976      *          regular file and a new regular file of that name cannot be
  1948      *          created, or if some other error occurs while opening or
  1977      *          created, or if some other error occurs while opening or
  1949      *          creating the file
  1978      *          creating the file
  1950      */
  1979      */
  1951     public Formatter(String fileName) throws FileNotFoundException {
  1980     public Formatter(String fileName) throws FileNotFoundException {
  1952         init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))),
  1981         this(Locale.getDefault(Locale.Category.FORMAT),
  1953              Locale.getDefault(Locale.Category.FORMAT));
  1982              new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))));
  1954     }
  1983     }
  1955 
  1984 
  1956     /**
  1985     /**
  1957      * Constructs a new formatter with the specified file name and charset.
  1986      * Constructs a new formatter with the specified file name and charset.
  1958      *
  1987      *
  2023      *          If the named charset is not supported
  2052      *          If the named charset is not supported
  2024      */
  2053      */
  2025     public Formatter(String fileName, String csn, Locale l)
  2054     public Formatter(String fileName, String csn, Locale l)
  2026         throws FileNotFoundException, UnsupportedEncodingException
  2055         throws FileNotFoundException, UnsupportedEncodingException
  2027     {
  2056     {
  2028         init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName), csn)),
  2057         this(toCharset(csn), l, new File(fileName));
  2029              l);
       
  2030     }
  2058     }
  2031 
  2059 
  2032     /**
  2060     /**
  2033      * Constructs a new formatter with the specified file.
  2061      * Constructs a new formatter with the specified file.
  2034      *
  2062      *
  2055      *          regular file and a new regular file of that name cannot be
  2083      *          regular file and a new regular file of that name cannot be
  2056      *          created, or if some other error occurs while opening or
  2084      *          created, or if some other error occurs while opening or
  2057      *          creating the file
  2085      *          creating the file
  2058      */
  2086      */
  2059     public Formatter(File file) throws FileNotFoundException {
  2087     public Formatter(File file) throws FileNotFoundException {
  2060         init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))),
  2088         this(Locale.getDefault(Locale.Category.FORMAT),
  2061              Locale.getDefault(Locale.Category.FORMAT));
  2089              new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))));
  2062     }
  2090     }
  2063 
  2091 
  2064     /**
  2092     /**
  2065      * Constructs a new formatter with the specified file and charset.
  2093      * Constructs a new formatter with the specified file and charset.
  2066      *
  2094      *
  2131      *          If the named charset is not supported
  2159      *          If the named charset is not supported
  2132      */
  2160      */
  2133     public Formatter(File file, String csn, Locale l)
  2161     public Formatter(File file, String csn, Locale l)
  2134         throws FileNotFoundException, UnsupportedEncodingException
  2162         throws FileNotFoundException, UnsupportedEncodingException
  2135     {
  2163     {
  2136         init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), csn)),
  2164         this(toCharset(csn), l, file);
  2137              l);
       
  2138     }
  2165     }
  2139 
  2166 
  2140     /**
  2167     /**
  2141      * Constructs a new formatter with the specified print stream.
  2168      * Constructs a new formatter with the specified print stream.
  2142      *
  2169      *
  2149      *
  2176      *
  2150      * @param  ps
  2177      * @param  ps
  2151      *         The stream to use as the destination of this formatter.
  2178      *         The stream to use as the destination of this formatter.
  2152      */
  2179      */
  2153     public Formatter(PrintStream ps) {
  2180     public Formatter(PrintStream ps) {
  2154         if (ps == null)
  2181         this(Locale.getDefault(Locale.Category.FORMAT),
  2155             throw new NullPointerException();
  2182              (Appendable)Objects.nonNull(ps));
  2156         init((Appendable)ps, Locale.getDefault(Locale.Category.FORMAT));
       
  2157     }
  2183     }
  2158 
  2184 
  2159     /**
  2185     /**
  2160      * Constructs a new formatter with the specified output stream.
  2186      * Constructs a new formatter with the specified output stream.
  2161      *
  2187      *
  2169      * @param  os
  2195      * @param  os
  2170      *         The output stream to use as the destination of this formatter.
  2196      *         The output stream to use as the destination of this formatter.
  2171      *         The output will be buffered.
  2197      *         The output will be buffered.
  2172      */
  2198      */
  2173     public Formatter(OutputStream os) {
  2199     public Formatter(OutputStream os) {
  2174         init(new BufferedWriter(new OutputStreamWriter(os)),
  2200         this(Locale.getDefault(Locale.Category.FORMAT),
  2175              Locale.getDefault(Locale.Category.FORMAT));
  2201              new BufferedWriter(new OutputStreamWriter(os)));
  2176     }
  2202     }
  2177 
  2203 
  2178     /**
  2204     /**
  2179      * Constructs a new formatter with the specified output stream and
  2205      * Constructs a new formatter with the specified output stream and
  2180      * charset.
  2206      * charset.
  2220      *          If the named charset is not supported
  2246      *          If the named charset is not supported
  2221      */
  2247      */
  2222     public Formatter(OutputStream os, String csn, Locale l)
  2248     public Formatter(OutputStream os, String csn, Locale l)
  2223         throws UnsupportedEncodingException
  2249         throws UnsupportedEncodingException
  2224     {
  2250     {
  2225         init(new BufferedWriter(new OutputStreamWriter(os, csn)), l);
  2251         this(l, new BufferedWriter(new OutputStreamWriter(os, csn)));
  2226     }
  2252     }
  2227 
  2253 
  2228     private void setZero() {
  2254     private static char getZero(Locale l) {
  2229         if ((l != null) && !l.equals(Locale.US)) {
  2255         if ((l != null) && !l.equals(Locale.US)) {
  2230             DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(l);
  2256             DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(l);
  2231             zero = dfs.getZeroDigit();
  2257             return dfs.getZeroDigit();
       
  2258         } else {
       
  2259             return '0';
  2232         }
  2260         }
  2233     }
  2261     }
  2234 
  2262 
  2235     /**
  2263     /**
  2236      * Returns the locale set by the construction of this formatter.
  2264      * Returns the locale set by the construction of this formatter.