ICU-5903 support pluralformat in message pattern
(there are a number of whitespace changes in these files where trailing whitespace was deleted, sorry) X-SVN-Rev: 24369
This commit is contained in:
parent
b4515acba5
commit
ff8a03216d
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2007, International Business Machines Corporation and *
|
||||
* Copyright (C) 2007-2008, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
@ -12,6 +12,8 @@ import com.ibm.icu.dev.test.TestFmwk;
|
||||
import com.ibm.icu.text.*;
|
||||
import com.ibm.icu.util.ULocale;
|
||||
|
||||
import java.text.ChoiceFormat;
|
||||
import java.text.Format;
|
||||
import java.text.ParsePosition;
|
||||
|
||||
/**
|
||||
@ -22,7 +24,7 @@ public class PluralFormatUnitTest extends TestFmwk {
|
||||
public static void main(String[] args) throws Exception {
|
||||
new PluralFormatUnitTest().run(args);
|
||||
}
|
||||
|
||||
|
||||
public void TestConstructor() {
|
||||
// Test correct formatting of numbers.
|
||||
PluralFormat plFmts[] = new PluralFormat[8];
|
||||
@ -40,7 +42,7 @@ public class PluralFormatUnitTest extends TestFmwk {
|
||||
PluralRules.DEFAULT,
|
||||
"other{#}");
|
||||
plFmts[7] = new PluralFormat(ULocale.getDefault(), "other{#}");
|
||||
|
||||
|
||||
// These plural formats should produce the same output as a
|
||||
// NumberFormat for the default locale.
|
||||
NumberFormat numberFmt = NumberFormat.getInstance(ULocale.getDefault());
|
||||
@ -60,7 +62,7 @@ public class PluralFormatUnitTest extends TestFmwk {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void TestApplyPatternAndFormat() {
|
||||
// Create rules for testing.
|
||||
PluralRules oddAndEven = PluralRules.createRules("odd: n mod 2 is 1");
|
||||
@ -68,11 +70,11 @@ public class PluralFormatUnitTest extends TestFmwk {
|
||||
// Test full specified case for testing RuleSet
|
||||
PluralFormat plfOddAndEven = new PluralFormat(oddAndEven);
|
||||
plfOddAndEven.applyPattern("odd{# is odd.} other{# is even.}");
|
||||
|
||||
|
||||
// Test fall back to other.
|
||||
PluralFormat plfOddOrEven = new PluralFormat(oddAndEven);
|
||||
plfOddOrEven.applyPattern("other{# is odd or even.}");
|
||||
|
||||
|
||||
NumberFormat numberFormat =
|
||||
NumberFormat.getInstance(ULocale.getDefault());
|
||||
for (int i = 0; i < 22; ++i) {
|
||||
@ -84,7 +86,7 @@ public class PluralFormatUnitTest extends TestFmwk {
|
||||
: " is even."),
|
||||
plfOddAndEven.format(i));
|
||||
}
|
||||
|
||||
|
||||
// Check that double definition results in an exception.
|
||||
try {
|
||||
PluralFormat plFmt = new PluralFormat(oddAndEven);
|
||||
@ -103,26 +105,26 @@ public class PluralFormatUnitTest extends TestFmwk {
|
||||
try {
|
||||
PluralFormat plFmt = new PluralFormat(oddAndEven);
|
||||
plFmt.applyPattern("odd{foo}");
|
||||
errln("Not defining plural case other should result in an " +
|
||||
errln("Not defining plural case other should result in an " +
|
||||
"exception but did not.");
|
||||
}catch (IllegalArgumentException e){}
|
||||
|
||||
|
||||
// Test unknown keyword.
|
||||
try {
|
||||
PluralFormat plFmt = new PluralFormat(oddAndEven);
|
||||
plFmt.applyPattern("otto{foo} other{bar}");
|
||||
errln("Defining a message for an unknown keyword should result in" +
|
||||
errln("Defining a message for an unknown keyword should result in" +
|
||||
"an exception but did not.");
|
||||
}catch (IllegalArgumentException e){}
|
||||
|
||||
|
||||
// Test invalid keyword.
|
||||
try {
|
||||
PluralFormat plFmt = new PluralFormat(oddAndEven);
|
||||
plFmt.applyPattern("1odd{foo} other{bar}");
|
||||
errln("Defining a message for an invalid keyword should result in" +
|
||||
errln("Defining a message for an invalid keyword should result in" +
|
||||
"an exception but did not.");
|
||||
}catch (IllegalArgumentException e){}
|
||||
|
||||
|
||||
// Test invalid syntax
|
||||
// -- comma between keyword{message} clauses
|
||||
// -- space in keywords
|
||||
@ -130,7 +132,7 @@ public class PluralFormatUnitTest extends TestFmwk {
|
||||
try {
|
||||
PluralFormat plFmt = new PluralFormat(oddAndEven);
|
||||
plFmt.applyPattern("odd{foo},other{bar}");
|
||||
errln("Separating keyword{message} items with other characters " +
|
||||
errln("Separating keyword{message} items with other characters " +
|
||||
"than space should provoke an exception but did not.");
|
||||
}catch (IllegalArgumentException e){}
|
||||
try {
|
||||
@ -145,7 +147,7 @@ public class PluralFormatUnitTest extends TestFmwk {
|
||||
errln("Defining multiple messages after a keyword should provoke " +
|
||||
"an exception but did not.");
|
||||
}catch (IllegalArgumentException e){}
|
||||
|
||||
|
||||
// Check that nested format is preserved.
|
||||
{
|
||||
PluralFormat plFmt = new PluralFormat(oddAndEven);
|
||||
@ -153,8 +155,8 @@ public class PluralFormatUnitTest extends TestFmwk {
|
||||
"other{The number {0, number, #.#0} is even.}");
|
||||
for (int i = 1; i < 3; ++i) {
|
||||
assertEquals("format did not preserve a nested format string.",
|
||||
((i % 2 == 1) ?
|
||||
"The number {0, number, #.#0} is odd."
|
||||
((i % 2 == 1) ?
|
||||
"The number {0, number, #.#0} is odd."
|
||||
: "The number {0, number, #.#0} is even."),
|
||||
plFmt.format(i));
|
||||
}
|
||||
@ -167,18 +169,18 @@ public class PluralFormatUnitTest extends TestFmwk {
|
||||
"other{The number {#} is even.}");
|
||||
for (int i = 1; i < 3; ++i) {
|
||||
assertEquals("format did not preserve # inside curly braces.",
|
||||
((i % 2 == 1) ? "The number {#} is odd."
|
||||
((i % 2 == 1) ? "The number {#} is odd."
|
||||
: "The number {#} is even."),
|
||||
plFmt.format(i));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void TestSetLocale() {
|
||||
// Create rules for testing.
|
||||
PluralRules oddAndEven = PluralRules.createRules("odd__: n mod 2 is 1");
|
||||
|
||||
|
||||
PluralFormat plFmt = new PluralFormat(oddAndEven);
|
||||
plFmt.applyPattern("odd__{odd} other{even}");
|
||||
plFmt.setLocale(ULocale.ENGLISH);
|
||||
@ -188,7 +190,7 @@ public class PluralFormatUnitTest extends TestFmwk {
|
||||
assertEquals("pattern was not resetted by setLocale() call.",
|
||||
nrFmt.format(5),
|
||||
plFmt.format(5));
|
||||
|
||||
|
||||
// Check that rules got updated.
|
||||
try {
|
||||
plFmt.applyPattern("odd__{odd} other{even}");
|
||||
@ -204,9 +206,8 @@ public class PluralFormatUnitTest extends TestFmwk {
|
||||
((i==1) ? "one" : "not one"),
|
||||
plFmt.format(i));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void TestParse() {
|
||||
PluralFormat plFmt = new PluralFormat("other{test}");
|
||||
try {
|
||||
@ -215,7 +216,7 @@ public class PluralFormatUnitTest extends TestFmwk {
|
||||
"did not");
|
||||
} catch (UnsupportedOperationException e) {
|
||||
}
|
||||
|
||||
|
||||
plFmt = new PluralFormat("other{test}");
|
||||
try {
|
||||
plFmt.parseObject("test", new ParsePosition(0));
|
||||
@ -224,4 +225,29 @@ public class PluralFormatUnitTest extends TestFmwk {
|
||||
} catch (UnsupportedOperationException e) {
|
||||
}
|
||||
}
|
||||
|
||||
public void TestPattern() {
|
||||
Object[] args = { "acme", null };
|
||||
|
||||
{
|
||||
PluralFormat pf = new PluralFormat(" one {one ''widget} other {# widgets} ");
|
||||
String pat = pf.toPattern();
|
||||
logln("pf pattern: '" + pat + "'");
|
||||
|
||||
assertEquals("no leading spaces", "o", pat.substring(0, 1));
|
||||
assertEquals("no trailing spaces", "}", pat.substring(pat.length() - 1));
|
||||
}
|
||||
|
||||
MessageFormat pfmt = new MessageFormat("The disk ''{0}'' contains {1, plural, one {one ''''{1, number, #.0}'''' widget} other {# widgets}}.");
|
||||
System.out.println();
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
args[1] = new Integer(i);
|
||||
logln(pfmt.format(args));
|
||||
}
|
||||
PluralFormat pf = (PluralFormat)pfmt.getFormatsByArgumentIndex()[1];
|
||||
logln(pf.toPattern());
|
||||
logln(pfmt.toPattern());
|
||||
MessageFormat pfmt2 = new MessageFormat(pfmt.toPattern());
|
||||
assertEquals("message formats are equal", pfmt, pfmt2);
|
||||
}
|
||||
}
|
||||
|
@ -1293,6 +1293,25 @@ public class TestMessageFormat extends com.ibm.icu.dev.test.TestFmwk {
|
||||
}
|
||||
}
|
||||
|
||||
// Test toPattern when there is a PluralFormat
|
||||
public void testPluralFormatToPattern() {
|
||||
String[] patterns = {
|
||||
"Beware of vicious {0, plural, one {hamster} other {hamsters}}.",
|
||||
"{0, plural, one {{0, number,C''''est #,##0.0# fichier}} other {Ce sont # fichiers}} dans la liste.",
|
||||
"{0, plural, one {C''est # fichier} other {Ce sont # fichiers}} dans la liste.",
|
||||
};
|
||||
|
||||
for (int i = 0; i < patterns.length; ++i) {
|
||||
String pattern = patterns[i];
|
||||
MessageFormat mf = new MessageFormat(pattern);
|
||||
MessageFormat mf2 = new MessageFormat(mf.toPattern());
|
||||
if (!mf.equals(mf2)) {
|
||||
errln("message formats not equal for pattern:\n*** '" + pattern + "'\n*** '" +
|
||||
mf.toPattern() + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//#if defined(FOUNDATION10) || defined(J2SE13)
|
||||
//#else
|
||||
// Test case for formatToCharacterIterator
|
||||
|
@ -59,28 +59,28 @@ import com.ibm.icu.util.ULocale;
|
||||
* <p>
|
||||
* <strong>Note:</strong>
|
||||
* In ICU 3.8 MessageFormat supports named arguments. If a named argument
|
||||
* is used, all arguments must be named. Names start with a character in
|
||||
* <code>:ID_START:</code> and continue with characters in <code>:ID_CONTINUE:</code>,
|
||||
* is used, all arguments must be named. Names start with a character in
|
||||
* <code>:ID_START:</code> and continue with characters in <code>:ID_CONTINUE:</code>,
|
||||
* in particular they do not start with a digit. If named arguments
|
||||
* are used, {@link #usesNamedArguments()} will return true.
|
||||
* <p>
|
||||
* The other new APIs supporting named arguments are
|
||||
* The other new APIs supporting named arguments are
|
||||
* {@link #setFormatsByArgumentName(Map)},
|
||||
* {@link #setFormatByArgumentName(String, Format)},
|
||||
* {@link #format(Map, StringBuffer, FieldPosition)},
|
||||
* {@link #format(String, Map)}, {@link #parseToMap(String, ParsePosition)},
|
||||
* and {@link #parseToMap(String)}. These APIs are all compatible
|
||||
* and {@link #parseToMap(String)}. These APIs are all compatible
|
||||
* with patterns that do not used named arguments-- in these cases
|
||||
* the keys in the input or output <code>Map</code>s use
|
||||
* <code>String</code>s that name the argument indices, e.g. "0",
|
||||
* the keys in the input or output <code>Map</code>s use
|
||||
* <code>String</code>s that name the argument indices, e.g. "0",
|
||||
* "1", "2"... etc.
|
||||
* <p>
|
||||
* When named arguments are used, certain APIs on Message that take or
|
||||
* return arrays will throw an exception, since it is not possible to
|
||||
* identify positions in an array using a name. These APIs are {@link
|
||||
* #setFormatsByArgumentIndex(Format[])}, {@link #getFormatsByArgumentIndex()},
|
||||
* {@link #format(Object[], StringBuffer, FieldPosition)},
|
||||
* {@link #format(String, Object[])},{@link #parse(String, ParsePosition)},
|
||||
* #setFormatsByArgumentIndex(Format[])}, {@link #getFormatsByArgumentIndex()},
|
||||
* {@link #format(Object[], StringBuffer, FieldPosition)},
|
||||
* {@link #format(String, Object[])},{@link #parse(String, ParsePosition)},
|
||||
* and {@link #parse(String)}.
|
||||
* These APIs all have corresponding new versions as listed above.
|
||||
* <p>
|
||||
@ -593,7 +593,7 @@ public class MessageFormat extends UFormat {
|
||||
/**
|
||||
* Returns a pattern representing the current state of the message format.
|
||||
* The string is constructed from internal information and therefore
|
||||
* does not necessarily equal the previously applied pattern.
|
||||
* does not necessarily equal the previously applied pattern.
|
||||
*
|
||||
* @return a pattern representing the current state of the message format
|
||||
* @stable ICU 3.0
|
||||
@ -652,9 +652,20 @@ public class MessageFormat extends UFormat {
|
||||
result.append(",choice,"
|
||||
+ ((ChoiceFormat) formats[i]).toPattern());
|
||||
} else if (formats[i] instanceof PluralFormat) {
|
||||
// TODO: Implement PluralFormat.toPattern().
|
||||
result.append(", plural, support for converting PluralFormat "
|
||||
+ "to pattern not yet available.");
|
||||
String pattern = ((PluralFormat)formats[i]).toPattern();
|
||||
// TODO: PluralFormat doesn't do the single quote thing, just reapply
|
||||
if (pattern.indexOf('\'') != 0) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
for (int j = 0; j < pattern.length(); ++j) {
|
||||
char ch = pattern.charAt(j);
|
||||
if (ch == '\'') {
|
||||
buf.append(ch); // double it
|
||||
}
|
||||
buf.append(ch);
|
||||
}
|
||||
pattern = buf.toString();
|
||||
}
|
||||
result.append(",plural," + pattern);
|
||||
} else {
|
||||
//result.append(", unknown");
|
||||
}
|
||||
@ -682,10 +693,10 @@ public class MessageFormat extends UFormat {
|
||||
* corresponding new format is ignored. If fewer formats are provided
|
||||
* than needed, then only the formats for argument indices less
|
||||
* than <code>newFormats.length</code> are replaced.
|
||||
*
|
||||
*
|
||||
* This method is only supported if the format does not use
|
||||
* named arguments, otherwise an IllegalArgumentException is thrown.
|
||||
*
|
||||
*
|
||||
* @param newFormats
|
||||
* the new formats to use
|
||||
* @throws NullPointerException
|
||||
@ -693,7 +704,7 @@ public class MessageFormat extends UFormat {
|
||||
* @throws IllegalArgumentException
|
||||
* if this formatter uses named arguments
|
||||
* @stable ICU 3.0
|
||||
*/
|
||||
*/
|
||||
public void setFormatsByArgumentIndex(Format[] newFormats) {
|
||||
if (!argumentNamesAreNumeric) {
|
||||
throw new IllegalArgumentException(
|
||||
@ -707,7 +718,7 @@ public class MessageFormat extends UFormat {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the formats to use for the values passed into
|
||||
* <code>format</code> methods or returned from <code>parse</code>
|
||||
@ -784,10 +795,10 @@ public class MessageFormat extends UFormat {
|
||||
* in the pattern string, then the new format is used for all such
|
||||
* format elements. If the argument index is not used for any format
|
||||
* element in the pattern string, then the new format is ignored.
|
||||
*
|
||||
*
|
||||
* This method is only supported when exclusively numbers are used for
|
||||
* argument names. Otherwise an IllegalArgumentException is thrown.
|
||||
*
|
||||
*
|
||||
* @param argumentIndex
|
||||
* the argument index for which to use the new format
|
||||
* @param newFormat
|
||||
@ -874,10 +885,10 @@ public class MessageFormat extends UFormat {
|
||||
* format element is returned in the array. If an argument index
|
||||
* is not used for any format element in the pattern string, then
|
||||
* null is returned in the array.
|
||||
*
|
||||
*
|
||||
* This method is only supported when exclusively numbers are used for
|
||||
* argument names. Otherwise an IllegalArgumentException is thrown.
|
||||
*
|
||||
*
|
||||
* @return the formats used for the arguments within the pattern
|
||||
* @throws IllegalArgumentException
|
||||
* if this format uses named arguments
|
||||
@ -886,7 +897,7 @@ public class MessageFormat extends UFormat {
|
||||
public Format[] getFormatsByArgumentIndex() {
|
||||
if (!argumentNamesAreNumeric) {
|
||||
throw new IllegalArgumentException(
|
||||
"This method is not available in MessageFormat objects " +
|
||||
"This method is not available in MessageFormat objects " +
|
||||
"that use alphanumeric argument names.");
|
||||
}
|
||||
int maximumArgumentNumber = -1;
|
||||
@ -904,7 +915,7 @@ public class MessageFormat extends UFormat {
|
||||
}
|
||||
// TODO: provide method public Map getFormatsByArgumentName().
|
||||
// Where Map is: String argumentName --> Format format.
|
||||
|
||||
|
||||
/**
|
||||
* Gets the formats used for the format elements in the
|
||||
* previously set pattern string.
|
||||
@ -921,7 +932,7 @@ public class MessageFormat extends UFormat {
|
||||
*
|
||||
* This method is only supported when exclusively numbers are used for
|
||||
* argument names. Otherwise an IllegalArgumentException is thrown.
|
||||
*
|
||||
*
|
||||
* @return the formats used for the format elements in the pattern
|
||||
* @stable ICU 3.0
|
||||
*/
|
||||
@ -991,7 +1002,7 @@ public class MessageFormat extends UFormat {
|
||||
*
|
||||
* This method is only supported when the format does not use named
|
||||
* arguments, otherwise an IllegalArgumentException is thrown.
|
||||
*
|
||||
*
|
||||
* @param arguments an array of objects to be formatted and substituted.
|
||||
* @param result where text is appended.
|
||||
* @param pos On input: an alignment field, if desired.
|
||||
@ -1005,7 +1016,7 @@ public class MessageFormat extends UFormat {
|
||||
*/
|
||||
public final StringBuffer format(Object[] arguments, StringBuffer result,
|
||||
FieldPosition pos)
|
||||
{
|
||||
{
|
||||
if (!argumentNamesAreNumeric) {
|
||||
throw new IllegalArgumentException(
|
||||
"This method is not available in MessageFormat objects " +
|
||||
@ -1021,7 +1032,7 @@ public class MessageFormat extends UFormat {
|
||||
* <p>
|
||||
* The text substituted for the individual format elements is derived from
|
||||
* the current subformat of the format element and the
|
||||
* <code>arguments</code> value corresopnding to the format element's
|
||||
* <code>arguments</code> value corresopnding to the format element's
|
||||
* argument name.
|
||||
* <p>
|
||||
* This API may be called on formats that do not use named arguments.
|
||||
@ -1047,7 +1058,7 @@ public class MessageFormat extends UFormat {
|
||||
FieldPosition pos) {
|
||||
return subformat(arguments, result, pos, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a MessageFormat with the given pattern and uses it
|
||||
* to format the given arguments. This is equivalent to
|
||||
@ -1102,7 +1113,7 @@ public class MessageFormat extends UFormat {
|
||||
* Formats a map or array of objects and appends the <code>MessageFormat</code>'s
|
||||
* pattern, with format elements replaced by the formatted objects, to the
|
||||
* provided <code>StringBuffer</code>.
|
||||
* This is equivalent to either of
|
||||
* This is equivalent to either of
|
||||
* <blockquote>
|
||||
* <code>{@link #format(java.lang.Object[], java.lang.StringBuffer, java.text.FieldPosition) format}((Object[]) arguments, result, pos)</code>
|
||||
* <code>{@link #format(java.util.Map, java.lang.StringBuffer, java.text.FieldPosition) format}((Map) arguments, result, pos)</code>
|
||||
@ -1128,7 +1139,7 @@ public class MessageFormat extends UFormat {
|
||||
} else {
|
||||
if (!argumentNamesAreNumeric) {
|
||||
throw new IllegalArgumentException(
|
||||
"This method is not available in MessageFormat objects " +
|
||||
"This method is not available in MessageFormat objects " +
|
||||
"that use alphanumeric argument names.");
|
||||
}
|
||||
return subformat((Object[]) arguments, result, pos, null);
|
||||
@ -1224,7 +1235,7 @@ public class MessageFormat extends UFormat {
|
||||
* This method is only supported with numbered arguments. If
|
||||
* the format pattern used named argument an
|
||||
* IllegalArgumentException is thrown.
|
||||
*
|
||||
*
|
||||
* @throws IllegalArgumentException if this format uses named arguments
|
||||
* @stable ICU 3.0
|
||||
*/
|
||||
@ -1242,21 +1253,21 @@ public class MessageFormat extends UFormat {
|
||||
maximumArgumentNumber = argumentNumber;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (objectMap == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Object[] resultArray = new Object[maximumArgumentNumber + 1];
|
||||
Iterator keyIter = objectMap.keySet().iterator();
|
||||
while (keyIter.hasNext()) {
|
||||
String key = (String) keyIter.next();
|
||||
resultArray[Integer.parseInt(key)] = objectMap.get(key);
|
||||
}
|
||||
|
||||
|
||||
return resultArray;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses the string, returning the results in a Map.
|
||||
* This is similar to the version that returns an array
|
||||
@ -1286,7 +1297,7 @@ public class MessageFormat extends UFormat {
|
||||
// Object[] resultArray = new Object[maximumArgumentNumber + 1];
|
||||
|
||||
Map resultMap = new HashMap();
|
||||
|
||||
|
||||
int patternOffset = 0;
|
||||
int sourceOffset = pos.getIndex();
|
||||
ParsePosition tempStatus = new ParsePosition(0);
|
||||
@ -1323,14 +1334,14 @@ public class MessageFormat extends UFormat {
|
||||
String strValue = source.substring(sourceOffset, next);
|
||||
if (!strValue.equals("{" + argumentNames[i] + "}"))
|
||||
resultMap.put(argumentNames[i], source.substring(sourceOffset, next));
|
||||
// resultArray[Integer.parseInt(argumentNames[i])] =
|
||||
// resultArray[Integer.parseInt(argumentNames[i])] =
|
||||
// source.substring(sourceOffset, next);
|
||||
sourceOffset = next;
|
||||
}
|
||||
} else {
|
||||
tempStatus.setIndex(sourceOffset);
|
||||
resultMap.put(argumentNames[i], formats[i].parseObject(source, tempStatus));
|
||||
// resultArray[Integer.parseInt(argumentNames[i])] =
|
||||
// resultArray[Integer.parseInt(argumentNames[i])] =
|
||||
// formats[i].parseObject(source, tempStatus);
|
||||
if (tempStatus.getIndex() == sourceOffset) {
|
||||
pos.setErrorIndex(sourceOffset);
|
||||
@ -1375,7 +1386,7 @@ public class MessageFormat extends UFormat {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses text from the beginning of the given string to produce a map from
|
||||
* argument to values. The method may not use the entire text of the given string.
|
||||
@ -1385,13 +1396,13 @@ public class MessageFormat extends UFormat {
|
||||
*
|
||||
* @param source A <code>String</code> whose beginning should be parsed.
|
||||
* @return A <code>Map</code> parsed from the string.
|
||||
* @throws ParseException if the beginning of the specified string cannot
|
||||
* @throws ParseException if the beginning of the specified string cannot
|
||||
* be parsed.
|
||||
* @see #parseToMap(String, ParsePosition)
|
||||
* @stable ICU 3.8
|
||||
*/
|
||||
public Map parseToMap(String source) throws ParseException {
|
||||
|
||||
|
||||
ParsePosition pos = new ParsePosition(0);
|
||||
Map result = parseToMap(source, pos);
|
||||
if (pos.getIndex() == 0) // unchanged, returned object is null
|
||||
@ -1400,7 +1411,7 @@ public class MessageFormat extends UFormat {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses text from a string to produce an object array or Map.
|
||||
* <p>
|
||||
@ -1432,7 +1443,7 @@ public class MessageFormat extends UFormat {
|
||||
if (argumentNamesAreNumeric) {
|
||||
return parse(source, pos);
|
||||
} else {
|
||||
return parseToMap(source, pos);
|
||||
return parseToMap(source, pos);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1492,7 +1503,7 @@ public class MessageFormat extends UFormat {
|
||||
* Defines constants that are used as attribute keys in the
|
||||
* <code>AttributedCharacterIterator</code> returned
|
||||
* from <code>MessageFormat.formatToCharacterIterator</code>.
|
||||
*
|
||||
*
|
||||
* @stable ICU 3.8
|
||||
*/
|
||||
public static class Field extends Format.Field {
|
||||
@ -1501,9 +1512,9 @@ public class MessageFormat extends UFormat {
|
||||
|
||||
/**
|
||||
* Create a <code>Field</code> with the specified name.
|
||||
*
|
||||
*
|
||||
* @param name The name of the attribute
|
||||
*
|
||||
*
|
||||
* @stable ICU 3.8
|
||||
*/
|
||||
protected Field(String name) {
|
||||
@ -1512,10 +1523,10 @@ public class MessageFormat extends UFormat {
|
||||
|
||||
/**
|
||||
* Resolves instances being deserialized to the predefined constants.
|
||||
*
|
||||
*
|
||||
* @return resolved MessageFormat.Field constant
|
||||
* @throws InvalidObjectException if the constant could not be resolved.
|
||||
*
|
||||
*
|
||||
* @stable ICU 3.8
|
||||
*/
|
||||
protected Object readResolve() throws InvalidObjectException {
|
||||
@ -1535,7 +1546,7 @@ public class MessageFormat extends UFormat {
|
||||
* The value associated with the key will be an <code>Integer</code>
|
||||
* indicating the index in the <code>arguments</code> array of the
|
||||
* argument from which the text was generated.
|
||||
*
|
||||
*
|
||||
* @stable ICU 3.8
|
||||
*/
|
||||
public static final Field ARGUMENT = new Field("message argument field");
|
||||
@ -1577,7 +1588,7 @@ public class MessageFormat extends UFormat {
|
||||
/**
|
||||
* The positions where the results of formatting each argument are to be
|
||||
* inserted into the pattern.
|
||||
*
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private int[] offsets = new int[INITIAL_FORMATS];
|
||||
@ -1595,14 +1606,14 @@ public class MessageFormat extends UFormat {
|
||||
* The argument names corresponding to each formatter. (The formatters are
|
||||
* stored in the order they occur in the pattern, not in the order in which
|
||||
* the arguments are specified.)
|
||||
*
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private String[] argumentNames = new String[INITIAL_FORMATS];
|
||||
|
||||
/**
|
||||
* Is true iff all argument names are non-negative numbers.
|
||||
*
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private boolean argumentNamesAreNumeric = true;
|
||||
@ -1784,7 +1795,7 @@ public class MessageFormat extends UFormat {
|
||||
private static final String[] typeList =
|
||||
{"", "number", "date", "time", "choice", "spellout", "ordinal",
|
||||
"duration", "plural"};
|
||||
private static final int
|
||||
private static final int
|
||||
TYPE_EMPTY = 0,
|
||||
TYPE_NUMBER = 1,
|
||||
TYPE_DATE = 2,
|
||||
@ -1797,23 +1808,23 @@ public class MessageFormat extends UFormat {
|
||||
|
||||
private static final String[] modifierList =
|
||||
{"", "currency", "percent", "integer"};
|
||||
|
||||
|
||||
private static final int
|
||||
MODIFIER_EMPTY = 0,
|
||||
MODIFIER_CURRENCY = 1,
|
||||
MODIFIER_PERCENT = 2,
|
||||
MODIFIER_INTEGER = 3;
|
||||
|
||||
|
||||
private static final String[] dateModifierList =
|
||||
{"", "short", "medium", "long", "full"};
|
||||
|
||||
|
||||
private static final int
|
||||
DATE_MODIFIER_EMPTY = 0,
|
||||
DATE_MODIFIER_SHORT = 1,
|
||||
DATE_MODIFIER_MEDIUM = 2,
|
||||
DATE_MODIFIER_LONG = 3,
|
||||
DATE_MODIFIER_FULL = 4;
|
||||
|
||||
|
||||
private void makeFormat(int position, int offsetNumber,
|
||||
StringBuffer[] segments)
|
||||
{
|
||||
@ -1852,7 +1863,7 @@ public class MessageFormat extends UFormat {
|
||||
int argumentNumber;
|
||||
try {
|
||||
// always unlocalized!
|
||||
argumentNumber = Integer.parseInt(segments[1].toString());
|
||||
argumentNumber = Integer.parseInt(segments[1].toString());
|
||||
} catch (NumberFormatException e) {
|
||||
argumentNumber = -1;
|
||||
}
|
||||
@ -1861,9 +1872,9 @@ public class MessageFormat extends UFormat {
|
||||
// to be numbers or (IDStartChars IDContChars*) strings.
|
||||
argumentNamesAreNumeric = argumentNumber >= 0;
|
||||
}
|
||||
|
||||
|
||||
if (argumentNamesAreNumeric && argumentNumber < 0 ||
|
||||
!argumentNamesAreNumeric &&
|
||||
!argumentNamesAreNumeric &&
|
||||
!isAlphaIdentifier(argumentNames[offsetNumber])) {
|
||||
throw new IllegalArgumentException(
|
||||
"All argument identifiers have to be either non-negative " +
|
||||
@ -1949,7 +1960,7 @@ public class MessageFormat extends UFormat {
|
||||
throw new IllegalArgumentException("Choice Pattern incorrect");
|
||||
}
|
||||
break;
|
||||
case TYPE_SPELLOUT:
|
||||
case TYPE_SPELLOUT:
|
||||
{
|
||||
RuleBasedNumberFormat rbnf = new RuleBasedNumberFormat(ulocale, RuleBasedNumberFormat.SPELLOUT);
|
||||
String ruleset = segments[3].toString().trim();
|
||||
@ -1962,7 +1973,7 @@ public class MessageFormat extends UFormat {
|
||||
}
|
||||
}
|
||||
newFormat = rbnf;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TYPE_ORDINAL:
|
||||
{
|
||||
@ -1977,7 +1988,7 @@ public class MessageFormat extends UFormat {
|
||||
}
|
||||
}
|
||||
newFormat = rbnf;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TYPE_DURATION:
|
||||
{
|
||||
@ -2105,7 +2116,7 @@ public class MessageFormat extends UFormat {
|
||||
* This is a helper method for converting an object array into a map. The
|
||||
* key set of the map is [0, ..., array.length]. The value associated with
|
||||
* each key is the ith entry of the passed object array.
|
||||
*
|
||||
*
|
||||
* @throws InvalidObjectException
|
||||
* if the objects read from the stream is invalid.
|
||||
*/
|
||||
@ -2118,14 +2129,14 @@ public class MessageFormat extends UFormat {
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
private boolean isAlphaIdentifier(String argument) {
|
||||
if (argument.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < argument.length(); ++i ) {
|
||||
if (i == 0 && !IDStartChars.contains(argument.charAt(i)) ||
|
||||
i > 0 && !IDContChars.contains(argument.charAt(i))){
|
||||
i > 0 && !IDContChars.contains(argument.charAt(i))){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -2140,14 +2151,14 @@ public class MessageFormat extends UFormat {
|
||||
private static final int STATE_SINGLE_QUOTE = 1;
|
||||
private static final int STATE_IN_QUOTE = 2;
|
||||
private static final int STATE_MSG_ELEMENT = 3;
|
||||
|
||||
|
||||
private static UnicodeSet IDStartChars = new UnicodeSet("[:ID_Start:]");
|
||||
private static UnicodeSet IDContChars = new UnicodeSet("[:ID_Continue:]");
|
||||
|
||||
/**
|
||||
* Convert an 'apostrophe-friendly' pattern into a standard
|
||||
* pattern. Standard patterns treat all apostrophes as
|
||||
* quotes, which is problematic in some languages, e.g.
|
||||
* quotes, which is problematic in some languages, e.g.
|
||||
* French, where apostrophe is commonly used. This utility
|
||||
* assumes that only an unpaired apostrophe immediately before
|
||||
* a brace is a true quote. Other unpaired apostrophes are paired,
|
||||
|
@ -21,7 +21,7 @@ import java.util.Set;
|
||||
* <p>
|
||||
* <code>PluralFormat</code> supports the creation of internationalized
|
||||
* messages with plural inflection. It is based on <i>plural
|
||||
* selection</i>, i.e. the caller specifies messages for each
|
||||
* selection</i>, i.e. the caller specifies messages for each
|
||||
* plural case that can appear in the users language and the
|
||||
* <code>PluralFormat</code> selects the appropriate message based on
|
||||
* the number.
|
||||
@ -68,7 +68,7 @@ import java.util.Set;
|
||||
* <h5>Patterns and Their Interpretation</h5>
|
||||
* <p>
|
||||
* The pattern text defines the message output for each plural case of the
|
||||
* used locale. The pattern is a sequence of
|
||||
* used locale. The pattern is a sequence of
|
||||
* <code><i>caseKeyword</i>{<i>message</i>}</code> clauses, separated by white
|
||||
* space characters. Each clause assigns the message <code><i>message</i></code>
|
||||
* to the plural case identified by <code><i>caseKeyword</i></code>.
|
||||
@ -84,9 +84,9 @@ import java.util.Set;
|
||||
* an <code>IllegalArgumentException</code> is thrown.
|
||||
* <br/>
|
||||
* Spaces between <code><i>caseKeyword</i></code> and
|
||||
* <code><i>message</i></code> will be ignored; spaces within
|
||||
* <code><i>message</i></code> will be ignored; spaces within
|
||||
* <code><i>message</i></code> will be preserved.
|
||||
* </p><p>
|
||||
* </p><p>
|
||||
* The message text for a particular plural case may contain other message
|
||||
* format patterns. <code>PluralFormat</code> preserves these so that you
|
||||
* can use the strings produced by <code>PluralFormat</code> with other
|
||||
@ -143,7 +143,7 @@ import java.util.Set;
|
||||
* For more information about <code>PluralRules</code>, see
|
||||
* {@link PluralRules}.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author tschumann (Tim Schumann)
|
||||
* @draft ICU 3.8
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
@ -169,8 +169,8 @@ public class PluralFormat extends UFormat {
|
||||
|
||||
/**
|
||||
* The format messages for each plural case. It is a mapping:
|
||||
* <code>String</code>(plural case keyword) --> <code>String</code>
|
||||
* (message for this plural case).
|
||||
* <code>String</code>(plural case keyword) --> <code>String</code>
|
||||
* (message for this plural case).
|
||||
*/
|
||||
private Map parsedValues = null;
|
||||
|
||||
@ -202,10 +202,10 @@ public class PluralFormat extends UFormat {
|
||||
public PluralFormat(ULocale ulocale) {
|
||||
init(null, ulocale);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>PluralFormat</code> for a given set of rules.
|
||||
* The standard number formatting will be done using the default locale.
|
||||
* The standard number formatting will be done using the default locale.
|
||||
* @param rules defines the behavior of the <code>PluralFormat</code>
|
||||
* object.
|
||||
* @draft ICU 3.8
|
||||
@ -244,7 +244,7 @@ public class PluralFormat extends UFormat {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>PluralFormat</code> for a given pattern string and
|
||||
* Creates a new <code>PluralFormat</code> for a given pattern string and
|
||||
* locale.
|
||||
* The locale will be used to get the set of plural rules and for
|
||||
* standard number formatting.
|
||||
@ -262,23 +262,23 @@ public class PluralFormat extends UFormat {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>PluralFormat</code> for a given set of rules and a
|
||||
* Creates a new <code>PluralFormat</code> for a given set of rules and a
|
||||
* pattern.
|
||||
* The standard number formatting will be done using the default locale.
|
||||
* The standard number formatting will be done using the default locale.
|
||||
* @param rules defines the behavior of the <code>PluralFormat</code>
|
||||
* object.
|
||||
* @param pattern the pattern for this <code>PluralFormat</code>.
|
||||
* @throws IllegalArgumentException if the pattern is invalid.
|
||||
* @draft ICU 3.8
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
*/
|
||||
public PluralFormat(PluralRules rules, String pattern) {
|
||||
init(rules, ULocale.getDefault());
|
||||
applyPattern(pattern);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>PluralFormat</code> for a given set of rules, a
|
||||
* Creates a new <code>PluralFormat</code> for a given set of rules, a
|
||||
* pattern and a locale.
|
||||
* @param ulocale the <code>PluralFormat</code> will be configured with
|
||||
* rules for this locale. This locale will also be used for standard
|
||||
@ -299,10 +299,10 @@ public class PluralFormat extends UFormat {
|
||||
* Initializes the <code>PluralRules</code> object.
|
||||
* Postcondition:<br/>
|
||||
* <code>ulocale</code> : is <code>locale</code><br/>
|
||||
* <code>pluralRules</code>: if <code>rules</code> != <code>null</code>
|
||||
* it's set to rules, otherwise it is the
|
||||
* <code>pluralRules</code>: if <code>rules</code> != <code>null</code>
|
||||
* it's set to rules, otherwise it is the
|
||||
* predefined plural rule set for the locale
|
||||
* <code>ulocale</code>.<br/>
|
||||
* <code>ulocale</code>.<br/>
|
||||
* <code>parsedValues</code>: is <code>null</code><br/>
|
||||
* <code>pattern</code>: is <code>null</code><br/>
|
||||
* <code>numberFormat</code>: a <code>NumberFormat</code> for the locale
|
||||
@ -322,13 +322,15 @@ public class PluralFormat extends UFormat {
|
||||
* The method parses the pattern and creates a map of format strings
|
||||
* for the plural rules.
|
||||
* Patterns and their interpretation are specified in the class description.
|
||||
*
|
||||
*
|
||||
* @param pttrn the pattern for this plural format.
|
||||
* @throws IllegalArgumentException if the pattern is invalid.
|
||||
* @draft ICU 3.8
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public void applyPattern(String pttrn) {
|
||||
pttrn = pttrn.trim();
|
||||
|
||||
this.pattern = pttrn;
|
||||
int braceStack = 0;
|
||||
Set ruleNames = pluralRules.getKeywords();
|
||||
@ -413,9 +415,20 @@ public class PluralFormat extends UFormat {
|
||||
checkSufficientDefinition();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pattern for this PluralFormat.
|
||||
*
|
||||
* @return the pattern string
|
||||
* @draft ICU 4.2
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public String toPattern() {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a plural message for a given number.
|
||||
*
|
||||
*
|
||||
* @param number a number for which the plural message should be formatted.
|
||||
* If no pattern has been applied to this
|
||||
* <code>PluralFormat</code> object yet, the formatted number will
|
||||
@ -434,14 +447,13 @@ public class PluralFormat extends UFormat {
|
||||
String selectedRule = pluralRules.select(number);
|
||||
String selectedPattern = (String) parsedValues.get(selectedRule);
|
||||
if (selectedPattern == null) { // Fallback to others.
|
||||
selectedPattern =
|
||||
selectedPattern =
|
||||
(String) parsedValues.get(PluralRules.KEYWORD_OTHER);
|
||||
}
|
||||
// Get formatted number and insert it into String.
|
||||
// Will replace all '#' which are not inside curly braces by the
|
||||
// formatted number.
|
||||
return insertFormattedNumber(number, selectedPattern);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -452,10 +464,10 @@ public class PluralFormat extends UFormat {
|
||||
* applied to this <code>PluralFormat</code> object yet, the
|
||||
* formatted number will be returned.
|
||||
* Note: If this object is not an instance of <code>Number</code>,
|
||||
* the <code>toAppendTo</code> will not be modified.
|
||||
* the <code>toAppendTo</code> will not be modified.
|
||||
* @param toAppendTo the formatted message will be appended to this
|
||||
* <code>StringBuffer</code>.
|
||||
* @param pos will be ignored by this method.
|
||||
* @param pos will be ignored by this method.
|
||||
* @return the string buffer passed in as toAppendTo, with formatted text
|
||||
* appended.
|
||||
* @throws IllegalArgumentException if number is not an instance of Number
|
||||
@ -468,7 +480,7 @@ public class PluralFormat extends UFormat {
|
||||
toAppendTo.append(format(((Number) number).doubleValue()));
|
||||
return toAppendTo;
|
||||
}
|
||||
throw new IllegalArgumentException("'" + number +
|
||||
throw new IllegalArgumentException("'" + number +
|
||||
"' is not a Number");
|
||||
}
|
||||
|
||||
@ -487,7 +499,7 @@ public class PluralFormat extends UFormat {
|
||||
public Number parse(String text, ParsePosition parsePosition) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method is not yet supported by <code>PluralFormat</code>.
|
||||
* @param source the string to be parsed.
|
||||
@ -564,7 +576,7 @@ public class PluralFormat extends UFormat {
|
||||
init(null, ULocale.getDefault());
|
||||
throw new IllegalArgumentException(errorText);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper method that is called during formatting.
|
||||
* It replaces the character '#' by the number used for plural selection in
|
||||
@ -586,10 +598,10 @@ public class PluralFormat extends UFormat {
|
||||
int startIndex = 0;
|
||||
for (int i = 0; i < message.length(); ++i) {
|
||||
switch (message.charAt(i)) {
|
||||
case '{':
|
||||
case '{':
|
||||
++braceStack;
|
||||
break;
|
||||
case '}':
|
||||
case '}':
|
||||
--braceStack;
|
||||
break;
|
||||
case '#':
|
||||
@ -628,7 +640,7 @@ public class PluralFormat extends UFormat {
|
||||
parsedValues.equals(rhs.parsedValues) &&
|
||||
numberFormat.equals(rhs.numberFormat);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @draft ICU 3.8
|
||||
|
Loading…
Reference in New Issue
Block a user