| package org.unicode.cldr.test; |
| |
| import java.util.List; |
| |
| import org.unicode.cldr.test.CheckCLDR.CheckStatus.Subtype; |
| import org.unicode.cldr.util.CLDRFile; |
| import org.unicode.cldr.util.XPathParts; |
| |
| import com.ibm.icu.lang.UCharacter; |
| import com.ibm.icu.text.BreakIterator; |
| import com.ibm.icu.util.ULocale; |
| |
| public class CheckCasing extends CheckCLDR { |
| public enum Case { |
| mixed, lowercase_words, titlecase_words, titlecase_firstword, verbatim; |
| public static Case forString(String input) { |
| return valueOf(input.replace('-', '_')); |
| } |
| }; |
| |
| // remember to add this class to the list in CheckCLDR.getCheckAll |
| // to run just this test, on just locales starting with 'nl', use CheckCLDR with -fnl.* -t.*Currencies.* |
| |
| XPathParts parts = new XPathParts(); // used to parse out a path |
| ULocale uLocale = null; |
| BreakIterator breaker = null; |
| |
| @Override |
| public CheckCLDR setCldrFileToCheck(CLDRFile cldrFileToCheck, Options options, |
| List<CheckStatus> possibleErrors) { |
| if (cldrFileToCheck == null) return this; |
| super.setCldrFileToCheck(cldrFileToCheck, options, possibleErrors); |
| uLocale = new ULocale(cldrFileToCheck.getLocaleID()); |
| breaker = BreakIterator.getWordInstance(uLocale); |
| return this; |
| } |
| |
| // If you don't need any file initialization or postprocessing, you only need this one routine |
| public CheckCLDR handleCheck(String path, String fullPath, String value, Options options, |
| List<CheckStatus> result) { |
| // it helps performance to have a quick reject of most paths |
| if (fullPath == null) return this; // skip paths that we don't have |
| if (fullPath.indexOf("casing") < 0) return this; |
| |
| // pick up the casing attributes from the full path |
| parts.set(fullPath); |
| |
| Case caseTest = Case.mixed; |
| for (int i = 0; i < parts.size(); ++i) { |
| String casingValue = parts.getAttributeValue(i, "casing"); |
| if (casingValue == null) { |
| continue; |
| } |
| caseTest = Case.forString(casingValue); |
| if (caseTest == Case.verbatim) { |
| return this; // we're done |
| } |
| } |
| |
| String newValue = value; |
| switch (caseTest) { |
| case lowercase_words: |
| newValue = UCharacter.toLowerCase(uLocale, value); |
| break; |
| case titlecase_words: |
| newValue = UCharacter.toTitleCase(uLocale, value, null); |
| break; |
| case titlecase_firstword: |
| newValue = TitleCaseFirst(uLocale, value); |
| break; |
| default: |
| break; |
| |
| } |
| if (!newValue.equals(value)) { |
| // the following is how you signal an error or warning (or add a demo....) |
| result.add(new CheckStatus().setCause(this) |
| .setMainType(CheckStatus.errorType) |
| .setSubtype(Subtype.incorrectCasing) |
| // typically warningType or errorType |
| .setMessage("Casing incorrect: either should have casing=\"verbatim\" or be <{0}>", |
| new Object[] { newValue })); // the message; can be MessageFormat with arguments |
| } |
| return this; |
| } |
| |
| // -f(bg|cs|da|el|et|is|it|lt|ro|ru|sl|uk) -t(.*casing.*) |
| |
| private String TitleCaseFirst(ULocale locale, String value) { |
| if (value.length() == 0) { |
| return value; |
| } |
| breaker.setText(value); |
| breaker.first(); |
| int endOfFirstWord = breaker.next(); |
| return UCharacter.toTitleCase(uLocale, value.substring(0, endOfFirstWord), breaker) |
| + value.substring(endOfFirstWord); |
| } |
| |
| } |