• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.unicode.cldr.test;
2 
3 import java.util.HashMap;
4 import java.util.Iterator;
5 import java.util.Locale;
6 import java.util.Map;
7 import java.util.Set;
8 import java.util.TreeMap;
9 import java.util.regex.Pattern;
10 
11 import org.unicode.cldr.util.CLDRFile;
12 import org.unicode.cldr.util.ICUServiceBuilder;
13 import org.unicode.cldr.util.PatternCache;
14 import org.unicode.cldr.util.SupplementalDataInfo;
15 import org.unicode.cldr.util.XPathParts;
16 
17 import com.ibm.icu.impl.number.DecimalFormatProperties;
18 import com.ibm.icu.impl.number.PatternStringParser;
19 import com.ibm.icu.text.CompactDecimalFormat;
20 import com.ibm.icu.text.CompactDecimalFormat.CompactStyle;
21 import com.ibm.icu.text.DecimalFormat;
22 import com.ibm.icu.text.DecimalFormat.PropertySetter;
23 import com.ibm.icu.text.PluralRules;
24 import com.ibm.icu.util.Currency;
25 import com.ibm.icu.util.ULocale;
26 
27 @SuppressWarnings("deprecation")
28 public class BuildIcuCompactDecimalFormat {
29     static SupplementalDataInfo sdi = SupplementalDataInfo.getInstance();
30     static final int MINIMUM_ARRAY_LENGTH = 15;
31     static final Pattern PATTERN = PatternCache.get("([^0,]*)([0]+)([.]0+)?([^0]*)");
32     static final Pattern TYPE = PatternCache.get("1([0]*)");
33     private static final boolean DEBUG = false;
34 
35     public enum CurrencyStyle {
36         PLAIN, CURRENCY, LONG_CURRENCY, ISO_CURRENCY, UNIT
37     }
38 
39     /**
40      * JUST FOR DEVELOPMENT
41      *
42      * @param currencyStyle
43      * @param currencyCode
44      */
build( CLDRFile resolvedCldrFile, Set<String> debugCreationErrors, String[] debugOriginals, CompactStyle style, ULocale locale, CurrencyStyle currencyStyle, String currencyCodeOrUnit)45     public static final CompactDecimalFormat build(
46         CLDRFile resolvedCldrFile,
47         Set<String> debugCreationErrors, String[] debugOriginals,
48         CompactStyle style, ULocale locale, CurrencyStyle currencyStyle, String currencyCodeOrUnit) {
49 
50         // get the custom data from CLDR for use with the special setCompactCustomData
51 
52         final Map<String, Map<String, String>> customData = buildCustomData(resolvedCldrFile, style, currencyStyle);
53         if (DEBUG) {
54             System.out.println("\nCustom Data:");
55             customData.forEach((k, v) -> System.out.println("\t" + k + "\t" + v));
56         }
57 
58         // get the common CLDR data used for number/date/time formats
59 
60         ICUServiceBuilder builder = new ICUServiceBuilder().setCldrFile(resolvedCldrFile);
61 
62         DecimalFormat decimalFormat = currencyStyle == CurrencyStyle.PLAIN
63             ?  builder.getNumberFormat(1)
64                 : builder.getCurrencyFormat(currencyCodeOrUnit);
65         final String pattern = decimalFormat.toPattern();
66         if (DEBUG) {
67             System.out.println("Pattern:\t" + pattern);
68         }
69 
70         final PluralRules rules = SupplementalDataInfo.getInstance().getPlurals(locale.toString()).getPluralRules();
71 
72         // create a compact decimal format, and reset its data
73 
74         CompactDecimalFormat cdf = CompactDecimalFormat.getInstance(locale, style);
75         cdf.setDecimalFormatSymbols(builder.getDecimalFormatSymbols("latn"));
76 
77         cdf.setProperties(new PropertySetter() {
78             @Override
79             public void set(DecimalFormatProperties props) {
80                 props.setCompactCustomData(customData);
81                 PatternStringParser.parseToExistingProperties(pattern, props, PatternStringParser.IGNORE_ROUNDING_ALWAYS);
82                 props.setPluralRules(rules);
83             }
84         });
85 
86         if (DEBUG) {
87             System.out.println("CompactDecimalFormat:\t" + cdf.toString().replace("}, ", "},\n\t"));
88         }
89         return cdf;
90     }
91 
buildCustomData(CLDRFile resolvedCldrFile, CompactStyle style, CurrencyStyle currencyStyle)92     public static Map<String, Map<String, String>> buildCustomData(CLDRFile resolvedCldrFile, CompactStyle style, CurrencyStyle currencyStyle) {
93 
94         final Map<String, Map<String, String>> customData = new TreeMap<>();
95 
96         String prefix = currencyStyle == CurrencyStyle.PLAIN
97             ? "//ldml/numbers/decimalFormats[@numberSystem=\"latn\"]/decimalFormatLength"
98             : "//ldml/numbers/currencyFormats[@numberSystem=\"latn\"]/currencyFormatLength";
99 
100         Iterator<String> it = resolvedCldrFile.iterator(prefix);
101 
102         String styleString = style.toString().toLowerCase(Locale.ENGLISH);
103         while (it.hasNext()) {
104             String path = it.next();
105             if (path.endsWith("/alias")) {
106                 continue;
107             }
108             XPathParts parts = XPathParts.getFrozenInstance(path);
109             String stype = parts.getAttributeValue(3, "type");
110             if (!styleString.equals(stype)) {
111                 continue;
112             }
113             String type = parts.getAttributeValue(-1, "type");
114             String key = parts.getAttributeValue(-1, "count");
115             String pattern = resolvedCldrFile.getStringValue(path);
116             if (pattern.contentEquals("0")) {
117                 continue;
118             }
119 
120             /*
121                     <pattern type="1000" count="one">0K</pattern>
122              */
123 
124             add(customData, type, key, pattern);
125         }
126         return customData;
127     }
128 
add(Map<A, Map<B, C>> customData, A a, B b, C c)129     private static <A, B, C> void add(Map<A, Map<B, C>> customData, A a, B b, C c) {
130         Map<B, C> inner = customData.get(a);
131         if (inner == null) {
132             customData.put(a, inner = new HashMap<>());
133         }
134         inner.put(b, c);
135     }
136 
137     static class MyCurrencySymbolDisplay {
138         CLDRFile cldrFile;
139 
MyCurrencySymbolDisplay(CLDRFile cldrFile)140         public MyCurrencySymbolDisplay(CLDRFile cldrFile) {
141             this.cldrFile = cldrFile;
142         }
143 
getName(Currency currency, int count)144         public String getName(Currency currency, int count) {
145             final String currencyCode = currency.getCurrencyCode();
146             if (count > 1) {
147                 return currencyCode;
148             }
149             String prefix = "//ldml/numbers/currencies/currency[@type=\"" + currencyCode + "\"]/";
150             String currencySymbol = cldrFile.getWinningValue(prefix + "symbol");
151             return currencySymbol != null ? currencySymbol : currencyCode;
152         }
153     }
154 
155 }
156