Top Description Inners Fields Constructors Methods
com.ibm.icu.text

public Class MessageFormat

extends UFormat
Class Inheritance
Imports
java.io.IOException, .InvalidObjectException, .ObjectInputStream, java.text.AttributedCharacterIterator, .AttributedCharacterIterator.Attribute, .AttributedString, .CharacterIterator, .ChoiceFormat, .FieldPosition, .Format, .ParseException, .ParsePosition, java.util.ArrayList, .Date, .HashMap, .HashSet, .Iterator, .List, .Locale, .Map, .Objects, .Set, com.ibm.icu.impl.PatternProps, com.ibm.icu.number.NumberFormatter, com.ibm.icu.text.MessagePattern.ArgType, .MessagePattern.Part, .PluralRules.IFixedDecimal, .PluralRules.PluralType, com.ibm.icu.util.ICUUncheckedIOException, .ULocale, .ULocale.Category

ICU Enhancement

This class is ICU's replacement for java.text.MessageFormat.

ICU

Methods, fields, and other functionality specific to ICU are labeled 'ICU'.

MessageFormat prepares strings for display to users, with optional arguments (variables/placeholders). The arguments can occur in any order, which is necessary for translation into languages with different grammars.

A MessageFormat is constructed from a pattern string with arguments in {curly braces} which will be replaced by formatted values.

MessageFormat differs from the other Format classes in that you create a MessageFormat object with one of its constructors (not with a getInstance style factory method). Factory methods aren't necessary because MessageFormat itself doesn't implement locale-specific behavior. Any locale-specific behavior is defined by the pattern that you provide and the subformats used for inserted arguments.

Arguments can be named (using identifiers) or numbered (using small ASCII-digit integers). Some of the API methods work only with argument numbers and throw an exception if the pattern has named arguments (see usesNamedArguments()).

An argument might not specify any format type. In this case, a Number value is formatted with a default (for the locale) NumberFormat, a Date value is formatted with a default (for the locale) DateFormat, and for any other value its toString() value is used.

An argument might specify a "simple" type for which the specified Format object is created, cached and used.

An argument might have a "complex" type with nested MessageFormat sub-patterns. During formatting, one of these sub-messages is selected according to the argument value and recursively formatted.

After construction, a custom Format object can be set for a top-level argument, overriding the default formatting and parsing behavior for that argument. However, custom formatting can be achieved more simply by writing a typeless argument in the pattern string and supplying it with a preformatted string value.

When formatting, MessageFormat takes a collection of argument values and writes an output string. The argument values may be passed as an array (when the pattern contains only numbered arguments) or as a Map (which works for both named and numbered arguments).

Each argument is matched with one of the input values by array index or map key and formatted according to its pattern specification (or using a custom Format object if one was set). A numbered pattern argument is matched with a map key that contains that number as an ASCII-decimal-digit string (without leading zero).

Patterns and Their Interpretation

MessageFormat uses patterns of the following form:
message = messageText (argument messageText)*
argument = noneArg | simpleArg | complexArg
complexArg = choiceArg | pluralArg | selectArg | selectordinalArg

noneArg = '{' argNameOrNumber '}'
simpleArg = '{' argNameOrNumber ',' argType [',' argStyle] '}'
choiceArg = '{' argNameOrNumber ',' "choice" ',' choiceStyle '}'
pluralArg = '{' argNameOrNumber ',' "plural" ',' pluralStyle '}'
selectArg = '{' argNameOrNumber ',' "select" ',' selectStyle '}'
selectordinalArg = '{' argNameOrNumber ',' "selectordinal" ',' pluralStyle '}'

choiceStyle: see ChoiceFormat
pluralStyle: see PluralFormat
selectStyle: see SelectFormat

argNameOrNumber = argName | argNumber
argName = [^[[:Pattern_Syntax:][:Pattern_White_Space:]]]+
argNumber = '0' | ('1'..'9' ('0'..'9')*)

argType = "number" | "date" | "time" | "spellout" | "ordinal" | "duration"
argStyle = "short" | "medium" | "long" | "full" | "integer" | "currency" | "percent" | argStyleText | "::" argSkeletonText

