1 /* 2 ****************************************************************************** 3 * Copyright (C) 2005, 2007 International Business Machines Corporation and * 4 * others. All Rights Reserved. * 5 ****************************************************************************** 6 */ 7 package org.unicode.cldr.test; 8 9 import java.util.List; 10 11 import org.unicode.cldr.test.CheckCLDR.CheckStatus.Subtype; 12 import org.unicode.cldr.util.CLDRFile; 13 import org.unicode.cldr.util.Factory; 14 import org.unicode.cldr.util.InternalCldrException; 15 import org.unicode.cldr.util.TimezoneFormatter; 16 import org.unicode.cldr.util.XPathParts; 17 18 import com.ibm.icu.util.TimeZone; 19 20 public class CheckZones extends FactoryCheckCLDR { 21 // private final UnicodeSet commonAndInherited = new UnicodeSet(CheckExemplars.Allowed).complement(); 22 // "[[:script=common:][:script=inherited:][:alphabetic=false:]]"); 23 24 private TimezoneFormatter timezoneFormatter; 25 CheckZones(Factory factory)26 public CheckZones(Factory factory) { 27 super(factory); 28 } 29 30 @Override setCldrFileToCheck(CLDRFile cldrFile, Options options, List<CheckStatus> possibleErrors)31 public CheckCLDR setCldrFileToCheck(CLDRFile cldrFile, Options options, List<CheckStatus> possibleErrors) { 32 if (cldrFile == null) return this; 33 // if (Phase.FINAL_TESTING == getPhase()) { 34 // setSkipTest(false); // ok 35 // } else { 36 // setSkipTest(true); 37 // return this; 38 // } 39 40 super.setCldrFileToCheck(cldrFile, options, possibleErrors); 41 try { 42 timezoneFormatter = new TimezoneFormatter(getResolvedCldrFileToCheck()); 43 } catch (RuntimeException e) { 44 possibleErrors.add(new CheckStatus().setCause(this).setMainType(CheckStatus.errorType) 45 .setSubtype(Subtype.cannotCreateZoneFormatter) 46 .setMessage("Checking zones: " + e.getMessage())); 47 } 48 return this; 49 } 50 51 XPathParts parts = new XPathParts(null, null); 52 String previousZone = new String(); 53 String previousFrom = new String("1970-01-01"); 54 String previousTo = new String("present"); 55 handleCheck(String path, String fullPath, String value, Options options, List<CheckStatus> result)56 public CheckCLDR handleCheck(String path, String fullPath, String value, 57 Options options, List<CheckStatus> result) { 58 if (fullPath == null) return this; // skip paths that we don't have 59 if (path.indexOf("timeZoneNames") < 0 || path.indexOf("usesMetazone") < 0) 60 return this; 61 if (timezoneFormatter == null) { 62 if (true) return this; 63 throw new InternalCldrException( 64 "This should not occur: setCldrFileToCheck must create a TimezoneFormatter."); 65 } 66 parts.set(path); 67 68 String zone = parts.getAttributeValue(3, "type"); 69 String from; 70 if (parts.containsAttribute("from")) 71 from = parts.getAttributeValue(4, "from"); 72 else 73 from = "1970-01-01"; 74 String to; 75 if (parts.containsAttribute("to")) 76 to = parts.getAttributeValue(4, "to"); 77 else 78 to = "present"; 79 80 if (zone.equals(previousZone)) { 81 if (from.compareTo(previousTo) < 0) { 82 result.add(new CheckStatus().setCause(this).setMainType(CheckStatus.errorType) 83 .setSubtype(Subtype.multipleMetazoneMappings) 84 .setMessage("Multiple metazone mappings between {1} and {0}", 85 new Object[] { previousTo, from })); 86 } 87 if (from.compareTo(previousTo) > 0) { 88 result.add(new CheckStatus().setCause(this).setMainType(CheckStatus.warningType) 89 .setSubtype(Subtype.noMetazoneMapping) 90 .setMessage("No metazone mapping between {0} and {1}", 91 new Object[] { previousTo, from })); 92 } 93 } else { 94 if (previousFrom.compareTo("1970-01-01") != 0) { 95 result.add(new CheckStatus().setCause(this).setMainType(CheckStatus.warningType) 96 .setSubtype(Subtype.noMetazoneMappingAfter1970) 97 .setMessage("Zone {0} has no metazone mapping between 1970-01-01 and {1}", 98 new Object[] { previousZone, previousFrom })); 99 } 100 if (previousTo.compareTo("present") != 0) { 101 result.add(new CheckStatus().setCause(this).setMainType(CheckStatus.warningType) 102 .setSubtype(Subtype.noMetazoneMappingBeforeNow) 103 .setMessage("Zone {0} has no metazone mapping between {1} and present.", 104 new Object[] { previousZone, previousTo })); 105 } 106 previousFrom = from; 107 } 108 109 previousTo = to; 110 previousZone = zone; 111 112 return this; 113 } 114 exampleTextForXpath(XPathParts parts, TimezoneFormatter timezoneFormatter, String path)115 public static String exampleTextForXpath(XPathParts parts, TimezoneFormatter timezoneFormatter, 116 String path) { 117 parts.set(path); 118 if (parts.containsElement("zone")) { 119 String id = (String) parts.getAttributeValue(3, "type"); 120 TimeZone tz = TimeZone.getTimeZone(id); 121 String pat = "vvvv"; 122 if (parts.containsElement("exemplarCity")) { 123 int delim = id.indexOf('/'); 124 if (delim >= 0) { 125 String formatted = id.substring(delim + 1).replaceAll("_", " "); 126 return formatted; 127 } 128 } else if (!parts.containsElement("usesMetazone")) { 129 if (parts.containsElement("generic")) { 130 pat = "vvvv"; 131 if (parts.containsElement("short")) pat = "v"; 132 } else { 133 pat = "zzzz"; 134 if (parts.containsElement("short")) pat = "z"; 135 } 136 boolean daylight = parts.containsElement("daylight"); 137 int offset = tz.getRawOffset(); 138 if (daylight) 139 offset += tz.getDSTSavings(); 140 String formatted = timezoneFormatter.getFormattedZone(id, pat, 141 daylight, offset, true); 142 return formatted; 143 } 144 } 145 return null; // unknown 146 } 147 148 @Override handleGetExamples(String path, String fullPath, String value, Options options, List result)149 public CheckCLDR handleGetExamples(String path, String fullPath, String value, 150 Options options, List result) { 151 if (path.indexOf("timeZoneNames") < 0) { 152 return this; 153 } 154 if (timezoneFormatter == null) { 155 throw new InternalCldrException( 156 "This should not occur: setCldrFileToCheck must create a TimezoneFormatter."); 157 } 158 String formatted = exampleTextForXpath(parts, timezoneFormatter, path); 159 160 if (formatted != null) { 161 result.add(new CheckStatus().setCause(this).setMainType(CheckStatus.exampleType) 162 .setMessage("Formatted value (if removed): \"{0}\"", 163 new Object[] { formatted })); 164 } 165 return this; 166 } 167 } 168