Path: blob/master/src/java.base/share/classes/sun/util/locale/provider/CalendarDataUtility.java
41161 views
/*1* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.util.locale.provider;2627import static java.util.Calendar.*;28import java.util.Locale;29import java.util.Map;30import java.util.spi.CalendarDataProvider;31import java.util.spi.CalendarNameProvider;3233/**34* {@code CalendarDataUtility} is a utility class for calling the35* {@link CalendarDataProvider} methods.36*37* @author Masayoshi Okutsu38* @author Naoto Sato39*/40public class CalendarDataUtility {41public static final String FIRST_DAY_OF_WEEK = "firstDayOfWeek";42public static final String MINIMAL_DAYS_IN_FIRST_WEEK = "minimalDaysInFirstWeek";43private static final Locale.Builder OVERRIDE_BUILDER = new Locale.Builder();4445// No instantiation46private CalendarDataUtility() {47}4849public static int retrieveFirstDayOfWeek(Locale locale) {50// Look for the Unicode Extension in the locale parameter51if (locale.hasExtensions()) {52String fw = locale.getUnicodeLocaleType("fw");53if (fw != null) {54switch (fw.toLowerCase(Locale.ROOT)) {55case "mon":56return MONDAY;57case "tue":58return TUESDAY;59case "wed":60return WEDNESDAY;61case "thu":62return THURSDAY;63case "fri":64return FRIDAY;65case "sat":66return SATURDAY;67case "sun":68return SUNDAY;69}70}71}7273LocaleServiceProviderPool pool =74LocaleServiceProviderPool.getPool(CalendarDataProvider.class);75Integer value = pool.getLocalizedObject(CalendarWeekParameterGetter.INSTANCE,76findRegionOverride(locale),77true, FIRST_DAY_OF_WEEK);78return (value != null && (value >= SUNDAY && value <= SATURDAY)) ? value : SUNDAY;79}8081public static int retrieveMinimalDaysInFirstWeek(Locale locale) {82LocaleServiceProviderPool pool =83LocaleServiceProviderPool.getPool(CalendarDataProvider.class);84Integer value = pool.getLocalizedObject(CalendarWeekParameterGetter.INSTANCE,85findRegionOverride(locale),86true, MINIMAL_DAYS_IN_FIRST_WEEK);87return (value != null && (value >= 1 && value <= 7)) ? value : 1;88}8990public static String retrieveFieldValueName(String id, int field, int value, int style, Locale locale) {91LocaleServiceProviderPool pool =92LocaleServiceProviderPool.getPool(CalendarNameProvider.class);93return pool.getLocalizedObject(CalendarFieldValueNameGetter.INSTANCE, locale, normalizeCalendarType(id),94field, value, style, false);95}9697public static String retrieveJavaTimeFieldValueName(String id, int field, int value, int style, Locale locale) {98LocaleServiceProviderPool pool =99LocaleServiceProviderPool.getPool(CalendarNameProvider.class);100String name;101name = pool.getLocalizedObject(CalendarFieldValueNameGetter.INSTANCE, locale, normalizeCalendarType(id),102field, value, style, true);103if (name == null) {104name = pool.getLocalizedObject(CalendarFieldValueNameGetter.INSTANCE, locale, normalizeCalendarType(id),105field, value, style, false);106}107return name;108}109110public static Map<String, Integer> retrieveFieldValueNames(String id, int field, int style, Locale locale) {111LocaleServiceProviderPool pool =112LocaleServiceProviderPool.getPool(CalendarNameProvider.class);113return pool.getLocalizedObject(CalendarFieldValueNamesMapGetter.INSTANCE, locale,114normalizeCalendarType(id), field, style, false);115}116117public static Map<String, Integer> retrieveJavaTimeFieldValueNames(String id, int field, int style, Locale locale) {118LocaleServiceProviderPool pool =119LocaleServiceProviderPool.getPool(CalendarNameProvider.class);120Map<String, Integer> map;121map = pool.getLocalizedObject(CalendarFieldValueNamesMapGetter.INSTANCE, locale,122normalizeCalendarType(id), field, style, true);123if (map == null) {124map = pool.getLocalizedObject(CalendarFieldValueNamesMapGetter.INSTANCE, locale,125normalizeCalendarType(id), field, style, false);126}127return map;128}129130/**131* Utility to look for a region override extension.132* If no region override is found, returns the original locale.133*/134public static Locale findRegionOverride(Locale l) {135String rg = l.getUnicodeLocaleType("rg");136Locale override = l;137138if (rg != null && rg.length() == 6) {139// UN M.49 code should not be allowed here140// cannot use regex here, as it could be a recursive call141rg = rg.toUpperCase(Locale.ROOT);142if (rg.charAt(0) >= 0x0041 &&143rg.charAt(0) <= 0x005A &&144rg.charAt(1) >= 0x0041 &&145rg.charAt(1) <= 0x005A &&146rg.substring(2).equals("ZZZZ")) {147override = OVERRIDE_BUILDER148.clear()149.setLocale(l)150.setRegion(rg.substring(0, 2))151.build();152}153}154155return override;156}157158static String normalizeCalendarType(String requestID) {159String type;160if (requestID.equals("gregorian") || requestID.equals("iso8601")) {161type = "gregory";162} else if (requestID.startsWith("islamic")) {163type = "islamic";164} else {165type = requestID;166}167return type;168}169170/**171* Obtains a localized field value string from a CalendarDataProvider172* implementation.173*/174private static class CalendarFieldValueNameGetter175implements LocaleServiceProviderPool.LocalizedObjectGetter<CalendarNameProvider,176String> {177private static final CalendarFieldValueNameGetter INSTANCE =178new CalendarFieldValueNameGetter();179180@Override181public String getObject(CalendarNameProvider calendarNameProvider,182Locale locale,183String requestID, // calendarType184Object... params) {185assert params.length == 4;186int field = (int) params[0];187int value = (int) params[1];188int style = (int) params[2];189boolean javatime = (boolean) params[3];190191// If javatime is true, resources from CLDR have precedence over JRE192// native resources.193if (javatime && calendarNameProvider instanceof CalendarNameProviderImpl) {194String name;195name = ((CalendarNameProviderImpl)calendarNameProvider)196.getJavaTimeDisplayName(requestID, field, value, style, locale);197return name;198}199return calendarNameProvider.getDisplayName(requestID, field, value, style, locale);200}201}202203/**204* Obtains a localized field-value pairs from a CalendarDataProvider205* implementation.206*/207private static class CalendarFieldValueNamesMapGetter208implements LocaleServiceProviderPool.LocalizedObjectGetter<CalendarNameProvider,209Map<String, Integer>> {210private static final CalendarFieldValueNamesMapGetter INSTANCE =211new CalendarFieldValueNamesMapGetter();212213@Override214public Map<String, Integer> getObject(CalendarNameProvider calendarNameProvider,215Locale locale,216String requestID, // calendarType217Object... params) {218assert params.length == 3;219int field = (int) params[0];220int style = (int) params[1];221boolean javatime = (boolean) params[2];222223// If javatime is true, resources from CLDR have precedence over JRE224// native resources.225if (javatime && calendarNameProvider instanceof CalendarNameProviderImpl) {226Map<String, Integer> map;227map = ((CalendarNameProviderImpl)calendarNameProvider)228.getJavaTimeDisplayNames(requestID, field, style, locale);229return map;230}231return calendarNameProvider.getDisplayNames(requestID, field, style, locale);232}233}234235private static class CalendarWeekParameterGetter236implements LocaleServiceProviderPool.LocalizedObjectGetter<CalendarDataProvider,237Integer> {238private static final CalendarWeekParameterGetter INSTANCE =239new CalendarWeekParameterGetter();240241@Override242public Integer getObject(CalendarDataProvider calendarDataProvider,243Locale locale,244String requestID, // resource key245Object... params) {246assert params.length == 0;247int value;248switch (requestID) {249case FIRST_DAY_OF_WEEK:250value = calendarDataProvider.getFirstDayOfWeek(locale);251if (value == 0) {252value = MONDAY; // default for the world ("001")253}254break;255case MINIMAL_DAYS_IN_FIRST_WEEK:256value = calendarDataProvider.getMinimalDaysInFirstWeek(locale);257if (value == 0) {258value = 1; // default for the world ("001")259}260break;261default:262throw new InternalError("invalid requestID: " + requestID);263}264265assert value != 0;266return value;267}268}269}270271272