private void setup( String resourceKey, Map<TimeUnit, Map<String, Object[]>> timeUnitToCountToPatterns, int style) { // fill timeUnitToCountToPatterns from resource file try { ICUResourceBundle resource = (ICUResourceBundle) UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, locale); ICUResourceBundle unitsRes = resource.getWithFallback(resourceKey); int size = unitsRes.getSize(); for (int index = 0; index < size; ++index) { String timeUnitName = unitsRes.get(index).getKey(); TimeUnit timeUnit = null; if (timeUnitName.equals("year")) { timeUnit = TimeUnit.YEAR; } else if (timeUnitName.equals("month")) { timeUnit = TimeUnit.MONTH; } else if (timeUnitName.equals("day")) { timeUnit = TimeUnit.DAY; } else if (timeUnitName.equals("hour")) { timeUnit = TimeUnit.HOUR; } else if (timeUnitName.equals("minute")) { timeUnit = TimeUnit.MINUTE; } else if (timeUnitName.equals("second")) { timeUnit = TimeUnit.SECOND; } else if (timeUnitName.equals("week")) { timeUnit = TimeUnit.WEEK; } else { continue; } ICUResourceBundle oneUnitRes = unitsRes.getWithFallback(timeUnitName); int count = oneUnitRes.getSize(); Map<String, Object[]> countToPatterns = timeUnitToCountToPatterns.get(timeUnit); if (countToPatterns == null) { countToPatterns = new TreeMap<String, Object[]>(); timeUnitToCountToPatterns.put(timeUnit, countToPatterns); } for (int pluralIndex = 0; pluralIndex < count; ++pluralIndex) { String pluralCount = oneUnitRes.get(pluralIndex).getKey(); String pattern = oneUnitRes.get(pluralIndex).getString(); final MessageFormat messageFormat = new MessageFormat(pattern, locale); if (format != null) { messageFormat.setFormatByArgumentIndex(0, format); } // save both full name and abbreviated name in one table // is good space-wise, but it degrades performance, // since it needs to check whether the needed space // is already allocated or not. Object[] pair = countToPatterns.get(pluralCount); if (pair == null) { pair = new Object[2]; countToPatterns.put(pluralCount, pair); } pair[style] = messageFormat; } } } catch (MissingResourceException e) { } // there should be patterns for each plural rule in each time unit. // For each time unit, // for each plural rule, following is unit pattern fall-back rule: // ( for example: "one" hour ) // look for its unit pattern in its locale tree. // if pattern is not found in its own locale, such as de_DE, // look for the pattern in its parent, such as de, // keep looking till found or till root. // if the pattern is not found in root either, // fallback to plural count "other", // look for the pattern of "other" in the locale tree: // "de_DE" to "de" to "root". // If not found, fall back to value of // static variable DEFAULT_PATTERN_FOR_xxx, such as "{0} h". // // Following is consistency check to create pattern for each // plural rule in each time unit using above fall-back rule. // final TimeUnit[] timeUnits = TimeUnit.values(); Set<String> keywords = pluralRules.getKeywords(); for (int i = 0; i < timeUnits.length; ++i) { // for each time unit, // get all the patterns for each plural rule in this locale. final TimeUnit timeUnit = timeUnits[i]; Map<String, Object[]> countToPatterns = timeUnitToCountToPatterns.get(timeUnit); if (countToPatterns == null) { countToPatterns = new TreeMap<String, Object[]>(); timeUnitToCountToPatterns.put(timeUnit, countToPatterns); } for (String pluralCount : keywords) { if (countToPatterns.get(pluralCount) == null || countToPatterns.get(pluralCount)[style] == null) { // look through parents searchInTree(resourceKey, style, timeUnit, pluralCount, pluralCount, countToPatterns); } } } }