• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
getKeywordStatus(PluralRules rules, String keyword, int offset, Set<Double> explicits, boolean integerOnly)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<>(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