| /* |
| ************************************************************************************** |
| * Copyright (C) 2009-2013, Google, Inc.; International Business Machines Corporation * |
| * and others. All Rights Reserved. * |
| ************************************************************************************** |
| */ |
| package com.ibm.icu.util; |
| |
| import java.util.MissingResourceException; |
| |
| import com.ibm.icu.impl.ICUResourceBundle; |
| import com.ibm.icu.text.UnicodeSet; |
| import com.ibm.icu.util.ULocale.Category; |
| |
| /** |
| * A class for accessing miscellaneous data in the locale bundles |
| * @author ram |
| * @stable ICU 2.8 |
| */ |
| public final class LocaleData { |
| |
| // private static final String EXEMPLAR_CHARS = "ExemplarCharacters"; |
| private static final String MEASUREMENT_SYSTEM = "MeasurementSystem"; |
| private static final String PAPER_SIZE = "PaperSize"; |
| private static final String LOCALE_DISPLAY_PATTERN = "localeDisplayPattern"; |
| private static final String PATTERN = "pattern"; |
| private static final String SEPARATOR = "separator"; |
| private boolean noSubstitute; |
| private ICUResourceBundle bundle; |
| private ICUResourceBundle langBundle; |
| |
| /** |
| * EXType for {@link #getExemplarSet(int, int)}. |
| * @stable ICU 3.4 |
| */ |
| public static final int ES_STANDARD = 0; |
| |
| /** |
| * EXType for {@link #getExemplarSet(int, int)}. |
| * @stable ICU 3.4 |
| */ |
| public static final int ES_AUXILIARY = 1; |
| |
| /** |
| * EXType for {@link #getExemplarSet(int, int)}. |
| * @stable ICU 4.4 |
| */ |
| public static final int ES_INDEX = 2; |
| |
| /** |
| * EXType for {@link #getExemplarSet(int, int)}. |
| * Note: This type is no longer supported. |
| * @deprecated ICU 51 |
| */ |
| public static final int ES_CURRENCY = 3; |
| |
| /** |
| * EXType for {@link #getExemplarSet(int, int)}. |
| * @stable ICU 49 |
| */ |
| public static final int ES_PUNCTUATION = 4; |
| |
| /** |
| * Count of EXTypes for {@link #getExemplarSet(int, int)}. |
| * @stable ICU 3.4 |
| */ |
| public static final int ES_COUNT = 5; |
| |
| /** |
| * Delimiter type for {@link #getDelimiter(int)}. |
| * @stable ICU 3.4 |
| */ |
| public static final int QUOTATION_START = 0; |
| |
| /** |
| * Delimiter type for {@link #getDelimiter(int)}. |
| * @stable ICU 3.4 |
| */ |
| public static final int QUOTATION_END = 1; |
| |
| /** |
| * Delimiter type for {@link #getDelimiter(int)}. |
| * @stable ICU 3.4 |
| */ |
| public static final int ALT_QUOTATION_START = 2; |
| |
| /** |
| * Delimiter type for {@link #getDelimiter(int)}. |
| * @stable ICU 3.4 |
| */ |
| public static final int ALT_QUOTATION_END = 3; |
| |
| /** |
| * Count of delimiter types for {@link #getDelimiter(int)}. |
| * @stable ICU 3.4 |
| */ |
| public static final int DELIMITER_COUNT = 4; |
| |
| // private constructor to prevent default construction |
| ///CLOVER:OFF |
| private LocaleData(){} |
| ///CLOVER:ON |
| |
| /** |
| * Returns the set of exemplar characters for a locale. |
| * |
| * @param locale Locale for which the exemplar character set |
| * is to be retrieved. |
| * @param options Bitmask for options to apply to the exemplar pattern. |
| * Specify zero to retrieve the exemplar set as it is |
| * defined in the locale data. Specify |
| * UnicodeSet.CASE to retrieve a case-folded exemplar |
| * set. See {@link UnicodeSet#applyPattern(String, |
| * int)} for a complete list of valid options. The |
| * IGNORE_SPACE bit is always set, regardless of the |
| * value of 'options'. |
| * @return The set of exemplar characters for the given locale. |
| * @stable ICU 3.0 |
| */ |
| public static UnicodeSet getExemplarSet(ULocale locale, int options) { |
| return LocaleData.getInstance(locale).getExemplarSet(options, ES_STANDARD); |
| } |
| |
| /** |
| * Returns the set of exemplar characters for a locale. |
| * |
| * @param locale Locale for which the exemplar character set |
| * is to be retrieved. |
| * @param options Bitmask for options to apply to the exemplar pattern. |
| * Specify zero to retrieve the exemplar set as it is |
| * defined in the locale data. Specify |
| * UnicodeSet.CASE to retrieve a case-folded exemplar |
| * set. See {@link UnicodeSet#applyPattern(String, |
| * int)} for a complete list of valid options. The |
| * IGNORE_SPACE bit is always set, regardless of the |
| * value of 'options'. |
| * @param extype The type of exemplar character set to retrieve. |
| * @return The set of exemplar characters for the given locale. |
| * @stable ICU 3.0 |
| */ |
| public static UnicodeSet getExemplarSet(ULocale locale, int options, int extype) { |
| return LocaleData.getInstance(locale).getExemplarSet(options, extype); |
| } |
| |
| /** |
| * Returns the set of exemplar characters for a locale. |
| * |
| * @param options Bitmask for options to apply to the exemplar pattern. |
| * Specify zero to retrieve the exemplar set as it is |
| * defined in the locale data. Specify |
| * UnicodeSet.CASE to retrieve a case-folded exemplar |
| * set. See {@link UnicodeSet#applyPattern(String, |
| * int)} for a complete list of valid options. The |
| * IGNORE_SPACE bit is always set, regardless of the |
| * value of 'options'. |
| * @param extype The type of exemplar set to be retrieved, |
| * ES_STANDARD, ES_INDEX, ES_AUXILIARY, or ES_PUNCTUATION |
| * @return The set of exemplar characters for the given locale. |
| * @stable ICU 3.4 |
| */ |
| public UnicodeSet getExemplarSet(int options, int extype) { |
| String [] exemplarSetTypes = { |
| "ExemplarCharacters", "AuxExemplarCharacters", |
| "ExemplarCharactersIndex", "ExemplarCharactersCurrency", |
| "ExemplarCharactersPunctuation" |
| }; |
| |
| if (extype == ES_CURRENCY) { |
| // currency symbol exemplar is no longer available |
| return new UnicodeSet(); |
| } |
| |
| try{ |
| ICUResourceBundle stringBundle = (ICUResourceBundle) bundle.get(exemplarSetTypes[extype]); |
| |
| if ( noSubstitute && (stringBundle.getLoadingStatus() == ICUResourceBundle.FROM_ROOT) ) |
| return null; |
| |
| String unicodeSetPattern = stringBundle.getString(); |
| if (extype == ES_PUNCTUATION) { |
| try { |
| return new UnicodeSet(unicodeSetPattern, UnicodeSet.IGNORE_SPACE | options); |
| } catch (IllegalArgumentException e) { |
| throw new IllegalArgumentException("Can't create exemplars for " + exemplarSetTypes[extype] + " in " + bundle.getLocale(), e); |
| } |
| } |
| return new UnicodeSet(unicodeSetPattern, UnicodeSet.IGNORE_SPACE | options); |
| }catch(MissingResourceException ex){ |
| if(extype==LocaleData.ES_AUXILIARY){ |
| return new UnicodeSet(); |
| } else if (extype==LocaleData.ES_INDEX){ |
| return null; |
| } |
| throw ex; |
| } |
| } |
| |
| /** |
| * Gets the LocaleData object associated with the ULocale specified in locale |
| * |
| * @param locale Locale with thich the locale data object is associated. |
| * @return A locale data object. |
| * @stable ICU 3.4 |
| */ |
| public static final LocaleData getInstance(ULocale locale) { |
| LocaleData ld = new LocaleData(); |
| ld.bundle = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, locale); |
| ld.langBundle = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_LANG_BASE_NAME, locale); |
| ld.noSubstitute = false; |
| return ld; |
| } |
| |
| /** |
| * Gets the LocaleData object associated with the default <code>FORMAT</code> locale |
| * |
| * @return A locale data object. |
| * @see Category#FORMAT |
| * @stable ICU 3.4 |
| */ |
| public static final LocaleData getInstance() { |
| return LocaleData.getInstance(ULocale.getDefault(Category.FORMAT)); |
| } |
| |
| /** |
| * Sets the "no substitute" behavior of this locale data object. |
| * |
| * @param setting Value for the no substitute behavior. If TRUE, |
| * methods of this locale data object will return |
| * an error when no data is available for that method, |
| * given the locale ID supplied to the constructor. |
| * @stable ICU 3.4 |
| */ |
| public void setNoSubstitute(boolean setting) { |
| noSubstitute = setting; |
| } |
| |
| /** |
| * Gets the "no substitute" behavior of this locale data object. |
| * |
| * @return Value for the no substitute behavior. If TRUE, |
| * methods of this locale data object will return |
| * an error when no data is available for that method, |
| * given the locale ID supplied to the constructor. |
| * @stable ICU 3.4 |
| */ |
| public boolean getNoSubstitute() { |
| return noSubstitute; |
| } |
| |
| private static final String [] DELIMITER_TYPES = { |
| "quotationStart", |
| "quotationEnd", |
| "alternateQuotationStart", |
| "alternateQuotationEnd" |
| }; |
| |
| /** |
| * Retrieves a delimiter string from the locale data. |
| * |
| * @param type The type of delimiter string desired. Currently, |
| * the valid choices are QUOTATION_START, QUOTATION_END, |
| * ALT_QUOTATION_START, or ALT_QUOTATION_END. |
| * @return The desired delimiter string. |
| * @stable ICU 3.4 |
| */ |
| public String getDelimiter(int type) { |
| ICUResourceBundle delimitersBundle = (ICUResourceBundle) bundle.get("delimiters"); |
| // Only some of the quotation marks may be here. So we make sure that we do a multilevel fallback. |
| ICUResourceBundle stringBundle = delimitersBundle.getWithFallback(DELIMITER_TYPES[type]); |
| |
| if ( noSubstitute && (stringBundle.getLoadingStatus() == ICUResourceBundle.FROM_ROOT) ) |
| return null; |
| |
| return stringBundle.getString(); |
| } |
| |
| /** |
| * Utility for getMeasurementSystem and getPaperSize |
| */ |
| private static UResourceBundle measurementTypeBundleForLocale(ULocale locale, String measurementType){ |
| // Much of this is taken from getCalendarType in impl/CalendarUtil.java |
| UResourceBundle measTypeBundle = null; |
| ULocale fullLoc = ULocale.addLikelySubtags(locale); |
| String region = fullLoc.getCountry(); |
| try { |
| UResourceBundle rb = UResourceBundle.getBundleInstance( |
| ICUResourceBundle.ICU_BASE_NAME, |
| "supplementalData", |
| ICUResourceBundle.ICU_DATA_CLASS_LOADER); |
| UResourceBundle measurementData = rb.get("measurementData"); |
| UResourceBundle measDataBundle = null; |
| try { |
| measDataBundle = measurementData.get(region); |
| measTypeBundle = measDataBundle.get(measurementType); |
| } catch (MissingResourceException mre) { |
| // use "001" as fallback |
| measDataBundle = measurementData.get("001"); |
| measTypeBundle = measDataBundle.get(measurementType); |
| } |
| } catch (MissingResourceException mre) { |
| // fall through |
| } |
| return measTypeBundle; |
| } |
| |
| |
| /** |
| * Enumeration for representing the measurement systems. |
| * @stable ICU 2.8 |
| */ |
| public static final class MeasurementSystem{ |
| /** |
| * Measurement system specified by Le Système International d'Unités (SI) |
| * otherwise known as Metric system. |
| * @stable ICU 2.8 |
| */ |
| public static final MeasurementSystem SI = new MeasurementSystem(0); |
| |
| /** |
| * Measurement system followed in the United States of America. |
| * @stable ICU 2.8 |
| */ |
| public static final MeasurementSystem US = new MeasurementSystem(1); |
| |
| private int systemID; |
| private MeasurementSystem(int id){ |
| systemID = id; |
| } |
| |
| private boolean equals(int id){ |
| return systemID == id; |
| } |
| } |
| |
| /** |
| * Returns the measurement system used in the locale specified by the locale. |
| * |
| * @param locale The locale for which the measurement system to be retrieved. |
| * @return MeasurementSystem the measurement system used in the locale. |
| * @stable ICU 3.0 |
| */ |
| public static final MeasurementSystem getMeasurementSystem(ULocale locale){ |
| UResourceBundle sysBundle = measurementTypeBundleForLocale(locale, MEASUREMENT_SYSTEM); |
| |
| int system = sysBundle.getInt(); |
| if(MeasurementSystem.US.equals(system)){ |
| return MeasurementSystem.US; |
| } |
| if(MeasurementSystem.SI.equals(system)){ |
| return MeasurementSystem.SI; |
| } |
| // return null if the object is null or is not an instance |
| // of integer indicating an error |
| return null; |
| } |
| |
| /** |
| * A class that represents the size of letter head |
| * used in the country |
| * @stable ICU 2.8 |
| */ |
| public static final class PaperSize{ |
| private int height; |
| private int width; |
| |
| private PaperSize(int h, int w){ |
| height = h; |
| width = w; |
| } |
| /** |
| * Retruns the height of the paper |
| * @return the height |
| * @stable ICU 2.8 |
| */ |
| public int getHeight(){ |
| return height; |
| } |
| /** |
| * Returns the width of the paper |
| * @return the width |
| * @stable ICU 2.8 |
| */ |
| public int getWidth(){ |
| return width; |
| } |
| } |
| |
| /** |
| * Returns the size of paper used in the locale. The paper sizes returned are always in |
| * <em> milli-meters<em>. |
| * @param locale The locale for which the measurement system to be retrieved. |
| * @return The paper size used in the locale |
| * @stable ICU 3.0 |
| */ |
| public static final PaperSize getPaperSize(ULocale locale){ |
| UResourceBundle obj = measurementTypeBundleForLocale(locale, PAPER_SIZE); |
| int[] size = obj.getIntVector(); |
| return new PaperSize(size[0], size[1]); |
| } |
| |
| /** |
| * Returns LocaleDisplayPattern for this locale, e.g., {0}({1}) |
| * @return locale display pattern as a String. |
| * @stable ICU 4.2 |
| */ |
| public String getLocaleDisplayPattern() { |
| ICUResourceBundle locDispBundle = (ICUResourceBundle) langBundle.get(LOCALE_DISPLAY_PATTERN); |
| String localeDisplayPattern = locDispBundle.getStringWithFallback(PATTERN); |
| return localeDisplayPattern; |
| } |
| |
| /** |
| * Returns LocaleDisplaySeparator for this locale. |
| * @return locale display separator as a char. |
| * @stable ICU 4.2 |
| */ |
| public String getLocaleSeparator() { |
| String sub0 = "{0}"; |
| String sub1 = "{1}"; |
| ICUResourceBundle locDispBundle = (ICUResourceBundle) langBundle.get(LOCALE_DISPLAY_PATTERN); |
| String localeSeparator = locDispBundle.getStringWithFallback(SEPARATOR); |
| int index0 = localeSeparator.indexOf(sub0); |
| int index1 = localeSeparator.indexOf(sub1); |
| if (index0 >= 0 && index1 >= 0 && index0 <= index1) { |
| return localeSeparator.substring(index0 + sub0.length(), index1); |
| } |
| return localeSeparator; |
| } |
| |
| private static VersionInfo gCLDRVersion = null; |
| |
| /** |
| * Returns the current CLDR version |
| * @stable ICU 4.2 |
| */ |
| public static VersionInfo getCLDRVersion() { |
| // fetching this data should be idempotent. |
| if(gCLDRVersion == null) { |
| // from ZoneMeta.java |
| UResourceBundle supplementalDataBundle = UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "supplementalData", ICUResourceBundle.ICU_DATA_CLASS_LOADER); |
| UResourceBundle cldrVersionBundle = supplementalDataBundle.get("cldrVersion"); |
| gCLDRVersion = VersionInfo.getInstance(cldrVersionBundle.getString()); |
| } |
| return gCLDRVersion; |
| } |
| } |