mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-11 14:11:36 +00:00
8008576: Calendar mismatch using Host LocaleProviderAdapter
Reviewed-by: okutsu
This commit is contained in:
parent
a7f501c620
commit
96ca9c4174
@ -209,6 +209,7 @@ JAVA_JAVA_java = \
|
||||
sun/util/locale/provider/CalendarDataProviderImpl.java \
|
||||
sun/util/locale/provider/CalendarDataUtility.java \
|
||||
sun/util/locale/provider/CalendarNameProviderImpl.java \
|
||||
sun/util/locale/provider/CalendarProviderImpl.java \
|
||||
sun/util/locale/provider/CollationRules.java \
|
||||
sun/util/locale/provider/CollatorProviderImpl.java \
|
||||
sun/util/locale/provider/CurrencyNameProviderImpl.java \
|
||||
@ -232,6 +233,7 @@ JAVA_JAVA_java = \
|
||||
sun/util/locale/provider/SPILocaleProviderAdapter.java \
|
||||
sun/util/locale/provider/TimeZoneNameProviderImpl.java \
|
||||
sun/util/locale/provider/TimeZoneNameUtility.java \
|
||||
sun/util/spi/CalendarProvider.java \
|
||||
java/util/LocaleISOData.java \
|
||||
sun/util/cldr/CLDRLocaleProviderAdapter.java \
|
||||
java/util/MissingResourceException.java \
|
||||
|
||||
@ -32,11 +32,13 @@ import java.text.spi.DateFormatSymbolsProvider;
|
||||
import java.text.spi.DecimalFormatSymbolsProvider;
|
||||
import java.text.spi.NumberFormatProvider;
|
||||
import java.util.Collections;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle.Control;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||
@ -45,6 +47,7 @@ import java.util.spi.CalendarNameProvider;
|
||||
import java.util.spi.CurrencyNameProvider;
|
||||
import java.util.spi.LocaleNameProvider;
|
||||
import java.util.spi.TimeZoneNameProvider;
|
||||
import sun.util.spi.CalendarProvider;
|
||||
|
||||
/**
|
||||
* LocaleProviderAdapter implementation for the Mac OS X locale data
|
||||
@ -94,17 +97,56 @@ public class HostLocaleProviderAdapterImpl {
|
||||
|
||||
private static final Set<Locale> supportedLocaleSet;
|
||||
static {
|
||||
Set<Locale> tmpSet = new HashSet<Locale>();
|
||||
Set<Locale> tmpSet = new HashSet<>();
|
||||
// Assuming the default locales do not include any extensions, so
|
||||
// no stripping is needed here.
|
||||
Locale l = Locale.forLanguageTag(getDefaultLocale(CAT_FORMAT).replaceAll("_","-"));
|
||||
Locale l = convertMacOSXLocaleToJavaLocale(getDefaultLocale(CAT_FORMAT));
|
||||
tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l));
|
||||
l = Locale.forLanguageTag(getDefaultLocale(CAT_DISPLAY).replaceAll("_","-"));
|
||||
l = convertMacOSXLocaleToJavaLocale(getDefaultLocale(CAT_DISPLAY));
|
||||
tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l));
|
||||
supportedLocaleSet = Collections.unmodifiableSet(tmpSet);
|
||||
}
|
||||
private final static Locale[] supportedLocale = supportedLocaleSet.toArray(new Locale[0]);
|
||||
|
||||
@SuppressWarnings("fallthrough")
|
||||
private static Locale convertMacOSXLocaleToJavaLocale(String macosxloc) {
|
||||
// MacOSX may return ICU notation, here is the quote from CFLocale doc:
|
||||
// "The corresponding value is a CFString containing the POSIX locale
|
||||
// identifier as used by ICU, such as "ja_JP". If you have a variant
|
||||
// locale or a different currency or calendar, it can be as complex as
|
||||
// "en_US_POSIX@calendar=japanese;currency=EUR" or
|
||||
// "az_Cyrl_AZ@calendar=buddhist;currency=JPY".
|
||||
String[] tmp = macosxloc.split("@");
|
||||
String langTag = tmp[0].replace('_', '-');
|
||||
if (tmp.length > 1) {
|
||||
String[] ext = tmp[1].split(";");
|
||||
for (String keyval : ext) {
|
||||
// We are only interested in "calendar" value for now.
|
||||
if (keyval.startsWith("calendar=")) {
|
||||
String calid = keyval.substring(keyval.indexOf('=')+1);
|
||||
switch (calid) {
|
||||
case "gregorian":
|
||||
langTag += "-u-ca-gregory";
|
||||
break;
|
||||
case "japanese":
|
||||
// Tweak for ja_JP_JP
|
||||
if (tmp[0].equals("ja_JP")) {
|
||||
return JRELocaleConstants.JA_JP_JP;
|
||||
}
|
||||
|
||||
// fall through
|
||||
|
||||
default:
|
||||
langTag += "-u-ca-" + calid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Locale.forLanguageTag(langTag);
|
||||
}
|
||||
|
||||
public static DateFormatProvider getDateFormatProvider() {
|
||||
return new DateFormatProvider() {
|
||||
|
||||
@ -170,9 +212,8 @@ public class HostLocaleProviderAdapterImpl {
|
||||
if (isSupportedLocale(Locale.getDefault(Locale.Category.FORMAT))) {
|
||||
return supportedLocale;
|
||||
}
|
||||
|
||||
return new Locale[0];
|
||||
}
|
||||
return new Locale[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportedLocale(Locale locale) {
|
||||
@ -362,6 +403,30 @@ public class HostLocaleProviderAdapterImpl {
|
||||
};
|
||||
}
|
||||
|
||||
public static CalendarProvider getCalendarProvider() {
|
||||
return new CalendarProvider() {
|
||||
@Override
|
||||
public Locale[] getAvailableLocales() {
|
||||
return getSupportedCalendarLocales();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportedLocale(Locale locale) {
|
||||
return isSupportedCalendarLocale(locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Calendar getInstance(TimeZone zone, Locale locale) {
|
||||
return new Calendar.Builder()
|
||||
.setLocale(locale)
|
||||
.setCalendarType(getCalendarID(locale.toLanguageTag()))
|
||||
.setTimeZone(zone)
|
||||
.setInstant(System.currentTimeMillis())
|
||||
.build();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static CurrencyNameProvider getCurrencyNameProvider() {
|
||||
return new CurrencyNameProvider() {
|
||||
@Override
|
||||
@ -455,23 +520,20 @@ public class HostLocaleProviderAdapterImpl {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
String requestedCalType = locale.getUnicodeLocaleType("ca");
|
||||
String nativeCalType =
|
||||
getCalendarID(locale.toLanguageTag()).replaceFirst("gregorian", "gregory");
|
||||
|
||||
return caltype.replaceFirst("gregory", "gregorian").equals(
|
||||
getCalendarID(locale.toLanguageTag()));
|
||||
if (requestedCalType == null) {
|
||||
return Calendar.getAvailableCalendarTypes().contains(nativeCalType);
|
||||
} else {
|
||||
return requestedCalType.equals(nativeCalType);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isJapaneseCalendar() {
|
||||
@ -479,18 +541,15 @@ public class HostLocaleProviderAdapterImpl {
|
||||
}
|
||||
|
||||
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;
|
||||
String nativeCalType = getCalendarID(locale.toLanguageTag())
|
||||
.replaceFirst("gregorian", "gregory");
|
||||
if (Calendar.getAvailableCalendarTypes().contains(nativeCalType)) {
|
||||
return new Locale.Builder()
|
||||
.setLocale(locale)
|
||||
.setUnicodeLocaleKeyword("ca", nativeCalType)
|
||||
.build();
|
||||
} else {
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -57,6 +57,8 @@ import java.util.concurrent.ConcurrentMap;
|
||||
import sun.util.BuddhistCalendar;
|
||||
import sun.util.calendar.ZoneInfo;
|
||||
import sun.util.locale.provider.CalendarDataUtility;
|
||||
import sun.util.locale.provider.LocaleProviderAdapter;
|
||||
import sun.util.spi.CalendarProvider;
|
||||
|
||||
/**
|
||||
* The <code>Calendar</code> class is an abstract class that provides methods
|
||||
@ -1608,9 +1610,7 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
|
||||
*/
|
||||
public static Calendar getInstance()
|
||||
{
|
||||
Calendar cal = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault(Locale.Category.FORMAT));
|
||||
cal.sharedZone = true;
|
||||
return cal;
|
||||
return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1637,9 +1637,7 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
|
||||
*/
|
||||
public static Calendar getInstance(Locale aLocale)
|
||||
{
|
||||
Calendar cal = createCalendar(TimeZone.getDefaultRef(), aLocale);
|
||||
cal.sharedZone = true;
|
||||
return cal;
|
||||
return createCalendar(TimeZone.getDefault(), aLocale);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1660,6 +1658,17 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
|
||||
private static Calendar createCalendar(TimeZone zone,
|
||||
Locale aLocale)
|
||||
{
|
||||
CalendarProvider provider =
|
||||
LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
|
||||
.getCalendarProvider();
|
||||
if (provider != null) {
|
||||
try {
|
||||
return provider.getInstance(zone, aLocale);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// fall back to the default instantiation
|
||||
}
|
||||
}
|
||||
|
||||
Calendar cal = null;
|
||||
|
||||
if (aLocale.hasExtensions()) {
|
||||
|
||||
@ -134,7 +134,7 @@ public class LanguageTag {
|
||||
}
|
||||
|
||||
/*
|
||||
* BNF in RFC5464
|
||||
* BNF in RFC5646
|
||||
*
|
||||
* Language-Tag = langtag ; normal language tags
|
||||
* / privateuse ; private use tag
|
||||
|
||||
@ -43,6 +43,7 @@ import java.util.spi.CurrencyNameProvider;
|
||||
import java.util.spi.LocaleNameProvider;
|
||||
import java.util.spi.LocaleServiceProvider;
|
||||
import java.util.spi.TimeZoneNameProvider;
|
||||
import sun.util.spi.CalendarProvider;
|
||||
|
||||
/**
|
||||
* An abstract parent class for the
|
||||
@ -140,6 +141,14 @@ public abstract class AuxLocaleProviderAdapter extends LocaleProviderAdapter {
|
||||
return getLocaleServiceProvider(CalendarNameProvider.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter methods for sun.util.spi.* providers
|
||||
*/
|
||||
@Override
|
||||
public CalendarProvider getCalendarProvider() {
|
||||
return getLocaleServiceProvider(CalendarProvider.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocaleResources getLocaleResources(Locale locale) {
|
||||
return null;
|
||||
|
||||
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 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
|
||||
* 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.util.Calendar;
|
||||
import java.util.Calendar.Builder;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import sun.util.spi.CalendarProvider;
|
||||
|
||||
/**
|
||||
* Concrete implementation of the {@link sun.util.spi.CalendarProvider
|
||||
* CalendarProvider} class for the JRE LocaleProviderAdapter.
|
||||
*
|
||||
* @author Naoto Sato
|
||||
*/
|
||||
public class CalendarProviderImpl extends CalendarProvider implements AvailableLanguageTags {
|
||||
private final LocaleProviderAdapter.Type type;
|
||||
private final Set<String> langtags;
|
||||
|
||||
public CalendarProviderImpl(LocaleProviderAdapter.Type type, Set<String> langtags) {
|
||||
this.type = type;
|
||||
this.langtags = langtags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all locales for which this locale service provider
|
||||
* can provide localized objects or names.
|
||||
*
|
||||
* @return An array of all locales for which this locale service provider
|
||||
* can provide localized objects or names.
|
||||
*/
|
||||
@Override
|
||||
public Locale[] getAvailableLocales() {
|
||||
return LocaleProviderAdapter.toLocaleArray(langtags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportedLocale(Locale locale) {
|
||||
// Support any locales.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new <code>Calendar</code> instance for the
|
||||
* specified locale.
|
||||
*
|
||||
* @param zone the time zone
|
||||
* @param locale the desired locale
|
||||
* @exception NullPointerException if <code>locale</code> is null
|
||||
* @exception IllegalArgumentException if <code>locale</code> isn't
|
||||
* one of the locales returned from
|
||||
* {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
|
||||
* getAvailableLocales()}.
|
||||
* @return a <code>Calendar</code> instance.
|
||||
* @see java.util.Calendar#getInstance(java.util.Locale)
|
||||
*/
|
||||
@Override
|
||||
public Calendar getInstance(TimeZone zone, Locale locale) {
|
||||
return new Calendar.Builder()
|
||||
.setLocale(locale)
|
||||
.setTimeZone(zone)
|
||||
.setInstant(System.currentTimeMillis())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getAvailableLanguageTags() {
|
||||
return langtags;
|
||||
}
|
||||
}
|
||||
@ -34,10 +34,12 @@ import java.text.spi.DateFormatProvider;
|
||||
import java.text.spi.DateFormatSymbolsProvider;
|
||||
import java.text.spi.DecimalFormatSymbolsProvider;
|
||||
import java.text.spi.NumberFormatProvider;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.spi.CalendarDataProvider;
|
||||
@ -47,6 +49,7 @@ import java.util.spi.LocaleNameProvider;
|
||||
import java.util.spi.LocaleServiceProvider;
|
||||
import java.util.spi.TimeZoneNameProvider;
|
||||
import sun.util.resources.LocaleData;
|
||||
import sun.util.spi.CalendarProvider;
|
||||
|
||||
/**
|
||||
* LocaleProviderAdapter implementation for the legacy JRE locale data.
|
||||
@ -104,6 +107,8 @@ public class JRELocaleProviderAdapter extends LocaleProviderAdapter implements R
|
||||
return (P) getCalendarDataProvider();
|
||||
case "CalendarNameProvider":
|
||||
return (P) getCalendarNameProvider();
|
||||
case "CalendarProvider":
|
||||
return (P) getCalendarProvider();
|
||||
default:
|
||||
throw new InternalError("should not come down here");
|
||||
}
|
||||
@ -122,6 +127,8 @@ public class JRELocaleProviderAdapter extends LocaleProviderAdapter implements R
|
||||
private volatile CalendarDataProvider calendarDataProvider = null;
|
||||
private volatile CalendarNameProvider calendarNameProvider = null;
|
||||
|
||||
private volatile CalendarProvider calendarProvider = null;
|
||||
|
||||
/*
|
||||
* Getter methods for java.text.spi.* providers
|
||||
*/
|
||||
@ -283,6 +290,23 @@ public class JRELocaleProviderAdapter extends LocaleProviderAdapter implements R
|
||||
return calendarNameProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter methods for sun.util.spi.* providers
|
||||
*/
|
||||
@Override
|
||||
public CalendarProvider getCalendarProvider() {
|
||||
if (calendarProvider == null) {
|
||||
CalendarProvider provider = new CalendarProviderImpl(getAdapterType(),
|
||||
getLanguageTagSet("CalendarData"));
|
||||
synchronized (this) {
|
||||
if (calendarProvider == null) {
|
||||
calendarProvider = provider;
|
||||
}
|
||||
}
|
||||
}
|
||||
return calendarProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocaleResources getLocaleResources(Locale locale) {
|
||||
LocaleResources lr = localeResourcesMap.get(locale);
|
||||
|
||||
@ -47,6 +47,7 @@ import java.util.spi.LocaleNameProvider;
|
||||
import java.util.spi.LocaleServiceProvider;
|
||||
import java.util.spi.TimeZoneNameProvider;
|
||||
import sun.util.cldr.CLDRLocaleProviderAdapter;
|
||||
import sun.util.spi.CalendarProvider;
|
||||
|
||||
/**
|
||||
* The LocaleProviderAdapter abstract class.
|
||||
@ -295,7 +296,10 @@ public abstract class LocaleProviderAdapter {
|
||||
}
|
||||
if (type == Type.JRE) {
|
||||
String oldname = locale.toString().replace('_', '-');
|
||||
return langtags.contains(oldname);
|
||||
return langtags.contains(oldname) ||
|
||||
"ja-JP-JP".equals(oldname) ||
|
||||
"th-TH-TH".equals(oldname) ||
|
||||
"no-NO-NY".equals(oldname);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -422,6 +426,14 @@ public abstract class LocaleProviderAdapter {
|
||||
*/
|
||||
public abstract CalendarNameProvider getCalendarNameProvider();
|
||||
|
||||
/**
|
||||
* Returns a CalendarProvider for this LocaleProviderAdapter, or null if no
|
||||
* CalendarProvider is available.
|
||||
*
|
||||
* @return a CalendarProvider
|
||||
*/
|
||||
public abstract CalendarProvider getCalendarProvider();
|
||||
|
||||
public abstract LocaleResources getLocaleResources(Locale locale);
|
||||
|
||||
public abstract Locale[] getAvailableLocales();
|
||||
|
||||
64
jdk/src/share/classes/sun/util/spi/CalendarProvider.java
Normal file
64
jdk/src/share/classes/sun/util/spi/CalendarProvider.java
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 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
|
||||
* 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.spi;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
import java.util.spi.LocaleServiceProvider;
|
||||
|
||||
/**
|
||||
* An abstract class for service providers that
|
||||
* provide instances of the
|
||||
* {@link java.util.Calendar Calendar} class.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public abstract class CalendarProvider extends LocaleServiceProvider {
|
||||
|
||||
/**
|
||||
* Sole constructor. (For invocation by subclass constructors, typically
|
||||
* implicit.)
|
||||
*/
|
||||
protected CalendarProvider() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new <code>Calendar</code> instance for the
|
||||
* specified locale.
|
||||
*
|
||||
* @param zone the time zone
|
||||
* @param locale the desired locale
|
||||
* @exception NullPointerException if <code>locale</code> is null
|
||||
* @exception IllegalArgumentException if <code>locale</code> isn't
|
||||
* one of the locales returned from
|
||||
* {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
|
||||
* getAvailableLocales()}.
|
||||
* @return a <code>Calendar</code> instance.
|
||||
* @see java.util.Calendar#getInstance(java.util.Locale)
|
||||
*/
|
||||
public abstract Calendar getInstance(TimeZone zone, Locale locale);
|
||||
}
|
||||
@ -35,17 +35,20 @@ import java.text.spi.DateFormatProvider;
|
||||
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.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle.Control;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
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 sun.util.spi.CalendarProvider;
|
||||
|
||||
/**
|
||||
* LocaleProviderdapter implementation for the Windows locale data.
|
||||
@ -98,9 +101,9 @@ public class HostLocaleProviderAdapterImpl {
|
||||
if (initialize()) {
|
||||
// Assuming the default locales do not include any extensions, so
|
||||
// no stripping is needed here.
|
||||
Locale l = Locale.forLanguageTag(getDefaultLocale(CAT_FORMAT).replaceAll("_","-"));
|
||||
Locale l = Locale.forLanguageTag(getDefaultLocale(CAT_FORMAT).replace('_', '-'));
|
||||
tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l));
|
||||
l = Locale.forLanguageTag(getDefaultLocale(CAT_DISPLAY).replaceAll("_","-"));
|
||||
l = Locale.forLanguageTag(getDefaultLocale(CAT_DISPLAY).replace('_', '-'));
|
||||
tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l));
|
||||
}
|
||||
supportedLocaleSet = Collections.unmodifiableSet(tmpSet);
|
||||
@ -173,24 +176,12 @@ public class HostLocaleProviderAdapterImpl {
|
||||
|
||||
@Override
|
||||
public Locale[] getAvailableLocales() {
|
||||
if (isSupportedLocale(Locale.getDefault(Locale.Category.FORMAT))) {
|
||||
return supportedLocale;
|
||||
}
|
||||
|
||||
return new Locale[0];
|
||||
return getSupportedCalendarLocales();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportedLocale(Locale locale) {
|
||||
// Only supports the locale with Gregorian calendar
|
||||
if (supportedLocale.length != 0) {
|
||||
int calid = getCalendarID(locale.toLanguageTag());
|
||||
if (calid > 0 && calid < calIDToLDML.length) {
|
||||
return calIDToLDML[calid].startsWith("gregory");
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return isSupportedCalendarLocale(locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -380,6 +371,29 @@ public class HostLocaleProviderAdapterImpl {
|
||||
};
|
||||
}
|
||||
|
||||
public static CalendarProvider getCalendarProvider() {
|
||||
return new CalendarProvider() {
|
||||
@Override
|
||||
public Locale[] getAvailableLocales() {
|
||||
return getSupportedCalendarLocales();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportedLocale(Locale locale) {
|
||||
return isSupportedCalendarLocale(locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Calendar getInstance(TimeZone zone, Locale locale) {
|
||||
return new Calendar.Builder()
|
||||
.setLocale(getCalendarLocale(locale))
|
||||
.setTimeZone(zone)
|
||||
.setInstant(System.currentTimeMillis())
|
||||
.build();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static String convertDateTimePattern(String winPattern) {
|
||||
String ret = winPattern.replaceAll("dddd", "EEEE");
|
||||
ret = ret.replaceAll("ddd", "EEE");
|
||||
@ -401,24 +415,21 @@ public class HostLocaleProviderAdapterImpl {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
String requestedCalType = locale.getUnicodeLocaleType("ca");
|
||||
String nativeCalType =
|
||||
calIDToLDML[getCalendarID(locale.toLanguageTag())]
|
||||
.replaceFirst("_.*", ""); // remove locale part.
|
||||
|
||||
return caltype.equals(
|
||||
calIDToLDML[getCalendarID(locale.toLanguageTag())]
|
||||
.replaceFirst("_.*", ""));
|
||||
if (requestedCalType == null) {
|
||||
return Calendar.getAvailableCalendarTypes().contains(nativeCalType);
|
||||
} else {
|
||||
return requestedCalType.equals(nativeCalType);
|
||||
}
|
||||
}
|
||||
|
||||
private static Locale[] getSupportedNativeDigitLocales() {
|
||||
|
||||
@ -611,7 +611,12 @@ JNIEXPORT jint JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterIm
|
||||
|
||||
int getLocaleInfoWrapper(const jchar *langtag, LCTYPE type, LPWSTR data, int buflen) {
|
||||
if (pGetLocaleInfoEx) {
|
||||
return pGetLocaleInfoEx((LPWSTR)langtag, type, data, buflen);
|
||||
if (wcscmp(L"und", (LPWSTR)langtag) == 0) {
|
||||
// defaults to "en"
|
||||
return pGetLocaleInfoEx(L"en", type, data, buflen);
|
||||
} else {
|
||||
return pGetLocaleInfoEx((LPWSTR)langtag, type, data, buflen);
|
||||
}
|
||||
} else {
|
||||
// If we ever wanted to support WinXP, we will need extra module from
|
||||
// MS...
|
||||
@ -622,7 +627,12 @@ int getLocaleInfoWrapper(const jchar *langtag, LCTYPE type, LPWSTR data, int buf
|
||||
|
||||
int getCalendarInfoWrapper(const jchar *langtag, CALID id, LPCWSTR reserved, CALTYPE type, LPWSTR data, int buflen, LPDWORD val) {
|
||||
if (pGetCalendarInfoEx) {
|
||||
return pGetCalendarInfoEx((LPWSTR)langtag, id, reserved, type, data, buflen, val);
|
||||
if (wcscmp(L"und", (LPWSTR)langtag) == 0) {
|
||||
// defaults to "en"
|
||||
return pGetCalendarInfoEx(L"en", id, reserved, type, data, buflen, val);
|
||||
} else {
|
||||
return pGetCalendarInfoEx((LPWSTR)langtag, id, reserved, type, data, buflen, val);
|
||||
}
|
||||
} else {
|
||||
// If we ever wanted to support WinXP, we will need extra module from
|
||||
// MS...
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user