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.ICUCloneNotSupportedException;
|
||||||
import com.ibm.icu.util.ULocale;
|
import com.ibm.icu.util.ULocale;
|
||||||
import com.ibm.icu.util.ULocale.Category;
|
import com.ibm.icu.util.ULocale.Category;
|
||||||
|
import com.ibm.icu.impl.UResource;
|
||||||
import com.ibm.icu.util.UResourceBundle;
|
import com.ibm.icu.util.UResourceBundle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -840,6 +841,84 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
return (c=='\u200E' || c=='\u200F' || c=='\u061C');
|
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.
|
* Initializes the symbols from the LocaleElements resource bundle.
|
||||||
* Note: The organization of LocaleElements badly needs to be
|
* 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[7] = DecimalFormat.PATTERN_SEVEN_DIGIT;
|
||||||
digits[8] = DecimalFormat.PATTERN_EIGHT_DIGIT;
|
digits[8] = DecimalFormat.PATTERN_EIGHT_DIGIT;
|
||||||
digits[9] = DecimalFormat.PATTERN_NINE_DIGIT;
|
digits[9] = DecimalFormat.PATTERN_NINE_DIGIT;
|
||||||
nsName = "latn"; // Default numbering system
|
nsName = LATIN_NUMBERING_SYSTEM; // Default numbering system
|
||||||
}
|
}
|
||||||
|
|
||||||
/* try the cache first */
|
// Open the resource bundle and get the locale IDs
|
||||||
String[][] data = cachedLocaleData.get(locale);
|
// TODO: Is there a better way to get the locale than making an ICUResourceBundle instance?
|
||||||
String[] numberElements;
|
|
||||||
if (data == null) { /* cache miss */
|
|
||||||
data = new String[1][];
|
|
||||||
ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.
|
ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.
|
||||||
getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, locale);
|
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.
|
// TODO: Determine actual and valid locale correctly.
|
||||||
ULocale uloc = r.getULocale();
|
ULocale uloc = rb.getULocale();
|
||||||
setLocale(uloc, uloc);
|
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);
|
decimalSeparator = numberElements[0].charAt(0);
|
||||||
groupingSeparator = numberElements[1].charAt(0);
|
groupingSeparator = numberElements[1].charAt(0);
|
||||||
patternSeparator = numberElements[2].charAt(0);
|
patternSeparator = numberElements[2].charAt(0);
|
||||||
@ -936,24 +1030,9 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
perMill = numberElements[7].charAt(0);
|
perMill = numberElements[7].charAt(0);
|
||||||
infinity = numberElements[8];
|
infinity = numberElements[8];
|
||||||
NaN = numberElements[9];
|
NaN = numberElements[9];
|
||||||
|
|
||||||
if ( numberElements[10] != null) {
|
|
||||||
monetarySeparator = numberElements[10].charAt(0);
|
monetarySeparator = numberElements[10].charAt(0);
|
||||||
} else {
|
|
||||||
monetarySeparator = decimalSeparator;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( numberElements[11] != null) {
|
|
||||||
monetaryGroupingSeparator = numberElements[11].charAt(0);
|
monetaryGroupingSeparator = numberElements[11].charAt(0);
|
||||||
} else {
|
|
||||||
monetaryGroupingSeparator = groupingSeparator;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( numberElements[12] != null) {
|
|
||||||
exponentMultiplicationSign = numberElements[12];
|
exponentMultiplicationSign = numberElements[12];
|
||||||
} else {
|
|
||||||
exponentMultiplicationSign = "\u00D7";
|
|
||||||
}
|
|
||||||
|
|
||||||
digit = DecimalFormat.PATTERN_DIGIT; // Localized pattern character no longer in CLDR
|
digit = DecimalFormat.PATTERN_DIGIT; // Localized pattern character no longer in CLDR
|
||||||
padEscape = DecimalFormat.PATTERN_PAD_ESCAPE;
|
padEscape = DecimalFormat.PATTERN_PAD_ESCAPE;
|
||||||
|
Loading…
Reference in New Issue
Block a user