ICU-12521 Updating DecimalFormatSymbols to data sink
X-SVN-Rev: 38676
This commit is contained in:
parent
456857b494
commit
ac7474e79f
@ -24,6 +24,7 @@ import com.ibm.icu.util.Currency;
|
||||
import com.ibm.icu.util.ICUCloneNotSupportedException;
|
||||
import com.ibm.icu.util.ULocale;
|
||||
import com.ibm.icu.util.ULocale.Category;
|
||||
import com.ibm.icu.impl.UResource;
|
||||
import com.ibm.icu.util.UResourceBundle;
|
||||
|
||||
/**
|
||||
@ -840,6 +841,84 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
||||
return (c=='\u200E' || c=='\u200F' || c=='\u061C');
|
||||
}
|
||||
|
||||
/**
|
||||
* List of field names to be loaded from the data files.
|
||||
* The indices of each name into the array correspond to the position of that item in the
|
||||
* numberElements array.
|
||||
*/
|
||||
private static final String[] SYMBOL_KEYS = {
|
||||
"decimal",
|
||||
"group",
|
||||
"list",
|
||||
"percentSign",
|
||||
"minusSign",
|
||||
"plusSign",
|
||||
"exponential",
|
||||
"perMille",
|
||||
"infinity",
|
||||
"nan",
|
||||
"currencyDecimal",
|
||||
"currencyGroup",
|
||||
"superscriptingExponent"
|
||||
};
|
||||
|
||||
/**
|
||||
* List of default values for the symbols.
|
||||
*/
|
||||
private static final String[] SYMBOL_DEFAULTS = new String[] {
|
||||
".", // decimal
|
||||
",", // group
|
||||
";", // list
|
||||
"%", // percentSign
|
||||
"-", // minusSign
|
||||
"+", // plusSign
|
||||
"E", // exponential
|
||||
"\u2030", // perMille
|
||||
"\u221e", // infinity
|
||||
"NaN", // NaN
|
||||
null, // currency decimal
|
||||
null, // currency group
|
||||
"\u00D7" // superscripting exponent
|
||||
};
|
||||
|
||||
/**
|
||||
* Constants for path names in the data bundles.
|
||||
*/
|
||||
private static final String LATIN_NUMBERING_SYSTEM = "latn";
|
||||
private static final String NUMBER_ELEMENTS = "NumberElements";
|
||||
private static final String SYMBOLS = "symbols";
|
||||
|
||||
/**
|
||||
* Sink for enumerating all of the decimal format symbols (more specifically, anything
|
||||
* under the "NumberElements.symbols" tree).
|
||||
*
|
||||
* More specific bundles (en_GB) are enumerated before their parents (en_001, en, root):
|
||||
* Only store a value if it is still missing, that is, it has not been overridden.
|
||||
*/
|
||||
private static final class DecFmtDataSink extends UResource.Sink {
|
||||
|
||||
private String[] numberElements; // Array where to store the characters (set in constructor)
|
||||
|
||||
public DecFmtDataSink(String[] numberElements) {
|
||||
this.numberElements = numberElements;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(UResource.Key key, UResource.Value value, boolean noFallback) {
|
||||
UResource.Table symbolsTable = value.getTable();
|
||||
for (int j = 0; symbolsTable.getKeyAndValue(j, key, value); ++j) {
|
||||
for (int i = 0; i < SYMBOL_KEYS.length; i++) {
|
||||
if (key.contentEquals(SYMBOL_KEYS[i])) {
|
||||
if (numberElements[i] == null) {
|
||||
numberElements[i] = value.toString();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the symbols from the LocaleElements resource bundle.
|
||||
* Note: The organization of LocaleElements badly needs to be
|
||||
@ -878,52 +957,67 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
||||
digits[7] = DecimalFormat.PATTERN_SEVEN_DIGIT;
|
||||
digits[8] = DecimalFormat.PATTERN_EIGHT_DIGIT;
|
||||
digits[9] = DecimalFormat.PATTERN_NINE_DIGIT;
|
||||
nsName = "latn"; // Default numbering system
|
||||
nsName = LATIN_NUMBERING_SYSTEM; // Default numbering system
|
||||
}
|
||||
|
||||
/* try the cache first */
|
||||
String[][] data = cachedLocaleData.get(locale);
|
||||
String[] numberElements;
|
||||
if (data == null) { /* cache miss */
|
||||
data = new String[1][];
|
||||
// Open the resource bundle and get the locale IDs
|
||||
// TODO: Is there a better way to get the locale than making an ICUResourceBundle instance?
|
||||
ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.
|
||||
getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, locale);
|
||||
boolean isLatn = nsName.equals("latn");
|
||||
String baseKey = "NumberElements/" + nsName + "/symbols/";
|
||||
String latnKey = "NumberElements/latn/symbols/";
|
||||
String[] symbolKeys = { "decimal", "group", "list", "percentSign", "minusSign", "plusSign", "exponential", "perMille", "infinity", "nan", "currencyDecimal", "currencyGroup", "superscriptingExponent" };
|
||||
String[] fallbackElements = { ".", ",", ";", "%", "-", "+", "E", "\u2030", "\u221e", "NaN", null, null };
|
||||
String[] symbolsArray = new String[symbolKeys.length];
|
||||
for ( int i = 0 ; i < symbolKeys.length; i++ ) {
|
||||
try {
|
||||
symbolsArray[i] = rb.getStringWithFallback(baseKey+symbolKeys[i]);
|
||||
} catch (MissingResourceException ex) {
|
||||
if (!isLatn) { // Fall back to latn numbering system for symbols if desired symbol isn't found.
|
||||
try {
|
||||
symbolsArray[i] = rb.getStringWithFallback(latnKey+symbolKeys[i]);
|
||||
} catch (MissingResourceException ex1) {
|
||||
symbolsArray[i] = fallbackElements[i];
|
||||
}
|
||||
} else {
|
||||
symbolsArray[i] = fallbackElements[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data[0] = symbolsArray;
|
||||
/* update cache */
|
||||
cachedLocaleData.put(locale, data);
|
||||
}
|
||||
numberElements = data[0];
|
||||
|
||||
ICUResourceBundle r = (ICUResourceBundle)UResourceBundle.
|
||||
getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, locale);
|
||||
|
||||
// TODO: Determine actual and valid locale correctly.
|
||||
ULocale uloc = r.getULocale();
|
||||
ULocale uloc = rb.getULocale();
|
||||
setLocale(uloc, uloc);
|
||||
|
||||
// Try loading from the cache
|
||||
String[][] data = cachedLocaleData.get(locale);
|
||||
if (data == null) {
|
||||
// Cache miss!
|
||||
// TODO: There does not appear to be a good reason why the "data" array is 2-D.
|
||||
data = new String[1][SYMBOL_KEYS.length];
|
||||
|
||||
// Load using a data sink
|
||||
DecFmtDataSink sink = new DecFmtDataSink(data[0]);
|
||||
try {
|
||||
rb.getAllItemsWithFallback(NUMBER_ELEMENTS + "/" + nsName + "/" + SYMBOLS, sink);
|
||||
} catch (MissingResourceException e) {
|
||||
// The symbols don't exist for the given nsName and resource bundle.
|
||||
// Silently ignore and fall back to Latin.
|
||||
}
|
||||
|
||||
// Load the Latin fallback if necessary
|
||||
boolean hasNull = false;
|
||||
for (String entry : data[0]) {
|
||||
if (entry == null) {
|
||||
hasNull = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasNull && !nsName.equals(LATIN_NUMBERING_SYSTEM)) {
|
||||
rb.getAllItemsWithFallback(NUMBER_ELEMENTS + "/" + LATIN_NUMBERING_SYSTEM + "/" + SYMBOLS, sink);
|
||||
}
|
||||
|
||||
// If monetary decimal or grouping were not explicitly set, then set them to be the same as
|
||||
// their non-monetary counterparts.
|
||||
if (data[0][10] == null) {
|
||||
data[0][10] = data[0][0];
|
||||
}
|
||||
if (data[0][11] == null) {
|
||||
data[0][11] = data[0][1];
|
||||
}
|
||||
|
||||
// Fill in any remaining missing values
|
||||
for (int i = 0; i < SYMBOL_KEYS.length; i++) {
|
||||
if (data[0][i] == null) {
|
||||
data[0][i] = SYMBOL_DEFAULTS[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Save in cache
|
||||
cachedLocaleData.put(locale, data);
|
||||
}
|
||||
String[] numberElements = data[0];
|
||||
|
||||
// Copy data from the numberElements map into instance fields
|
||||
decimalSeparator = numberElements[0].charAt(0);
|
||||
groupingSeparator = numberElements[1].charAt(0);
|
||||
patternSeparator = numberElements[2].charAt(0);
|
||||
@ -936,24 +1030,9 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
||||
perMill = numberElements[7].charAt(0);
|
||||
infinity = numberElements[8];
|
||||
NaN = numberElements[9];
|
||||
|
||||
if ( numberElements[10] != null) {
|
||||
monetarySeparator = numberElements[10].charAt(0);
|
||||
} else {
|
||||
monetarySeparator = decimalSeparator;
|
||||
}
|
||||
|
||||
if ( numberElements[11] != null) {
|
||||
monetaryGroupingSeparator = numberElements[11].charAt(0);
|
||||
} else {
|
||||
monetaryGroupingSeparator = groupingSeparator;
|
||||
}
|
||||
|
||||
if ( numberElements[12] != null) {
|
||||
exponentMultiplicationSign = numberElements[12];
|
||||
} else {
|
||||
exponentMultiplicationSign = "\u00D7";
|
||||
}
|
||||
|
||||
digit = DecimalFormat.PATTERN_DIGIT; // Localized pattern character no longer in CLDR
|
||||
padEscape = DecimalFormat.PATTERN_PAD_ESCAPE;
|
||||
|
Loading…
Reference in New Issue
Block a user