From 77fc1e4f5dd99b073addbdc03d8173e474614bbe Mon Sep 17 00:00:00 2001 From: Shane Carr Date: Mon, 6 Jun 2016 23:25:13 +0000 Subject: [PATCH] ICU-12576 Updating Java DateTimePatternGenerator to use data sinks for data loading. X-SVN-Rev: 38801 --- .../icu/text/DateTimePatternGenerator.java | 360 ++++++++++-------- .../test/format/DateTimeGeneratorTest.java | 28 +- 2 files changed, 219 insertions(+), 169 deletions(-) diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/DateTimePatternGenerator.java b/icu4j/main/classes/core/src/com/ibm/icu/text/DateTimePatternGenerator.java index 7cb0f15a892..3414f33fb78 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/text/DateTimePatternGenerator.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/text/DateTimePatternGenerator.java @@ -117,38 +117,139 @@ public class DateTimePatternGenerator implements Freezable items = fp.getItems(); - for (int idx = 0; idx < items.size(); idx++) { - Object item = items.get(idx); - if (item instanceof VariableField) { - VariableField fld = (VariableField)item; - if (fld.getType() == HOUR) { - result.defaultHourFormatChar = fld.toString().charAt(0); - break; - } + consumeShortTimePattern(df, returnInfo); + } + } + } + + private void consumeShortTimePattern(SimpleDateFormat df, PatternInfo returnInfo) { + // keep this pattern to populate other time field + // combination patterns by hackTimes later in this method. + String shortTimePattern = df.toPattern(); + + // use hour style in SHORT time pattern as the default + // hour style for the locale + FormatParser fp = new FormatParser(); + fp.set(shortTimePattern); + List items = fp.getItems(); + for (int idx = 0; idx < items.size(); idx++) { + Object item = items.get(idx); + if (item instanceof VariableField) { + VariableField fld = (VariableField)item; + if (fld.getType() == HOUR) { + defaultHourFormatChar = fld.toString().charAt(0); + break; + } + } + } + + // some languages didn't add mm:ss or HH:mm, so put in a hack to compute that from the short time. + hackTimes(returnInfo, shortTimePattern); + } + + private class AppendItemFormatsSink extends UResource.Sink { + @Override + public void put(UResource.Key key, UResource.Value value, boolean noFallback) { + UResource.Table itemsTable = value.getTable(); + for (int i = 0; itemsTable.getKeyAndValue(i, key, value); ++i) { + int field = getAppendFormatNumber(key); + assert field != -1; + if (getAppendItemFormat(field) == null) { + setAppendItemFormat(field, value.toString()); + } + } + } + public void fillInMissing() { + for (int i = 0; i < TYPE_LIMIT; ++i) { + if (getAppendItemFormat(i) == null) { + setAppendItemFormat(i, "{0} \u251C{2}: {1}\u2524"); + } + } + } + } + + private class AppendItemNamesSink extends UResource.Sink { + @Override + public void put(UResource.Key key, UResource.Value value, boolean noFallback) { + UResource.Table itemsTable = value.getTable(); + for (int i = 0; itemsTable.getKeyAndValue(i, key, value); ++i) { + int field = getCLDRFieldNumber(key); + if (field == -1) { continue; } + UResource.Table detailsTable = value.getTable(); + for (int j = 0; detailsTable.getKeyAndValue(j, key, value); ++j) { + if (!key.contentEquals("dn")) continue; + if (getAppendItemName(field) == null) { + setAppendItemName(field, value.toString()); } + break; + } + } + } + public void fillInMissing() { + for (int i = 0; i < TYPE_LIMIT; ++i) { + if (getAppendItemName(i) == null) { + setAppendItemName(i, "F" + i); } } } + } + + private class AvailableFormatsSink extends UResource.Sink { + PatternInfo returnInfo; + public AvailableFormatsSink(PatternInfo returnInfo) { + this.returnInfo = returnInfo; + } + + @Override + public void put(UResource.Key key, UResource.Value value, boolean isRoot) { + UResource.Table formatsTable = value.getTable(); + for (int i = 0; formatsTable.getKeyAndValue(i, key, value); ++i) { + String formatKey = key.toString(); + if (!isAvailableFormatSet(formatKey)) { + setAvailableFormat(formatKey); + // Add pattern with its associated skeleton. Override any duplicate derived from std patterns, + // but not a previous availableFormats entry: + String formatValue = value.toString(); + addPatternWithSkeleton(formatValue, formatKey, !isRoot, returnInfo); + } + } + } + } + private void addCLDRData(PatternInfo returnInfo, ULocale uLocale) { ICUResourceBundle rb = (ICUResourceBundle) UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME, uLocale); // Get the correct calendar type String calendarTypeToUse = uLocale.getKeywordValue("calendar"); @@ -168,34 +269,21 @@ public class DateTimePatternGenerator implements Freezable tempMap; + + private DayPeriodAllowedHoursSink(HashMap tempMap) { + this.tempMap = tempMap; + } + + @Override + public void put(UResource.Key key, UResource.Value value, boolean noFallback) { + UResource.Table timeData = value.getTable(); + for (int i = 0; timeData.getKeyAndValue(i, key, value); ++i) { + String regionOrLocale = key.toString(); + UResource.Table formatList = value.getTable(); + for (int j = 0; formatList.getKeyAndValue(j, key, value); ++j) { + if (key.contentEquals("allowed")) { // Ignore "preferred" list. + tempMap.put(regionOrLocale, value.getStringArrayOrStringAsArray()); + } + } + } + } + } + + // Get the data for dayperiod C. + static final Map LOCALE_TO_ALLOWED_HOUR; + static { + HashMap temp = new HashMap(); + ICUResourceBundle suppData = (ICUResourceBundle)ICUResourceBundle.getBundleInstance( + ICUData.ICU_BASE_NAME, + "supplementalData", + ICUResourceBundle.ICU_DATA_CLASS_LOADER); + + DayPeriodAllowedHoursSink allowedHoursSink = new DayPeriodAllowedHoursSink(temp); + suppData.getAllItemsWithFallback("timeData", allowedHoursSink); + + LOCALE_TO_ALLOWED_HOUR = Collections.unmodifiableMap(temp); } /** @@ -312,16 +400,16 @@ public class DateTimePatternGenerator implements Freezable=TYPE_LIMIT)) { - return false; - } - if (CLDR_FIELD_NAME[index].charAt(0) == '*') { - return false; - } - else { - return true; + private static int getCLDRFieldNumber(UResource.Key key) { + for (int i = 0; i < CLDR_FIELD_NAME.length; ++i) { + if (key.contentEquals(CLDR_FIELD_NAME[i])) { + return i; + } } + return -1; } /** @@ -437,43 +523,6 @@ public class DateTimePatternGenerator implements Freezable tempMap; - - private DayPeriodAllowedHoursSink(HashMap tempMap) { - this.tempMap = tempMap; - } - - @Override - public void put(UResource.Key key, UResource.Value value, boolean noFallback) { - UResource.Table timeData = value.getTable(); - for (int i = 0; timeData.getKeyAndValue(i, key, value); ++i) { - String regionOrLocale = key.toString(); - UResource.Table formatList = value.getTable(); - for (int j = 0; formatList.getKeyAndValue(j, key, value); ++j) { - if (key.contentEquals("allowed")) { // Ignore "preferred" list. - tempMap.put(regionOrLocale, value.getStringArrayOrStringAsArray()); - } - } - } - } - } - - // Get the data for dayperiod C. - static final Map LOCALE_TO_ALLOWED_HOUR; - static { - HashMap temp = new HashMap(); - ICUResourceBundle suppData = (ICUResourceBundle)ICUResourceBundle.getBundleInstance( - ICUData.ICU_BASE_NAME, - "supplementalData", - ICUResourceBundle.ICU_DATA_CLASS_LOADER); - - DayPeriodAllowedHoursSink allowedHoursSink = new DayPeriodAllowedHoursSink(temp); - suppData.getAllItemsWithFallback("timeData", allowedHoursSink); - - LOCALE_TO_ALLOWED_HOUR = Collections.unmodifiableMap(temp); - } - /* * getBestPattern which takes optional skip matcher */ @@ -1679,12 +1728,6 @@ public class DateTimePatternGenerator implements Freezable