1/*
2 *******************************************************************************
3 * Copyright (C) 2009, International Business Machines Corporation and         *
4 * others. All Rights Reserved.                                                *
5 *******************************************************************************
6 */
7package com.ibm.icu.impl;
8
9import java.util.MissingResourceException;
10
11import com.ibm.icu.util.ULocale;
12import com.ibm.icu.util.UResourceBundle;
13
14/**
15 * Calendar utilities.
16 *
17 * Date/time format service classes in com.ibm.icu.text packages
18 * sometimes need to access calendar internal APIs.  But calendar
19 * classes are in com.ibm.icu.util package, so the package local
20 * cannot be used.  This class is added in com.ibm.icu.impl
21 * package for sharing some calendar internal code for calendar
22 * and date format.
23 */
24public class CalendarUtil {
25
26    private static ICUCache<String, String> CALTYPE_CACHE = new SimpleCache<String, String>();
27
28    private static final String CALKEY = "calendar";
29    private static final String DEFCAL = "gregorian";
30
31    /**
32     * Returns a calendar type for the given locale.
33     * When the given locale has calendar keyword, the
34     * value of calendar keyword is returned.  Otherwise,
35     * the default calendar type for the locale is returned.
36     * @param loc The locale
37     * @return Calendar type string, such as "gregorian"
38     */
39    public static String getCalendarType(ULocale loc) {
40        String calType = null;
41
42        calType = loc.getKeywordValue(CALKEY);
43        if (calType != null) {
44            return calType;
45        }
46
47        String baseLoc = loc.getBaseName();
48
49        // Check the cache
50        calType = CALTYPE_CACHE.get(baseLoc);
51        if (calType != null) {
52            return calType;
53        }
54
55        // Canonicalize, so grandfathered variant will be transformed to keywords
56        ULocale canonical = ULocale.createCanonical(loc.toString());
57        calType = canonical.getKeywordValue("calendar");
58
59        if (calType == null) {
60            // When calendar keyword is not available, use the locale's
61            // region to get the default calendar type
62            String region = canonical.getCountry();
63            if (region.length() == 0) {
64                ULocale fullLoc = ULocale.addLikelySubtags(canonical);
65                region = fullLoc.getCountry();
66            }
67
68            // Read supplementalData to get the default calendar type for
69            // the locale's region
70            try {
71                UResourceBundle rb = UResourceBundle.getBundleInstance(
72                                        ICUResourceBundle.ICU_BASE_NAME,
73                                        "supplementalData",
74                                        ICUResourceBundle.ICU_DATA_CLASS_LOADER);
75                UResourceBundle calPref = rb.get("calendarPreferenceData");
76                UResourceBundle order = null;
77                try {
78                    order = calPref.get(region);
79                } catch (MissingResourceException mre) {
80                    // use "001" as fallback
81                    order = calPref.get("001");
82                }
83                // the first calendar type is the default for the region
84                calType = order.getString(0);
85            } catch (MissingResourceException mre) {
86                // fall through
87            }
88
89            if (calType == null) {
90                // Use "gregorian" as the last resort fallback.
91                calType = DEFCAL;
92            }
93        }
94
95        // Cache the resolved value for the next time
96        CALTYPE_CACHE.put(baseLoc, calType);
97
98        return calType;
99    }
100}
101