2 *******************************************************************************
\r
3 * Copyright (C) 2009, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
8 package com.ibm.icu.text;
\r
10 import java.util.ArrayList;
\r
11 import java.util.Locale;
\r
12 import java.util.MissingResourceException;
\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
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
28 * @author John Emmons
\r
31 class NumberingSystem {
\r
34 * Default constructor. Returns a numbering system that uses the Western decimal
\r
35 * digits 0 through 9.
\r
38 public NumberingSystem() {
\r
40 algorithmic = false;
\r
41 desc = "0123456789";
\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
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
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
68 NumberingSystem ns = new NumberingSystem();
\r
69 ns.radix = radix_in;
\r
70 ns.algorithmic = isAlgorithmic_in;
\r
76 * Returns the default numbering system for the specified locale.
\r
79 public static NumberingSystem getInstance(Locale inLocale) {
\r
80 return getInstance(ULocale.forLocale(inLocale));
\r
84 * Returns the default numbering system for the specified ULocale.
\r
87 public static NumberingSystem getInstance(ULocale locale) {
\r
89 String numbersKeyword = locale.getKeywordValue("numbers");
\r
90 if (numbersKeyword != null) {
\r
91 NumberingSystem ns = getInstanceByName(numbersKeyword);
\r
97 String defaultNumberingSystem;
\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
106 NumberingSystem ns = getInstanceByName(defaultNumberingSystem);
\r
107 if ( ns != null ) {
\r
111 return new NumberingSystem();
\r
115 * Returns the default numbering system for the default locale.
\r
118 public static NumberingSystem getInstance() {
\r
119 return getInstance(ULocale.getDefault());
\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
132 public static NumberingSystem getInstanceByName(String name) {
\r
134 boolean isAlgorithmic;
\r
135 String description;
\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
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
147 isAlgorithmic = ( algorithmic == 1 );
\r
149 } catch (MissingResourceException ex) {
\r
153 return getInstance(radix,isAlgorithmic,description);
\r
157 * Returns a string array containing a list of the names of numbering systems
\r
158 * currently known to ICU.
\r
161 public static String [] getAvailableNames() {
\r
163 UResourceBundle numberingSystemsInfo = UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "numberingSystems");
\r
164 UResourceBundle nsCurrent = numberingSystemsInfo.get("numberingSystems");
\r
165 UResourceBundle temp;
\r
168 ArrayList output = new ArrayList();
\r
169 UResourceBundleIterator it = nsCurrent.getIterator();
\r
170 while (it.hasNext()) {
\r
172 nsName = temp.getKey();
\r
173 output.add(nsName);
\r
175 return (String[]) output.toArray(new String[output.size()]);
\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
187 public static boolean isValidDigitString(String str) {
\r
192 UCharacterIterator it = UCharacterIterator.getInstance(str);
\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
199 if ( prev != 0 && c != prev + 1 ) { // Non-contiguous digits are not currently supported
\r
202 if ( UCharacter.isSupplementary(c)) { // Digits outside the BMP are not currently supported
\r
212 * Returns the radix of the current numbering system.
\r
215 public int getRadix() {
\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
229 public String getDescription() {
\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
240 public boolean isAlgorithmic() {
\r
241 return algorithmic;
\r
245 private String desc;
\r
247 private boolean algorithmic;
\r