--- old/src/windows/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java Thu Apr 18 13:25:11 2013 +++ new/src/windows/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java Thu Apr 18 13:25:09 2013 @@ -1,5 +1,5 @@ /* - * 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 @@ -37,6 +37,7 @@ 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; @@ -48,6 +49,8 @@ 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; /** @@ -72,6 +75,14 @@ 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 = { "", @@ -96,15 +107,25 @@ private static ConcurrentMap> decimalFormatSymbolsCache = new ConcurrentHashMap<>(); private static final Set supportedLocaleSet; + private static final String nativeDisplayLanguage; static { Set 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); } @@ -392,6 +413,96 @@ }; } + 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"); @@ -413,12 +524,21 @@ } 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; } @@ -546,4 +666,7 @@ // 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); }