1/*
2 *******************************************************************************
3 * Copyright (C) 2004-2014, International Business Machines Corporation and    *
4 * others. All Rights Reserved.                                                *
5 *******************************************************************************
6 */
7package com.ibm.icu.impl;
8
9import java.util.ArrayList;
10import java.util.MissingResourceException;
11
12import com.ibm.icu.util.ULocale;
13import com.ibm.icu.util.UResourceBundle;
14import com.ibm.icu.util.UResourceBundleIterator;
15
16/**
17 * This class abstracts access to calendar (Calendar and DateFormat) data.
18 * @internal ICU 3.0
19 */
20public class CalendarData {
21    /**
22     * Construct a CalendarData from the given locale.
23     * @param loc locale to use. The 'calendar' keyword will be ignored.
24     * @param type calendar type. NULL indicates the gregorian calendar.
25     * No default lookup is done.
26     */
27    public CalendarData(ULocale loc, String type) {
28        this((ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, loc), type);
29    }
30
31    public CalendarData(ICUResourceBundle b, String type) {
32        fBundle = b;
33        if((type == null) || (type.equals("")) || (type.equals("gregorian"))) {
34            fMainType = "gregorian";
35            fFallbackType = null;
36        } else {
37            fMainType = type;
38            fFallbackType = "gregorian";
39        }
40    }
41
42    /**
43     * Load data for calendar. Note, this object owns the resources, do NOT call ures_close()!
44     *
45     * @param key Resource key to data
46     * @internal
47     */
48    public ICUResourceBundle get(String key) {
49        try {
50            return fBundle.getWithFallback("calendar/" + fMainType + "/" + key);
51        } catch(MissingResourceException m) {
52            if(fFallbackType != null) {
53                return fBundle.getWithFallback("calendar/" + fFallbackType + "/" + key);
54            }
55            throw m;
56
57        }
58    }
59
60    /**
61     * Load data for calendar. Note, this object owns the resources, do NOT call ures_close()!
62     * There is an implicit key of 'format'
63     * data is located in:   "calendar/key/format/subKey"
64     * for example,  calendar/dayNames/format/abbreviated
65     *
66     * @param key Resource key to data
67     * @param subKey Resource key to data
68     * @internal
69     */
70    public ICUResourceBundle get(String key, String subKey) {
71        try {
72            return fBundle.getWithFallback("calendar/" + fMainType + "/" + key + "/format/" + subKey);
73        } catch(MissingResourceException m) {
74            if(fFallbackType != null) {
75                return fBundle.getWithFallback("calendar/" + fFallbackType + "/" + key + "/format/" + subKey);
76            }
77            throw m;
78
79        }
80    }
81
82    /**
83     * Load data for calendar. Note, this object owns the resources, do NOT call ures_close()!
84     * data is located in:   "calendar/key/contextKey/subKey"
85     * for example,  calendar/dayNames/stand-alone/narrow
86     *
87     * @param key Resource key to data
88     * @param contextKey Resource key to data
89     * @param subKey Resource key to data
90     * @internal
91     */
92    public ICUResourceBundle get(String key, String contextKey, String subKey) {
93        try {
94            return fBundle.getWithFallback("calendar/" + fMainType + "/" + key + "/" + contextKey + "/" + subKey);
95        } catch(MissingResourceException m) {
96            if(fFallbackType != null) {
97                return fBundle.getWithFallback("calendar/" + fFallbackType + "/" + key + "/" + contextKey + "/" + subKey);
98            }
99            throw m;
100
101        }
102    }
103
104     /**
105     * Load data for calendar. Note, this object owns the resources...
106     * data is located in:   "calendar/key/set/contextKey/subKey"
107     * for example,  calendar/cyclicNameSets/years/format/abbreviated
108     *
109     * @param key Resource key to data
110     * @param set Resource key to data
111     * @param contextKey Resource key to data
112     * @param subKey Resource key to data
113     * @internal
114     */
115    public ICUResourceBundle get(String key, String set, String contextKey, String subKey) {
116        try {
117            return fBundle.getWithFallback("calendar/" + fMainType + "/" + key + "/" + set + "/" + contextKey + "/" + subKey);
118        } catch(MissingResourceException m) {
119            if(fFallbackType != null) {
120                return fBundle.getWithFallback("calendar/" + fFallbackType + "/" + key + "/" + set + "/" + contextKey + "/" + subKey);
121            }
122            throw m;
123
124        }
125    }
126
127   public String[] getStringArray(String key) {
128        return get(key).getStringArray();
129    }
130
131    public String[] getStringArray(String key, String subKey) {
132        return get(key, subKey).getStringArray();
133    }
134
135    public String[] getStringArray(String key, String contextKey, String subKey) {
136        return get(key, contextKey, subKey).getStringArray();
137    }
138    public String[] getEras(String subkey){
139        ICUResourceBundle bundle = get("eras/"+subkey);
140        return bundle.getStringArray();
141    }
142    public String[] getDateTimePatterns(){
143        ICUResourceBundle bundle = get("DateTimePatterns");
144        ArrayList<String> list = new ArrayList<String>();
145        UResourceBundleIterator iter = bundle.getIterator();
146        while (iter.hasNext()) {
147            UResourceBundle patResource = iter.next();
148            int resourceType = patResource.getType();
149            switch (resourceType) {
150                case UResourceBundle.STRING:
151                    list.add(patResource.getString());
152                    break;
153                case UResourceBundle.ARRAY:
154                    String[] items = patResource.getStringArray();
155                    list.add(items[0]);
156                    break;
157            }
158        }
159
160        return list.toArray(new String[list.size()]);
161    }
162
163    /**
164     * Returns the default date-time pattern such as <code>{1}, {0}</code>.
165     * {1} is always the date and {0} is always the time.
166     */
167    public String getDateTimePattern() {
168        // this is a hack to get offset 8 from the dateTimePatterns array.
169        return _getDateTimePattern(-1);
170    }
171
172    /**
173     * Returns the date-time pattern by style where style is one of the style fields defined
174     * in DateFormat. If date-time patterns by style are not available, it returns what
175     * {@link #getDateTimePattern()} would return.
176     * @param style the style e.g DateFormat.LONG.
177     * @return the pattern, e.g {1}, {0}.
178     */
179    public String getDateTimePattern(int style) {
180        // mask away high order bits such as the DateFormat.RELATIVE bit.
181        // We do it this way to avoid making this class depend on DateFormat. It makes this
182        // code more brittle, but it is no more brittle than how we access patterns by style.
183        return _getDateTimePattern(style & 7);
184    }
185
186    private String _getDateTimePattern(int offset) {
187        String[] patterns = null;
188        try {
189            patterns = getDateTimePatterns();
190        } catch (MissingResourceException ignored) {
191            // ignore. patterns remains null.
192        }
193        if (patterns == null || patterns.length < 9) {
194            // Return hard-coded default. patterns array not available or it has too few
195            // elements.
196            return "{1} {0}";
197        }
198        if (patterns.length < 13) {
199            // Offset 8 contains default pattern if we don't have per style patterns.
200            return patterns[8];
201        }
202        // DateTimePatterns start at index 9 in the array.
203        return patterns[9 + offset];
204    }
205
206    public String[] getOverrides(){
207        ICUResourceBundle bundle = get("DateTimePatterns");
208        ArrayList<String> list = new ArrayList<String>();
209        UResourceBundleIterator iter = bundle.getIterator();
210        while (iter.hasNext()) {
211            UResourceBundle patResource = iter.next();
212            int resourceType = patResource.getType();
213            switch (resourceType) {
214                case UResourceBundle.STRING:
215                    list.add(null);
216                    break;
217                case UResourceBundle.ARRAY:
218                    String[] items = patResource.getStringArray();
219                    list.add(items[1]);
220                    break;
221            }
222        }
223        return list.toArray(new String[list.size()]);
224    }
225
226    public ULocale getULocale() {
227        return fBundle.getULocale();
228    }
229
230    private ICUResourceBundle fBundle;
231    private String fMainType;
232    private String fFallbackType;
233}
234