MessageFormatpublic class MessageFormat extends Format Produces concatenated
messages in language-neutral way. Use this class to construct messages
displayed for end users.
{@code MessageFormat} takes a set of objects, formats them and then
inserts the formatted strings into the pattern at the appropriate places.
Note: {@code MessageFormat} differs from the other
{@code Format} classes in that you create a {@code MessageFormat}
object with one of its constructors (not with a {@code getInstance}
style factory method). The factory methods aren't necessary because
{@code MessageFormat} itself doesn't implement locale specific
behavior. Any locale specific behavior is defined by the pattern that you
provide as well as the subformats used for inserted arguments.
{@code MessageFormat} uses patterns of the following form:
MessageFormatPattern:
String
MessageFormatPattern FormatElement String
FormatElement:
{ ArgumentIndex }
{ ArgumentIndex , FormatType }
{ ArgumentIndex , FormatType , FormatStyle }
FormatType: one of
number date time choice
FormatStyle:
short
medium
long
full
integer
currency
percent
SubformatPattern
String:
StringPart<sub>opt</sub>
String StringPart
StringPart:
''
' QuotedString '
UnquotedString
SubformatPattern:
SubformatPatternPart<sub>opt</sub>
SubformatPattern SubformatPatternPart
SubFormatPatternPart:
' QuotedPattern '
UnquotedPattern
Within a String, {@code "''"} represents a single quote. A
QuotedString can contain arbitrary characters except single quotes;
the surrounding single quotes are removed. An UnquotedString can
contain arbitrary characters except single quotes and left curly brackets.
Thus, a string that should result in the formatted message "'{0}'" can be
written as {@code "'''{'0}''"} or {@code "'''{0}'''"}.
Within a SubformatPattern, different rules apply. A QuotedPattern
can contain arbitrary characters except single quotes, but the surrounding
single quotes are not removed, so they may be interpreted
by the subformat. For example, {@code "{1,number,$'#',##}"} will
produce a number format with the hash-sign quoted, with a result such as:
"$#31,45". An UnquotedPattern can contain arbitrary characters except
single quotes, but curly braces within it must be balanced. For example,
{@code "ab {0} de"} and {@code "ab '}' de"} are valid subformat
patterns, but {@code "ab {0'}' de"} and {@code "ab } de"} are
not.
- Warning:
- The rules for using quotes within message format patterns unfortunately
have shown to be somewhat confusing. In particular, it isn't always obvious
to localizers whether single quotes need to be doubled or not. Make sure to
inform localizers about the rules, and tell them (for example, by using
comments in resource bundle source files) which strings will be processed by
{@code MessageFormat}. Note that localizers may need to use single quotes in
translated strings where the original version doesn't have them.
Note also that the simplest way to avoid the problem is to use the real
apostrophe (single quote) character \u2019 (') for human-readable text, and
to use the ASCII apostrophe (\u0027 ' ) only in program syntax, like quoting
in {@code MessageFormat}. See the annotations for U+0027 Apostrophe in The Unicode
Standard.
The ArgumentIndex value is a non-negative integer written using the
digits '0' through '9', and represents an index into the
{@code arguments} array passed to the {@code format} methods or
the result array returned by the {@code parse} methods.
The FormatType and FormatStyle values are used to create a
{@code Format} instance for the format element. The following table
shows how the values map to {@code Format} instances. Combinations not shown in the
table are illegal. A SubformatPattern must be a valid pattern string
for the {@code Format} subclass used.
Format Type |
Format Style |
Subformat Created |
(none) |
{@code null} |
{@code number} |
(none) |
{@code NumberFormat.getInstance(getLocale())} |
{@code integer} |
{@code NumberFormat.getIntegerInstance(getLocale())} |
{@code currency} |
{@code NumberFormat.getCurrencyInstance(getLocale())} |
{@code percent} |
{@code NumberFormat.getPercentInstance(getLocale())} |
SubformatPattern |
{@code new DecimalFormat(subformatPattern, new DecimalFormatSymbols(getLocale()))} |
{@code date} |
(none) |
{@code DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())} |
{@code short} |
{@code DateFormat.getDateInstance(DateFormat.SHORT, getLocale())} |
{@code medium} |
{@code DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())} |
{@code long} |
{@code DateFormat.getDateInstance(DateFormat.LONG, getLocale())} |
{@code full} |
{@code DateFormat.getDateInstance(DateFormat.FULL, getLocale())} |
SubformatPattern |
{@code new SimpleDateFormat(subformatPattern, getLocale())} |
{@code time} |
(none) |
{@code DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())} |
{@code short} |
{@code DateFormat.getTimeInstance(DateFormat.SHORT, getLocale())} |
{@code medium} |
{@code DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())} |
{@code long} |
{@code DateFormat.getTimeInstance(DateFormat.LONG, getLocale())} |
{@code full} |
{@code DateFormat.getTimeInstance(DateFormat.FULL, getLocale())} |
SubformatPattern |
{@code new SimpleDateFormat(subformatPattern, getLocale())} |
{@code choice} |
SubformatPattern |
{@code new ChoiceFormat(subformatPattern)} |
Usage Information
Here are some examples of usage:
Object[] arguments = {
new Integer(7), new Date(System.currentTimeMillis()),
"a disturbance in the Force"};
String result = MessageFormat.format(
"At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.",
arguments);
Output:
At 12:30 PM on Jul 3, 2053, 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 = {new Long(3), "MyDisk"};
MessageFormat form = new MessageFormat("The disk \"{1}\" contains {0} file(s).");
System.out.println(form.format(testArgs));
Output with different testArgs:
The disk "MyDisk" contains 0 file(s).
The disk "MyDisk" contains 1 file(s).
The disk "MyDisk" contains 1,273 file(s).
For more sophisticated patterns, you can use a {@code ChoiceFormat} to
get output such as:
MessageFormat form = new MessageFormat("The disk \"{1}\" contains {0}.");
double[] filelimits = {0,1,2};
String[] filepart = {"no files","one file","{0,number} files"};
ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);
form.setFormatByArgumentIndex(0, fileform);
Object[] testArgs = {new Long(12373), "MyDisk"};
System.out.println(form.format(testArgs));
Output (with different testArgs):
The disk "MyDisk" contains no files.
The disk "MyDisk" contains one file.
The disk "MyDisk" contains 1,273 files.
You can either do this programmatically, as in the above
example, or by using a pattern (see {@link ChoiceFormat} for more
information) as in:
form.applyPattern("There {0,choice,0#are no files|1#is one file|1<are {0,number,integer} files}.");
Note: As we see above, the string produced by a
{@code ChoiceFormat} in {@code MessageFormat} is treated
specially; occurances of '{' are used to indicated subformats, and cause
recursion. If you create both a {@code MessageFormat} and
{@code ChoiceFormat} programmatically (instead of using the string
patterns), then be careful not to produce a format that recurses on itself,
which will cause an infinite loop.
When a single argument is parsed more than once in the string, the last match
will be the final result of the parsing. For example:
MessageFormat mf = new MessageFormat("{0,number,#.##}, {0,number,#.#}");
Object[] objs = {new Double(3.1415)};
String result = mf.format(objs);
// result now equals "3.14, 3.1"
objs = null;
objs = mf.parse(result, new ParsePosition(0));
// objs now equals {new Double(3.1)}
Likewise, parsing with a {@code MessageFormat} object using patterns
containing multiple occurrences of the same argument would return the last
match. For example:
MessageFormat mf = new MessageFormat("{0}, {0}, {0}");
String forParsing = "x, y, z";
Object[] objs = mf.parse(forParsing, new ParsePosition(0));
// result now equals {new String("z")}
Message formats 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.
|
Fields Summary |
---|
private static final long | serialVersionUID | private Locale | locale | private transient String[] | strings | private int[] | argumentNumbers | private Format[] | formats | private int | maxOffset | private transient int | maxArgumentIndex | private static final ObjectStreamField[] | serialPersistentFields |
Constructors Summary |
---|
public MessageFormat(String template, Locale locale)Constructs a new {@code MessageFormat} using the specified pattern and
the specified locale for formats.
this.locale = locale;
applyPattern(template);
| public MessageFormat(String template)Constructs a new {@code MessageFormat} using the specified pattern and
the default locale for formats.
applyPattern(template);
|
Methods Summary |
---|
private void | appendQuoted(java.lang.StringBuffer buffer, java.lang.String string)
int length = string.length();
for (int i = 0; i < length; i++) {
char ch = string.charAt(i);
if (ch == '{" || ch == '}") {
buffer.append('\'");
buffer.append(ch);
buffer.append('\'");
} else {
buffer.append(ch);
}
}
| public void | applyPattern(java.lang.String template)Changes this {@code MessageFormat} to use the specified pattern.
int length = template.length();
StringBuffer buffer = new StringBuffer();
ParsePosition position = new ParsePosition(0);
Vector<String> localStrings = new Vector<String>();
int argCount = 0;
int[] args = new int[10];
int maxArg = -1;
Vector<Format> localFormats = new Vector<Format>();
while (position.getIndex() < length) {
if (Format.upTo(template, position, buffer, '{")) {
byte arg;
int offset = position.getIndex();
if (offset >= length
|| (arg = (byte) Character.digit(template
.charAt(offset++), 10)) == -1) {
// text.19=Invalid argument number
throw new IllegalArgumentException(Messages
.getString("text.19")); //$NON-NLS-1$
}
position.setIndex(offset);
localFormats.addElement(parseVariable(template, position));
if (argCount >= args.length) {
int[] newArgs = new int[args.length * 2];
System.arraycopy(args, 0, newArgs, 0, args.length);
args = newArgs;
}
args[argCount++] = arg;
if (arg > maxArg) {
maxArg = arg;
}
}
localStrings.addElement(buffer.toString());
buffer.setLength(0);
}
this.strings = new String[localStrings.size()];
for (int i = 0; i < localStrings.size(); i++) {
this.strings[i] = localStrings.elementAt(i);
}
argumentNumbers = args;
this.formats = new Format[argCount];
for (int i = 0; i < argCount; i++) {
this.formats[i] = localFormats.elementAt(i);
}
maxOffset = argCount - 1;
maxArgumentIndex = maxArg;
| public java.lang.Object | clone()Returns a new instance of {@code MessageFormat} with the same pattern and
formats as this {@code MessageFormat}.
MessageFormat clone = (MessageFormat) super.clone();
Format[] array = new Format[formats.length];
for (int i = formats.length; --i >= 0;) {
if (formats[i] != null) {
array[i] = (Format) formats[i].clone();
}
}
clone.formats = array;
return clone;
| private java.lang.String | decodeDecimalFormat(java.lang.StringBuffer buffer, java.text.Format format)
buffer.append(",number"); //$NON-NLS-1$
if (format.equals(NumberFormat.getNumberInstance(locale))) {
// Empty block
} else if (format.equals(NumberFormat.getIntegerInstance(locale))) {
buffer.append(",integer"); //$NON-NLS-1$
} else if (format.equals(NumberFormat.getCurrencyInstance(locale))) {
buffer.append(",currency"); //$NON-NLS-1$
} else if (format.equals(NumberFormat.getPercentInstance(locale))) {
buffer.append(",percent"); //$NON-NLS-1$
} else {
buffer.append(',");
return ((DecimalFormat) format).toPattern();
}
return null;
| private java.lang.String | decodeSimpleDateFormat(java.lang.StringBuffer buffer, java.text.Format format)
if (format.equals(DateFormat
.getTimeInstance(DateFormat.DEFAULT, locale))) {
buffer.append(",time"); //$NON-NLS-1$
} else if (format.equals(DateFormat.getDateInstance(DateFormat.DEFAULT,
locale))) {
buffer.append(",date"); //$NON-NLS-1$
} else if (format.equals(DateFormat.getTimeInstance(DateFormat.SHORT,
locale))) {
buffer.append(",time,short"); //$NON-NLS-1$
} else if (format.equals(DateFormat.getDateInstance(DateFormat.SHORT,
locale))) {
buffer.append(",date,short"); //$NON-NLS-1$
} else if (format.equals(DateFormat.getTimeInstance(DateFormat.LONG,
locale))) {
buffer.append(",time,long"); //$NON-NLS-1$
} else if (format.equals(DateFormat.getDateInstance(DateFormat.LONG,
locale))) {
buffer.append(",date,long"); //$NON-NLS-1$
} else if (format.equals(DateFormat.getTimeInstance(DateFormat.FULL,
locale))) {
buffer.append(",time,full"); //$NON-NLS-1$
} else if (format.equals(DateFormat.getDateInstance(DateFormat.FULL,
locale))) {
buffer.append(",date,full"); //$NON-NLS-1$
} else {
buffer.append(",date,"); //$NON-NLS-1$
return ((SimpleDateFormat) format).toPattern();
}
return null;
| public boolean | equals(java.lang.Object object)Compares the specified object to this {@code MessageFormat} and indicates
if they are equal. In order to be equal, {@code object} must be an
instance of {@code MessageFormat} and have the same pattern.
if (this == object) {
return true;
}
if (!(object instanceof MessageFormat)) {
return false;
}
MessageFormat format = (MessageFormat) object;
if (maxOffset != format.maxOffset) {
return false;
}
// Must use a loop since the lengths may be different due
// to serialization cross-loading
for (int i = 0; i <= maxOffset; i++) {
if (argumentNumbers[i] != format.argumentNumbers[i]) {
return false;
}
}
return locale.equals(format.locale)
&& Arrays.equals(strings, format.strings)
&& Arrays.equals(formats, format.formats);
| public final java.lang.StringBuffer | format(java.lang.Object object, java.lang.StringBuffer buffer, java.text.FieldPosition field)Converts the specified objects into a string which it appends to the
specified string buffer using the pattern of this message format.
If the {@code field} member of the specified {@code FieldPosition} is
{@code MessageFormat.Field.ARGUMENT}, then the begin and end index of
this field position is set to the location of the first occurrence of a
message format argument. Otherwise, the {@code FieldPosition} is ignored.
Calling this method is equivalent to calling
format((Object[])object, buffer, field)
return format((Object[]) object, buffer, field);
| public static java.lang.String | format(java.lang.String template, java.lang.Object objects)Formats the supplied objects using the specified message format pattern.
// BEGIN android-note
// changed parameter type from array to varargs.
// END android-note
return new MessageFormat(template).format(objects);
| public final java.lang.StringBuffer | format(java.lang.Object[] objects, java.lang.StringBuffer buffer, java.text.FieldPosition field)Converts the specified objects into a string which it appends to the
specified string buffer using the pattern of this message format.
If the {@code field} member of the specified {@code FieldPosition} is
{@code MessageFormat.Field.ARGUMENT}, then the begin and end index of
this field position is set to the location of the first occurrence of a
message format argument. Otherwise, the {@code FieldPosition} is ignored.
return formatImpl(objects, buffer, field, null);
| private java.lang.StringBuffer | formatImpl(java.lang.Object[] objects, java.lang.StringBuffer buffer, java.text.FieldPosition position, java.util.Vector fields)
FieldPosition passedField = new FieldPosition(0);
for (int i = 0; i <= maxOffset; i++) {
buffer.append(strings[i]);
int begin = buffer.length();
Object arg;
if (objects != null && argumentNumbers[i] < objects.length) {
arg = objects[argumentNumbers[i]];
} else {
buffer.append('{");
buffer.append(argumentNumbers[i]);
buffer.append('}");
handleArgumentField(begin, buffer.length(), argumentNumbers[i],
position, fields);
continue;
}
Format format = formats[i];
if (format == null || arg == null) {
if (arg instanceof Number) {
format = NumberFormat.getInstance();
} else if (arg instanceof Date) {
format = DateFormat.getInstance();
} else {
buffer.append(arg);
handleArgumentField(begin, buffer.length(),
argumentNumbers[i], position, fields);
continue;
}
}
if (format instanceof ChoiceFormat) {
String result = format.format(arg);
MessageFormat mf = new MessageFormat(result);
mf.setLocale(locale);
mf.format(objects, buffer, passedField);
handleArgumentField(begin, buffer.length(), argumentNumbers[i],
position, fields);
handleformat(format, arg, begin, fields);
} else {
format.format(arg, buffer, passedField);
handleArgumentField(begin, buffer.length(), argumentNumbers[i],
position, fields);
handleformat(format, arg, begin, fields);
}
}
if (maxOffset + 1 < strings.length) {
buffer.append(strings[maxOffset + 1]);
}
return buffer;
| public java.text.AttributedCharacterIterator | formatToCharacterIterator(java.lang.Object object)Formats the specified object using the rules of this message format and
returns an {@code AttributedCharacterIterator} with the formatted message and
attributes. The {@code AttributedCharacterIterator} returned also includes the
attributes from the formats of this message format.
if (object == null) {
throw new NullPointerException();
}
StringBuffer buffer = new StringBuffer();
Vector<FieldContainer> fields = new Vector<FieldContainer>();
// format the message, and find fields
formatImpl((Object[]) object, buffer, new FieldPosition(0), fields);
// create an AttributedString with the formatted buffer
AttributedString as = new AttributedString(buffer.toString());
// add MessageFormat field attributes and values to the AttributedString
for (int i = 0; i < fields.size(); i++) {
FieldContainer fc = fields.elementAt(i);
as.addAttribute(fc.attribute, fc.value, fc.start, fc.end);
}
// return the CharacterIterator from AttributedString
return as.getIterator();
| public java.text.Format[] | getFormats()Returns the {@code Format} instances used by this message format.
return formats.clone();
| public java.text.Format[] | getFormatsByArgumentIndex()Returns the formats used for each argument index. If an argument is
placed more than once in the pattern string, then this returns the format
of the last one.
Format[] answer = new Format[maxArgumentIndex + 1];
for (int i = 0; i < maxOffset + 1; i++) {
answer[argumentNumbers[i]] = formats[i];
}
return answer;
| public java.util.Locale | getLocale()Returns the locale used when creating formats.
return locale;
| private void | handleArgumentField(int begin, int end, int argnumber, java.text.FieldPosition position, java.util.Vector fields)Adds a new FieldContainer with MessageFormat.Field.ARGUMENT field,
argnumber, begin and end index to the fields vector, or sets the
position's begin and end index if it has MessageFormat.Field.ARGUMENT as
its field attribute.
if (fields != null) {
fields.add(new FieldContainer(begin, end, Field.ARGUMENT,
new Integer(argnumber)));
} else {
if (position != null
&& position.getFieldAttribute() == Field.ARGUMENT
&& position.getEndIndex() == 0) {
position.setBeginIndex(begin);
position.setEndIndex(end);
}
}
| private void | handleformat(java.text.Format format, java.lang.Object arg, int begin, java.util.Vector fields)If fields vector is not null, find and add the fields of this format to
the fields vector by iterating through its AttributedCharacterIterator
if (fields != null) {
AttributedCharacterIterator iterator = format
.formatToCharacterIterator(arg);
while (iterator.getIndex() != iterator.getEndIndex()) {
int start = iterator.getRunStart();
int end = iterator.getRunLimit();
Iterator<?> it = iterator.getAttributes().keySet().iterator();
while (it.hasNext()) {
AttributedCharacterIterator.Attribute attribute = (AttributedCharacterIterator.Attribute) it
.next();
Object value = iterator.getAttribute(attribute);
fields.add(new FieldContainer(begin + start, begin + end,
attribute, value));
}
iterator.setIndex(end);
}
}
| public int | hashCode()
int hashCode = 0;
for (int i = 0; i <= maxOffset; i++) {
hashCode += argumentNumbers[i] + strings[i].hashCode();
if (formats[i] != null) {
hashCode += formats[i].hashCode();
}
}
if (maxOffset + 1 < strings.length) {
hashCode += strings[maxOffset + 1].hashCode();
}
if (locale != null) {
return hashCode + locale.hashCode();
}
return hashCode;
| private int | match(java.lang.String string, java.text.ParsePosition position, boolean last, java.lang.String[] tokens)
int length = string.length(), offset = position.getIndex(), token = -1;
while (offset < length && Character.isWhitespace(string.charAt(offset))) {
offset++;
}
for (int i = tokens.length; --i >= 0;) {
if (string.regionMatches(true, offset, tokens[i], 0, tokens[i]
.length())) {
token = i;
break;
}
}
if (token == -1) {
return -1;
}
offset += tokens[token].length();
while (offset < length && Character.isWhitespace(string.charAt(offset))) {
offset++;
}
char ch;
if (offset < length
&& ((ch = string.charAt(offset)) == '}" || (!last && ch == ',"))) {
position.setIndex(offset + 1);
return token;
}
return -1;
| public java.lang.Object[] | parse(java.lang.String string)Parses the message arguments from the specified string using the rules of
this message format.
ParsePosition position = new ParsePosition(0);
Object[] result = parse(string, position);
if (position.getErrorIndex() != -1 || position.getIndex() == 0) {
throw new ParseException(null, position.getErrorIndex());
}
return result;
| public java.lang.Object[] | parse(java.lang.String string, java.text.ParsePosition position)Parses the message argument from the specified string starting at the
index specified by {@code position}. If the string is successfully
parsed then the index of the {@code ParsePosition} is updated to the
index following the parsed text. On error, the index is unchanged and the
error index of {@code ParsePosition} is set to the index where the error
occurred.
if (string == null) {
return new Object[0];
}
ParsePosition internalPos = new ParsePosition(0);
int offset = position.getIndex();
Object[] result = new Object[maxArgumentIndex + 1];
for (int i = 0; i <= maxOffset; i++) {
String sub = strings[i];
if (!string.startsWith(sub, offset)) {
position.setErrorIndex(offset);
return null;
}
offset += sub.length();
Object parse;
Format format = formats[i];
if (format == null) {
if (i + 1 < strings.length) {
int next = string.indexOf(strings[i + 1], offset);
if (next == -1) {
position.setErrorIndex(offset);
return null;
}
parse = string.substring(offset, next);
offset = next;
} else {
parse = string.substring(offset);
offset = string.length();
}
} else {
internalPos.setIndex(offset);
parse = format.parseObject(string, internalPos);
if (internalPos.getErrorIndex() != -1) {
position.setErrorIndex(offset);
return null;
}
offset = internalPos.getIndex();
}
result[argumentNumbers[i]] = parse;
}
if (maxOffset + 1 < strings.length) {
String sub = strings[maxOffset + 1];
if (!string.startsWith(sub, offset)) {
position.setErrorIndex(offset);
return null;
}
offset += sub.length();
}
position.setIndex(offset);
return result;
| public java.lang.Object | parseObject(java.lang.String string, java.text.ParsePosition position)Parses the message argument from the specified string starting at the
index specified by {@code position}. If the string is successfully
parsed then the index of the {@code ParsePosition} is updated to the
index following the parsed text. On error, the index is unchanged and the
error index of {@code ParsePosition} is set to the index where the error
occurred.
return parse(string, position);
| private java.text.Format | parseVariable(java.lang.String string, java.text.ParsePosition position)
int length = string.length(), offset = position.getIndex();
char ch;
if (offset >= length
|| ((ch = string.charAt(offset++)) != '}" && ch != ',")) {
// text.15=Missing element format
throw new IllegalArgumentException(Messages.getString("text.15")); //$NON-NLS-1$
}
position.setIndex(offset);
if (ch == '}") {
return null;
}
int type = match(string, position, false, new String[] { "time", //$NON-NLS-1$
"date", "number", "choice" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
if (type == -1) {
// text.16=Unknown element format
throw new IllegalArgumentException(Messages.getString("text.16")); //$NON-NLS-1$
}
StringBuffer buffer = new StringBuffer();
ch = string.charAt(position.getIndex() - 1);
switch (type) {
case 0: // time
case 1: // date
if (ch == '}") {
return type == 1 ? DateFormat.getDateInstance(
DateFormat.DEFAULT, locale) : DateFormat
.getTimeInstance(DateFormat.DEFAULT, locale);
}
int dateStyle = match(string, position, true, new String[] {
"full", "long", "medium", "short" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
if (dateStyle == -1) {
Format.upToWithQuotes(string, position, buffer, '}", '{");
return new SimpleDateFormat(buffer.toString(), locale);
}
switch (dateStyle) {
case 0:
dateStyle = DateFormat.FULL;
break;
case 1:
dateStyle = DateFormat.LONG;
break;
case 2:
dateStyle = DateFormat.MEDIUM;
break;
case 3:
dateStyle = DateFormat.SHORT;
break;
}
return type == 1 ? DateFormat
.getDateInstance(dateStyle, locale) : DateFormat
.getTimeInstance(dateStyle, locale);
case 2: // number
if (ch == '}") {
// BEGIN android-changed
return NumberFormat.getInstance(locale);
// END android-changed
}
int numberStyle = match(string, position, true, new String[] {
"currency", "percent", "integer" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
if (numberStyle == -1) {
Format.upToWithQuotes(string, position, buffer, '}", '{");
return new DecimalFormat(buffer.toString(),
new DecimalFormatSymbols(locale));
}
switch (numberStyle) {
case 0: // currency
return NumberFormat.getCurrencyInstance(locale);
case 1: // percent
return NumberFormat.getPercentInstance(locale);
}
return NumberFormat.getIntegerInstance(locale);
}
// choice
try {
Format.upToWithQuotes(string, position, buffer, '}", '{");
} catch (IllegalArgumentException e) {
// ignored
}
return new ChoiceFormat(buffer.toString());
| private void | readObject(java.io.ObjectInputStream stream)
ObjectInputStream.GetField fields = stream.readFields();
argumentNumbers = (int[]) fields.get("argumentNumbers", null); //$NON-NLS-1$
formats = (Format[]) fields.get("formats", null); //$NON-NLS-1$
locale = (Locale) fields.get("locale", null); //$NON-NLS-1$
maxOffset = fields.get("maxOffset", 0); //$NON-NLS-1$
int[] offsets = (int[]) fields.get("offsets", null); //$NON-NLS-1$
String pattern = (String) fields.get("pattern", null); //$NON-NLS-1$
int length;
if (maxOffset < 0) {
length = pattern.length() > 0 ? 1 : 0;
} else {
length = maxOffset
+ (offsets[maxOffset] == pattern.length() ? 1 : 2);
}
strings = new String[length];
int last = 0;
for (int i = 0; i <= maxOffset; i++) {
strings[i] = pattern.substring(last, offsets[i]);
last = offsets[i];
}
if (maxOffset + 1 < strings.length) {
strings[strings.length - 1] = pattern.substring(last, pattern
.length());
}
| public void | setFormat(int offset, java.text.Format format)Sets the specified format used by this message format.
formats[offset] = format;
| public void | setFormatByArgumentIndex(int argIndex, java.text.Format format)Sets the format used for the argument at index {@code argIndex} to
{@code format}.
for (int i = 0; i < maxOffset + 1; i++) {
if (argumentNumbers[i] == argIndex) {
formats[i] = format;
}
}
| public void | setFormats(java.text.Format[] formats)Sets the formats used by this message format.
int min = this.formats.length;
if (formats.length < min) {
min = formats.length;
}
for (int i = 0; i < min; i++) {
this.formats[i] = formats[i];
}
| public void | setFormatsByArgumentIndex(java.text.Format[] formats)Sets the formats used for each argument. The {@code formats} array
elements should be in the order of the argument indices.
for (int j = 0; j < formats.length; j++) {
for (int i = 0; i < maxOffset + 1; i++) {
if (argumentNumbers[i] == j) {
this.formats[i] = formats[j];
}
}
}
| public void | setLocale(java.util.Locale locale)Sets the locale to use when creating {@code Format} instances. Changing
the locale may change the behavior of {@code applyPattern},
{@code toPattern}, {@code format} and {@code formatToCharacterIterator}.
this.locale = locale;
for (int i = 0; i <= maxOffset; i++) {
Format format = formats[i];
// BEGIN android-removed
//if (format instanceof DecimalFormat) {
// formats[i] = new DecimalFormat(((DecimalFormat) format)
// .toPattern(), new DecimalFormatSymbols(locale));
//} else if (format instanceof SimpleDateFormat) {
// formats[i] = new SimpleDateFormat(((SimpleDateFormat) format)
// .toPattern(), locale);
//}
// END android-removed
// BEGIN android-added
// java specification undefined for null argument, change into
// a more tolerant implementation
if (format instanceof DecimalFormat) {
try {
formats[i] = new DecimalFormat(((DecimalFormat) format)
.toPattern(), new DecimalFormatSymbols(locale));
} catch (NullPointerException npe){
formats[i] = null;
}
} else if (format instanceof SimpleDateFormat) {
try {
formats[i] = new SimpleDateFormat(((SimpleDateFormat) format)
.toPattern(), locale);
} catch (NullPointerException npe) {
formats[i] = null;
}
}
// END android-added
}
| public java.lang.String | toPattern()Returns the pattern of this message format.
StringBuffer buffer = new StringBuffer();
for (int i = 0; i <= maxOffset; i++) {
appendQuoted(buffer, strings[i]);
buffer.append('{");
buffer.append(argumentNumbers[i]);
Format format = formats[i];
String pattern = null;
if (format instanceof ChoiceFormat) {
buffer.append(",choice,"); //$NON-NLS-1$
pattern = ((ChoiceFormat) format).toPattern();
} else if (format instanceof DecimalFormat) {
pattern = decodeDecimalFormat(buffer, format);
} else if (format instanceof SimpleDateFormat) {
pattern = decodeSimpleDateFormat(buffer, format);
} else if (format != null) {
// text.17=Unknown format
throw new IllegalArgumentException(Messages
.getString("text.17")); //$NON-NLS-1$
}
if (pattern != null) {
boolean quote = false;
int index = 0, length = pattern.length(), count = 0;
while (index < length) {
char ch = pattern.charAt(index++);
if (ch == '\'") {
quote = !quote;
}
if (!quote) {
if (ch == '{") {
count++;
}
if (ch == '}") {
if (count > 0) {
count--;
} else {
buffer.append("'}"); //$NON-NLS-1$
ch = '\'";
}
}
}
buffer.append(ch);
}
}
buffer.append('}");
}
if (maxOffset + 1 < strings.length) {
appendQuoted(buffer, strings[maxOffset + 1]);
}
return buffer.toString();
| private void | writeObject(java.io.ObjectOutputStream stream) //$NON-NLS-1$
ObjectOutputStream.PutField fields = stream.putFields();
fields.put("argumentNumbers", argumentNumbers); //$NON-NLS-1$
Format[] compatibleFormats = formats;
fields.put("formats", compatibleFormats); //$NON-NLS-1$
fields.put("locale", locale); //$NON-NLS-1$
fields.put("maxOffset", maxOffset); //$NON-NLS-1$
int offset = 0;
int offsetsLength = maxOffset + 1;
int[] offsets = new int[offsetsLength];
StringBuffer pattern = new StringBuffer();
for (int i = 0; i <= maxOffset; i++) {
offset += strings[i].length();
offsets[i] = offset;
pattern.append(strings[i]);
}
if (maxOffset + 1 < strings.length) {
pattern.append(strings[maxOffset + 1]);
}
fields.put("offsets", offsets); //$NON-NLS-1$
fields.put("pattern", pattern.toString()); //$NON-NLS-1$
stream.writeFields();
|
|