From dcb76aab7235eaebbd2702e90d71e008129f7807 Mon Sep 17 00:00:00 2001 From: Markus Scherer Date: Tue, 26 Jan 2016 22:52:45 +0000 Subject: [PATCH] ICU-7618 replace MessageFormat with SimpleFormatterImpl where easy; remove obsolete ChoiceFormat handling of currency names X-SVN-Rev: 38199 --- .../ibm/icu/impl/LocaleDisplayNamesImpl.java | 30 +++++----- .../com/ibm/icu/impl/SimpleFormatterImpl.java | 19 ++++++ .../com/ibm/icu/text/DateIntervalFormat.java | 13 ++-- .../icu/text/DateTimePatternGenerator.java | 11 ++-- .../src/com/ibm/icu/text/DecimalFormat.java | 59 ++++--------------- .../ibm/icu/text/DecimalFormatSymbols.java | 14 +---- .../icu/text/RelativeDateTimeFormatter.java | 11 ++-- .../com/ibm/icu/text/SimpleDateFormat.java | 14 +++-- .../core/src/com/ibm/icu/util/Calendar.java | 11 ++-- .../test/format/DateTimeGeneratorTest.java | 17 +++--- 10 files changed, 94 insertions(+), 105 deletions(-) diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/LocaleDisplayNamesImpl.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/LocaleDisplayNamesImpl.java index abff069a901..4ab482ceeba 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/LocaleDisplayNamesImpl.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/LocaleDisplayNamesImpl.java @@ -1,7 +1,7 @@ /* ******************************************************************************* - * Copyright (C) 2009-2015, International Business Machines Corporation and * - * others. All Rights Reserved. * + * Copyright (C) 2009-2016, International Business Machines Corporation and + * others. All Rights Reserved. ******************************************************************************* */ package com.ibm.icu.impl; @@ -27,7 +27,6 @@ import com.ibm.icu.text.BreakIterator; import com.ibm.icu.text.DisplayContext; import com.ibm.icu.text.DisplayContext.Type; import com.ibm.icu.text.LocaleDisplayNames; -import com.ibm.icu.text.MessageFormat; import com.ibm.icu.util.ULocale; import com.ibm.icu.util.UResourceBundle; import com.ibm.icu.util.UResourceBundleIterator; @@ -39,9 +38,10 @@ public class LocaleDisplayNamesImpl extends LocaleDisplayNames { private final DisplayContext nameLength; private final DataTable langData; private final DataTable regionData; - private final MessageFormat separatorFormat; - private final MessageFormat format; - private final MessageFormat keyTypeFormat; + // Compiled SimpleFormatter patterns. + private final String separatorFormat; + private final String format; + private final String keyTypeFormat; private final char formatOpenParen; private final char formatReplaceOpenParen; private final char formatCloseParen; @@ -139,13 +139,14 @@ public class LocaleDisplayNamesImpl extends LocaleDisplayNames { if ("separator".equals(sep)) { sep = "{0}, {1}"; } - this.separatorFormat = new MessageFormat(sep); + StringBuilder sb = new StringBuilder(); + this.separatorFormat = SimpleFormatterImpl.compileToStringMinMaxArguments(sep, sb, 2, 2); String pattern = langData.get("localeDisplayPattern", "pattern"); if ("pattern".equals(pattern)) { pattern = "{0} ({1})"; } - this.format = new MessageFormat(pattern); + this.format = SimpleFormatterImpl.compileToStringMinMaxArguments(pattern, sb, 2, 2); if (pattern.contains("(")) { formatOpenParen = '('; formatCloseParen = ')'; @@ -162,7 +163,8 @@ public class LocaleDisplayNamesImpl extends LocaleDisplayNames { if ("keyTypePattern".equals(keyTypePattern)) { keyTypePattern = "{0}={1}"; } - this.keyTypeFormat = new MessageFormat(keyTypePattern); + this.keyTypeFormat = SimpleFormatterImpl.compileToStringMinMaxArguments( + keyTypePattern, sb, 2, 2); // Get values from the contextTransforms data if we need them // Also check whether we will need a break iterator (depends on the data) @@ -365,8 +367,8 @@ public class LocaleDisplayNamesImpl extends LocaleDisplayNames { if (!valueDisplayName.equals(value)) { appendWithSep(valueDisplayName, buf); } else if (!key.equals(keyDisplayName)) { - String keyValue = keyTypeFormat.format( - new String[] { keyDisplayName, valueDisplayName }); + String keyValue = SimpleFormatterImpl.formatCompiledPattern( + keyTypeFormat, keyDisplayName, valueDisplayName); appendWithSep(keyValue, buf); } else { appendWithSep(keyDisplayName, buf) @@ -382,7 +384,8 @@ public class LocaleDisplayNamesImpl extends LocaleDisplayNames { } if (resultRemainder != null) { - resultName = format.format(new Object[] {resultName, resultRemainder}); + resultName = SimpleFormatterImpl.formatCompiledPattern( + format, resultName, resultRemainder); } return adjustForUsageAndContext(CapitalizationContextUsage.LANGUAGE, resultName); @@ -639,8 +642,7 @@ public class LocaleDisplayNamesImpl extends LocaleDisplayNames { if (b.length() == 0) { b.append(s); } else { - String combined = separatorFormat.format(new String[] { b.toString(), s }); - b.replace(0, b.length(), combined); + SimpleFormatterImpl.formatAndReplace(separatorFormat, b, null, b, s); } return b; } diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/SimpleFormatterImpl.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/SimpleFormatterImpl.java index 7098c607d02..4ce541953fc 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/SimpleFormatterImpl.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/SimpleFormatterImpl.java @@ -186,6 +186,25 @@ public final class SimpleFormatterImpl { return formatAndAppend(compiledPattern, new StringBuilder(), null, values).toString(); } + /** + * Formats the not-compiled pattern with the given values. + * Equivalent to compileToStringMinMaxArguments() followed by formatCompiledPattern(). + * The number of arguments checked against the given limits is the + * highest argument number plus one, not the number of occurrences of arguments. + * + * @param pattern Not-compiled form of a pattern string. + * @param min The pattern must have at least this many arguments. + * @param max The pattern must have at most this many arguments. + * @return The compiled-pattern string. + * @throws IllegalArgumentException for bad argument syntax and too few or too many arguments. + */ + public static String formatRawPattern(String pattern, int min, int max, CharSequence... values) { + StringBuilder sb = new StringBuilder(); + String compiledPattern = compileToStringMinMaxArguments(pattern, sb, min, max); + sb.setLength(0); + return formatAndAppend(compiledPattern, sb, null, values).toString(); + } + /** * Formats the given values, appending to the appendTo builder. * diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/DateIntervalFormat.java b/icu4j/main/classes/core/src/com/ibm/icu/text/DateIntervalFormat.java index 0808052d4c1..2eb69af7ec8 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/text/DateIntervalFormat.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/text/DateIntervalFormat.java @@ -17,6 +17,7 @@ import java.util.Map; import com.ibm.icu.impl.CalendarData; import com.ibm.icu.impl.ICUCache; import com.ibm.icu.impl.SimpleCache; +import com.ibm.icu.impl.SimpleFormatterImpl; import com.ibm.icu.text.DateIntervalInfo.PatternInfo; import com.ibm.icu.util.Calendar; import com.ibm.icu.util.DateInterval; @@ -858,8 +859,8 @@ public class DateIntervalFormat extends UFormat { laterDate = fDateFormat.format(toCalendar, laterDate, otherPos); String fallbackPattern = fInfo.getFallbackIntervalPattern(); adjustPosition(fallbackPattern, earlierDate.toString(), pos, laterDate.toString(), otherPos, pos); - String fallbackRange = MessageFormat.format(fallbackPattern, new Object[] - {earlierDate.toString(), laterDate.toString()}); + String fallbackRange = SimpleFormatterImpl.formatRawPattern( + fallbackPattern, 2, 2, earlierDate, laterDate); if (formatDatePlusTimeRange) { // fallbackRange has just the time range, need to format the date part and combine that fDateFormat.applyPattern(fDatePattern); @@ -868,8 +869,8 @@ public class DateIntervalFormat extends UFormat { otherPos.setEndIndex(0); datePortion = fDateFormat.format(fromCalendar, datePortion, otherPos); adjustPosition(fDateTimeFormat, fallbackRange, pos, datePortion.toString(), otherPos, pos); - fallbackRange = MessageFormat.format(fDateTimeFormat, new Object[] - {fallbackRange, datePortion.toString()}); + fallbackRange = SimpleFormatterImpl.formatRawPattern( + fDateTimeFormat, 2, 2, fallbackRange, datePortion); } appendTo.append(fallbackRange); if (formatDatePlusTimeRange) { @@ -1813,8 +1814,8 @@ public class DateIntervalFormat extends UFormat { if ( timeItvPtnInfo != null ) { String timeIntervalPattern = timeItvPtnInfo.getFirstPart() + timeItvPtnInfo.getSecondPart(); - String pattern = MessageFormat.format(dtfmt, new Object[] - {timeIntervalPattern, datePattern}); + String pattern = SimpleFormatterImpl.formatRawPattern( + dtfmt, 2, 2, timeIntervalPattern, datePattern); timeItvPtnInfo = DateIntervalInfo.genPatternInfo(pattern, timeItvPtnInfo.firstDateInPtnIsLaterDate()); intervalPatterns.put( 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 a53a69fac53..c7221726408 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 @@ -1,7 +1,7 @@ /* ******************************************************************************** - * Copyright (C) 2006-2015, Google, International Business Machines Corporation * - * and others. All Rights Reserved. * + * Copyright (C) 2006-2016, Google, International Business Machines Corporation + * and others. All Rights Reserved. ******************************************************************************** */ package com.ibm.icu.text; @@ -27,6 +27,7 @@ import com.ibm.icu.impl.ICUCache; import com.ibm.icu.impl.ICUResourceBundle; import com.ibm.icu.impl.PatternTokenizer; import com.ibm.icu.impl.SimpleCache; +import com.ibm.icu.impl.SimpleFormatterImpl; import com.ibm.icu.impl.Utility; import com.ibm.icu.util.Calendar; import com.ibm.icu.util.Freezable; @@ -434,7 +435,8 @@ public class DateTimePatternGenerator implements Freezable>> qualitativeUnitMap, EnumMap> patternMap, - MessageFormat combinedDateAndTime, + String combinedDateAndTime, PluralRules pluralRules, NumberFormat numberFormat, Style style, @@ -601,7 +602,7 @@ public final class RelativeDateTimeFormatter { private final EnumMap>> qualitativeUnitMap; private final EnumMap> patternMap; - private final MessageFormat combinedDateAndTime; + private final String combinedDateAndTime; // compiled SimpleFormatter pattern private final PluralRules pluralRules; private final NumberFormat numberFormat; diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/SimpleDateFormat.java b/icu4j/main/classes/core/src/com/ibm/icu/text/SimpleDateFormat.java index 0ea71278a9c..cd0d9ff109d 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/text/SimpleDateFormat.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/text/SimpleDateFormat.java @@ -1,6 +1,6 @@ /* ******************************************************************************* - * Copyright (C) 1996-2015, International Business Machines Corporation and + * Copyright (C) 1996-2016, International Business Machines Corporation and * others. All Rights Reserved. ******************************************************************************* */ @@ -28,6 +28,7 @@ import com.ibm.icu.impl.DateNumberFormat; import com.ibm.icu.impl.ICUCache; import com.ibm.icu.impl.PatternProps; import com.ibm.icu.impl.SimpleCache; +import com.ibm.icu.impl.SimpleFormatterImpl; import com.ibm.icu.lang.UCharacter; import com.ibm.icu.text.TimeZoneFormat.Style; import com.ibm.icu.text.TimeZoneFormat.TimeType; @@ -1181,8 +1182,9 @@ public class SimpleDateFormat extends DateFormat { { glueIndex += (SHORT + 1); } - cachedDefaultPattern = MessageFormat.format(dateTimePatterns[glueIndex], - new Object[] {dateTimePatterns[SHORT], dateTimePatterns[SHORT + 4]}); + cachedDefaultPattern = SimpleFormatterImpl.formatRawPattern( + dateTimePatterns[glueIndex], 2, 2, + dateTimePatterns[SHORT], dateTimePatterns[SHORT + 4]); } catch (MissingResourceException e) { cachedDefaultPattern = FALLBACKPATTERN; } @@ -1919,7 +1921,8 @@ public class SimpleDateFormat extends DateFormat { if (monthPattern == null) { appendTo.append(array[value]); } else { - appendTo.append(MessageFormat.format(monthPattern, array[value])); + String s = SimpleFormatterImpl.formatRawPattern(monthPattern, 1, 1, array[value]); + appendTo.append(s); } } } @@ -2684,7 +2687,8 @@ public class SimpleDateFormat extends DateFormat { isLeapMonth = 0; } if (monthPattern != null) { - String leapMonthName = MessageFormat.format(monthPattern, data[i]); + String leapMonthName = SimpleFormatterImpl.formatRawPattern( + monthPattern, 1, 1, data[i]); length = leapMonthName.length(); if (length > bestMatchLength && (matchLength = regionMatchesWithOptionalDot(text, start, leapMonthName, length)) >= 0) diff --git a/icu4j/main/classes/core/src/com/ibm/icu/util/Calendar.java b/icu4j/main/classes/core/src/com/ibm/icu/util/Calendar.java index 93329747c38..2eabb5d6d38 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/util/Calendar.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/util/Calendar.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 1996-2015, International Business Machines + * Copyright (C) 1996-2016, International Business Machines * Corporation and others. All Rights Reserved. */ @@ -20,10 +20,10 @@ import com.ibm.icu.impl.CalendarUtil; import com.ibm.icu.impl.ICUCache; import com.ibm.icu.impl.ICUResourceBundle; import com.ibm.icu.impl.SimpleCache; +import com.ibm.icu.impl.SimpleFormatterImpl; import com.ibm.icu.impl.SoftCache; import com.ibm.icu.text.DateFormat; import com.ibm.icu.text.DateFormatSymbols; -import com.ibm.icu.text.MessageFormat; import com.ibm.icu.text.SimpleDateFormat; import com.ibm.icu.util.ULocale.Category; @@ -3555,9 +3555,10 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable= 0) && (dateStyle >= 0)) { - pattern = MessageFormat.format(patternData.getDateTimePattern(dateStyle), - new Object[] {patternData.patterns[timeStyle], - patternData.patterns[dateStyle + 4]}); + pattern = SimpleFormatterImpl.formatRawPattern( + patternData.getDateTimePattern(dateStyle), 2, 2, + patternData.patterns[timeStyle], + patternData.patterns[dateStyle + 4]); // Might need to merge the overrides from the date and time into a single // override string TODO: Right now we are forcing the date's override into the // time style. diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateTimeGeneratorTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateTimeGeneratorTest.java index c731af70336..7ded29da052 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateTimeGeneratorTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateTimeGeneratorTest.java @@ -1,7 +1,7 @@ /* ******************************************************************************* - * Copyright (C) 2006-2015, Google, International Business Machines Corporation * - * and others. All Rights Reserved. * + * Copyright (C) 2006-2016, Google, International Business Machines Corporation + * and others. All Rights Reserved. ******************************************************************************* */ @@ -866,24 +866,23 @@ public class DateTimeGeneratorTest extends TestFmwk { */ public void TestGetRedundants(){ DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(); - + // Tests when "if (output == null)" is true try{ dtpg.getRedundants(null); } catch(Exception e){ - errln("DateTimeGenerator.getRedundants was not suppose to return " + - "an exception when passing a null parameter."); + errln("DateTimeGenerator.getRedundants was not supposed to return " + + "an exception when passing a null parameter: " + e); } - + // Tests when "if (output == null)" is false try{ Collection out = new LinkedHashSet(); dtpg.getRedundants(out); } catch(Exception e){ - errln("DateTimeGenerator.getRedundants was not suppose to return " + - "an exception when passing a new LinkedHashSet() parameter."); + errln("DateTimeGenerator.getRedundants was not supposed to return " + + "an exception when passing a new LinkedHashSet() parameter: " + e); } - } /* Tests the method