/*
*******************************************************************************
- * 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;
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;
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;
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 = ')';
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)
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)
}
if (resultRemainder != null) {
- resultName = format.format(new Object[] {resultName, resultRemainder});
+ resultName = SimpleFormatterImpl.formatCompiledPattern(
+ format, resultName, resultRemainder);
}
return adjustForUsageAndContext(CapitalizationContextUsage.LANGUAGE, resultName);
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;
}
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.
*
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;
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);
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) {
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(
/*
********************************************************************************
- * 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;
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;
if (datePattern == null) return timePattern == null ? "" : timePattern;
if (timePattern == null) return datePattern;
- return MessageFormat.format(getDateTimeFormat(), new Object[]{timePattern, datePattern});
+ return SimpleFormatterImpl.formatRawPattern(
+ getDateTimeFormat(), 2, 2, timePattern, datePattern);
}
/**
String temp = adjustFieldTypes(tempWithMatcher, source, flags, options);
int foundMask = startingMask & ~distInfo.missingFieldMask;
int topField = getTopBitNumber(foundMask);
- resultPattern = MessageFormat.format(getAppendFormat(topField), new Object[]{resultPattern, temp, getAppendName(topField)});
+ resultPattern = SimpleFormatterImpl.formatRawPattern(
+ getAppendFormat(topField), 2, 3, resultPattern, temp, getAppendName(topField));
}
}
return resultPattern;
/*
*******************************************************************************
- * Copyright (C) 1996-2015, International Business Machines Corporation and *
- * others. All Rights Reserved. *
+ * Copyright (C) 1996-2016, International Business Machines Corporation and
+ * others. All Rights Reserved.
*******************************************************************************
*/
package com.ibm.icu.text;
// Reuse one StringBuffer for better performance
StringBuffer buffer = new StringBuffer();
if (posPrefixPattern != null) {
- expandAffix(posPrefixPattern, pluralCount, buffer, false);
+ expandAffix(posPrefixPattern, pluralCount, buffer);
positivePrefix = buffer.toString();
}
if (posSuffixPattern != null) {
- expandAffix(posSuffixPattern, pluralCount, buffer, false);
+ expandAffix(posSuffixPattern, pluralCount, buffer);
positiveSuffix = buffer.toString();
}
if (negPrefixPattern != null) {
- expandAffix(negPrefixPattern, pluralCount, buffer, false);
+ expandAffix(negPrefixPattern, pluralCount, buffer);
negativePrefix = buffer.toString();
}
if (negSuffixPattern != null) {
- expandAffix(negSuffixPattern, pluralCount, buffer, false);
+ expandAffix(negSuffixPattern, pluralCount, buffer);
negativeSuffix = buffer.toString();
}
}
* it is used to expand the stored affix patterns given a specific number (doFormat ==
* true), for those rare cases in which a currency format references a ChoiceFormat
* (e.g., en_IN display name for INR). The number itself is taken from digitList.
+ * TODO: There are no currency ChoiceFormat patterns, figure out what is still relevant here.
*
* When used in the first way, this method has a side effect: It sets currencyChoice
* to a ChoiceFormat object, if the currency's display name in this locale is a
* it is the singular "one", or the plural "other". For all other cases, it is null,
* and is not being used.
* @param buffer a scratch StringBuffer; its contents will be lost
- * @param doFormat if false, then the pattern will be expanded, and if a currency
- * symbol is encountered that expands to a ChoiceFormat, the currencyChoice member
- * variable will be initialized if it is null. If doFormat is true, then it is assumed
- * that the currencyChoice has been created, and it will be used to format the value
- * in digitList.
*/
// Bug 4212072 [Richard/GCL]
- private void expandAffix(String pattern, String pluralCount, StringBuffer buffer,
- boolean doFormat) {
+ private void expandAffix(String pattern, String pluralCount, StringBuffer buffer) {
buffer.setLength(0);
for (int i = 0; i < pattern.length();) {
char c = pattern.charAt(i++);
// when formatting currency plural names. For other cases,
// pluralCount == null, and plural names are not needed.
if (plural && pluralCount != null) {
- boolean isChoiceFormat[] = new boolean[1];
s = currency.getName(symbols.getULocale(), Currency.PLURAL_LONG_NAME,
- pluralCount, isChoiceFormat);
+ pluralCount, null);
} else if (!intl) {
- boolean isChoiceFormat[] = new boolean[1];
- s = currency.getName(symbols.getULocale(), Currency.SYMBOL_NAME,
- isChoiceFormat);
- if (isChoiceFormat[0]) {
- // Two modes here: If doFormat is false, we set up
- // currencyChoice. If doFormat is true, we use the previously
- // created currencyChoice to format the value in digitList.
- if (!doFormat) {
- // If the currency is handled by a ChoiceFormat, then
- // we're not going to use the expanded
- // patterns. Instantiate the ChoiceFormat and return.
- if (currencyChoice == null) {
- currencyChoice = new ChoiceFormat(s);
- }
- // We could almost return null or "" here, since the
- // expanded affixes are almost not used at all in this
- // situation. However, one method -- toPattern() -- still
- // does use the expanded affixes, in order to set up a
- // padding pattern. We use the CURRENCY_SIGN as a
- // placeholder.
- s = String.valueOf(CURRENCY_SIGN);
- } else {
- FieldPosition pos = new FieldPosition(0); // ignored
- currencyChoice.format(digitList.getDouble(), buffer, pos);
- continue;
- }
- }
+ s = currency.getName(symbols.getULocale(), Currency.SYMBOL_NAME, null);
} else {
s = currency.getCurrencyCode();
}
affixPat = isNegative ? negSuffixPattern : posSuffixPattern;
}
StringBuffer affixBuf = new StringBuffer();
- expandAffix(affixPat, null, affixBuf, true);
+ expandAffix(affixPat, null, affixBuf);
buf.append(affixBuf);
return affixBuf.length();
}
super.setCurrency(theCurrency);
if (theCurrency != null) {
- boolean[] isChoiceFormat = new boolean[1];
- String s = theCurrency.getName(symbols.getULocale(),
- Currency.SYMBOL_NAME, isChoiceFormat);
+ String s = theCurrency.getName(symbols.getULocale(), Currency.SYMBOL_NAME, null);
symbols.setCurrency(theCurrency);
symbols.setCurrencySymbol(s);
}
/**
* Formatter for ChoiceFormat-based currency names. If this field is not null, then
* delegate to it to format currency symbols.
+ * TODO: This is obsolete: Remove, and design extensible serialization. ICU ticket #12090.
*
* @since ICU 2.6
*/
/*
*******************************************************************************
- * Copyright (C) 1996-2015, International Business Machines Corporation and *
- * others. All Rights Reserved. *
+ * Copyright (C) 1996-2016, International Business Machines Corporation and
+ * others. All Rights Reserved.
*******************************************************************************
*/
package com.ibm.icu.text;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
-import java.text.ChoiceFormat;
import java.util.Arrays;
import java.util.Locale;
import java.util.MissingResourceException;
// Obtain currency data from the currency API. This is strictly
// for backward compatibility; we don't use DecimalFormatSymbols
// for currency data anymore.
- String currname = null;
currency = Currency.getInstance(locale);
if (currency != null) {
intlCurrencySymbol = currency.getCurrencyCode();
- boolean[] isChoiceFormat = new boolean[1];
- currname = currency.getName(locale, Currency.SYMBOL_NAME, isChoiceFormat);
- // If this is a ChoiceFormat currency, then format an
- // arbitrary value; pick something != 1; more common.
- currencySymbol = isChoiceFormat[0]
- ? new ChoiceFormat(currname).format(2.0)
- : currname;
+ currencySymbol = currency.getName(locale, Currency.SYMBOL_NAME, null);
CurrencyFormatInfo fmtInfo = info.getFormatInfo(intlCurrencySymbol);
if (fmtInfo != null) {
currencyPattern = fmtInfo.currencyPattern;
return new RelativeDateTimeFormatter(
data.qualitativeUnitMap,
data.relUnitPatternMap,
- new MessageFormat(data.dateTimePattern),
+ SimpleFormatterImpl.compileToStringMinMaxArguments(
+ data.dateTimePattern, new StringBuilder(), 2, 2),
PluralRules.forLocale(locale),
nf,
style,
* @stable ICU 53
*/
public String combineDateAndTime(String relativeDateString, String timeString) {
- return this.combinedDateAndTime.format(
- new Object[]{timeString, relativeDateString}, new StringBuffer(), null).toString();
+ return SimpleFormatterImpl.formatCompiledPattern(
+ combinedDateAndTime, timeString, relativeDateString);
}
/**
private RelativeDateTimeFormatter(
EnumMap<Style, EnumMap<AbsoluteUnit, EnumMap<Direction, String>>> qualitativeUnitMap,
EnumMap<Style, EnumMap<RelativeUnit, String[][]>> patternMap,
- MessageFormat combinedDateAndTime,
+ String combinedDateAndTime,
PluralRules pluralRules,
NumberFormat numberFormat,
Style style,
private final EnumMap<Style, EnumMap<AbsoluteUnit, EnumMap<Direction, String>>> qualitativeUnitMap;
private final EnumMap<Style, EnumMap<RelativeUnit, String[][]>> patternMap;
- private final MessageFormat combinedDateAndTime;
+ private final String combinedDateAndTime; // compiled SimpleFormatter pattern
private final PluralRules pluralRules;
private final NumberFormat numberFormat;
/*
*******************************************************************************
- * Copyright (C) 1996-2015, International Business Machines Corporation and
+ * Copyright (C) 1996-2016, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
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;
{
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;
}
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);
}
}
}
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)
/*
- * Copyright (C) 1996-2015, International Business Machines
+ * Copyright (C) 1996-2016, International Business Machines
* Corporation and others. All Rights Reserved.
*/
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;
// Resolve a pattern for the date/time style
String pattern = null;
if ((timeStyle >= 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.
/*
*******************************************************************************
- * 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.
*******************************************************************************
*/
*/
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<String> out = new LinkedHashSet<String>();
dtpg.getRedundants(out);
} catch(Exception e){
- errln("DateTimeGenerator.getRedundants was not suppose to return " +
- "an exception when passing a new LinkedHashSet<String>() parameter.");
+ errln("DateTimeGenerator.getRedundants was not supposed to return " +
+ "an exception when passing a new LinkedHashSet<String>() parameter: " + e);
}
-
}
/* Tests the method