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