Home | History | Annotate | Download | only in util
      1 /* GENERATED SOURCE. DO NOT MODIFY. */
      2 //  2016 and later: Unicode, Inc. and others.
      3 // License & terms of use: http://www.unicode.org/copyright.html#License
      4 /*
      5  **************************************************************************************
      6  * Copyright (C) 2009-2016, International Business Machines Corporation,
      7  * Google, Inc. and others. All Rights Reserved.
      8  **************************************************************************************
      9  */
     10 package android.icu.util;
     11 
     12 import java.util.MissingResourceException;
     13 
     14 import android.icu.impl.ICUData;
     15 import android.icu.impl.ICUResourceBundle;
     16 import android.icu.text.UnicodeSet;
     17 import android.icu.util.ULocale.Category;
     18 
     19 /**
     20  * A class for accessing miscellaneous data in the locale bundles
     21  * @author ram
     22  */
     23 public final class LocaleData {
     24 
     25     //    private static final String EXEMPLAR_CHARS      = "ExemplarCharacters";
     26     private static final String MEASUREMENT_SYSTEM  = "MeasurementSystem";
     27     private static final String PAPER_SIZE          = "PaperSize";
     28     private static final String LOCALE_DISPLAY_PATTERN  = "localeDisplayPattern";
     29     private static final String PATTERN             = "pattern";
     30     private static final String SEPARATOR           = "separator";
     31     private boolean noSubstitute;
     32     private ICUResourceBundle bundle;
     33     private ICUResourceBundle langBundle;
     34 
     35     /**
     36      * EXType for {@link #getExemplarSet(int, int)}.
     37      * Corresponds to the 'main' (aka 'standard') CLDR exemplars in
     38      * <a href="http://www.unicode.org/reports/tr35/tr35-general.html#Character_Elements">
     39      *   http://www.unicode.org/reports/tr35/tr35-general.html#Character_Elements</a>.
     40      * @hide unsupported on Android
     41      */
     42     public static final int ES_STANDARD = 0;
     43 
     44     /**
     45      * EXType for {@link #getExemplarSet(int, int)}.
     46      * Corresponds to the 'auxiliary' CLDR exemplars in
     47      * <a href="http://www.unicode.org/reports/tr35/tr35-general.html#Character_Elements">
     48      *   http://www.unicode.org/reports/tr35/tr35-general.html#Character_Elements</a>.
     49      * @hide unsupported on Android
     50      */
     51     public static final int ES_AUXILIARY = 1;
     52 
     53     /**
     54      * EXType for {@link #getExemplarSet(int, int)}.
     55      * Corresponds to the 'index' CLDR exemplars in
     56      * <a href="http://www.unicode.org/reports/tr35/tr35-general.html#Character_Elements">
     57      *   http://www.unicode.org/reports/tr35/tr35-general.html#Character_Elements</a>.
     58      * @hide unsupported on Android
     59      */
     60     public static final int ES_INDEX = 2;
     61 
     62     /**
     63      * EXType for {@link #getExemplarSet(int, int)}.
     64      * Corresponds to the 'currencySymbol' CLDR exemplars in
     65      * <a href="http://www.unicode.org/reports/tr35/tr35-general.html#Character_Elements">
     66      *   http://www.unicode.org/reports/tr35/tr35-general.html#Character_Elements</a>.
     67      * Note: This type is no longer supported.
     68      * @deprecated ICU 51
     69      * @hide original deprecated declaration
     70      */
     71     @Deprecated
     72     public static final int ES_CURRENCY = 3;
     73 
     74     /**
     75      * Corresponds to the 'punctuation' CLDR exemplars in
     76      * <a href="http://www.unicode.org/reports/tr35/tr35-general.html#Character_Elements">
     77      *   http://www.unicode.org/reports/tr35/tr35-general.html#Character_Elements</a>.
     78      * EXType for {@link #getExemplarSet(int, int)}.
     79      * @hide unsupported on Android
     80      */
     81     public static final int ES_PUNCTUATION = 4;
     82 
     83     /**
     84      * Count of EXTypes for {@link #getExemplarSet(int, int)}.
     85      * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
     86      * @hide original deprecated declaration
     87      */
     88     @Deprecated
     89     public static final int ES_COUNT = 5;
     90 
     91     /**
     92      * Delimiter type for {@link #getDelimiter(int)}.
     93      */
     94     public static final int QUOTATION_START = 0;
     95 
     96     /**
     97      * Delimiter type for {@link #getDelimiter(int)}.
     98      */
     99     public static final int QUOTATION_END = 1;
    100 
    101     /**
    102      * Delimiter type for {@link #getDelimiter(int)}.
    103      */
    104     public static final int ALT_QUOTATION_START = 2;
    105 
    106     /**
    107      * Delimiter type for {@link #getDelimiter(int)}.
    108      */
    109     public static final int ALT_QUOTATION_END = 3;
    110 
    111     /**
    112      * Count of delimiter types for {@link #getDelimiter(int)}.
    113      * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
    114      * @hide original deprecated declaration
    115      */
    116     @Deprecated
    117     public static final int DELIMITER_COUNT = 4;
    118 
    119     // private constructor to prevent default construction
    120     ///CLOVER:OFF
    121     private LocaleData(){}
    122     ///CLOVER:ON
    123 
    124     /**
    125      * Returns the set of exemplar characters for a locale. Equivalent to calling {@link #getExemplarSet(ULocale, int, int)} with
    126      * the extype == {@link #ES_STANDARD}.
    127      *
    128      * @param locale    Locale for which the exemplar character set
    129      *                  is to be retrieved.
    130      * @param options   Bitmask for options to apply to the exemplar pattern.
    131      *                  Specify zero to retrieve the exemplar set as it is
    132      *                  defined in the locale data.  Specify
    133      *                  UnicodeSet.CASE to retrieve a case-folded exemplar
    134      *                  set.  See {@link UnicodeSet#applyPattern(String,
    135      *                  int)} for a complete list of valid options.  The
    136      *                  IGNORE_SPACE bit is always set, regardless of the
    137      *                  value of 'options'.
    138      * @return          The set of exemplar characters for the given locale.
    139      * @hide unsupported on Android
    140      */
    141     public static UnicodeSet getExemplarSet(ULocale locale, int options) {
    142         return LocaleData.getInstance(locale).getExemplarSet(options, ES_STANDARD);
    143     }
    144 
    145     /**
    146      * Returns the set of exemplar characters for a locale.
    147      * Equivalent to calling new LocaleData(locale).{@link #getExemplarSet(int, int)}.
    148      *
    149      * @param locale    Locale for which the exemplar character set
    150      *                  is to be retrieved.
    151      * @param options   Bitmask for options to apply to the exemplar pattern.
    152      *                  Specify zero to retrieve the exemplar set as it is
    153      *                  defined in the locale data.  Specify
    154      *                  UnicodeSet.CASE to retrieve a case-folded exemplar
    155      *                  set.  See {@link UnicodeSet#applyPattern(String,
    156      *                  int)} for a complete list of valid options.  The
    157      *                  IGNORE_SPACE bit is always set, regardless of the
    158      *                  value of 'options'.
    159      * @param extype    The type of exemplar character set to retrieve.
    160      * @return          The set of exemplar characters for the given locale.
    161      * @hide unsupported on Android
    162      */
    163     public static UnicodeSet getExemplarSet(ULocale locale, int options, int extype) {
    164         return LocaleData.getInstance(locale).getExemplarSet(options, extype);
    165     }
    166 
    167     /**
    168      * Returns the set of exemplar characters for a locale.
    169      *
    170      * @param options   Bitmask for options to apply to the exemplar pattern.
    171      *                  Specify zero to retrieve the exemplar set as it is
    172      *                  defined in the locale data.  Specify
    173      *                  UnicodeSet.CASE to retrieve a case-folded exemplar
    174      *                  set.  See {@link UnicodeSet#applyPattern(String,
    175      *                  int)} for a complete list of valid options.  The
    176      *                  IGNORE_SPACE bit is always set, regardless of the
    177      *                  value of 'options'.
    178      * @param extype    The type of exemplar set to be retrieved,
    179      *                  ES_STANDARD, ES_INDEX, ES_AUXILIARY, or ES_PUNCTUATION
    180      * @return          The set of exemplar characters for the given locale.
    181      *                  If there is nothing available for the locale,
    182      *                  then null is returned if {@link #getNoSubstitute()} is true, otherwise the
    183      *                  root value is returned (which may be UnicodeSet.EMPTY).
    184      * @exception       RuntimeException if the extype is invalid.
    185      * @hide unsupported on Android
    186      */
    187     public UnicodeSet getExemplarSet(int options, int extype) {
    188         String [] exemplarSetTypes = {
    189                 "ExemplarCharacters",
    190                 "AuxExemplarCharacters",
    191                 "ExemplarCharactersIndex",
    192                 "ExemplarCharactersCurrency",
    193                 "ExemplarCharactersPunctuation"
    194         };
    195 
    196         if (extype == ES_CURRENCY) {
    197             // currency symbol exemplar is no longer available
    198             return noSubstitute ? null : UnicodeSet.EMPTY;
    199         }
    200 
    201         try{
    202             final String aKey = exemplarSetTypes[extype]; // will throw an out-of-bounds exception
    203             ICUResourceBundle stringBundle = (ICUResourceBundle) bundle.get(aKey);
    204 
    205             if (noSubstitute && !bundle.isRoot() && stringBundle.isRoot()) {
    206                 return null;
    207             }
    208             String unicodeSetPattern = stringBundle.getString();
    209             return new UnicodeSet(unicodeSetPattern, UnicodeSet.IGNORE_SPACE | options);
    210         } catch (ArrayIndexOutOfBoundsException aiooe) {
    211             throw new IllegalArgumentException(aiooe);
    212         } catch (Exception ex){
    213             return noSubstitute ? null : UnicodeSet.EMPTY;
    214         }
    215     }
    216 
    217     /**
    218      * Gets the LocaleData object associated with the ULocale specified in locale
    219      *
    220      * @param locale    Locale with thich the locale data object is associated.
    221      * @return          A locale data object.
    222      */
    223     public static final LocaleData getInstance(ULocale locale) {
    224         LocaleData ld = new LocaleData();
    225         ld.bundle = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME, locale);
    226         ld.langBundle = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUData.ICU_LANG_BASE_NAME, locale);
    227         ld.noSubstitute = false;
    228         return ld;
    229     }
    230 
    231     /**
    232      * Gets the LocaleData object associated with the default <code>FORMAT</code> locale
    233      *
    234      * @return          A locale data object.
    235      * @see Category#FORMAT
    236      */
    237     public static final LocaleData getInstance() {
    238         return LocaleData.getInstance(ULocale.getDefault(Category.FORMAT));
    239     }
    240 
    241     /**
    242      * Sets the "no substitute" behavior of this locale data object.
    243      *
    244      * @param setting   Value for the no substitute behavior.  If TRUE,
    245      *                  methods of this locale data object will return
    246      *                  an error when no data is available for that method,
    247      *                  given the locale ID supplied to the constructor.
    248      */
    249     public void setNoSubstitute(boolean setting) {
    250         noSubstitute = setting;
    251     }
    252 
    253     /**
    254      * Gets the "no substitute" behavior of this locale data object.
    255      *
    256      * @return          Value for the no substitute behavior.  If TRUE,
    257      *                  methods of this locale data object will return
    258      *                  an error when no data is available for that method,
    259      *                  given the locale ID supplied to the constructor.
    260      */
    261     public boolean getNoSubstitute() {
    262         return noSubstitute;
    263     }
    264 
    265     private static final String [] DELIMITER_TYPES = {
    266         "quotationStart",
    267         "quotationEnd",
    268         "alternateQuotationStart",
    269         "alternateQuotationEnd"
    270     };
    271 
    272     /**
    273      * Retrieves a delimiter string from the locale data.
    274      *
    275      * @param type      The type of delimiter string desired.  Currently,
    276      *                  the valid choices are QUOTATION_START, QUOTATION_END,
    277      *                  ALT_QUOTATION_START, or ALT_QUOTATION_END.
    278      * @return          The desired delimiter string.
    279      */
    280     public String getDelimiter(int type) {
    281         ICUResourceBundle delimitersBundle = (ICUResourceBundle) bundle.get("delimiters");
    282         // Only some of the quotation marks may be here. So we make sure that we do a multilevel fallback.
    283         ICUResourceBundle stringBundle = delimitersBundle.getWithFallback(DELIMITER_TYPES[type]);
    284 
    285         if (noSubstitute && !bundle.isRoot() && stringBundle.isRoot()) {
    286             return null;
    287         }
    288         return stringBundle.getString();
    289     }
    290 
    291     /**
    292      * Utility for getMeasurementSystem and getPaperSize
    293      */
    294     private static UResourceBundle measurementTypeBundleForLocale(ULocale locale, String measurementType){
    295         // Much of this is taken from getCalendarType in impl/CalendarUtil.java
    296         UResourceBundle measTypeBundle = null;
    297         String region = ULocale.getRegionForSupplementalData(locale, true);
    298         try {
    299             UResourceBundle rb = UResourceBundle.getBundleInstance(
    300                     ICUData.ICU_BASE_NAME,
    301                     "supplementalData",
    302                     ICUResourceBundle.ICU_DATA_CLASS_LOADER);
    303             UResourceBundle measurementData = rb.get("measurementData");
    304             UResourceBundle measDataBundle = null;
    305             try {
    306                 measDataBundle = measurementData.get(region);
    307                 measTypeBundle = measDataBundle.get(measurementType);
    308             } catch (MissingResourceException mre) {
    309                 // use "001" as fallback
    310                 measDataBundle = measurementData.get("001");
    311                 measTypeBundle = measDataBundle.get(measurementType);
    312             }
    313         } catch (MissingResourceException mre) {
    314             // fall through
    315         }
    316         return measTypeBundle;
    317     }
    318 
    319 
    320     /**
    321      * Enumeration for representing the measurement systems.
    322      */
    323     public static final class MeasurementSystem{
    324         /**
    325          * Measurement system specified by Le Syst&#x00E8;me International d'Unit&#x00E9;s (SI)
    326          * otherwise known as Metric system.
    327          */
    328         public static final MeasurementSystem SI = new MeasurementSystem();
    329 
    330         /**
    331          * Measurement system followed in the United States of America.
    332          */
    333         public static final MeasurementSystem US = new MeasurementSystem();
    334 
    335         /**
    336          * Mix of metric and imperial units used in Great Britain.
    337          */
    338         public static final MeasurementSystem UK = new MeasurementSystem();
    339 
    340         private MeasurementSystem() {}
    341     }
    342 
    343     /**
    344      * Returns the measurement system used in the locale specified by the locale.
    345      *
    346      * @param locale      The locale for which the measurement system to be retrieved.
    347      * @return MeasurementSystem the measurement system used in the locale.
    348      */
    349     public static final MeasurementSystem getMeasurementSystem(ULocale locale){
    350         UResourceBundle sysBundle = measurementTypeBundleForLocale(locale, MEASUREMENT_SYSTEM);
    351 
    352         switch (sysBundle.getInt()) {
    353         case 0: return MeasurementSystem.SI;
    354         case 1: return MeasurementSystem.US;
    355         case 2: return MeasurementSystem.UK;
    356         default:
    357             // return null if the object is null or is not an instance
    358             // of integer indicating an error
    359             return null;
    360         }
    361     }
    362 
    363     /**
    364      * A class that represents the size of letter head
    365      * used in the country
    366      */
    367     public static final class PaperSize{
    368         private int height;
    369         private int width;
    370 
    371         private PaperSize(int h, int w){
    372             height = h;
    373             width = w;
    374         }
    375         /**
    376          * Retruns the height of the paper
    377          * @return the height
    378          */
    379         public int getHeight(){
    380             return height;
    381         }
    382         /**
    383          * Returns the width of the paper
    384          * @return the width
    385          */
    386         public int getWidth(){
    387             return width;
    388         }
    389     }
    390 
    391     /**
    392      * Returns the size of paper used in the locale. The paper sizes returned are always in
    393      * <em>milli-meters</em>.
    394      * @param locale The locale for which the measurement system to be retrieved.
    395      * @return The paper size used in the locale
    396      */
    397     public static final PaperSize getPaperSize(ULocale locale){
    398         UResourceBundle obj = measurementTypeBundleForLocale(locale, PAPER_SIZE);
    399         int[] size = obj.getIntVector();
    400         return new PaperSize(size[0], size[1]);
    401     }
    402 
    403     /**
    404      * Returns LocaleDisplayPattern for this locale, e.g., {0}({1})
    405      * @return locale display pattern as a String.
    406      * @hide unsupported on Android
    407      */
    408     public String getLocaleDisplayPattern() {
    409         ICUResourceBundle locDispBundle = (ICUResourceBundle) langBundle.get(LOCALE_DISPLAY_PATTERN);
    410         String localeDisplayPattern = locDispBundle.getStringWithFallback(PATTERN);
    411         return localeDisplayPattern;
    412     }
    413 
    414     /**
    415      * Returns LocaleDisplaySeparator for this locale.
    416      * @return locale display separator as a char.
    417      * @hide unsupported on Android
    418      */
    419     public String getLocaleSeparator() {
    420         String sub0 = "{0}";
    421         String sub1 = "{1}";
    422         ICUResourceBundle locDispBundle = (ICUResourceBundle) langBundle.get(LOCALE_DISPLAY_PATTERN);
    423         String  localeSeparator = locDispBundle.getStringWithFallback(SEPARATOR);
    424         int index0 = localeSeparator.indexOf(sub0);
    425         int index1 = localeSeparator.indexOf(sub1);
    426         if (index0 >= 0 && index1 >= 0 && index0 <= index1) {
    427             return localeSeparator.substring(index0 + sub0.length(), index1);
    428         }
    429         return localeSeparator;
    430     }
    431 
    432     private static VersionInfo gCLDRVersion = null;
    433 
    434     /**
    435      * Returns the current CLDR version
    436      */
    437     public static VersionInfo getCLDRVersion() {
    438         // fetching this data should be idempotent.
    439         if(gCLDRVersion == null) {
    440             // from ZoneMeta.java
    441             UResourceBundle supplementalDataBundle = UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME, "supplementalData", ICUResourceBundle.ICU_DATA_CLASS_LOADER);
    442             UResourceBundle cldrVersionBundle = supplementalDataBundle.get("cldrVersion");
    443             gCLDRVersion = VersionInfo.getInstance(cldrVersionBundle.getString());
    444         }
    445         return gCLDRVersion;
    446     }
    447 }
    448