src/windows/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java
Print this page
rev 6958 : imported patch 8010666
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -35,10 +35,11 @@
import java.text.spi.DateFormatSymbolsProvider;
import java.text.spi.DecimalFormatSymbolsProvider;
import java.text.spi.NumberFormatProvider;
import java.util.Calendar;
import java.util.Collections;
+import java.util.Currency;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle.Control;
import java.util.Set;
@@ -46,10 +47,12 @@
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.CalendarNameProvider;
+import java.util.spi.CurrencyNameProvider;
+import java.util.spi.LocaleNameProvider;
import sun.util.spi.CalendarProvider;
/**
* LocaleProviderdapter implementation for the Windows locale data.
*
@@ -70,10 +73,18 @@
// CalendarData value types
private static final int CD_FIRSTDAYOFWEEK = 0;
private static final int CD_MINIMALDAYSINFIRSTWEEK = 1;
+ // Currency/Locale display name types
+ private static final int DN_CURRENCY_NAME = 0;
+ private static final int DN_CURRENCY_SYMBOL = 1;
+ private static final int DN_LOCALE_LANGUAGE = 2;
+ private static final int DN_LOCALE_SCRIPT = 3;
+ private static final int DN_LOCALE_REGION = 4;
+ private static final int DN_LOCALE_VARIANT = 5;
+
// Native Calendar ID to LDML calendar type map
private static final String[] calIDToLDML = {
"",
"gregory",
"gregory_en-US",
@@ -94,20 +105,30 @@
private static ConcurrentMap<Locale, SoftReference<DateFormatSymbols>> dateFormatSymbolsCache = new ConcurrentHashMap<>();
private static ConcurrentMap<Locale, SoftReference<AtomicReferenceArray<String>>> numberFormatCache = new ConcurrentHashMap<>();
private static ConcurrentMap<Locale, SoftReference<DecimalFormatSymbols>> decimalFormatSymbolsCache = new ConcurrentHashMap<>();
private static final Set<Locale> supportedLocaleSet;
+ private static final String nativeDisplayLanguage;
static {
Set<Locale> tmpSet = new HashSet<>();
if (initialize()) {
// Assuming the default locales do not include any extensions, so
// no stripping is needed here.
- Locale l = Locale.forLanguageTag(getDefaultLocale(CAT_FORMAT).replace('_', '-'));
- tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l));
- l = Locale.forLanguageTag(getDefaultLocale(CAT_DISPLAY).replace('_', '-'));
- tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l));
+ Control c = Control.getNoFallbackControl(Control.FORMAT_DEFAULT);
+ String displayLocale = getDefaultLocale(CAT_DISPLAY);
+ Locale l = Locale.forLanguageTag(displayLocale.replace('_', '-'));
+ tmpSet.addAll(c.getCandidateLocales("", l));
+ nativeDisplayLanguage = l.getLanguage();
+
+ String formatLocale = getDefaultLocale(CAT_FORMAT);
+ if (!formatLocale.equals(displayLocale)) {
+ l = Locale.forLanguageTag(formatLocale.replace('_', '-'));
+ tmpSet.addAll(c.getCandidateLocales("", l));
}
+ } else {
+ nativeDisplayLanguage = "";
+ }
supportedLocaleSet = Collections.unmodifiableSet(tmpSet);
}
private final static Locale[] supportedLocale = supportedLocaleSet.toArray(new Locale[0]);
public static DateFormatProvider getDateFormatProvider() {
@@ -390,10 +411,100 @@
.build();
}
};
}
+ 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()) &&
+ locale.getLanguage().equals(nativeDisplayLanguage);
+ }
+
+ @Override
+ public String getSymbol(String currencyCode, Locale locale) {
+ // Retrieves the currency symbol by calling
+ // GetLocaleInfoEx(LOCALE_SCURRENCY).
+ // It only works with the "locale"'s currency in its native
+ // language.
+ try {
+ if (Currency.getInstance(locale).getCurrencyCode()
+ .equals(currencyCode)) {
+ return getDisplayString(locale.toLanguageTag(),
+ DN_CURRENCY_SYMBOL, currencyCode);
+ }
+ } catch (IllegalArgumentException iae) {}
+ return null;
+ }
+
+ @Override
+ public String getDisplayName(String currencyCode, Locale locale) {
+ // Retrieves the display name by calling
+ // GetLocaleInfoEx(LOCALE_SNATIVECURRNAME).
+ // It only works with the "locale"'s currency in its native
+ // language.
+ try {
+ if (Currency.getInstance(locale).getCurrencyCode()
+ .equals(currencyCode)) {
+ return getDisplayString(locale.toLanguageTag(),
+ DN_CURRENCY_NAME, currencyCode);
+ }
+ } catch (IllegalArgumentException iae) {}
+ return null;
+ }
+ };
+ }
+
+ public static LocaleNameProvider getLocaleNameProvider() {
+ return new LocaleNameProvider() {
+ @Override
+ public Locale[] getAvailableLocales() {
+ return supportedLocale;
+ }
+
+ @Override
+ public boolean isSupportedLocale(Locale locale) {
+ return supportedLocaleSet.contains(locale.stripExtensions()) &&
+ locale.getLanguage().equals(nativeDisplayLanguage);
+ }
+
+ @Override
+ public String getDisplayLanguage(String languageCode, Locale locale) {
+ // Retrieves the display language name by calling
+ // GetLocaleInfoEx(LOCALE_SLOCALIZEDLANGUAGENAME).
+ return getDisplayString(locale.toLanguageTag(),
+ DN_LOCALE_LANGUAGE, languageCode);
+ }
+
+ @Override
+ public String getDisplayCountry(String countryCode, Locale locale) {
+ // Retrieves the display country name by calling
+ // GetLocaleInfoEx(LOCALE_SLOCALIZEDCOUNTRYNAME).
+ return getDisplayString(locale.toLanguageTag(),
+ DN_LOCALE_REGION, nativeDisplayLanguage+"-"+countryCode);
+ }
+
+ @Override
+ public String getDisplayScript(String scriptCode, Locale locale) {
+ return null;
+ }
+
+ @Override
+ public String getDisplayVariant(String variantCode, Locale locale) {
+ return null;
+ }
+ };
+ }
+
+
private static String convertDateTimePattern(String winPattern) {
String ret = winPattern.replaceAll("dddd", "EEEE");
ret = ret.replaceAll("ddd", "EEE");
ret = ret.replaceAll("tt", "aa");
ret = ret.replaceAll("g", "GG");
@@ -411,16 +522,25 @@
}
return supportedLocale;
}
private static boolean isSupportedCalendarLocale(Locale locale) {
- Locale base = locale.stripExtensions();
+ Locale base = locale;
+
+ if (base.hasExtensions() || base.getVariant() != "") {
+ // strip off extensions and variant.
+ base = new Locale.Builder()
+ .setLocale(locale)
+ .clearExtensions()
+ .build();
+ }
+
if (!supportedLocaleSet.contains(base)) {
return false;
}
- int calid = getCalendarID(locale.toLanguageTag());
+ int calid = getCalendarID(base.toLanguageTag());
if (calid <= 0 || calid >= calIDToLDML.length) {
return false;
}
String requestedCalType = locale.getUnicodeLocaleType("ca");
@@ -544,6 +664,9 @@
private static native char getPerMill(String langTag, char perMill);
private static native char getZeroDigit(String langTag, char zeroDigit);
// For CalendarDataProvider
private static native int getCalendarDataValue(String langTag, int type);
+
+ // For Locale/CurrencyNameProvider
+ private static native String getDisplayString(String langTag, int key, String value);
}