--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/macosx/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java Tue Aug 21 11:00:30 2012 -0700
@@ -0,0 +1,667 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.util.locale.provider;
+
+import java.lang.ref.SoftReference;
+import java.text.*;
+import java.text.spi.DateFormatProvider;
+import java.text.spi.DateFormatSymbolsProvider;
+import java.text.spi.DecimalFormatSymbolsProvider;
+import java.text.spi.NumberFormatProvider;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle.Control;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicReferenceArray;
+import java.util.spi.CalendarDataProvider;
+import java.util.spi.CurrencyNameProvider;
+import java.util.spi.LocaleNameProvider;
+import java.util.spi.TimeZoneNameProvider;
+
+/**
+ * LocaleProviderAdapter implementation for the Mac OS X locale data
+ *
+ * @author Naoto Sato
+ */
+public class HostLocaleProviderAdapterImpl {
+
+ // per supported locale instances
+ private static ConcurrentMap<Locale, SoftReference<AtomicReferenceArray<String>>> dateFormatPatternsMap =
+ new ConcurrentHashMap<>(2);
+ private static ConcurrentMap<Locale, SoftReference<AtomicReferenceArray<String>>> numberFormatPatternsMap =
+ new ConcurrentHashMap<>(2);
+ private static ConcurrentMap<Locale, SoftReference<DateFormatSymbols>> dateFormatSymbolsMap =
+ new ConcurrentHashMap<>(2);
+ private static ConcurrentMap<Locale, SoftReference<DecimalFormatSymbols>> decimalFormatSymbolsMap =
+ new ConcurrentHashMap<>(2);
+
+ // locale categories
+ private static final int CAT_DISPLAY = 0;
+ private static final int CAT_FORMAT = 1;
+
+ // NumberFormat styles
+ private static final int NF_NUMBER = 0;
+ private static final int NF_CURRENCY = 1;
+ private static final int NF_PERCENT = 2;
+ private static final int NF_INTEGER = 3;
+ private static final int NF_MAX = NF_INTEGER;
+
+ // CalendarData value types
+ private static final int CD_FIRSTDAYOFWEEK = 0;
+ private static final int CD_MINIMALDAYSINFIRSTWEEK = 1;
+
+ // Locale/Currency display name types
+ private static final int DN_LOCALE_LANGUAGE = 0;
+ private static final int DN_LOCALE_SCRIPT = 1;
+ private static final int DN_LOCALE_REGION = 2;
+ private static final int DN_LOCALE_VARIANT = 3;
+ private static final int DN_CURRENCY_CODE = 4;
+ private static final int DN_CURRENCY_SYMBOL = 5;
+
+ // TimeZone display name types
+ private static final int DN_TZ_SHORT_STANDARD = 0;
+ private static final int DN_TZ_SHORT_DST = 1;
+ private static final int DN_TZ_LONG_STANDARD = 2;
+ private static final int DN_TZ_LONG_DST = 3;
+
+ private static final Set<Locale> supportedLocaleSet;
+ static {
+ Set<Locale> tmpSet = new HashSet<Locale>();
+ // Assuming the default locales do not include any extensions, so
+ // no stripping is needed here.
+ Locale l = Locale.forLanguageTag(getDefaultLocale(CAT_FORMAT).replaceAll("_","-"));
+ tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l));
+ l = Locale.forLanguageTag(getDefaultLocale(CAT_DISPLAY).replaceAll("_","-"));
+ tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l));
+ supportedLocaleSet = Collections.unmodifiableSet(tmpSet);
+ }
+ private final static Locale[] supportedLocale = supportedLocaleSet.toArray(new Locale[0]);
+
+ public static DateFormatProvider getDateFormatProvider() {
+ return new DateFormatProvider() {
+
+ @Override
+ public Locale[] getAvailableLocales() {
+ return getSupportedCalendarLocales();
+ }
+
+ @Override
+ public boolean isSupportedLocale(Locale locale) {
+ return isSupportedCalendarLocale(locale);
+ }
+
+ @Override
+ public DateFormat getDateInstance(int style, Locale locale) {
+ return new SimpleDateFormat(getDateTimePattern(style, -1, locale),
+ getCalendarLocale(locale));
+ }
+
+ @Override
+ public DateFormat getTimeInstance(int style, Locale locale) {
+ return new SimpleDateFormat(getDateTimePattern(-1, style, locale),
+ getCalendarLocale(locale));
+ }
+
+ @Override
+ public DateFormat getDateTimeInstance(int dateStyle,
+ int timeStyle, Locale locale) {
+ return new SimpleDateFormat(getDateTimePattern(dateStyle, timeStyle, locale),
+ getCalendarLocale(locale));
+ }
+
+ private String getDateTimePattern(int dateStyle, int timeStyle, Locale locale) {
+ AtomicReferenceArray<String> dateFormatPatterns;
+ SoftReference<AtomicReferenceArray<String>> ref = dateFormatPatternsMap.get(locale);
+
+ if (ref == null || (dateFormatPatterns = ref.get()) == null) {
+ dateFormatPatterns = new AtomicReferenceArray<>(5 * 5);
+ ref = new SoftReference<>(dateFormatPatterns);
+ dateFormatPatternsMap.put(locale, ref);
+ }
+
+ int index = (dateStyle + 1) * 5 + timeStyle + 1;
+ String pattern = dateFormatPatterns.get(index);
+ if (pattern == null) {
+ String langTag = locale.toLanguageTag();
+ pattern = translateDateFormatLetters(getCalendarID(langTag),
+ getDateTimePatternNative(dateStyle, timeStyle, langTag));
+ if (!dateFormatPatterns.compareAndSet(index, null, pattern)) {
+ pattern = dateFormatPatterns.get(index);
+ }
+ }
+
+ return pattern;
+ }
+ };
+ }
+
+ public static DateFormatSymbolsProvider getDateFormatSymbolsProvider() {
+ return new DateFormatSymbolsProvider() {
+ @Override
+ public Locale[] getAvailableLocales() {
+ if (isSupportedLocale(Locale.getDefault(Locale.Category.FORMAT))) {
+ return supportedLocale;
+ }
+
+ return new Locale[0];
+ }
+
+ @Override
+ public boolean isSupportedLocale(Locale locale) {
+ // Only supports the locale with Gregorian calendar
+ Locale base = locale.stripExtensions();
+ if (supportedLocaleSet.contains(base)) {
+ return getCalendarID(locale.toLanguageTag()).equals("gregorian");
+ }
+ return false;
+ }
+
+ @Override
+ public DateFormatSymbols getInstance(Locale locale) {
+ DateFormatSymbols dateFormatSymbols;
+ SoftReference<DateFormatSymbols> ref = dateFormatSymbolsMap.get(locale);
+
+ if (ref == null || (dateFormatSymbols = ref.get()) == null) {
+ dateFormatSymbols = new DateFormatSymbols(locale);
+ String langTag = locale.toLanguageTag();
+ dateFormatSymbols.setAmPmStrings(getAmPmStrings(langTag, dateFormatSymbols.getAmPmStrings()));
+ dateFormatSymbols.setEras(getEras(langTag, dateFormatSymbols.getEras()));
+ dateFormatSymbols.setMonths(getMonths(langTag, dateFormatSymbols.getMonths()));
+ dateFormatSymbols.setShortMonths(getShortMonths(langTag, dateFormatSymbols.getShortMonths()));
+ dateFormatSymbols.setWeekdays(getWeekdays(langTag, dateFormatSymbols.getWeekdays()));
+ dateFormatSymbols.setShortWeekdays(getShortWeekdays(langTag, dateFormatSymbols.getShortWeekdays()));
+ ref = new SoftReference<>(dateFormatSymbols);
+ dateFormatSymbolsMap.put(locale, ref);
+ }
+ return (DateFormatSymbols)dateFormatSymbols.clone();
+ }
+ };
+ }
+
+ public static NumberFormatProvider getNumberFormatProvider() {
+ return new NumberFormatProvider() {
+ @Override
+ public Locale[] getAvailableLocales() {
+ return supportedLocale;
+ }
+
+ @Override
+ public boolean isSupportedLocale(Locale locale) {
+ // Ignore the extensions for now
+ return supportedLocaleSet.contains(locale.stripExtensions());
+ }
+
+ @Override
+ public NumberFormat getCurrencyInstance(Locale locale) {
+ return new DecimalFormat(getNumberPattern(NF_CURRENCY, locale),
+ DecimalFormatSymbols.getInstance(locale));
+ }
+
+ @Override
+ public NumberFormat getIntegerInstance(Locale locale) {
+ return new DecimalFormat(getNumberPattern(NF_INTEGER, locale),
+ DecimalFormatSymbols.getInstance(locale));
+ }
+
+ @Override
+ public NumberFormat getNumberInstance(Locale locale) {
+ return new DecimalFormat(getNumberPattern(NF_NUMBER, locale),
+ DecimalFormatSymbols.getInstance(locale));
+ }
+
+ @Override
+ public NumberFormat getPercentInstance(Locale locale) {
+ return new DecimalFormat(getNumberPattern(NF_PERCENT, locale),
+ DecimalFormatSymbols.getInstance(locale));
+ }
+
+ private String getNumberPattern(int style, Locale locale) {
+ AtomicReferenceArray<String> numberFormatPatterns;
+ SoftReference<AtomicReferenceArray<String>> ref = numberFormatPatternsMap.get(locale);
+
+ if (ref == null || (numberFormatPatterns = ref.get()) == null) {
+ numberFormatPatterns = new AtomicReferenceArray<>(4);
+ ref = new SoftReference<>(numberFormatPatterns);
+ numberFormatPatternsMap.put(locale, ref);
+ }
+
+ String pattern = numberFormatPatterns.get(style);
+ if (pattern == null) {
+ pattern = getNumberPatternNative(style, locale.toLanguageTag());
+ if (!numberFormatPatterns.compareAndSet(style, null, pattern)) {
+ pattern = numberFormatPatterns.get(style);
+ }
+ }
+
+ return pattern;
+ }
+ };
+ }
+
+ public static DecimalFormatSymbolsProvider getDecimalFormatSymbolsProvider() {
+ return new DecimalFormatSymbolsProvider() {
+
+ @Override
+ public Locale[] getAvailableLocales() {
+ return supportedLocale;
+ }
+
+ @Override
+ public boolean isSupportedLocale(Locale locale) {
+ // Ignore the extensions for now
+ return supportedLocaleSet.contains(locale.stripExtensions());
+ }
+
+ @Override
+ public DecimalFormatSymbols getInstance(Locale locale) {
+ DecimalFormatSymbols decimalFormatSymbols;
+ SoftReference<DecimalFormatSymbols> ref = decimalFormatSymbolsMap.get(locale);
+
+ if (ref == null || (decimalFormatSymbols = ref.get()) == null) {
+ decimalFormatSymbols = new DecimalFormatSymbols(locale);
+ String langTag = locale.toLanguageTag();
+
+ // DecimalFormatSymbols.setInternationalCurrencySymbol() has
+ // a side effect of setting the currency symbol as well. So
+ // the calling order is relevant here.
+ decimalFormatSymbols.setInternationalCurrencySymbol(getInternationalCurrencySymbol(langTag, decimalFormatSymbols.getInternationalCurrencySymbol()));
+ decimalFormatSymbols.setCurrencySymbol(getCurrencySymbol(langTag, decimalFormatSymbols.getCurrencySymbol()));
+ decimalFormatSymbols.setDecimalSeparator(getDecimalSeparator(langTag, decimalFormatSymbols.getDecimalSeparator()));
+ decimalFormatSymbols.setGroupingSeparator(getGroupingSeparator(langTag, decimalFormatSymbols.getGroupingSeparator()));
+ decimalFormatSymbols.setInfinity(getInfinity(langTag, decimalFormatSymbols.getInfinity()));
+ decimalFormatSymbols.setMinusSign(getMinusSign(langTag, decimalFormatSymbols.getMinusSign()));
+ decimalFormatSymbols.setMonetaryDecimalSeparator(getMonetaryDecimalSeparator(langTag, decimalFormatSymbols.getMonetaryDecimalSeparator()));
+ decimalFormatSymbols.setNaN(getNaN(langTag, decimalFormatSymbols.getNaN()));
+ decimalFormatSymbols.setPercent(getPercent(langTag, decimalFormatSymbols.getPercent()));
+ decimalFormatSymbols.setPerMill(getPerMill(langTag, decimalFormatSymbols.getPerMill()));
+ decimalFormatSymbols.setZeroDigit(getZeroDigit(langTag, decimalFormatSymbols.getZeroDigit()));
+ decimalFormatSymbols.setExponentSeparator(getExponentSeparator(langTag, decimalFormatSymbols.getExponentSeparator()));
+ ref = new SoftReference<>(decimalFormatSymbols);
+ decimalFormatSymbolsMap.put(locale, ref);
+ }
+ return (DecimalFormatSymbols)decimalFormatSymbols.clone();
+ }
+ };
+ }
+
+ public static CalendarDataProvider getCalendarDataProvider() {
+ return new CalendarDataProvider() {
+ @Override
+ public Locale[] getAvailableLocales() {
+ return getSupportedCalendarLocales();
+ }
+
+ @Override
+ public boolean isSupportedLocale(Locale locale) {
+ return isSupportedCalendarLocale(locale);
+ }
+
+ @Override
+ public String getDisplayName(String calType, int field, int value,
+ int style, Locale locale) {
+ return null;
+ }
+
+ @Override
+ public Map<String, Integer> getDisplayNames(String calType,
+ int field, int style, Locale locale) {
+ return null;
+ }
+
+ @Override
+ public int getFirstDayOfWeek(Locale locale) {
+ return getCalendarInt(locale.toLanguageTag(), CD_FIRSTDAYOFWEEK);
+ }
+
+ @Override
+ public int getMinimalDaysInFirstWeek(Locale locale) {
+ return getCalendarInt(locale.toLanguageTag(), CD_MINIMALDAYSINFIRSTWEEK);
+ }
+ };
+ }
+
+ public static CurrencyNameProvider getCurrencyNameProvider() {
+ return new CurrencyNameProvider() {
+ @Override
+ public Locale[] getAvailableLocales() {
+ return supportedLocale;
+ }
+
+ @Override
+ public boolean isSupportedLocale(Locale locale) {
+ // Ignore the extensions for now
+ return supportedLocaleSet.contains(locale.stripExtensions());
+ }
+
+ @Override
+ public String getDisplayName(String code, Locale locale) {
+ return getDisplayString(locale.toLanguageTag(), DN_CURRENCY_CODE, code);
+ }
+
+ @Override
+ public String getSymbol(String code, Locale locale) {
+ return getDisplayString(locale.toLanguageTag(), DN_CURRENCY_SYMBOL, code);
+ }
+ };
+ }
+
+ public static LocaleNameProvider getLocaleNameProvider() {
+ return new LocaleNameProvider() {
+ @Override
+ public Locale[] getAvailableLocales() {
+ return supportedLocale;
+ }
+
+ @Override
+ public boolean isSupportedLocale(Locale locale) {
+ // Ignore the extensions for now
+ return supportedLocaleSet.contains(locale.stripExtensions());
+ }
+
+ @Override
+ public String getDisplayLanguage(String languageCode, Locale locale) {
+ return getDisplayString(locale.toLanguageTag(), DN_LOCALE_LANGUAGE, languageCode);
+ }
+
+ @Override
+ public String getDisplayCountry(String countryCode, Locale locale) {
+ return getDisplayString(locale.toLanguageTag(), DN_LOCALE_REGION, countryCode);
+ }
+
+ @Override
+ public String getDisplayScript(String scriptCode, Locale locale) {
+ return getDisplayString(locale.toLanguageTag(), DN_LOCALE_SCRIPT, scriptCode);
+ }
+
+ @Override
+ public String getDisplayVariant(String variantCode, Locale locale) {
+ return getDisplayString(locale.toLanguageTag(), DN_LOCALE_VARIANT, variantCode);
+ }
+ };
+ }
+
+ public static TimeZoneNameProvider getTimeZoneNameProvider() {
+ return new TimeZoneNameProvider() {
+ @Override
+ public Locale[] getAvailableLocales() {
+ return supportedLocale;
+ }
+
+ @Override
+ public boolean isSupportedLocale(Locale locale) {
+ // Ignore the extensions for now
+ return supportedLocaleSet.contains(locale.stripExtensions());
+ }
+
+ @Override
+ public String getDisplayName(String ID, boolean daylight, int style, Locale locale) {
+ return getTimeZoneDisplayString(locale.toLanguageTag(), style * 2 + (daylight ? 1 : 0), ID);
+ }
+ };
+ }
+
+ private static Locale[] getSupportedCalendarLocales() {
+ if (supportedLocale.length != 0 &&
+ supportedLocaleSet.contains(Locale.JAPAN) &&
+ isJapaneseCalendar()) {
+ Locale[] sup = new Locale[supportedLocale.length+1];
+ sup[0] = JRELocaleConstants.JA_JP_JP;
+ System.arraycopy(supportedLocale, 0, sup, 1, supportedLocale.length);
+ return sup;
+ }
+ return supportedLocale;
+ }
+
+ private static boolean isSupportedCalendarLocale(Locale locale) {
+ // special case for ja_JP_JP
+ if (JRELocaleConstants.JA_JP_JP.equals(locale)) {
+ return isJapaneseCalendar();
+ }
+
+ Locale base = locale.stripExtensions();
+ if (!supportedLocaleSet.contains(base)) {
+ return false;
+ }
+
+ String caltype = locale.getUnicodeLocaleType("ca");
+ if (caltype == null) {
+ return true;
+ }
+
+ return caltype.replaceFirst("gregory", "gregorian").equals(
+ getCalendarID(locale.toLanguageTag()));
+ }
+
+ private static boolean isJapaneseCalendar() {
+ return getCalendarID("ja-JP").equals("japanese");
+ }
+
+ private static Locale getCalendarLocale(Locale locale) {
+ Locale.Builder lb = new Locale.Builder().setLocale(locale);
+ String calid = getCalendarID(locale.toLanguageTag());
+ switch (calid) {
+ case "gregorian":
+ calid = "gregory";
+ // FALL THROUGH!
+ case "japanese":
+ case "buddhist":
+ lb.setUnicodeLocaleKeyword("ca", calid);
+ return lb.build();
+ default:
+ return locale;
+ }
+ }
+
+ // The following methods are copied from CLDRConverter build tool.
+ private static String translateDateFormatLetters(String calendarType, String cldrFormat) {
+ String pattern = cldrFormat;
+ int length = pattern.length();
+ boolean inQuote = false;
+ StringBuilder jrePattern = new StringBuilder(length);
+ int count = 0;
+ char lastLetter = 0;
+
+ for (int i = 0; i < length; i++) {
+ char c = pattern.charAt(i);
+
+ if (c == '\'') {
+ // '' is treated as a single quote regardless of being
+ // in a quoted section.
+ if ((i + 1) < length) {
+ char nextc = pattern.charAt(i + 1);
+ if (nextc == '\'') {
+ i++;
+ if (count != 0) {
+ convert(calendarType, lastLetter, count, jrePattern);
+ lastLetter = 0;
+ count = 0;
+ }
+ jrePattern.append("''");
+ continue;
+ }
+ }
+ if (!inQuote) {
+ if (count != 0) {
+ convert(calendarType, lastLetter, count, jrePattern);
+ lastLetter = 0;
+ count = 0;
+ }
+ inQuote = true;
+ } else {
+ inQuote = false;
+ }
+ jrePattern.append(c);
+ continue;
+ }
+ if (inQuote) {
+ jrePattern.append(c);
+ continue;
+ }
+ if (!(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')) {
+ if (count != 0) {
+ convert(calendarType, lastLetter, count, jrePattern);
+ lastLetter = 0;
+ count = 0;
+ }
+ jrePattern.append(c);
+ continue;
+ }
+
+ if (lastLetter == 0 || lastLetter == c) {
+ lastLetter = c;
+ count++;
+ continue;
+ }
+ convert(calendarType, lastLetter, count, jrePattern);
+ lastLetter = c;
+ count = 1;
+ }
+
+ if (count != 0) {
+ convert(calendarType, lastLetter, count, jrePattern);
+ }
+ if (cldrFormat.contentEquals(jrePattern)) {
+ return cldrFormat;
+ }
+ return jrePattern.toString();
+ }
+
+ private static void convert(String calendarType, char cldrLetter, int count, StringBuilder sb) {
+ switch (cldrLetter) {
+ case 'G':
+ if (!calendarType.equals("gregorian")) {
+ // Adjust the number of 'G's for JRE SimpleDateFormat
+ if (count == 5) {
+ // CLDR narrow -> JRE short
+ count = 1;
+ } else if (count == 1) {
+ // CLDR abbr -> JRE long
+ count = 4;
+ }
+ }
+ appendN(cldrLetter, count, sb);
+ break;
+
+ // TODO: support 'c' and 'e' in JRE SimpleDateFormat
+ // Use 'u' and 'E' for now.
+ case 'c':
+ case 'e':
+ switch (count) {
+ case 1:
+ sb.append('u');
+ break;
+ case 3:
+ case 4:
+ appendN('E', count, sb);
+ break;
+ case 5:
+ appendN('E', 3, sb);
+ break;
+ }
+ break;
+
+ case 'v':
+ case 'V':
+ appendN('z', count, sb);
+ break;
+
+ case 'Z':
+ if (count == 4 || count == 5) {
+ sb.append("XXX");
+ }
+ break;
+
+ case 'u':
+ case 'U':
+ case 'q':
+ case 'Q':
+ case 'l':
+ case 'g':
+ case 'j':
+ case 'A':
+ // Unsupported letter. Just append it within quotes
+ sb.append('\'');
+ sb.append(cldrLetter);
+ sb.append('\'');
+ break;
+
+ default:
+ appendN(cldrLetter, count, sb);
+ break;
+ }
+ }
+
+ private static void appendN(char c, int n, StringBuilder sb) {
+ for (int i = 0; i < n; i++) {
+ sb.append(c);
+ }
+ }
+
+ // initialize
+ private static native String getDefaultLocale(int cat);
+
+ // For DateFormatProvider
+ private static native String getDateTimePatternNative(int dateStyle, int timeStyle, String langtag);
+ private static native String getCalendarID(String langTag);
+
+ // For NumberFormatProvider
+ private static native String getNumberPatternNative(int style, String langtag);
+
+ // For DateFormatSymbolsProvider
+ private static native String[] getAmPmStrings(String langTag, String[] ampm);
+ private static native String[] getEras(String langTag, String[] eras);
+ private static native String[] getMonths(String langTag, String[] months);
+ private static native String[] getShortMonths(String langTag, String[] smonths);
+ private static native String[] getWeekdays(String langTag, String[] wdays);
+ private static native String[] getShortWeekdays(String langTag, String[] swdays);
+
+ // For DecimalFormatSymbolsProvider
+ private static native String getCurrencySymbol(String langTag, String currencySymbol);
+ private static native char getDecimalSeparator(String langTag, char decimalSeparator);
+ private static native char getGroupingSeparator(String langTag, char groupingSeparator);
+ private static native String getInfinity(String langTag, String infinity);
+ private static native String getInternationalCurrencySymbol(String langTag, String internationalCurrencySymbol);
+ private static native char getMinusSign(String langTag, char minusSign);
+ private static native char getMonetaryDecimalSeparator(String langTag, char monetaryDecimalSeparator);
+ private static native String getNaN(String langTag, String nan);
+ private static native char getPercent(String langTag, char percent);
+ private static native char getPerMill(String langTag, char perMill);
+ private static native char getZeroDigit(String langTag, char zeroDigit);
+ private static native String getExponentSeparator(String langTag, String exponent);
+
+ // For CalendarDataProvider
+ private static native int getCalendarInt(String langTag, int type);
+
+ // For Locale/CurrencyNameProvider
+ private static native String getDisplayString(String langTag, int key, String value);
+
+ // For TimeZoneNameProvider
+ private static native String getTimeZoneDisplayString(String langTag, int style, String value);
+}