• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
set(CLDRFile cldrFile)78     public void set(CLDRFile cldrFile) {
79         icuServiceBuilder.setCldrFile(cldrFile);
80         gen = DateTimePatternGenerator.getEmptyInstance(); // for now
81         failureMap.clear();
82     }
83 
84     /**
85      *
86      */
showFlexibles()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      */
checkFlexibles(String path, String value, String fullPath)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 
stripLiterals(String pattern)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 
checkValueAgainstSkeleton(String path, String value)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 
getIndex(String s, String[] strings)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 
getRedundants(Collection<String> output)260     public Collection<String> getRedundants(Collection<String> output) {
261         return gen.getRedundants(output);
262     }
263 
getFailurePath(Object path)264     public Object getFailurePath(Object path) {
265         return failureMap.get(path);
266     }
267 
preferred12Hour()268     public boolean preferred12Hour() {
269         return isPreferred12Hour;
270     }
271 }
272