/** * Load a properties file for a given locale. Note that locale inheritance is the responsibility * of the caller. * * @param prefix classpath prefix of properties file * @param locale locale to load * @return LocalizedProperties instance containing properties file or null if not found. */ private LocalizedProperties getProperties(String prefix, GwtLocale locale) { String propFile = prefix; if (!locale.isDefault()) { propFile += "_" + locale.getAsString(); } propFile += ".properties"; InputStream str = null; ClassLoader classLoader = getClass().getClassLoader(); LocalizedProperties props = new LocalizedProperties(); try { str = classLoader.getResourceAsStream(propFile); if (str != null) { props.load(str, "UTF-8"); return props; } } catch (UnsupportedEncodingException e) { // UTF-8 should always be defined return null; } catch (IOException e) { return null; } finally { if (str != null) { try { str.close(); } catch (IOException e) { } } } return null; }
/** * Generate an implementation class for the requested locale, including all parent classes along * the inheritance chain. The data will be kept at the location in the inheritance chain where it * was defined in properties files. * * @param logger * @param context * @param targetClass * @param locale * @return generated class name for the requested locale */ private String generateLocaleTree( TreeLogger logger, GeneratorContext context, JClassType targetClass, GwtLocale locale) { String superClassName = CURRENCY_LIST; List<GwtLocale> searchList = locale.getCompleteSearchList(); /** Map of currency code -> CurrencyInfo for that code. */ Map<String, CurrencyInfo> allCurrencyData = new HashMap<String, CurrencyInfo>(); LocalizedProperties currencyExtra = null; /* * The searchList is guaranteed to be ordered such that subclasses always * precede superclasses. Therefore, we iterate backwards to ensure that * superclasses are always generated first. */ String lastDefaultCurrencyCode = null; for (int i = searchList.size(); i-- > 0; ) { GwtLocale search = searchList.get(i); LocalizedProperties newExtra = getProperties(CURRENCY_EXTRA_PREFIX, search); if (newExtra != null) { currencyExtra = newExtra; } Map<String, String> currencyData = getCurrencyData(search); Set<String> keySet = currencyData.keySet(); String[] currencies = new String[keySet.size()]; keySet.toArray(currencies); Arrays.sort(currencies); // Go ahead and populate the data map. for (String currencyCode : currencies) { String extraData = currencyExtra == null ? null : currencyExtra.getProperty(currencyCode); allCurrencyData.put( currencyCode, new CurrencyInfo(currencyCode, currencyData.get(currencyCode), extraData)); } String defCurrencyCode = getDefaultCurrency(search); // If this locale specifies a particular locale, or the one that is // inherited has been changed in this locale, re-specify the default // currency so the method will be generated. if (defCurrencyCode == null && keySet.contains(lastDefaultCurrencyCode)) { defCurrencyCode = lastDefaultCurrencyCode; } if (!currencyData.isEmpty() || defCurrencyCode != null) { String newClass = generateOneLocale( logger, context, targetClass, search, superClassName, currencies, allCurrencyData, defCurrencyCode); superClassName = newClass; lastDefaultCurrencyCode = defCurrencyCode; } } return superClassName; }
/** * Return a map of currency data for the requested locale, or null if there is not one (not that * inheritance is not handled here). * * <p>The keys are ISO4217 currency codes. The format of the map values is: * * <pre> * display name|symbol|decimal digits|not-used-flag * </pre> * * If a symbol is not supplied, the currency code will be used If # of decimal digits is omitted, * 2 is used If a currency is not generally used, not-used-flag=1 Trailing empty fields can be * omitted * * @param locale * @return currency data map */ @SuppressWarnings("unchecked") private Map<String, String> getCurrencyData(GwtLocale locale) { LocalizedProperties currencyData = getProperties(CURRENCY_DATA_PREFIX, locale); if (currencyData == null) { return Collections.emptyMap(); } return currencyData.getPropertyMap(); }
/** * Returns the default currency code for the requested locale. * * @param locale * @return ISO4217 currency code */ private String getDefaultCurrency(GwtLocale locale) { String defCurrencyCode = null; LocalizedProperties numberConstants = getProperties(NUMBER_CONSTANTS_PREFIX, locale); if (numberConstants != null) { defCurrencyCode = numberConstants.getProperty("defCurrencyCode"); } if (defCurrencyCode == null && locale.isDefault()) { defCurrencyCode = "USD"; } return defCurrencyCode; }