1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html#License
3 /*
4  *******************************************************************************
5  * Copyright (C) 2009-2016, International Business Machines Corporation and
6  * others. All Rights Reserved.
7  *******************************************************************************
8  */
9 package com.ibm.icu.impl;
10 
11 import java.util.Collections;
12 import java.util.Map;
13 
14 import com.ibm.icu.text.CurrencyDisplayNames;
15 import com.ibm.icu.text.DecimalFormatSymbols;
16 import com.ibm.icu.util.ULocale;
17 
18 public class CurrencyData {
19     public static final CurrencyDisplayInfoProvider provider;
20 
CurrencyData()21     private CurrencyData() {}
22 
23     public static interface CurrencyDisplayInfoProvider {
getInstance(ULocale locale, boolean withFallback)24         CurrencyDisplayInfo getInstance(ULocale locale, boolean withFallback);
hasData()25         boolean hasData();
26     }
27 
28     public static abstract class CurrencyDisplayInfo extends CurrencyDisplayNames {
getUnitPatterns()29         public abstract Map<String, String> getUnitPatterns();
getFormatInfo(String isoCode)30         public abstract CurrencyFormatInfo getFormatInfo(String isoCode);
getSpacingInfo()31         public abstract CurrencySpacingInfo getSpacingInfo();
32     }
33 
34     public static final class CurrencyFormatInfo {
35         public final String isoCode;
36         public final String currencyPattern;
37         public final String monetaryDecimalSeparator;
38         public final String monetaryGroupingSeparator;
39 
CurrencyFormatInfo(String isoCode, String currencyPattern, String monetarySeparator, String monetaryGroupingSeparator)40         public CurrencyFormatInfo(String isoCode, String currencyPattern, String monetarySeparator,
41                 String monetaryGroupingSeparator) {
42             this.isoCode = isoCode;
43             this.currencyPattern = currencyPattern;
44             this.monetaryDecimalSeparator = monetarySeparator;
45             this.monetaryGroupingSeparator = monetaryGroupingSeparator;
46         }
47     }
48 
49     public static final class CurrencySpacingInfo {
50         private final String[][] symbols = new String[SpacingType.COUNT.ordinal()][SpacingPattern.COUNT.ordinal()];
51 
52         public boolean hasBeforeCurrency = false;
53         public boolean hasAfterCurrency = false;
54 
55         public static enum SpacingType { BEFORE, AFTER, COUNT };
56         public static enum SpacingPattern {
57             CURRENCY_MATCH(DecimalFormatSymbols.CURRENCY_SPC_CURRENCY_MATCH),
58             SURROUNDING_MATCH(DecimalFormatSymbols.CURRENCY_SPC_SURROUNDING_MATCH),
59             INSERT_BETWEEN(DecimalFormatSymbols.CURRENCY_SPC_INSERT),
60             COUNT;
61 
SpacingPattern()62             SpacingPattern() {}
SpacingPattern(int value)63             SpacingPattern(int value) { assert value == ordinal(); }
64         };
65 
CurrencySpacingInfo()66         public CurrencySpacingInfo() {}
67 
CurrencySpacingInfo(String... strings)68         public CurrencySpacingInfo(String... strings) {
69             assert strings.length == 6;
70 
71             int k = 0;
72             for (int i=0; i<SpacingType.COUNT.ordinal(); i++) {
73                 for (int j=0; j<SpacingPattern.COUNT.ordinal(); j++) {
74                     symbols[i][j] = strings[k];
75                     k++;
76                 }
77             }
78         }
79 
setSymbolIfNull(SpacingType type, SpacingPattern pattern, String value)80         public void setSymbolIfNull(SpacingType type, SpacingPattern pattern, String value) {
81             int i = type.ordinal();
82             int j = pattern.ordinal();
83             if (symbols[i][j] == null) {
84                 symbols[i][j] = value;
85             }
86         }
87 
getBeforeSymbols()88         public String[] getBeforeSymbols() {
89             return symbols[SpacingType.BEFORE.ordinal()];
90         }
91 
getAfterSymbols()92         public String[] getAfterSymbols() {
93             return symbols[SpacingType.AFTER.ordinal()];
94         }
95 
96         private static final String DEFAULT_CUR_MATCH = "[:letter:]";
97         private static final String DEFAULT_CTX_MATCH = "[:digit:]";
98         private static final String DEFAULT_INSERT = " ";
99 
100         public static final CurrencySpacingInfo DEFAULT = new CurrencySpacingInfo(
101                 DEFAULT_CUR_MATCH, DEFAULT_CTX_MATCH, DEFAULT_INSERT,
102                 DEFAULT_CUR_MATCH, DEFAULT_CTX_MATCH, DEFAULT_INSERT);
103     }
104 
105     static {
106         CurrencyDisplayInfoProvider temp = null;
107         try {
108             Class<?> clzz = Class.forName("com.ibm.icu.impl.ICUCurrencyDisplayInfoProvider");
109             temp = (CurrencyDisplayInfoProvider) clzz.newInstance();
110         } catch (Throwable t) {
111             temp = new CurrencyDisplayInfoProvider() {
112                 @Override
113                 public CurrencyDisplayInfo getInstance(ULocale locale, boolean withFallback) {
114                     return DefaultInfo.getWithFallback(withFallback);
115                 }
116 
117                 @Override
118                 public boolean hasData() {
119                     return false;
120                 }
121             };
122         }
123         provider = temp;
124     }
125 
126     public static class DefaultInfo extends CurrencyDisplayInfo {
127         private final boolean fallback;
128 
DefaultInfo(boolean fallback)129         private DefaultInfo(boolean fallback) {
130             this.fallback = fallback;
131         }
132 
getWithFallback(boolean fallback)133         public static final CurrencyDisplayInfo getWithFallback(boolean fallback) {
134             return fallback ? FALLBACK_INSTANCE : NO_FALLBACK_INSTANCE;
135         }
136 
137         @Override
getName(String isoCode)138         public String getName(String isoCode) {
139             return fallback ? isoCode : null;
140         }
141 
142         @Override
getPluralName(String isoCode, String pluralType)143         public String getPluralName(String isoCode, String pluralType) {
144             return fallback ? isoCode : null;
145         }
146 
147         @Override
getSymbol(String isoCode)148         public String getSymbol(String isoCode) {
149             return fallback ? isoCode : null;
150         }
151 
152         @Override
getNarrowSymbol(String isoCode)153         public String getNarrowSymbol(String isoCode) {
154             return fallback ? isoCode : null;
155         }
156 
157         @Override
symbolMap()158         public Map<String, String> symbolMap() {
159             return Collections.emptyMap();
160         }
161 
162         @Override
nameMap()163         public Map<String, String> nameMap() {
164             return Collections.emptyMap();
165         }
166 
167         @Override
getULocale()168         public ULocale getULocale() {
169             return ULocale.ROOT;
170         }
171 
172         @Override
getUnitPatterns()173         public Map<String, String> getUnitPatterns() {
174             if (fallback) {
175                 return Collections.emptyMap();
176             }
177             return null;
178         }
179 
180         @Override
getFormatInfo(String isoCode)181         public CurrencyFormatInfo getFormatInfo(String isoCode) {
182             return null;
183         }
184 
185         @Override
getSpacingInfo()186         public CurrencySpacingInfo getSpacingInfo() {
187             return fallback ? CurrencySpacingInfo.DEFAULT : null;
188         }
189 
190         private static final CurrencyDisplayInfo FALLBACK_INSTANCE = new DefaultInfo(true);
191         private static final CurrencyDisplayInfo NO_FALLBACK_INSTANCE = new DefaultInfo(false);
192     }
193 }
194