]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_4_2-src/main/classes/core/src/com/ibm/icu/text/NumberingSystem.java
go
[Dictionary.git] / jars / icu4j-4_4_2-src / main / classes / core / src / com / ibm / icu / text / NumberingSystem.java
1 /*\r
2  *******************************************************************************\r
3  * Copyright (C) 2009-2010, International Business Machines Corporation and    *\r
4  * others. All Rights Reserved.                                                *\r
5  *******************************************************************************\r
6  */\r
7 \r
8 package com.ibm.icu.text;\r
9 \r
10 import java.util.ArrayList;\r
11 import java.util.Locale;\r
12 import java.util.MissingResourceException;\r
13 \r
14 import com.ibm.icu.impl.ICUCache;\r
15 import com.ibm.icu.impl.ICUResourceBundle;\r
16 import com.ibm.icu.impl.SimpleCache;\r
17 import com.ibm.icu.lang.UCharacter;\r
18 import com.ibm.icu.util.ULocale;\r
19 import com.ibm.icu.util.UResourceBundle;\r
20 import com.ibm.icu.util.UResourceBundleIterator;\r
21 \r
22 \r
23 /**\r
24  * <code>NumberingSystem</code> is the base class for all number\r
25  * systems. This class provides the interface for setting different numbering\r
26  * system types, whether it be a simple alternate digit system such as \r
27  * Thai digits or Devanagari digits, or an algorithmic numbering system such\r
28  * as Hebrew numbering or Chinese numbering.\r
29  *\r
30  * @author       John Emmons\r
31  * @stable ICU 4.2\r
32  */\r
33 class NumberingSystem {\r
34 \r
35     /**\r
36      * Default constructor.  Returns a numbering system that uses the Western decimal\r
37      * digits 0 through 9.\r
38      * @stable ICU 4.2\r
39      */\r
40     public NumberingSystem() {\r
41         radix = 10;\r
42         algorithmic = false;\r
43         desc = "0123456789";\r
44     }\r
45 \r
46     /**\r
47      * Factory method for creating a numbering system.\r
48      * @param radix_in The radix for this numbering system.  ICU currently \r
49      * supports only numbering systems whose radix is 10.\r
50      * @param isAlgorithmic_in Specifies whether the numbering system is algorithmic\r
51      * (true) or numeric (false).\r
52      * @param desc_in String used to describe the characteristics of the numbering\r
53      * system.  For numeric systems, this string contains the digits used by the\r
54      * numbering system, in order, starting from zero.  For algorithmic numbering\r
55      * systems, the string contains the name of the RBNF ruleset in the locale's\r
56      * NumberingSystemRules section that will be used to format numbers using\r
57      * this numbering system.\r
58      * @stable ICU 4.2\r
59      */\r
60     public static NumberingSystem getInstance(int radix_in, boolean isAlgorithmic_in, String desc_in ) {\r
61         if ( radix_in < 2 ) {\r
62             throw new IllegalArgumentException("Invalid radix for numbering system");\r
63         }\r
64 \r
65         if ( !isAlgorithmic_in ) {\r
66             if ( desc_in.length() != radix_in || !isValidDigitString(desc_in)) {\r
67                 throw new IllegalArgumentException("Invalid digit string for numbering system");\r
68             }\r
69         }\r
70         NumberingSystem ns = new NumberingSystem();\r
71         ns.radix = radix_in;\r
72         ns.algorithmic = isAlgorithmic_in;\r
73         ns.desc = desc_in;\r
74         return ns;\r
75     }\r
76 \r
77     /**\r
78      * Returns the default numbering system for the specified locale.\r
79      * @stable ICU 4.2\r
80      */\r
81     public static NumberingSystem getInstance(Locale inLocale) {\r
82         return getInstance(ULocale.forLocale(inLocale));\r
83     }\r
84 \r
85     /**\r
86      * Returns the default numbering system for the specified ULocale.\r
87      * @stable ICU 4.2\r
88      */\r
89     public static NumberingSystem getInstance(ULocale locale) {\r
90 \r
91         NumberingSystem ns;\r
92         String defaultNumberingSystem;\r
93         \r
94         // Check for @numbers\r
95         String numbersKeyword = locale.getKeywordValue("numbers");\r
96         if (numbersKeyword != null) {\r
97             ns = getInstanceByName(numbersKeyword);\r
98             if ( ns != null ) {\r
99                 return ns;\r
100             }\r
101         }\r
102 \r
103         // Get the numbering system from the cache\r
104         String baseName = locale.getBaseName();\r
105         ns = cachedLocaleData.get(baseName);\r
106         if (ns != null ) {\r
107             return ns;\r
108         }\r
109         \r
110         // Cache miss, create new instance\r
111         try {\r
112             ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME,locale);\r
113             defaultNumberingSystem = rb.getString("defaultNumberingSystem");\r
114         } catch (MissingResourceException ex) {\r
115             ns = new NumberingSystem();\r
116             cachedLocaleData.put(baseName, ns);\r
117             return ns;\r
118         }\r
119 \r
120         ns = getInstanceByName(defaultNumberingSystem);\r
121         if ( ns != null ) {\r
122            cachedLocaleData.put(baseName, ns);\r
123            return ns;\r
124         }\r
125 \r
126         ns = new NumberingSystem();\r
127         cachedLocaleData.put(baseName, ns);\r
128         return ns;        \r
129         \r
130     }\r
131 \r
132     /**\r
133      * Returns the default numbering system for the default locale.\r
134      * @stable ICU 4.2\r
135      */\r
136     public static NumberingSystem getInstance() {\r
137         return getInstance(ULocale.getDefault());\r
138     }\r
139 \r
140     /**\r
141      * Returns a numbering system from one of the predefined numbering systems\r
142      * known to ICU.  Numbering system names are based on the numbering systems\r
143      * defined in CLDR.  To get a list of available numbering systems, use the\r
144      * getAvailableNames method.\r
145      * @param name The name of the desired numbering system.  Numbering system\r
146      * names often correspond with the name of the script they are associated\r
147      * with.  For example, "thai" for Thai digits, "hebr" for Hebrew numerals.\r
148      * @stable ICU 4.2\r
149      */\r
150     public static NumberingSystem getInstanceByName(String name) {\r
151         int radix;\r
152         boolean isAlgorithmic;\r
153         String description;\r
154         \r
155         // Get the numbering system from the cache\r
156         NumberingSystem ns = cachedStringData.get(name);\r
157         if (ns != null ) {\r
158             return ns;\r
159         }        \r
160         \r
161         try {\r
162             UResourceBundle numberingSystemsInfo = UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "numberingSystems");\r
163             UResourceBundle nsCurrent = numberingSystemsInfo.get("numberingSystems");\r
164             UResourceBundle nsTop = nsCurrent.get(name);\r
165 \r
166             description = nsTop.getString("desc");\r
167             UResourceBundle nsRadixBundle = nsTop.get("radix");\r
168             UResourceBundle nsAlgBundle = nsTop.get("algorithmic");\r
169             radix = nsRadixBundle.getInt();\r
170             int algorithmic = nsAlgBundle.getInt();\r
171 \r
172             isAlgorithmic = ( algorithmic == 1 );\r
173 \r
174         } catch (MissingResourceException ex) {\r
175             return null;\r
176         }\r
177 \r
178         ns = getInstance(radix,isAlgorithmic,description);\r
179         cachedStringData.put(name, ns);                       \r
180         return ns;     \r
181     }\r
182 \r
183     /**\r
184      * Returns a string array containing a list of the names of numbering systems\r
185      * currently known to ICU.\r
186      * @stable ICU 4.2\r
187      */\r
188     public static String [] getAvailableNames() {\r
189     \r
190             UResourceBundle numberingSystemsInfo = UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "numberingSystems");\r
191             UResourceBundle nsCurrent = numberingSystemsInfo.get("numberingSystems");\r
192             UResourceBundle temp;\r
193 \r
194             String nsName;\r
195             ArrayList<String> output = new ArrayList<String>();\r
196             UResourceBundleIterator it = nsCurrent.getIterator();\r
197             while (it.hasNext()) {\r
198                 temp = it.next();\r
199                 nsName = temp.getKey();\r
200                 output.add(nsName);\r
201             }\r
202             return output.toArray(new String[output.size()]);\r
203     }\r
204 \r
205     /**\r
206      * Convenience method to determine if a given digit string is valid for use as a \r
207      * descriptor of a numeric ( non-algorithmic ) numbering system.  In order for\r
208      * a digit string to be valid, it must meet the following criteria:\r
209      * 1. It must only contain characters that are decimal digits as defined by Unicode.\r
210      * 2. It must contain characters that are contiguous code points.\r
211      * 3. Digits must be in Unicode's basic multilingual plane.\r
212      * @stable ICU 4.2\r
213      */\r
214     public static boolean isValidDigitString(String str) {\r
215 \r
216         int c;\r
217         int prev = 0;\r
218         int i = 0;\r
219         UCharacterIterator it = UCharacterIterator.getInstance(str);\r
220 \r
221         it.setToStart();\r
222         while ( (c = it.nextCodePoint()) != UCharacterIterator.DONE) {\r
223             if ( UCharacter.digit(c) != i ) { // Digits outside the Unicode decimal digit class are not currently supported\r
224                 return false;\r
225             }\r
226             if ( prev != 0 && c != prev + 1 ) { // Non-contiguous digits are not currently supported\r
227                 return false;\r
228             }\r
229             if ( UCharacter.isSupplementary(c)) { // Digits outside the BMP are not currently supported\r
230                 return false;\r
231             }\r
232             i++;\r
233             prev = c;\r
234         }\r
235         return true;\r
236     }\r
237 \r
238     /**\r
239      * Returns the radix of the current numbering system.\r
240      * @stable ICU 4.2\r
241      */\r
242     public int getRadix() {\r
243         return radix;\r
244     }\r
245 \r
246     /**\r
247      * Returns the description string of the current numbering system.\r
248      * The description string describes the characteristics of the numbering\r
249      * system.  For numeric systems, this string contains the digits used by the\r
250      * numbering system, in order, starting from zero.  For algorithmic numbering\r
251      * systems, the string contains the name of the RBNF ruleset in the locale's\r
252      * NumberingSystemRules section that will be used to format numbers using\r
253      * this numbering system.\r
254      * @stable ICU 4.2\r
255      */\r
256     public String getDescription() {\r
257         return desc;\r
258     }\r
259 \r
260     /**\r
261      * Returns the numbering system's algorithmic status.  If true,\r
262      * the numbering system is algorithmic and uses an RBNF formatter to\r
263      * format numerals.  If false, the numbering system is numeric and\r
264      * uses a fixed set of digits. \r
265      * @stable ICU 4.2\r
266      */\r
267     public boolean isAlgorithmic() {\r
268         return algorithmic;\r
269     }\r
270 \r
271     private String desc;\r
272     private int radix;\r
273     private boolean algorithmic;\r
274 \r
275     /**\r
276      * Cache to hold the NumberingSystems by Locale.\r
277      */\r
278     private static ICUCache<String, NumberingSystem> cachedLocaleData = new SimpleCache<String, NumberingSystem>();\r
279         \r
280     /**\r
281      * Cache to hold the NumberingSystems by name.\r
282      */\r
283     private static ICUCache<String, NumberingSystem> cachedStringData = new SimpleCache<String, NumberingSystem>();\r
284     \r
285 }\r