From 36eb56695c9ea6c45cde0611efa25586f8c2e01a Mon Sep 17 00:00:00 2001 From: Shane Carr Date: Wed, 4 May 2016 21:14:30 +0000 Subject: [PATCH] ICU-12529 Committing Java version of MeasureUnit data sink. X-SVN-Rev: 38697 --- .../com/ibm/icu/impl/ICUResourceBundle.java | 5 +- .../src/com/ibm/icu/util/MeasureUnit.java | 121 ++++++++++-------- 2 files changed, 74 insertions(+), 52 deletions(-) diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/ICUResourceBundle.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/ICUResourceBundle.java index 82815c75143..0e2b94392ec 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/ICUResourceBundle.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/ICUResourceBundle.java @@ -447,7 +447,8 @@ public class ICUResourceBundle extends UResourceBundle { ICUResourceBundleImpl impl = (ICUResourceBundleImpl)this; readerValue.reader = impl.wholeBundle.reader; readerValue.res = impl.getResource(); - sink.put(key.setString(this.key), readerValue, parent == null); + key.setString(this.key != null ? this.key : ""); + sink.put(key, readerValue, parent == null); } else { expectedType = arraySink != null ? ARRAY : TABLE; if (getType() == expectedType) { @@ -1023,7 +1024,7 @@ public class ICUResourceBundle extends UResourceBundle { } private static int countPathKeys(String path) { - if (path.length() == 0) { + if (path.isEmpty()) { return 0; } int num = 1; diff --git a/icu4j/main/classes/core/src/com/ibm/icu/util/MeasureUnit.java b/icu4j/main/classes/core/src/com/ibm/icu/util/MeasureUnit.java index 93c67706b8d..7adda14dda2 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/util/MeasureUnit.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/util/MeasureUnit.java @@ -13,17 +13,16 @@ import java.io.ObjectOutput; import java.io.ObjectStreamException; import java.io.Serializable; import java.util.Collections; -import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Map; -import java.util.MissingResourceException; import java.util.Set; import com.ibm.icu.impl.ICUData; import com.ibm.icu.impl.ICUResourceBundle; import com.ibm.icu.impl.Pair; import com.ibm.icu.text.UnicodeSet; +import com.ibm.icu.impl.UResource; /** * A unit such as length, mass, volume, currency, etc. A unit is @@ -38,9 +37,6 @@ import com.ibm.icu.text.UnicodeSet; public class MeasureUnit implements Serializable { private static final long serialVersionUID = -1839973855554750484L; - // Used to pre-fill the cache. These same constants appear in MeasureFormat too. - private static final String[] unitKeys = new String[]{"units", "unitsShort", "unitsNarrow"}; - // Cache of MeasureUnits. // All access to the cache or cacheIsPopulated flag must be synchronized on class MeasureUnit, // i.e. from synchronized static methods. Beware of non-static methods. @@ -248,6 +244,53 @@ public class MeasureUnit implements Serializable { } }; + /** + * Sink for enumerating the available measure units. + */ + private static final class MeasureUnitSink extends UResource.Sink { + @Override + public void put(UResource.Key key, UResource.Value value, boolean noFallback) { + UResource.Table unitFormatsTable = value.getTable(); + for (int i1 = 0; unitFormatsTable.getKeyAndValue(i1, key, value); ++i1) { + + // Only consume the tables related to units, defined as those beginning with "units". + if (!key.startsWith("units")) { + continue; + } + + UResource.Table unitTypesTable = value.getTable(); + for (int i2 = 0; unitTypesTable.getKeyAndValue(i2, key, value); ++i2) { + + // Special case: "compound" does not have plural variants. + if (key.contentEquals("compound")) { + continue; + } + + String unitType = key.toString(); + + UResource.Table unitNamesTable = value.getTable(); + for (int i3 = 0; unitNamesTable.getKeyAndValue(i3, key, value); ++i3) { + String unitName = key.toString(); + internalGetInstance(unitType, unitName); + } + } + } + } + } + + /** + * Sink for enumerating the currency numeric codes. + */ + private static final class CurrencyNumericCodeSink extends UResource.Sink { + @Override + public void put(UResource.Key key, UResource.Value value, boolean noFallback) { + UResource.Table codesTable = value.getTable(); + for (int i1 = 0; codesTable.getKeyAndValue(i1, key, value); ++i1) { + internalGetInstance("currency", key.toString()); + } + } + } + /** * Populate the MeasureUnit cache with all types from the data. * Population is done lazily, in response to MeasureUnit.getAvailable() @@ -263,55 +306,33 @@ public class MeasureUnit implements Serializable { * @internal */ static private void populateCache() { - // load all of the units for English, since we know that that is a superset. - /** - * units{ - * duration{ - * day{ - * one{"{0} ден"} - * other{"{0} дена"} - * } - */ if (cacheIsPopulated) { return; } - ICUResourceBundle resource = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME, "en"); - for (String key : unitKeys) { - try { - ICUResourceBundle unitsTypeRes = resource.getWithFallback(key); - int size = unitsTypeRes.getSize(); - for ( int index = 0; index < size; ++index) { - UResourceBundle unitsRes = unitsTypeRes.get(index); - String type = unitsRes.getKey(); - if (type.equals("compound")) { - continue; // special type, does not have any unit plurals - } - int unitsSize = unitsRes.getSize(); - for ( int index2 = 0; index2 < unitsSize; ++index2) { - ICUResourceBundle unitNameRes = (ICUResourceBundle)unitsRes.get(index2); - if (unitNameRes.get("other") != null) { - internalGetInstance(type, unitNameRes.getKey()); - } - } - } - } catch ( MissingResourceException e ) { - continue; - } - } - // preallocate currencies - try { - UResourceBundle bundle = UResourceBundle.getBundleInstance( - ICUData.ICU_BASE_NAME, - "currencyNumericCodes", - ICUResourceBundle.ICU_DATA_CLASS_LOADER); - UResourceBundle codeMap = bundle.get("codeMap"); - for (Enumeration it = codeMap.getKeys(); it.hasMoreElements();) { - MeasureUnit.internalGetInstance("currency", it.nextElement()); - } - } catch (MissingResourceException e) { - // fall through - } cacheIsPopulated = true; + + /* Schema: + * + * units{ + * duration{ + * day{ + * one{"{0} ден"} + * other{"{0} дена"} + * } + */ + + // Load the unit types. Use English, since we know that that is a superset. + ICUResourceBundle rb1 = (ICUResourceBundle) UResourceBundle.getBundleInstance( + ICUData.ICU_BASE_NAME, + "en"); + rb1.getAllItemsWithFallback("", new MeasureUnitSink()); + + // Load the currencies + ICUResourceBundle rb2 = (ICUResourceBundle) UResourceBundle.getBundleInstance( + ICUData.ICU_BASE_NAME, + "currencyNumericCodes", + ICUResourceBundle.ICU_DATA_CLASS_LOADER); + rb2.getAllItemsWithFallback("codeMap", new CurrencyNumericCodeSink()); } /** -- 2.40.0