Recommendation: Use the real apostrophe (single quote) character \\u2019 for human-readable text, and use the ASCII apostrophe (\\u0027 ' ) only in program syntax, like quoting in MessageFormat. See the annotations for U+0027 Apostrophe in The Unicode Standard.

The choice argument type is deprecated. Use plural arguments for proper plural selection, and select arguments for simple selection among a fixed set of choices.

The argType and argStyle values are used to create a Format instance for the format element. The following table shows how the values map to Format instances. Combinations not shown in the table are illegal. Any argStyleText must be a valid pattern string for the Format subclass used.

argType argStyle resulting Format object
(none) null
number (none) NumberFormat.getInstance(getLocale())
integer NumberFormat.getIntegerInstance(getLocale())
currency NumberFormat.getCurrencyInstance(getLocale())
percent NumberFormat.getPercentInstance(getLocale())
argStyleText new DecimalFormat(argStyleText, new DecimalFormatSymbols(getLocale()))
argSkeletonText NumberFormatter.forSkeleton(argSkeletonText).locale(getLocale()).toFormat()
date (none) DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())
short DateFormat.getDateInstance(DateFormat.SHORT, getLocale())
medium DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())
long DateFormat.getDateInstance(DateFormat.LONG, getLocale())
full DateFormat.getDateInstance(DateFormat.FULL, getLocale())
argStyleText new SimpleDateFormat(argStyleText, getLocale())
argSkeletonText DateFormat.getInstanceForSkeleton(argSkeletonText, getLocale())
time (none) DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())
short DateFormat.getTimeInstance(DateFormat.SHORT, getLocale())
medium DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())
long DateFormat.getTimeInstance(DateFormat.LONG, getLocale())
full DateFormat.getTimeInstance(DateFormat.FULL, getLocale())
argStyleText new SimpleDateFormat(argStyleText, getLocale())
spellout argStyleText (optional) new RuleBasedNumberFormat(getLocale(), RuleBasedNumberFormat.SPELLOUT)
    .setDefaultRuleset(argStyleText);
ordinal argStyleText (optional) new RuleBasedNumberFormat(getLocale(), RuleBasedNumberFormat.ORDINAL)
    .setDefaultRuleset(argStyleText);
duration argStyleText (optional) new RuleBasedNumberFormat(getLocale(), RuleBasedNumberFormat.DURATION)
    .setDefaultRuleset(argStyleText);

Differences from java.text.MessageFormat

The ICU MessageFormat supports both named and numbered arguments, while the JDK MessageFormat only supports numbered arguments. Named arguments make patterns more readable.

ICU implements a more user-friendly apostrophe quoting syntax. In message text, an apostrophe only begins quoting literal text if it immediately precedes a syntax character (mostly {curly braces}).
In the JDK MessageFormat, an apostrophe always begins quoting, which requires common text like "don't" and "aujourd'hui" to be written with doubled apostrophes like "don''t" and "aujourd''hui". For more details see MessagePattern.ApostropheMode.

ICU does not create a ChoiceFormat object for a choiceArg, pluralArg or selectArg but rather handles such arguments itself. The JDK MessageFormat does create and use a ChoiceFormat object (new ChoiceFormat(argStyleText)). The JDK does not support plural and select arguments at all.

Both the ICU and the JDK MessageFormat can control the argument formats by using argStyle. But the JDK MessageFormat only supports predefined formats and number / date / time pattern strings (which would need to be localized).
ICU supports everything the JDK does, and also number / date / time skeletons using the :: prefix (which automatically yield output appropriate for the MessageFormat locale).

Argument formatting

Arguments are formatted according to their type, using the default ICU formatters for those types, unless otherwise specified. For unknown types, MessageFormat will call toString().

There are also several ways to control the formatting.

We recommend you use default styles, predefined style values, skeletons, or preformatted values, but not pattern strings or custom format objects.

For more details, see the ICU User Guide.

Usage Information

Here are some examples of usage:

Object[] arguments = {
    7,
    new Date(System.currentTimeMillis()),
    "a disturbance in the Force"
};

String result = MessageFormat.format(
    "At {1,time,::jmm} on {1,date,::dMMMM}, there was {2} on planet {0,number,integer}.",
    arguments);

output: At 4:34 PM on March 23, there was a disturbance
          in the Force on planet 7.

Typically, the message format will come from resources, and the arguments will be dynamically set at runtime.

Example 2:

Object[] testArgs = { 3, "MyDisk" };

