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. |