• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.unicode.cldr.test;
2 
3 import java.util.List;
4 
5 import org.unicode.cldr.test.CheckCLDR.CheckStatus.Subtype;
6 import org.unicode.cldr.util.CLDRFile;
7 import org.unicode.cldr.util.XPathParts;
8 
9 import com.ibm.icu.lang.UCharacter;
10 import com.ibm.icu.text.BreakIterator;
11 import com.ibm.icu.util.ULocale;
12 
13 public class CheckCasing extends CheckCLDR {
14     public enum Case {
15         mixed, lowercase_words, titlecase_words, titlecase_firstword, verbatim;
forString(String input)16         public static Case forString(String input) {
17             return valueOf(input.replace('-', '_'));
18         }
19     };
20 
21     // remember to add this class to the list in CheckCLDR.getCheckAll
22     // to run just this test, on just locales starting with 'nl', use CheckCLDR with -fnl.* -t.*Currencies.*
23 
24     ULocale uLocale = null;
25     BreakIterator breaker = null;
26 
27     @Override
setCldrFileToCheck(CLDRFile cldrFileToCheck, Options options, List<CheckStatus> possibleErrors)28     public CheckCLDR setCldrFileToCheck(CLDRFile cldrFileToCheck, Options options,
29         List<CheckStatus> possibleErrors) {
30         if (cldrFileToCheck == null) return this;
31         super.setCldrFileToCheck(cldrFileToCheck, options, possibleErrors);
32         uLocale = new ULocale(cldrFileToCheck.getLocaleID());
33         breaker = BreakIterator.getWordInstance(uLocale);
34         return this;
35     }
36 
37     // If you don't need any file initialization or postprocessing, you only need this one routine
handleCheck(String path, String fullPath, String value, Options options, List<CheckStatus> result)38     public CheckCLDR handleCheck(String path, String fullPath, String value, Options options,
39         List<CheckStatus> result) {
40         // it helps performance to have a quick reject of most paths
41         if (fullPath == null) return this; // skip paths that we don't have
42         if (fullPath.indexOf("casing") < 0) return this;
43 
44         // pick up the casing attributes from the full path
45         XPathParts parts = XPathParts.getFrozenInstance(fullPath);
46 
47         Case caseTest = Case.mixed;
48         for (int i = 0; i < parts.size(); ++i) {
49             String casingValue = parts.getAttributeValue(i, "casing");
50             if (casingValue == null) {
51                 continue;
52             }
53             caseTest = Case.forString(casingValue);
54             if (caseTest == Case.verbatim) {
55                 return this; // we're done
56             }
57         }
58 
59         String newValue = value;
60         switch (caseTest) {
61         case lowercase_words:
62             newValue = UCharacter.toLowerCase(uLocale, value);
63             break;
64         case titlecase_words:
65             newValue = UCharacter.toTitleCase(uLocale, value, null);
66             break;
67         case titlecase_firstword:
68             newValue = TitleCaseFirst(uLocale, value);
69             break;
70         default:
71             break;
72 
73         }
74         if (!newValue.equals(value)) {
75             // the following is how you signal an error or warning (or add a demo....)
76             result.add(new CheckStatus().setCause(this)
77                 .setMainType(CheckStatus.errorType)
78                 .setSubtype(Subtype.incorrectCasing)
79                 // typically warningType or errorType
80                 .setMessage("Casing incorrect: either should have casing=\"verbatim\" or be <{0}>",
81                     new Object[] { newValue })); // the message; can be MessageFormat with arguments
82         }
83         return this;
84     }
85 
86     // -f(bg|cs|da|el|et|is|it|lt|ro|ru|sl|uk) -t(.*casing.*)
87 
TitleCaseFirst(ULocale locale, String value)88     private String TitleCaseFirst(ULocale locale, String value) {
89         if (value.length() == 0) {
90             return value;
91         }
92         breaker.setText(value);
93         breaker.first();
94         int endOfFirstWord = breaker.next();
95         return UCharacter.toTitleCase(uLocale, value.substring(0, endOfFirstWord), breaker)
96             + value.substring(endOfFirstWord);
97     }
98 
99 }