MessageFormat form = new MessageFormat(
    "The disk \"{1}\" contains {0} file(s).");

System.out.println(form.format(testArgs));

// output, with different testArgs
output: The disk "MyDisk" contains 0 file(s).
output: The disk "MyDisk" contains 1 file(s).
output: The disk "MyDisk" contains 1,273 file(s).

For messages that include plural forms, you can use a plural argument:

MessageFormat msgFmt = new MessageFormat(
    "{num_files, plural, " +
    "=0{There are no files on disk \"{disk_name}\".}" +
    "=1{There is one file on disk \"{disk_name}\".}" +
    "other{There are # files on disk \"{disk_name}\".}}",
    ULocale.ENGLISH);
Map args = new HashMap();
args.put("num_files", 0);
args.put("disk_name", "MyDisk");
System.out.println(msgFmt.format(args));
args.put("num_files", 3);
System.out.println(msgFmt.format(args));

output:
There are no files on disk "MyDisk".
There are 3 files on "MyDisk".
See PluralFormat and PluralRules for details.

Synchronization

MessageFormats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.

Authors
Mark Davis, Markus Scherer
ICU Status
Stable since ICU 3.0.
See Also
java.util.Locale, Format, NumberFormat, DecimalFormat, ChoiceFormat, PluralFormat, SelectFormat

Nested and Inner Type Summary

Modifier and TypeClass and Description
private static class
MessageFormat.AppendableWrapper

Convenience wrapper for Appendable, tracks the result string length.

private static class
public static class
MessageFormat.Field

Defines constants that are used as attribute keys in the AttributedCharacterIterator returned from MessageFormat.formatToCharacterIterator.

private static class
MessageFormat.PluralSelectorContext

Mutable input/output values for the PluralSelectorProvider.

private static class
MessageFormat.PluralSelectorProvider

This provider helps defer instantiation of a PluralRules object until we actually need to select a keyword.

Field Summary

Modifier and TypeField and Description
private transient Map<Integer, Format>
cachedFormatters

Cached formatters so we can just use them whenever needed instead of creating them from scratch every time.

private static final char
private static final char
private transient Set<Integer>
customFormatArgStarts

Set of ARG_START part indexes where custom, user-provided Format objects have been set via setFormat() or similar API.

private static final int
private static final int
private static final int
private static final int
private static final int
private static final String[]
private static final int
private static final int
private static final int
private static final int
private static final String[]
private transient MessagePattern
msgPattern

The MessagePattern which contains the parsed structure of the pattern string.

private transient MessageFormat.PluralSelectorProvider
private transient MessageFormat.PluralSelectorProvider
private static final Locale
pack-priv static final long
private static final char
private static final int
private static final int
private static final int
private static final int
private transient DateFormat
stockDateFormatter

Stock formatters.

private transient NumberFormat
private static final int
private static final int
private static final int
private static final int
private static final int
private static final int
private static final String[]
private transient ULocale
ulocale

The locale to use for formatting numbers and dates.

Constructor Summary

AccessConstructor and Description
public
MessageFormat(String
the pattern for this message format
pattern
)

Constructs a MessageFormat for the default FORMAT locale and the specified pattern.

public
MessageFormat(String
the pattern for this message format
pattern
,
Locale
the locale for this message format
locale
)

Constructs a MessageFormat for the specified locale and pattern.

public
MessageFormat(String
the pattern for this message format
pattern
,
ULocale
the locale for this message format
locale
)

Constructs a MessageFormat for the specified locale and pattern.

Method Summary

Modifier and TypeMethod and Description
public void
applyPattern(String
the pattern for this message format
pttrn
)

Sets the pattern used by this message format.

public void
applyPattern(String
the pattern for this message format
pattern
,
MessagePattern.ApostropheMode
the new ApostropheMode
aposMode
)

ICU

private boolean
argNameMatches(int partIndex, String argName, int argNumber)

public static String

Returns:

the standard equivalent of the original pattern
autoQuoteApostrophe
(String
the 'apostrophe-friendly' pattern to convert
pattern
)

ICU

private void
public Object
clone()

Overrides java.text.Format.clone.

Creates and returns a copy of this object.
private Format
pack-priv Format
public boolean
equals(Object
the reference object with which to compare.
obj
)

Overrides java.lang.Object.equals.

Indicates whether some other object is "equal to" this one.
private static int

Returns:

