1/* 2 * Copyright (c) 2007, 2010, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23/* 24 * 25 */ 26 27package com.foo; 28 29import java.text.*; 30import java.text.spi.*; 31import java.util.*; 32 33import com.foobar.Utils; 34 35public class NumberFormatProviderImpl extends NumberFormatProvider { 36 37 static Locale[] avail = { 38 Locale.JAPAN, 39 new Locale("ja", "JP", "osaka"), 40 new Locale("ja", "JP", "kyoto"), 41 new Locale("zz")}; 42 43 static String[] dialect = { 44 "\u3067\u3059\u3002", 45 "\u3084\u3002", 46 "\u3069\u3059\u3002", 47 "-zz" 48 }; 49 50 static String[] patterns = { 51 "#,##0.###{0};-#,##0.###{1}", // decimal pattern 52 "#{0};(#){1}", // integer pattern 53 "\u00A4#,##0{0};-\u00A4#,##0{1}", // currency pattern 54 "#,##0%{0}" // percent pattern 55 }; 56 // Constants used by factory methods to specify a style of format. 57 static final int NUMBERSTYLE = 0; 58 static final int INTEGERSTYLE = 1; 59 static final int CURRENCYSTYLE = 2; 60 static final int PERCENTSTYLE = 3; 61 62 public Locale[] getAvailableLocales() { 63 return avail; 64 } 65 66 public NumberFormat getCurrencyInstance(Locale locale) { 67 for (int i = 0; i < avail.length; i ++) { 68 if (Utils.supportsLocale(avail[i], locale)) { 69 String pattern = 70 MessageFormat.format(patterns[CURRENCYSTYLE], 71 dialect[i], 72 dialect[i]); 73 FooNumberFormat nf = new FooNumberFormat(pattern, 74 DecimalFormatSymbols.getInstance(locale)); 75 adjustForCurrencyDefaultFractionDigits(nf); 76 return nf; 77 } 78 } 79 throw new IllegalArgumentException("locale is not supported: "+locale); 80 } 81 82 public NumberFormat getIntegerInstance(Locale locale) { 83 for (int i = 0; i < avail.length; i ++) { 84 if (Utils.supportsLocale(avail[i], locale)) { 85 String pattern = 86 MessageFormat.format(patterns[INTEGERSTYLE], 87 dialect[i], 88 dialect[i]); 89 FooNumberFormat nf = new FooNumberFormat(pattern, 90 DecimalFormatSymbols.getInstance(locale)); 91 nf.setMaximumFractionDigits(0); 92 nf.setDecimalSeparatorAlwaysShown(false); 93 nf.setParseIntegerOnly(true); 94 return nf; 95 } 96 } 97 throw new IllegalArgumentException("locale is not supported: "+locale); 98 } 99 100 public NumberFormat getNumberInstance(Locale locale) { 101 for (int i = 0; i < avail.length; i ++) { 102 if (Utils.supportsLocale(avail[i], locale)) { 103 String pattern = 104 MessageFormat.format(patterns[NUMBERSTYLE], 105 dialect[i], 106 dialect[i]); 107 return new FooNumberFormat(pattern, 108 DecimalFormatSymbols.getInstance(locale)); 109 } 110 } 111 throw new IllegalArgumentException("locale is not supported: "+locale); 112 } 113 114 public NumberFormat getPercentInstance(Locale locale) { 115 for (int i = 0; i < avail.length; i ++) { 116 if (Utils.supportsLocale(avail[i], locale)) { 117 String pattern = 118 MessageFormat.format(patterns[PERCENTSTYLE], 119 dialect[i]); 120 return new FooNumberFormat(pattern, 121 DecimalFormatSymbols.getInstance(locale)); 122 } 123 } 124 throw new IllegalArgumentException("locale is not supported: "+locale); 125 } 126 127 /** 128 * Adjusts the minimum and maximum fraction digits to values that 129 * are reasonable for the currency's default fraction digits. 130 */ 131 void adjustForCurrencyDefaultFractionDigits(FooNumberFormat nf) { 132 DecimalFormatSymbols dfs = nf.getDecimalFormatSymbols(); 133 Currency currency = dfs.getCurrency(); 134 if (currency == null) { 135 try { 136 currency = Currency.getInstance(dfs.getInternationalCurrencySymbol()); 137 } catch (IllegalArgumentException e) { 138 } 139 } 140 if (currency != null) { 141 int digits = currency.getDefaultFractionDigits(); 142 if (digits != -1) { 143 int oldMinDigits = nf.getMinimumFractionDigits(); 144 // Common patterns are "#.##", "#.00", "#". 145 // Try to adjust all of them in a reasonable way. 146 if (oldMinDigits == nf.getMaximumFractionDigits()) { 147 nf.setMinimumFractionDigits(digits); 148 nf.setMaximumFractionDigits(digits); 149 } else { 150 nf.setMinimumFractionDigits(Math.min(digits, oldMinDigits)); 151 nf.setMaximumFractionDigits(digits); 152 } 153 } 154 } 155 } 156} 157