]> granicus.if.org Git - icu/commitdiff
ICU-12534 Optimizing currency spacing data loading in ICUCurrencyDisplayInfoProvider...
authorShane Carr <shane@unicode.org>
Tue, 31 May 2016 16:34:58 +0000 (16:34 +0000)
committerShane Carr <shane@unicode.org>
Tue, 31 May 2016 16:34:58 +0000 (16:34 +0000)
X-SVN-Rev: 38772

icu4j/main/classes/core/src/com/ibm/icu/impl/CurrencyData.java
icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormatSymbols.java
icu4j/main/classes/currdata/src/com/ibm/icu/impl/ICUCurrencyDisplayInfoProvider.java

index 343a45c4f2012bd41db39340fa60451956545a1b..e3d8bc8291354623be00f6b58b3447c51bea6dfa 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *******************************************************************************
- * Copyright (C) 2009-2012, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
+ * Copyright (C) 2009-2016, International Business Machines Corporation and
+ * others. All Rights Reserved.
  *******************************************************************************
  */
 package com.ibm.icu.impl;
@@ -40,24 +40,40 @@ public class CurrencyData {
     }
 
     public static final class CurrencySpacingInfo {
-        public final String beforeCurrencyMatch;
-        public final String beforeContextMatch;
-        public final String beforeInsert;
-        public final String afterCurrencyMatch;
-        public final String afterContextMatch;
-        public final String afterInsert;
-
-        public CurrencySpacingInfo(
-                String beforeCurrencyMatch, String beforeContextMatch, String beforeInsert,
-                String afterCurrencyMatch, String afterContextMatch, String afterInsert) {
-            this.beforeCurrencyMatch = beforeCurrencyMatch;
-            this.beforeContextMatch = beforeContextMatch;
-            this.beforeInsert = beforeInsert;
-            this.afterCurrencyMatch = afterCurrencyMatch;
-            this.afterContextMatch = afterContextMatch;
-            this.afterInsert = afterInsert;
+        private final String[][] symbols = new String[SpacingType.COUNT.ordinal()][SpacingPattern.COUNT.ordinal()];
+
+        public static enum SpacingType { BEFORE, AFTER, COUNT };
+        public static enum SpacingPattern { CURRENCY_MATCH, SURROUNDING_MATCH, INSERT_BETWEEN, COUNT };
+
+        public CurrencySpacingInfo() {}
+
+        public CurrencySpacingInfo(String... strings) {
+            assert strings.length == 6;
+
+            int k = 0;
+            for (int i=0; i<SpacingType.COUNT.ordinal(); i++) {
+                for (int j=0; j<SpacingPattern.COUNT.ordinal(); j++) {
+                    symbols[i][j] = strings[k];
+                    k++;
+                }
+            }
         }
 
+        public void setSymbolIfNull(SpacingType type, SpacingPattern pattern, String value) {
+            int i = type.ordinal();
+            int j = pattern.ordinal();
+            if (symbols[i][j] == null) {
+                symbols[i][j] = value;
+            }
+        }
+
+        public String[] getBeforeSymbols() {
+            return symbols[SpacingType.BEFORE.ordinal()];
+        }
+
+        public String[] getAfterSymbols() {
+            return symbols[SpacingType.AFTER.ordinal()];
+        }
 
         private static final String DEFAULT_CUR_MATCH = "[:letter:]";
         private static final String DEFAULT_CTX_MATCH = "[:digit:]";
index 154a85da0081afcc4090689155b8db3fdb734f64..8a9a59ba1c72b7b90b25ec321f60c2ac46f92853 100644 (file)
@@ -662,20 +662,23 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
      * {@icu} Indicates the currency match pattern used in {@link #getPatternForCurrencySpacing}.
      * @stable ICU 4.2
      */
-    public static final int CURRENCY_SPC_CURRENCY_MATCH = 0;
+    public static final int CURRENCY_SPC_CURRENCY_MATCH =
+            CurrencySpacingInfo.SpacingPattern.CURRENCY_MATCH.ordinal();
 
     /**
      * {@icu} Indicates the surrounding match pattern used in {@link
      * #getPatternForCurrencySpacing}.
      * @stable ICU 4.2
      */
-    public static final int CURRENCY_SPC_SURROUNDING_MATCH = 1;
+    public static final int CURRENCY_SPC_SURROUNDING_MATCH =
+            CurrencySpacingInfo.SpacingPattern.SURROUNDING_MATCH.ordinal();
 
     /**
      * {@icu} Indicates the insertion value used in {@link #getPatternForCurrencySpacing}.
      * @stable ICU 4.4
      */
-    public static final int CURRENCY_SPC_INSERT = 2;
+    public static final int CURRENCY_SPC_INSERT =
+            CurrencySpacingInfo.SpacingPattern.INSERT_BETWEEN.ordinal();
 
     private String[] currencySpcBeforeSym;
     private String[] currencySpcAfterSym;
@@ -976,8 +979,6 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
 
 
         // Get currency spacing data.
-        currencySpcBeforeSym = new String[3];
-        currencySpcAfterSym = new String[3];
         initSpacingInfo(info.getSpacingInfo());
     }
 
@@ -1064,12 +1065,8 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
     }
 
     private void initSpacingInfo(CurrencySpacingInfo spcInfo) {
-        currencySpcBeforeSym[CURRENCY_SPC_CURRENCY_MATCH] = spcInfo.beforeCurrencyMatch;
-        currencySpcBeforeSym[CURRENCY_SPC_SURROUNDING_MATCH] = spcInfo.beforeContextMatch;
-        currencySpcBeforeSym[CURRENCY_SPC_INSERT] = spcInfo.beforeInsert;
-        currencySpcAfterSym[CURRENCY_SPC_CURRENCY_MATCH] = spcInfo.afterCurrencyMatch;
-        currencySpcAfterSym[CURRENCY_SPC_SURROUNDING_MATCH] = spcInfo.afterContextMatch;
-        currencySpcAfterSym[CURRENCY_SPC_INSERT] = spcInfo.afterInsert;
+        currencySpcBeforeSym = spcInfo.getBeforeSymbols();
+        currencySpcAfterSym = spcInfo.getAfterSymbols();
     }
 
     /**
index af4eb1b936564c1962b8489a46c5b29c66eadd6e..5392904105b145b85e890769e18a8702d2a1ccde 100644 (file)
@@ -136,7 +136,7 @@ public class ICUCurrencyDisplayInfoProvider implements CurrencyDisplayInfoProvid
             return map;
         }
 
-       @Override
+        @Override
         public Map<String, String> getUnitPatterns() {
             Map<String, String> result = new HashMap<String, String>();
 
@@ -183,24 +183,72 @@ public class ICUCurrencyDisplayInfoProvider implements CurrencyDisplayInfoProvid
 
         @Override
         public CurrencySpacingInfo getSpacingInfo() {
-            ICUResourceBundle srb = rb.findWithFallback("currencySpacing");
-            if (srb != null) {
-                ICUResourceBundle brb = srb.findWithFallback("beforeCurrency");
-                ICUResourceBundle arb = srb.findWithFallback("afterCurrency");
-                if (arb != null && brb != null) {
-                    String beforeCurrencyMatch = brb.findStringWithFallback("currencyMatch");
-                    String beforeContextMatch = brb.findStringWithFallback("surroundingMatch");
-                    String beforeInsert = brb.findStringWithFallback("insertBetween");
-                    String afterCurrencyMatch = arb.findStringWithFallback("currencyMatch");
-                    String afterContextMatch = arb.findStringWithFallback("surroundingMatch");
-                    String afterInsert = arb.findStringWithFallback("insertBetween");
-
-                    return new CurrencySpacingInfo(
-                            beforeCurrencyMatch, beforeContextMatch, beforeInsert,
-                            afterCurrencyMatch, afterContextMatch, afterInsert);
+            SpacingInfoSink sink = new SpacingInfoSink();
+            rb.getAllItemsWithFallback("currencySpacing", sink);
+            return sink.getSpacingInfo(fallback);
+        }
+
+        private final class SpacingInfoSink extends UResource.Sink {
+            CurrencySpacingInfo spacingInfo = new CurrencySpacingInfo();
+            boolean hasBeforeCurrency = false;
+            boolean hasAfterCurrency = false;
+
+            /*
+             *  currencySpacing{
+             *      afterCurrency{
+             *          currencyMatch{"[:^S:]"}
+             *          insertBetween{" "}
+             *          surroundingMatch{"[:digit:]"}
+             *      }
+             *      beforeCurrency{
+             *          currencyMatch{"[:^S:]"}
+             *          insertBetween{" "}
+             *          surroundingMatch{"[:digit:]"}
+             *      }
+             *  }
+             */
+            @Override
+            public void put(UResource.Key key, UResource.Value value, boolean noFallback) {
+                UResource.Table spacingTypesTable = value.getTable();
+                for (int i = 0; spacingTypesTable.getKeyAndValue(i, key, value); ++i) {
+                    CurrencySpacingInfo.SpacingType type;
+                    if (key.contentEquals("beforeCurrency")) {
+                        type = CurrencySpacingInfo.SpacingType.BEFORE;
+                        hasBeforeCurrency = true;
+                    } else if (key.contentEquals("afterCurrency")) {
+                        type = CurrencySpacingInfo.SpacingType.AFTER;
+                        hasAfterCurrency = true;
+                    } else {
+                        continue;
+                    }
+
+                    UResource.Table patternsTable = value.getTable();
+                    for (int j = 0; patternsTable.getKeyAndValue(j, key, value); ++j) {
+                        CurrencySpacingInfo.SpacingPattern pattern;
+                        if (key.contentEquals("currencyMatch")) {
+                            pattern = CurrencySpacingInfo.SpacingPattern.CURRENCY_MATCH;
+                        } else if (key.contentEquals("surroundingMatch")) {
+                            pattern = CurrencySpacingInfo.SpacingPattern.SURROUNDING_MATCH;
+                        } else if (key.contentEquals("insertBetween")) {
+                            pattern = CurrencySpacingInfo.SpacingPattern.INSERT_BETWEEN;
+                        } else {
+                            continue;
+                        }
+
+                        spacingInfo.setSymbolIfNull(type, pattern, value.getString());
+                    }
+                }
+            }
+
+            CurrencySpacingInfo getSpacingInfo(boolean fallback) {
+                if (hasBeforeCurrency && hasAfterCurrency) {
+                    return spacingInfo;
+                } else if (fallback) {
+                    return CurrencySpacingInfo.DEFAULT;
+                } else {
+                    return null;
                 }
             }
-            return fallback ? CurrencySpacingInfo.DEFAULT : null;
         }
 
         private Map<String, String> _createSymbolMap() {