diff --git a/tools/cldr-code/src/main/java/org/unicode/cldr/tool/ListRbnf.java b/tools/cldr-code/src/main/java/org/unicode/cldr/tool/ListRbnf.java new file mode 100644 index 00000000000..5392112adef --- /dev/null +++ b/tools/cldr-code/src/main/java/org/unicode/cldr/tool/ListRbnf.java @@ -0,0 +1,70 @@ +package org.unicode.cldr.tool; + +import com.google.common.base.Joiner; +import com.google.common.base.Splitter; +import com.google.common.collect.Multimap; +import com.google.common.collect.TreeMultimap; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeSet; +import org.unicode.cldr.util.RbnfData; + +public class ListRbnf { + public static void main(String[] args) { + listRbnf(); + } + + public static void listRbnf() { + Joiner joinTab = Joiner.on('\t'); + Joiner joinCommaSpace = Joiner.on(", "); + Splitter splitDash = Splitter.on('-'); + System.out.println("\nLocale to type to subtype"); + Set keys = RbnfData.INSTANCE.getRbnfTypeToLocales().keySet(); + System.out.println("locale\t" + joinTab.join(keys)); + + Multimap typeToSubtype = TreeMultimap.create(); + + for (Entry> entry : + RbnfData.INSTANCE.getLocaleToTypesToSubtypes().entrySet()) { + String locale = entry.getKey(); + List row = new ArrayList<>(); + row.add(locale); + for (String key : keys) { + Collection values = entry.getValue().get(key); + row.add(values == null ? "" : joinCommaSpace.join(values)); + typeToSubtype.putAll(key, values); + } + System.out.println(joinTab.join(row)); + } + System.out.println("\nType to subtype"); + Set allPieces = new TreeSet<>(); + Set allSubtypes = new TreeSet<>(); + + for (Entry> entry : typeToSubtype.asMap().entrySet()) { + Collection values = entry.getValue(); + allSubtypes.addAll(values); + Set pieces = new TreeSet<>(); + values.stream().forEach(x -> pieces.addAll(splitDash.splitToList(x))); + System.out.println( + joinTab.join( + entry.getKey(), + joinCommaSpace.join(values), + joinCommaSpace.join(pieces))); + allPieces.addAll(pieces); + } + System.out.println("\nAll subtypes"); + System.out.println(joinCommaSpace.join(allSubtypes)); + + System.out.println("\nAll pieces"); + System.out.println(joinCommaSpace.join(allPieces)); + + System.out.println("\nSubtype to locale"); + for (Entry> entry : + RbnfData.INSTANCE.getRbnfTypeToLocales().asMap().entrySet()) { + System.out.println(entry.getKey() + "\t" + joinCommaSpace.join(entry.getValue())); + } + } +} diff --git a/tools/cldr-code/src/main/java/org/unicode/cldr/util/CoreCoverageInfo.java b/tools/cldr-code/src/main/java/org/unicode/cldr/util/CoreCoverageInfo.java index 301799cc655..b82d4143f59 100644 --- a/tools/cldr-code/src/main/java/org/unicode/cldr/util/CoreCoverageInfo.java +++ b/tools/cldr-code/src/main/java/org/unicode/cldr/util/CoreCoverageInfo.java @@ -52,9 +52,14 @@ public enum CoreItems { plurals(Level.MODERATE, Sublevel.start), collation(Level.MODERATE), - grammar(Level.MODERN, Sublevel.start), + spellout_cardinal(Level.MODERN), + spellout_ordinal(Level.MODERN), + digits_ordinals(Level.MODERN), + ordinals(Level.MODERN), romanization(Level.MODERN), + + grammar(Level.MODERN, Sublevel.start), ; public static final Set ALL = ImmutableSet.copyOf(CoreItems.values()); @@ -102,7 +107,8 @@ public static Set getCoreCoverageInfo( CLDRFile resolvedFile, Multimap detailedErrors) { detailedErrors.clear(); if (!resolvedFile.isResolved()) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException( + "Don't call on unresolved locales: " + resolvedFile.getLocaleID()); } CLDRFile file = resolvedFile.getUnresolved(); String locale = file.getLocaleID(); @@ -141,6 +147,10 @@ public static Set getCoreCoverageInfo( + "\"]/pluralRule[@count=\"other\"]"); } + rbnfHelper(baseLanguage, "spellout-cardinal", detailedErrors, CoreItems.spellout_cardinal); + rbnfHelper(baseLanguage, "spellout-ordinal", detailedErrors, CoreItems.spellout_ordinal); + rbnfHelper(baseLanguage, "digits-ordinal", detailedErrors, CoreItems.digits_ordinals); + // (01) Default content script and region (normally: normally country with largest // population using that language, and normal script for that). // [supplemental/supplementalMetadata.xml] @@ -289,6 +299,26 @@ public static Set getCoreCoverageInfo( return ImmutableSet.copyOf(Sets.difference(CoreItems.ALL, detailedErrors.keySet())); } + private static void rbnfHelper( + String stringLocale, + String rbnfType, + Multimap detailedErrors, + CoreItems coreItems) { + CLDRLocale cldrLocale = CLDRLocale.getInstance(stringLocale); + while (cldrLocale != null // if either null or root, we fail + && !cldrLocale.equals(CLDRLocale.ROOT)) { + Multimap typeInfo = + RbnfData.INSTANCE.getLocaleToTypesToSubtypes().get(cldrLocale.toString()); + if (typeInfo != null // if we succeed, just return + && typeInfo.containsKey(rbnfType)) { + return; + } + // otherwise try the parent + cldrLocale = cldrLocale.getParent(); + } + detailedErrors.put(coreItems, RbnfData.INSTANCE.getPath(rbnfType)); + } + private static final String[][] ROMANIZATION_PATHS = { {"", "-Latin"}, {"", "-Latin-BGN"}, diff --git a/tools/cldr-code/src/main/java/org/unicode/cldr/util/RbnfData.java b/tools/cldr-code/src/main/java/org/unicode/cldr/util/RbnfData.java new file mode 100644 index 00000000000..95b3a10d437 --- /dev/null +++ b/tools/cldr-code/src/main/java/org/unicode/cldr/util/RbnfData.java @@ -0,0 +1,69 @@ +package org.unicode.cldr.util; + +import com.google.common.collect.Multimap; +import com.google.common.collect.TreeMultimap; +import java.util.Map; +import java.util.TreeMap; + +public enum RbnfData { + INSTANCE; + + private final Map> localeToTypesToSubtypes; + private final Multimap rbnfTypeToLocales; + + { + Map> _localeToRbnfType = new TreeMap<>(); + Multimap _rbnfTypeToLocales = TreeMultimap.create(); + Factory factory = CLDRConfig.getInstance().getRBNFFactory(); + for (String locale : factory.getAvailable()) { + CLDRFile cldrFile = factory.make(locale, false); + Multimap typeToSubtype = _localeToRbnfType.get(locale); + if (typeToSubtype == null) { + _localeToRbnfType.put(locale, typeToSubtype = TreeMultimap.create()); + } + for (String dpath : cldrFile) { + String path = cldrFile.getFullXPath(dpath); + XPathParts parts = XPathParts.getFrozenInstance(path); + if (!"rbnf".equals(parts.getElement(1)) + || !"ruleset".equals(parts.getElement(3)) + || "private".equals(parts.getAttributeValue(3, "access"))) { + continue; + } + String fullType = parts.getAttributeValue(3, "type"); + String rbnfType; + String rbnfSubtype; + if (fullType.startsWith("spellout") || fullType.startsWith("digits")) { + int index2 = fullType.indexOf('-', fullType.indexOf('-') + 1); + if (index2 == -1) { + rbnfType = fullType; + rbnfSubtype = "DEFAULT"; + } else { + rbnfType = fullType.substring(0, index2); + rbnfSubtype = fullType.substring(index2 + 1); + } + } else { + rbnfType = "UNKNOWN"; + rbnfSubtype = fullType; + } + typeToSubtype.put(rbnfType, rbnfSubtype); + _rbnfTypeToLocales.put(rbnfType, locale); + } + } + this.localeToTypesToSubtypes = CldrUtility.protectCollection(_localeToRbnfType); + this.rbnfTypeToLocales = CldrUtility.protectCollection(_rbnfTypeToLocales); + } + + public Multimap getRbnfTypeToLocales() { + return rbnfTypeToLocales; + } + + public Map> getLocaleToTypesToSubtypes() { + return localeToTypesToSubtypes; + } + + public String getPath(String rbnfType) { + return "//ldml/rbnf/rulesetGrouping[@type=\"SpelloutRules\"]/ruleset[@type=\"" + + rbnfType + + "\"]"; + } +} diff --git a/tools/cldr-code/src/test/java/org/unicode/cldr/unittest/TestCoverage.java b/tools/cldr-code/src/test/java/org/unicode/cldr/unittest/TestCoverage.java index 03901daccdc..e02247ca163 100644 --- a/tools/cldr-code/src/test/java/org/unicode/cldr/unittest/TestCoverage.java +++ b/tools/cldr-code/src/test/java/org/unicode/cldr/unittest/TestCoverage.java @@ -41,14 +41,14 @@ public void TestBasic() { Multimap errors = LinkedHashMultimap.create(); Set coreCoverage = CoreCoverageInfo.getCoreCoverageInfo(engCldrFile, errors); if (!assertEquals("English should be complete", all, coreCoverage)) { - showDiff("Missing", all, coreCoverage); + showDiff("English Missing", all, coreCoverage); } - CLDRFile skimpyLocale = testInfo.getCldrFactory().make("asa", false); + CLDRFile skimpyLocale = testInfo.getCldrFactory().make("asa", true); errors.clear(); coreCoverage = CoreCoverageInfo.getCoreCoverageInfo(skimpyLocale, errors); if (!assertEquals("Skimpy locale should not be complete", none, coreCoverage)) { - showDiff("Missing", all, coreCoverage); - showDiff("Extra", coreCoverage, none); + showDiff("Skimpy Missing", all, coreCoverage); + showDiff("Skimpy Extra", coreCoverage, none); } }