1 package org.unicode.cldr.util; 2 3 import java.util.List; 4 5 import org.unicode.cldr.util.CLDRFile.WinningChoice; 6 import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo; 7 import org.unicode.cldr.util.SupplementalDataInfo.PluralInfo.Count; 8 9 import com.ibm.icu.text.Transform; 10 import com.ibm.icu.text.UnicodeSet; 11 import com.ibm.icu.util.Output; 12 13 public class ValuePathStatus { 14 15 public enum MissingOK { 16 ok, latin, alias, compact 17 } 18 19 public static final UnicodeSet LATIN = new UnicodeSet("[:sc=Latn:]").freeze(); 20 isLatinScriptLocale(CLDRFile sourceFile)21 public static boolean isLatinScriptLocale(CLDRFile sourceFile) { 22 UnicodeSet main = sourceFile.getExemplarSet("", WinningChoice.WINNING); 23 return LATIN.containsSome(main); 24 } 25 26 public static Transform<String, ValuePathStatus.MissingOK> MISSING_STATUS_TRANSFORM = new Transform<String, ValuePathStatus.MissingOK>() { 27 @Override 28 public ValuePathStatus.MissingOK transform(String source) { 29 return ValuePathStatus.MissingOK.valueOf(source); 30 } 31 }; 32 33 static final RegexLookup<ValuePathStatus.MissingOK> missingOk = new RegexLookup<ValuePathStatus.MissingOK>() 34 .setPatternTransform(RegexLookup.RegexFinderTransformPath) 35 .setValueTransform(MISSING_STATUS_TRANSFORM) 36 .loadFromFile(ValuePathStatus.class, "data/paths/missingOk.txt"); 37 countZeros(String otherValue)38 static int countZeros(String otherValue) { 39 int result = 0; 40 for (int i = 0; i < otherValue.length(); ++i) { 41 if (otherValue.charAt(i) == '0') { 42 ++result; 43 } 44 } 45 return result; 46 } 47 48 static final UnicodeSet ASCII_DIGITS = new UnicodeSet("[0-9]"); 49 isMissingOk(CLDRFile sourceFile, String path, boolean latin, boolean aliased)50 public static boolean isMissingOk(CLDRFile sourceFile, String path, boolean latin, boolean aliased) { 51 if (sourceFile.getLocaleID().equals("en")) { 52 return true; 53 } 54 Output<String[]> arguments = new Output<>(); 55 List<String> failures = null; 56 // if (path.startsWith("//ldml/characters/parseLenients")) { 57 // int debug = 0; 58 // failures = new ArrayList<>(); 59 // } 60 ValuePathStatus.MissingOK value = missingOk.get(path, null, arguments, null, failures); 61 if (value == null) { 62 return false; 63 } 64 switch (value) { 65 case ok: 66 return true; 67 case latin: 68 return latin; 69 case alias: 70 return aliased; 71 case compact: 72 // special processing for compact numbers 73 // //ldml/numbers/decimalFormats[@numberSystem="%A"]/decimalFormatLength[@type="%A"]/decimalFormat[@type="standard"]/pattern[@type="%A"][@count="%A"] ; compact 74 if (path.contains("[@count=\"other\"]")) { 75 return false; // the 'other' class always counts as missing 76 } 77 final String numberSystem = arguments.value[1]; 78 final String formatLength = arguments.value[2]; 79 final String patternType = arguments.value[3]; 80 String otherPath = "//ldml/numbers/decimalFormats[@numberSystem=\"" + numberSystem 81 + "\"]/decimalFormatLength[@type=\"" + formatLength 82 + "\"]/decimalFormat[@type=\"standard\"]/pattern[@type=\"" + patternType 83 + "\"][@count=\"other\"]"; 84 String otherValue = sourceFile.getWinningValue(otherPath); 85 if (otherValue == null) { 86 return false; // something's wrong, bail 87 } 88 int digits = countZeros(otherValue); 89 if (digits > 4) { // we can only handle to 4 digits 90 return false; 91 } 92 // If the count is numeric or if there are no possible Count values for this many digits, then it is ok to be missing. 93 final String count = arguments.value[4]; 94 if (ASCII_DIGITS.containsAll(count)) { 95 return true; // ok to be missing 96 } 97 Count c = Count.valueOf(count); 98 99 SupplementalDataInfo supplementalDataInfo2 = CLDRConfig.getInstance().getSupplementalDataInfo(); 100 // SupplementalDataInfo.getInstance(sourceFile.getSupplementalDirectory()); 101 PluralInfo plurals = supplementalDataInfo2.getPlurals(sourceFile.getLocaleID()); 102 return plurals == null || !plurals.hasSamples(c, digits); // ok if no samples 103 // TODO: handle fractions 104 default: 105 throw new IllegalArgumentException(); 106 } 107 } 108 109 } 110