Home | History | Annotate | Download | only in test
      1 /*
      2  ******************************************************************************
      3  * Copyright (C) 2006-2009,2012, International Business Machines Corporation  *
      4  * and others. All Rights Reserved.                                           *
      5  ******************************************************************************
      6  * $Source$
      7  * $Revision: 12133 $
      8  ******************************************************************************
      9  */
     10 package org.unicode.cldr.test;
     11 
     12 import java.util.ArrayList;
     13 import java.util.Arrays;
     14 import java.util.Collection;
     15 import java.util.Date;
     16 import java.util.Iterator;
     17 import java.util.LinkedHashMap;
     18 import java.util.List;
     19 import java.util.Map;
     20 import java.util.TreeMap;
     21 
     22 import org.unicode.cldr.util.CLDRFile;
     23 import org.unicode.cldr.util.ICUServiceBuilder;
     24 import org.unicode.cldr.util.XPathParts;
     25 
     26 import com.ibm.icu.text.DateFormat;
     27 import com.ibm.icu.text.DateTimePatternGenerator;
     28 import com.ibm.icu.text.DateTimePatternGenerator.PatternInfo;
     29 
     30 /**
     31  * Temporary class while refactoring.
     32  *
     33  * @author markdavis
     34  *
     35  */
     36 class FlexibleDateFromCLDR {
     37     DateTimePatternGenerator gen = DateTimePatternGenerator.getEmptyInstance();
     38     transient XPathParts parts = new XPathParts(null, null);
     39     private transient ICUServiceBuilder icuServiceBuilder = new ICUServiceBuilder();
     40 
     41     static List<String> tests = Arrays.asList(new String[] {
     42 
     43         "HHmmssSSSvvvv", // 'complete' time
     44         "HHmm",
     45         "HHmmvvvv",
     46         "HHmmss",
     47         "HHmmssSSSSS",
     48         "HHmmssvvvv",
     49 
     50         "MMMd",
     51         "Md",
     52 
     53         "YYYYD", // (maybe?)
     54 
     55         "yyyyww",
     56         "yyyywwEEE",
     57 
     58         "yyyyQQQQ",
     59         "yyyyMM",
     60 
     61         "yyyyMd",
     62         "yyyyMMMd",
     63         "yyyyMMMEEEd",
     64 
     65         "GyyyyMMMd",
     66         "GyyyyMMMEEEd", // 'complete' date
     67 
     68         "YYYYwEEE", // year, week of year, weekday
     69         "yyyyDD", // year, day of year
     70         "yyyyMMFE", // year, month, nth day of week in month
     71         // misc
     72         "eG", "dMMy", "GHHmm", "yyyyHHmm", "Kmm", "kmm",
     73         "MMdd", "ddHH", "yyyyMMMd", "yyyyMMddHHmmss",
     74         "GEEEEyyyyMMddHHmmss",
     75         "GuuuuQMMMMwwWddDDDFEEEEaHHmmssSSSvvvv", // bizarre case just for testing
     76     });
     77 
     78     public void set(CLDRFile cldrFile) {
     79         icuServiceBuilder.setCldrFile(cldrFile);
     80         gen = DateTimePatternGenerator.getEmptyInstance(); // for now
     81         failureMap.clear();
     82     }
     83 
     84     /**
     85      *
     86      */
     87     public void showFlexibles() {
     88         Map<String, String> items = gen.getSkeletons(new LinkedHashMap<String, String>());
     89         System.out.println("ERRORS");
     90         for (Iterator<String> it = failureMap.keySet().iterator(); it.hasNext();) {
     91             String item = it.next();
     92             String value = failureMap.get(item);
     93             System.out.println("\t" + value);
     94         }
     95         for (int i = 0; i < DateTimePatternGenerator.TYPE_LIMIT; ++i) {
     96             String format = gen.getAppendItemFormat(i);
     97             if (format.indexOf('\u251C') >= 0) {
     98                 System.out.println("\tMissing AppendItem format:\t" + DISPLAY_NAME_MAP[i]);
     99             }
    100             if (i == DateTimePatternGenerator.FRACTIONAL_SECOND) continue; // don't need this field
    101             String name = gen.getAppendItemName(i);
    102             if (name.matches("F[0-9]+")) {
    103                 System.out.println("\tMissing Field Name:\t" + DISPLAY_NAME_MAP[i]);
    104             }
    105         }
    106         System.out.println("SKELETON\t=> PATTERN LIST");
    107         for (Iterator<String> it = items.keySet().iterator(); it.hasNext();) {
    108             String skeleton = it.next();
    109             System.out.println("\t\"" + skeleton + "\"\t=>\t\"" + items.get(skeleton) + "\"");
    110         }
    111         System.out.println("REDUNDANTS");
    112         Collection<String> redundants = gen.getRedundants(new ArrayList<String>());
    113         for (String item : redundants) {
    114             System.out.println("\t" + item);
    115         }
    116         System.out.println("TESTS");
    117         for (String item : tests) {
    118             try {
    119                 String pat = gen.getBestPattern(item);
    120                 String sample = "<can't format>";
    121                 try {
    122                     DateFormat df = icuServiceBuilder.getDateFormat("gregorian", pat);
    123                     sample = df.format(new Date());
    124                 } catch (RuntimeException e) {
    125                 }
    126                 System.out.println("\t\"" + item + "\"\t=>\t\"" + pat + "\"\t=>\t\"" + sample + "\"");
    127             } catch (RuntimeException e) {
    128                 System.out.println(e.getMessage()); // e.printStackTrace();
    129             }
    130         }
    131         System.out.println("END");
    132     }
    133 
    134     Map<String, String> failureMap = new TreeMap<String, String>();
    135 
    136     /**
    137      * @param path
    138      * @param value
    139      * @param fullPath
    140      */
    141     public void checkFlexibles(String path, String value, String fullPath) {
    142         if (path.indexOf("numbers/symbols/decimal") >= 0) {
    143             gen.setDecimal(value);
    144             return;
    145         }
    146         if (path.indexOf("gregorian") < 0) return;
    147         if (path.indexOf("/appendItem") >= 0) {
    148             String key = (String) parts.set(path).getAttributeValue(-1, "request");
    149             try {
    150                 gen.setAppendItemFormat(getIndex(key, APPEND_ITEM_NAME_MAP), value);
    151             } catch (RuntimeException e) {
    152                 failureMap.put(path, "\tWarning: can't set AppendItemFormat:\t" + key + ":\t" + value);
    153             }
    154             return;
    155         }
    156         if (path.indexOf("/fields") >= 0) {
    157             String key = (String) parts.set(path).getAttributeValue(-2, "type");
    158             try {
    159                 gen.setAppendItemName(getIndex(key, DISPLAY_NAME_MAP), value);
    160             } catch (RuntimeException e) {
    161                 failureMap.put(path, "\tWarning: can't set AppendItemName:\t" + key + ":\t" + value);
    162             }
    163             return;
    164         }
    165 
    166         if (path.indexOf("pattern") < 0 && path.indexOf("dateFormatItem") < 0 && path.indexOf("intervalFormatItem") < 0) return;
    167         // set the am/pm preference
    168         if (path.indexOf("timeFormatLength[@type=\"short\"]") >= 0) {
    169             fp.set(value);
    170             for (Object item : fp.getItems()) {
    171                 if (item instanceof DateTimePatternGenerator.VariableField) {
    172                     if (item.toString().charAt(0) == 'h') {
    173                         isPreferred12Hour = true;
    174                     }
    175                 }
    176             }
    177         }
    178         if (path.indexOf("dateTimeFormatLength") > 0) return; // exclude {1} {0}
    179         if (path.indexOf("intervalFormatItem") < 0) {
    180             // add to generator
    181             try {
    182                 gen.addPattern(value, false, patternInfo);
    183                 switch (patternInfo.status) {
    184                 case PatternInfo.CONFLICT:
    185                     failureMap.put(path, "Conflicting Patterns: \"" + value + "\"\t&\t\"" + patternInfo.conflictingPattern
    186                         + "\"");
    187                     break;
    188                 }
    189             } catch (RuntimeException e) {
    190                 failureMap.put(path, e.getMessage());
    191             }
    192         }
    193     }
    194 
    195     private String stripLiterals(String pattern) {
    196         int i = 0, patlen = pattern.length();
    197         StringBuilder stripped = new StringBuilder(patlen);
    198         boolean inLiteral = false;
    199         while (i < patlen) {
    200             char c = pattern.charAt(i++);
    201             if (c == '\'') {
    202                 inLiteral = !inLiteral;
    203             } else if (!inLiteral) {
    204                 stripped.append(c);
    205             }
    206         }
    207         return stripped.toString();
    208     }
    209 
    210     public String checkValueAgainstSkeleton(String path, String value) {
    211         String failure = null;
    212         String skeleton = null;
    213         String strippedPattern = null;
    214         if (path.contains("dateFormatItem")) {
    215             skeleton = (String) parts.set(path).findAttributeValue("dateFormatItem", "id"); // the skeleton
    216             strippedPattern = gen.getSkeleton(value); // the pattern stripped of literals
    217         } else if (path.contains("intervalFormatItem")) {
    218             skeleton = (String) parts.set(path).findAttributeValue("intervalFormatItem", "id"); // the skeleton
    219             strippedPattern = stripLiterals(value); // can't use gen on intervalFormat pattern (throws exception)
    220         }
    221         if (skeleton != null && strippedPattern != null) {
    222             if (skeleton.indexOf('H') >= 0 || skeleton.indexOf('k') >= 0) { // if skeleton uses 24-hour time
    223                 if (strippedPattern.indexOf('h') >= 0 || strippedPattern.indexOf('K') >= 0) { // but pattern uses 12...
    224                     failure = "Skeleton uses 24-hour cycle (H,k) but pattern uses 12-hour (h,K)";
    225                 }
    226             } else if (skeleton.indexOf('h') >= 0 || skeleton.indexOf('K') >= 0) { // if skeleton uses 12-hour time
    227                 if (strippedPattern.indexOf('H') >= 0 || strippedPattern.indexOf('k') >= 0) { // but pattern uses 24...
    228                     failure = "Skeleton uses 12-hour cycle (h,K) but pattern uses 24-hour (H,k)";
    229                 }
    230             }
    231         }
    232         return failure;
    233     }
    234 
    235     DateTimePatternGenerator.FormatParser fp = new DateTimePatternGenerator.FormatParser();
    236 
    237     boolean isPreferred12Hour = false;
    238 
    239     static private String[] DISPLAY_NAME_MAP = {
    240         "era", "year", "quarter", "month", "week", "week_in_month", "weekday",
    241         "day", "day_of_year", "day_of_week_in_month", "dayperiod",
    242         "hour", "minute", "second", "fractional_second", "zone", "-"
    243     };
    244 
    245     static private String[] APPEND_ITEM_NAME_MAP = {
    246         "Era", "Year", "Quarter", "Month", "Week", "Week", "Day-Of-Week",
    247         "Day", "Day", "Day-Of-Week", "-",
    248         "Hour", "Minute", "Second", "-", "Timezone", "-"
    249     };
    250 
    251     int getIndex(String s, String[] strings) {
    252         for (int i = 0; i < strings.length; ++i) {
    253             if (s.equals(strings[i])) return i;
    254         }
    255         return -1;
    256     }
    257 
    258     PatternInfo patternInfo = new PatternInfo();
    259 
    260     public Collection<String> getRedundants(Collection<String> output) {
    261         return gen.getRedundants(output);
    262     }
    263 
    264     public Object getFailurePath(Object path) {
    265         return failureMap.get(path);
    266     }
    267 
    268     public boolean preferred12Hour() {
    269         return isPreferred12Hour;
    270     }
    271 }
    272