the sub-message start part index.
findChoiceSubMessage
(MessagePattern
A MessagePattern.
pattern
,
int
the index of the first ChoiceFormat argument style part.
partIndex
,
double
a number to be mapped to one of the ChoiceFormat argument's intervals
number
)

Finds the ChoiceFormat sub-message for the given number.

private int
findFirstPluralNumberArg(int msgStart, String argName)

Returns the ARG_START index of the first occurrence of the plural number in a sub-message.

private static final int
private int

Returns:

the "other" sub-message start part index.
findOtherSubMessage
(int
the index of the first PluralFormat argument style part.
partIndex
)

Finds the "other" sub-message.

public final StringBuffer
format(Object[]
an array of objects to be formatted and substituted.
arguments
,
StringBuffer
where text is appended.
result
,
FieldPosition
On input: an alignment field, if desired. On output: the offsets of the alignment field.
pos
)

Formats an array of objects and appends the MessageFormat's pattern, with arguments replaced by the formatted objects, to the provided StringBuffer.

public final StringBuffer

Returns:

the passed-in StringBuffer
format
(Map<String, Object>
a map of objects to be formatted and substituted.
arguments
,
StringBuffer
where text is appended.
result
,
FieldPosition
On input: an alignment field, if desired. On output: the offsets of the alignment field.
pos
)

Formats a map of objects and appends the MessageFormat's pattern, with arguments replaced by the formatted objects, to the provided StringBuffer.

public static String
format(String pattern, Object... arguments)

Creates a MessageFormat with the given pattern and uses it to format the given arguments.

public static String
format(String pattern, Map<String, Object> arguments)

Creates a MessageFormat with the given pattern and uses it to format the given arguments.

public final StringBuffer
format(Object
a map or array of objects to be formatted
arguments
,
StringBuffer
where text is appended
result
,
FieldPosition
On input: an alignment field, if desired On output: the offsets of the alignment field
pos
)

Implements abstract java.text.Format.format.

Formats a map or array of objects and appends the MessageFormat's pattern, with format elements replaced by the formatted objects, to the provided StringBuffer.
private void
format(int
Index to msgPattern part to start formatting from.
msgStart
,
MessageFormat.PluralSelectorContext
null except when formatting a plural argument sub-message where a '#' is replaced by the format string for this number.
pluralNumber
,
Object[]
The formattable objects array. Non-null iff numbered values are used.
args
,
Map<String, Object>
The key-value map of formattable objects. Non-null iff named values are used.
argsMap
,
MessageFormat.AppendableWrapper
Output parameter to receive the result. The result (string & attributes) is appended to existing contents.
dest
,
FieldPosition
Field position status.
fp
)

Formats the arguments and writes the result into the AppendableWrapper, updates the field position.

private void
private void
format(Object[] arguments, Map<String, Object> argsMap, MessageFormat.AppendableWrapper dest, FieldPosition fp)

Internal routine used by format.

private void
public AttributedCharacterIterator

Returns:

AttributedCharacterIterator describing the formatted value.
formatToCharacterIterator
(Object
an array of objects to be formatted and substituted.
arguments
)

Overrides java.text.Format.formatToCharacterIterator.

Formats an array of objects and inserts them into the MessageFormat's pattern, producing an AttributedCharacterIterator.
public MessagePattern.ApostropheMode

Returns:

this instance's ApostropheMode.
getApostropheMode
()

ICU

private String
getArgName(int partIndex)

public Set<String>

Returns:

a Set of argument names
getArgumentNames
()

ICU

public Format

Returns:

the Format associated with the name, or null if there isn't one.
getFormatByArgumentName
(String
The name of the desired argument.
argumentName
)

ICU

public Format[]

Returns:

the formats used for the format elements in the pattern
getFormats
()

Returns the Format objects used for the format elements in the previously set pattern string.

public Format[]

Returns:

the formats used for the arguments within the pattern
getFormatsByArgumentIndex
()

Returns the Format objects used for the values passed into format methods or returned from parse methods.

private String

Returns:

A substring from the pattern string representing the longest possible substring with no arguments.
getLiteralStringUntilNextArgument
(int
Index in the pattern string to start from.
from
)

Read as much literal string from the pattern string as possible.

public Locale

Returns:

the locale used when creating or comparing subformats
getLocale
()

