Home | History | Annotate | Download | only in number
      1 /* GENERATED SOURCE. DO NOT MODIFY. */
      2 //  2017 and later: Unicode, Inc. and others.
      3 // License & terms of use: http://www.unicode.org/copyright.html#License
      4 package android.icu.impl.number;
      5 
      6 import java.util.EnumMap;
      7 import java.util.Map;
      8 
      9 import android.icu.impl.CurrencyData;
     10 import android.icu.impl.ICUData;
     11 import android.icu.impl.ICUResourceBundle;
     12 import android.icu.impl.SimpleFormatterImpl;
     13 import android.icu.impl.StandardPlural;
     14 import android.icu.impl.UResource;
     15 import android.icu.number.NumberFormatter.UnitWidth;
     16 import android.icu.text.NumberFormat;
     17 import android.icu.text.PluralRules;
     18 import android.icu.util.Currency;
     19 import android.icu.util.ICUException;
     20 import android.icu.util.MeasureUnit;
     21 import android.icu.util.ULocale;
     22 import android.icu.util.UResourceBundle;
     23 
     24 /**
     25  * @hide Only a subset of ICU is exposed in Android
     26  */
     27 public class LongNameHandler implements MicroPropsGenerator {
     28 
     29     //////////////////////////
     30     /// BEGIN DATA LOADING ///
     31     //////////////////////////
     32 
     33     private static final class PluralTableSink extends UResource.Sink {
     34 
     35         Map<StandardPlural, String> output;
     36 
     37         public PluralTableSink(Map<StandardPlural, String> output) {
     38             this.output = output;
     39         }
     40 
     41         @Override
     42         public void put(UResource.Key key, UResource.Value value, boolean noFallback) {
     43             UResource.Table pluralsTable = value.getTable();
     44             for (int i = 0; pluralsTable.getKeyAndValue(i, key, value); ++i) {
     45                 if (key.contentEquals("dnam") || key.contentEquals("per")) {
     46                     continue;
     47                 }
     48                 StandardPlural plural = StandardPlural.fromString(key);
     49                 if (output.containsKey(plural)) {
     50                     continue;
     51                 }
     52                 String formatString = value.getString();
     53                 output.put(plural, formatString);
     54             }
     55         }
     56     }
     57 
     58     private static void getMeasureData(ULocale locale, MeasureUnit unit, UnitWidth width,
     59             Map<StandardPlural, String> output) {
     60         PluralTableSink sink = new PluralTableSink(output);
     61         ICUResourceBundle resource;
     62         resource = (ICUResourceBundle) UResourceBundle.getBundleInstance(ICUData.ICU_UNIT_BASE_NAME, locale);
     63         StringBuilder key = new StringBuilder();
     64         key.append("units");
     65         if (width == UnitWidth.NARROW) {
     66             key.append("Narrow");
     67         } else if (width == UnitWidth.SHORT) {
     68             key.append("Short");
     69         }
     70         key.append("/");
     71         key.append(unit.getType());
     72         key.append("/");
     73         key.append(unit.getSubtype());
     74         resource.getAllItemsWithFallback(key.toString(), sink);
     75     }
     76 
     77     private static void getCurrencyLongNameData(ULocale locale, Currency currency, Map<StandardPlural, String> output) {
     78         // In ICU4J, this method gets a CurrencyData from CurrencyData.provider.
     79         // TODO(ICU4J): Implement this without going through CurrencyData, like in ICU4C?
     80         Map<String, String> data = CurrencyData.provider.getInstance(locale, true).getUnitPatterns();
     81         for (Map.Entry<String, String> e : data.entrySet()) {
     82             String pluralKeyword = e.getKey();
     83             StandardPlural plural = StandardPlural.fromString(e.getKey());
     84             String longName = currency.getName(locale, Currency.PLURAL_LONG_NAME, pluralKeyword, null);
     85             String simpleFormat = e.getValue();
     86             // Example pattern from data: "{0} {1}"
     87             // Example output after find-and-replace: "{0} US dollars"
     88             simpleFormat = simpleFormat.replace("{1}", longName);
     89             // String compiled = SimpleFormatterImpl.compileToStringMinMaxArguments(simpleFormat, sb, 1, 1);
     90             // SimpleModifier mod = new SimpleModifier(compiled, Field.CURRENCY, false);
     91             output.put(plural, simpleFormat);
     92         }
     93     }
     94 
     95     ////////////////////////
     96     /// END DATA LOADING ///
     97     ////////////////////////
     98 
     99     private final Map<StandardPlural, SimpleModifier> modifiers;
    100     private final PluralRules rules;
    101     private final MicroPropsGenerator parent;
    102 
    103     private LongNameHandler(Map<StandardPlural, SimpleModifier> modifiers, PluralRules rules,
    104             MicroPropsGenerator parent) {
    105         this.modifiers = modifiers;
    106         this.rules = rules;
    107         this.parent = parent;
    108     }
    109 
    110     public static LongNameHandler forCurrencyLongNames(ULocale locale, Currency currency, PluralRules rules,
    111             MicroPropsGenerator parent) {
    112         Map<StandardPlural, String> simpleFormats = new EnumMap<StandardPlural, String>(StandardPlural.class);
    113         getCurrencyLongNameData(locale, currency, simpleFormats);
    114         // TODO(ICU4J): Reduce the number of object creations here?
    115         Map<StandardPlural, SimpleModifier> modifiers = new EnumMap<StandardPlural, SimpleModifier>(
    116                 StandardPlural.class);
    117         simpleFormatsToModifiers(simpleFormats, null, modifiers);
    118         return new LongNameHandler(modifiers, rules, parent);
    119     }
    120 
    121     public static LongNameHandler forMeasureUnit(ULocale locale, MeasureUnit unit, UnitWidth width, PluralRules rules,
    122             MicroPropsGenerator parent) {
    123         Map<StandardPlural, String> simpleFormats = new EnumMap<StandardPlural, String>(StandardPlural.class);
    124         getMeasureData(locale, unit, width, simpleFormats);
    125         // TODO: What field to use for units?
    126         // TODO(ICU4J): Reduce the number of object creations here?
    127         Map<StandardPlural, SimpleModifier> modifiers = new EnumMap<StandardPlural, SimpleModifier>(
    128                 StandardPlural.class);
    129         simpleFormatsToModifiers(simpleFormats, null, modifiers);
    130         return new LongNameHandler(modifiers, rules, parent);
    131     }
    132 
    133     private static void simpleFormatsToModifiers(Map<StandardPlural, String> simpleFormats, NumberFormat.Field field,
    134             Map<StandardPlural, SimpleModifier> output) {
    135         StringBuilder sb = new StringBuilder();
    136         for (StandardPlural plural : StandardPlural.VALUES) {
    137             String simpleFormat = simpleFormats.get(plural);
    138             if (simpleFormat == null) {
    139                 simpleFormat = simpleFormats.get(StandardPlural.OTHER);
    140             }
    141             if (simpleFormat == null) {
    142                 // There should always be data in the "other" plural variant.
    143                 throw new ICUException("Could not find data in 'other' plural variant with field " + field);
    144             }
    145             String compiled = SimpleFormatterImpl.compileToStringMinMaxArguments(simpleFormat, sb, 1, 1);
    146             output.put(plural, new SimpleModifier(compiled, null, false));
    147         }
    148     }
    149 
    150     @Override
    151     public MicroProps processQuantity(DecimalQuantity quantity) {
    152         MicroProps micros = parent.processQuantity(quantity);
    153         // TODO: Avoid the copy here?
    154         DecimalQuantity copy = quantity.createCopy();
    155         micros.rounding.apply(copy);
    156         micros.modOuter = modifiers.get(copy.getStandardPlural(rules));
    157         return micros;
    158     }
    159 }
    160