Home | History | Annotate | Download | only in util
      1 package org.unicode.cldr.util;
      2 
      3 import java.util.Collection;
      4 import java.util.Collections;
      5 import java.util.HashSet;
      6 import java.util.Set;
      7 
      8 import com.ibm.icu.text.PluralRules;
      9 
     10 public class PluralRulesUtil {
     11     /**
     12      * Status of the keyword for the rules, given a set of explicit values.
     13      */
     14     public enum KeywordStatus {
     15         /**
     16          * The keyword is not valid for the rules.
     17          */
     18         INVALID,
     19         /**
     20          * The keyword is valid, but unused (it is covered by the explicit values).
     21          */
     22         SUPPRESSED,
     23         /**
     24          * The keyword is valid and used, but completely covered by the explicit values.
     25          */
     26         UNIQUE,
     27         /**
     28          * The keyword is valid, used, not suppressed, and has a finite set of values.
     29          */
     30         BOUNDED,
     31         /**
     32          * The keyword is valid but not bounded; there are indefinitely many matching values.
     33          */
     34         UNBOUNDED
     35     }
     36 
     37     /**
     38      * Find the status for the keyword, given a certain set of explicit values.
     39      *
     40      * @param rules
     41      *            the PluralRules
     42      * @param keyword
     43      *            the particular keyword (call rules.getKeywords() to get the valid ones)
     44      * @param offset
     45      *            the offset used, or 0.0d if not. Internally, the offset is subtracted from each explicit value before
     46      *            checking against the keyword values.
     47      * @param explicits
     48      *            a set of Doubles that are used explicitly (eg [=0], "[=1]"). May be empty or null.
     49      * @param integerOnly
     50      *            In circumstances where the values are known to be integers, this parameter can be set to true.
     51      *            Examples: "There are 3 people in..." (integerOnly=true) vs. "There are 1.2 people per household
     52      *            (integerOnly=false).
     53      *            This may produce different results in languages where fractions have the same format as integers for
     54      *            some keywords.
     55      * @return the KeywordStatus
     56      *         <p>
     57      *         NOTE: For testing, this is a static with the first parameter being the rules. Those will disappear.
     58      */
     59     public static KeywordStatus getKeywordStatus(PluralRules rules, String keyword, int offset, Set<Double> explicits,
     60         boolean integerOnly) {
     61         if (!rules.getKeywords().contains(keyword)) {
     62             return KeywordStatus.INVALID;
     63         }
     64         Collection<Double> values = rules.getAllKeywordValues(keyword);
     65         if (values == null) {
     66             return KeywordStatus.UNBOUNDED;
     67         }
     68         int originalSize = values.size();
     69 
     70         // Quick check on whether there are multiple elements
     71 
     72         if (explicits == null) {
     73             explicits = Collections.emptySet();
     74         }
     75         if (originalSize > explicits.size()) {
     76             return originalSize == 1 ? KeywordStatus.UNIQUE : KeywordStatus.BOUNDED;
     77         }
     78 
     79         // Compute if the quick test is insufficient.
     80 
     81         HashSet<Double> subtractedSet = new HashSet<Double>(values);
     82         for (Double explicit : explicits) {
     83             // int rounded = (int) Math.round(explicit*1000000);
     84             subtractedSet.remove(explicit - offset);
     85         }
     86         if (subtractedSet.size() == 0) {
     87             return KeywordStatus.SUPPRESSED;
     88         }
     89 
     90         return originalSize == 1 ? KeywordStatus.UNIQUE : KeywordStatus.BOUNDED;
     91     }
     92 
     93     // static final Map<String,Set<String>> locale2keywords = new HashMap<String,Set<String>>();
     94     // static final Map<String,PluralRules> locale2pluralRules = new HashMap<String,PluralRules>();
     95     // static final Set<Double> explicits = new HashSet<Double>();
     96     // static {
     97     // explicits.add(0.0d);
     98     // explicits.add(1.0d);
     99     // }
    100     // public static Set<String> getCanonicalKeywords(String locale) {
    101     // synchronized (locale2keywords) {
    102     // Set<String> result = locale2keywords.get(locale);
    103     // if (result != null) {
    104     // return result;
    105     // }
    106     // // special caching because locales don't differ
    107     // int pos = locale.indexOf('_');
    108     // String lang = pos < 0 ? locale : locale.substring(0,pos);
    109     // if (pos >= 0) {
    110     // result = locale2keywords.get(locale);
    111     // if (result != null) {
    112     // locale2keywords.put(locale, result);
    113     // return result;
    114     // }
    115     // }
    116     // PluralInfo pluralInfo = SupplementalDataInfo.getInstance().getPlurals(SupplementalDataInfo.PluralType.cardinal,
    117     // lang);
    118     // PluralRules pluralRules = PluralRules.createRules(pluralInfo.getRules());
    119     // locale2pluralRules.put(lang, pluralRules);
    120     // result = new HashSet();
    121     // for (String keyword : pluralRules.getKeywords()) {
    122     // KeywordStatus status = getKeywordStatus(pluralRules, keyword, 0, explicits, true);
    123     // if (status != KeywordStatus.SUPPRESSED) {
    124     // result.add(keyword);
    125     // }
    126     // }
    127     // result = Collections.unmodifiableSet(result);
    128     // locale2keywords.put(locale, result);
    129     // if (pos >= 0) {
    130     // locale2keywords.put(lang, result);
    131     // }
    132     // return result;
    133     // }
    134     //
    135     // }
    136 }
    137