Returns the locale that's used when creating or comparing subformats.

private DateFormat
private NumberFormat
public ULocale

Returns:

the locale used when creating or comparing subformats
getULocale
()

ICU

public int
hashCode()

Overrides java.lang.Object.hashCode.

Returns a hash code value for the object.
private static int
matchStringUntilLimitPart(MessagePattern pattern, int partIndex, int limitPartIndex, String source, int sourceOffset)

Matches the pattern string from the end of the partIndex to the beginning of the limitPartIndex, including all syntax except SKIP_SYNTAX, against the source string starting at sourceOffset.

private int
nextTopLevelArgStart(int
Part index of the previous ARG_START (initially 0).
partIndex
)

Returns the part index of the next ARG_START after partIndex, or -1 if there is none more.

public Object[]
parse(String source, ParsePosition pos)

Parses the string.

public Object[]

Returns:

An Object array parsed from the string.
parse
(String
A String whose beginning should be parsed.
source
)

Parses text from the beginning of the given string to produce an object array.

private void
parse(int
index in the message pattern to start from.
msgStart
,
String
the text to parse
source
,
ParsePosition
the position at which to start parsing. on return, contains the result of the parse.
pos
,
Object[]
if not null, the parse results will be filled here (The pattern has to have numbered arguments in order for this to not be null).
args
,
Map<String, Object>
if not null, the parse results will be filled here.
argsMap
)

Parses the string, filling either the Map or the Array.

private static double
parseChoiceArgument(MessagePattern pattern, int partIndex, String source, ParsePosition pos)

public Object

Returns:

An Object parsed from the string, either an array of Object, or a Map, depending on whether named arguments are used. This can be queried using usesNamedArguments. In case of error, returns null.
parseObject
(String
A String, part of which should be parsed.
source
,
ParsePosition
A ParsePosition object with index and error index information as described above.
pos
)

Implements abstract java.text.Format.parseObject.

Parses text from a string to produce an object array or Map.
public Map<String, Object>

Returns:

a Map containing key/value pairs for each parsed argument.
parseToMap
(String
the text to parse
source
,
ParsePosition
the position at which to start parsing. on return, contains the result of the parse.
pos
)

ICU

public Map<String, Object>

Returns:

A Map parsed from the string.
parseToMap
(String
A String whose beginning should be parsed.
source
)

ICU

private void
readObject(ObjectInputStream in)

Custom deserialization, new in ICU 4.8.

private void
private void
setArgStartFormat(int argStart, Format formatter)

Sets a formatter for a MessagePattern ARG_START part index.

private void
setCustomArgStartFormat(int argStart, Format formatter)

Sets a custom formatter for a MessagePattern ARG_START part index.

public void
setFormat(int
the index of a format element within the pattern
formatElementIndex
,
Format
the format to use for the specified format element
newFormat
)

Sets the Format object to use for the format element with the given format element index within the previously set pattern string.

public void
setFormatByArgumentIndex(int
the argument index for which to use the new format
argumentIndex
,
Format
the new format to use
newFormat
)

Sets the Format object to use for the format elements within the previously set pattern string that use the given argument index.

public void
setFormatByArgumentName(String
the name of the argument to change
argumentName
,
Format
the new format to use
newFormat
)

ICU

public void
setFormats(Format[]
the new formats to use
newFormats
)

Sets the Format objects to use for the format elements in the previously set pattern string.

public void
setFormatsByArgumentIndex(Format[]
the new formats to use
newFormats
)

Sets the Format objects to use for the values passed into format methods or returned from parse methods.

public void
setFormatsByArgumentName(Map<String, Format>
a map from String to Format providing new formats for named arguments.
newFormats
)

ICU

public void
setLocale(Locale
the locale to be used when creating or comparing subformats
locale
)

Sets the locale to be used for creating argument Format objects.

public void
setLocale(ULocale
the locale to be used when creating or comparing subformats
locale
)

Sets the locale to be used for creating argument Format objects.

public String

Returns:

the pattern string
toPattern
()

Returns the applied pattern string.

private FieldPosition
public boolean

Returns:

true if named arguments are used.
usesNamedArguments
()

ICU

private void
writeObject(ObjectOutputStream
The output stream.
out
)

Custom serialization, new in ICU 4.8.

Inherited from com.ibm.icu.text.UFormat:
getLocalesetLocale