| /* |
| ****************************************************************************** |
| * Copyright (C) 2005, 2007 International Business Machines Corporation and * |
| * others. All Rights Reserved. * |
| ****************************************************************************** |
| */ |
| package org.unicode.cldr.test; |
| |
| import com.ibm.icu.util.TimeZone; |
| import java.util.List; |
| import org.unicode.cldr.test.CheckCLDR.CheckStatus.Subtype; |
| import org.unicode.cldr.util.CLDRFile; |
| import org.unicode.cldr.util.Factory; |
| import org.unicode.cldr.util.InternalCldrException; |
| import org.unicode.cldr.util.TimezoneFormatter; |
| import org.unicode.cldr.util.XPathParts; |
| |
| public class CheckZones extends FactoryCheckCLDR { |
| // private final UnicodeSet commonAndInherited = new |
| // UnicodeSet(CheckExemplars.Allowed).complement(); |
| // "[[:script=common:][:script=inherited:][:alphabetic=false:]]"); |
| |
| private TimezoneFormatter timezoneFormatter; |
| |
| public CheckZones(Factory factory) { |
| super(factory); |
| } |
| |
| @Override |
| public CheckCLDR handleSetCldrFileToCheck( |
| CLDRFile cldrFile, Options options, List<CheckStatus> possibleErrors) { |
| if (cldrFile == null) return this; |
| // if (Phase.FINAL_TESTING == getPhase()) { |
| // setSkipTest(false); // ok |
| // } else { |
| // setSkipTest(true); |
| // return this; |
| // } |
| |
| super.handleSetCldrFileToCheck(cldrFile, options, possibleErrors); |
| try { |
| timezoneFormatter = new TimezoneFormatter(getResolvedCldrFileToCheck()); |
| } catch (RuntimeException e) { |
| possibleErrors.add( |
| new CheckStatus() |
| .setCause(this) |
| .setMainType(CheckStatus.errorType) |
| .setSubtype(Subtype.cannotCreateZoneFormatter) |
| .setMessage("Checking zones: " + e.getMessage())); |
| } |
| return this; |
| } |
| |
| String previousZone = new String(); |
| String previousFrom = new String("1970-01-01"); |
| String previousTo = new String("present"); |
| |
| @Override |
| public CheckCLDR handleCheck( |
| String path, String fullPath, String value, Options options, List<CheckStatus> result) { |
| if (fullPath == null) return this; // skip paths that we don't have |
| if (path.indexOf("timeZoneNames") < 0 || path.indexOf("usesMetazone") < 0) return this; |
| if (!accept(result)) return this; |
| if (timezoneFormatter == null) { |
| return this; // error thrown above |
| } |
| XPathParts parts = XPathParts.getFrozenInstance(path); |
| |
| String zone = parts.getAttributeValue(3, "type"); |
| String from; |
| if (parts.containsAttribute("from")) from = parts.getAttributeValue(4, "from"); |
| else from = "1970-01-01"; |
| String to; |
| if (parts.containsAttribute("to")) to = parts.getAttributeValue(4, "to"); |
| else to = "present"; |
| |
| if (zone.equals(previousZone)) { |
| if (from.compareTo(previousTo) < 0) { |
| result.add( |
| new CheckStatus() |
| .setCause(this) |
| .setMainType(CheckStatus.errorType) |
| .setSubtype(Subtype.multipleMetazoneMappings) |
| .setMessage( |
| "Multiple metazone mappings between {1} and {0}", |
| new Object[] {previousTo, from})); |
| } |
| if (from.compareTo(previousTo) > 0) { |
| result.add( |
| new CheckStatus() |
| .setCause(this) |
| .setMainType(CheckStatus.warningType) |
| .setSubtype(Subtype.noMetazoneMapping) |
| .setMessage( |
| "No metazone mapping between {0} and {1}", |
| new Object[] {previousTo, from})); |
| } |
| } else { |
| if (previousFrom.compareTo("1970-01-01") != 0) { |
| result.add( |
| new CheckStatus() |
| .setCause(this) |
| .setMainType(CheckStatus.warningType) |
| .setSubtype(Subtype.noMetazoneMappingAfter1970) |
| .setMessage( |
| "Zone {0} has no metazone mapping between 1970-01-01 and {1}", |
| new Object[] {previousZone, previousFrom})); |
| } |
| if (previousTo.compareTo("present") != 0) { |
| result.add( |
| new CheckStatus() |
| .setCause(this) |
| .setMainType(CheckStatus.warningType) |
| .setSubtype(Subtype.noMetazoneMappingBeforeNow) |
| .setMessage( |
| "Zone {0} has no metazone mapping between {1} and present.", |
| new Object[] {previousZone, previousTo})); |
| } |
| previousFrom = from; |
| } |
| |
| previousTo = to; |
| previousZone = zone; |
| |
| return this; |
| } |
| |
| public static String exampleTextForXpath(TimezoneFormatter timezoneFormatter, String path) { |
| XPathParts parts = XPathParts.getFrozenInstance(path); |
| if (parts.containsElement("zone")) { |
| String id = parts.getAttributeValue(3, "type"); |
| TimeZone tz = TimeZone.getTimeZone(id); |
| String pat = "vvvv"; |
| if (parts.containsElement("exemplarCity")) { |
| int delim = id.indexOf('/'); |
| if (delim >= 0) { |
| String formatted = id.substring(delim + 1).replaceAll("_", " "); |
| return formatted; |
| } |
| } else if (!parts.containsElement("usesMetazone")) { |
| if (parts.containsElement("generic")) { |
| pat = "vvvv"; |
| if (parts.containsElement("short")) pat = "v"; |
| } else { |
| pat = "zzzz"; |
| if (parts.containsElement("short")) pat = "z"; |
| } |
| boolean daylight = parts.containsElement("daylight"); |
| int offset = tz.getRawOffset(); |
| if (daylight) offset += tz.getDSTSavings(); |
| String formatted = |
| timezoneFormatter.getFormattedZone(id, pat, daylight, offset, true); |
| return formatted; |
| } |
| } |
| return null; // unknown |
| } |
| |
| @Override |
| public CheckCLDR handleGetExamples( |
| String path, String fullPath, String value, Options options, List result) { |
| if (path.indexOf("timeZoneNames") < 0) { |
| return this; |
| } |
| if (timezoneFormatter == null) { |
| throw new InternalCldrException( |
| "This should not occur: setCldrFileToCheck must create a TimezoneFormatter."); |
| } |
| String formatted = exampleTextForXpath(timezoneFormatter, path); |
| |
| if (formatted != null) { |
| result.add( |
| new CheckStatus() |
| .setCause(this) |
| .setMainType(CheckStatus.exampleType) |
| .setMessage( |
| "Formatted value (if removed): \"{0}\"", |
| new Object[] {formatted})); |
| } |
| return this; |
| } |
| } |