| package org.unicode.cldr.util; |
| |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| import com.ibm.icu.text.PluralRules; |
| |
| public class PluralRulesUtil { |
| /** |
| * Status of the keyword for the rules, given a set of explicit values. |
| */ |
| public enum KeywordStatus { |
| /** |
| * The keyword is not valid for the rules. |
| */ |
| INVALID, |
| /** |
| * The keyword is valid, but unused (it is covered by the explicit values). |
| */ |
| SUPPRESSED, |
| /** |
| * The keyword is valid and used, but completely covered by the explicit values. |
| */ |
| UNIQUE, |
| /** |
| * The keyword is valid, used, not suppressed, and has a finite set of values. |
| */ |
| BOUNDED, |
| /** |
| * The keyword is valid but not bounded; there are indefinitely many matching values. |
| */ |
| UNBOUNDED |
| } |
| |
| /** |
| * Find the status for the keyword, given a certain set of explicit values. |
| * |
| * @param rules |
| * the PluralRules |
| * @param keyword |
| * the particular keyword (call rules.getKeywords() to get the valid ones) |
| * @param offset |
| * the offset used, or 0.0d if not. Internally, the offset is subtracted from each explicit value before |
| * checking against the keyword values. |
| * @param explicits |
| * a set of Doubles that are used explicitly (eg [=0], "[=1]"). May be empty or null. |
| * @param integerOnly |
| * In circumstances where the values are known to be integers, this parameter can be set to true. |
| * Examples: "There are 3 people in..." (integerOnly=true) vs. "There are 1.2 people per household |
| * (integerOnly=false). |
| * This may produce different results in languages where fractions have the same format as integers for |
| * some keywords. |
| * @return the KeywordStatus |
| * <p> |
| * NOTE: For testing, this is a static with the first parameter being the rules. Those will disappear. |
| */ |
| public static KeywordStatus getKeywordStatus(PluralRules rules, String keyword, int offset, Set<Double> explicits, |
| boolean integerOnly) { |
| if (!rules.getKeywords().contains(keyword)) { |
| return KeywordStatus.INVALID; |
| } |
| Collection<Double> values = rules.getAllKeywordValues(keyword); |
| if (values == null) { |
| return KeywordStatus.UNBOUNDED; |
| } |
| int originalSize = values.size(); |
| |
| // Quick check on whether there are multiple elements |
| |
| if (explicits == null) { |
| explicits = Collections.emptySet(); |
| } |
| if (originalSize > explicits.size()) { |
| return originalSize == 1 ? KeywordStatus.UNIQUE : KeywordStatus.BOUNDED; |
| } |
| |
| // Compute if the quick test is insufficient. |
| |
| HashSet<Double> subtractedSet = new HashSet<Double>(values); |
| for (Double explicit : explicits) { |
| // int rounded = (int) Math.round(explicit*1000000); |
| subtractedSet.remove(explicit - offset); |
| } |
| if (subtractedSet.size() == 0) { |
| return KeywordStatus.SUPPRESSED; |
| } |
| |
| return originalSize == 1 ? KeywordStatus.UNIQUE : KeywordStatus.BOUNDED; |
| } |
| |
| // static final Map<String,Set<String>> locale2keywords = new HashMap<String,Set<String>>(); |
| // static final Map<String,PluralRules> locale2pluralRules = new HashMap<String,PluralRules>(); |
| // static final Set<Double> explicits = new HashSet<Double>(); |
| // static { |
| // explicits.add(0.0d); |
| // explicits.add(1.0d); |
| // } |
| // public static Set<String> getCanonicalKeywords(String locale) { |
| // synchronized (locale2keywords) { |
| // Set<String> result = locale2keywords.get(locale); |
| // if (result != null) { |
| // return result; |
| // } |
| // // special caching because locales don't differ |
| // int pos = locale.indexOf('_'); |
| // String lang = pos < 0 ? locale : locale.substring(0,pos); |
| // if (pos >= 0) { |
| // result = locale2keywords.get(locale); |
| // if (result != null) { |
| // locale2keywords.put(locale, result); |
| // return result; |
| // } |
| // } |
| // PluralInfo pluralInfo = SupplementalDataInfo.getInstance().getPlurals(SupplementalDataInfo.PluralType.cardinal, |
| // lang); |
| // PluralRules pluralRules = PluralRules.createRules(pluralInfo.getRules()); |
| // locale2pluralRules.put(lang, pluralRules); |
| // result = new HashSet(); |
| // for (String keyword : pluralRules.getKeywords()) { |
| // KeywordStatus status = getKeywordStatus(pluralRules, keyword, 0, explicits, true); |
| // if (status != KeywordStatus.SUPPRESSED) { |
| // result.add(keyword); |
| // } |
| // } |
| // result = Collections.unmodifiableSet(result); |
| // locale2keywords.put(locale, result); |
| // if (pos >= 0) { |
| // locale2keywords.put(lang, result); |
| // } |
| // return result; |
| // } |
| // |
| // } |
| } |