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