break; } } } } if (braceStack == 0 && part != 0) { maxOffset = -1; throw new IllegalArgumentException("Unmatched braces in the pattern."); } this.pattern = segments[0].toString(); } /** * 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. * * @return a pattern representing the current state of the message format */ public String toPattern() { // later, make this more extensible int lastOffset = 0; StringBuilder result = new StringBuilder(); for (int i = 0; i <= maxOffset; ++i) { copyAndFixQuotes(pattern, lastOffset, offsets[i], result); lastOffset = offsets[i]; result.append('{').append(argumentNumbers[i]); Format fmt = formats[i]; if (fmt == null) { // do nothing, string format } else if (fmt instanceof NumberFormat) { if (fmt.equals(NumberFormat.getInstance(locale))) { result.append(",number"); } else if (fmt.equals(NumberFormat.getCurrencyInstance(locale))) { result.append(",number,currency"); } else if (fmt.equals(NumberFormat.getPercentInstance(locale))) { result.append(",number,percent"); } else if (fmt.equals(NumberFormat.getIntegerInstance(locale))) { result.append(",number,integer"); } else { if (fmt instanceof DecimalFormat) { result.append(",number,").append(((DecimalFormat)fmt).toPattern()); } else if (fmt instanceof ChoiceFormat) { result.append(",choice,").append(((ChoiceFormat)fmt).toPattern()); } else { // UNKNOWN } } } else if (fmt instanceof DateFormat) { int index; for (index = MODIFIER_DEFAULT; index < DATE_TIME_MODIFIERS.length; index++) { DateFormat df = DateFormat.getDateInstance(DATE_TIME_MODIFIERS[index], locale); if (fmt.equals(df)) { result.append(",date"); break; } df = DateFormat.getTimeInstance(DATE_TIME_MODIFIERS[index], locale); if (fmt.equals(df)) { result.append(",time"); break; } } if (index >= DATE_TIME_MODIFIERS.length) { if (fmt instanceof SimpleDateFormat) { result.append(",date,").append(((SimpleDateFormat)fmt).toPattern()); } else { // UNKNOWN } } else if (index != MODIFIER_DEFAULT) { result.append(',').append(DATE_TIME_MODIFIER_KEYWORDS[index]); } } else { //result.append(", unknown"); } result.append('}'); } copyAndFixQuotes(pattern, lastOffset, pattern.length(), result); return result.toString(); } /** * Sets the formats to use for the values passed into * <code>format</code> methods or returned from <code>parse</code> * methods. The indices of elements in <code>newFormats</code> * correspond to the argument indices used in the previously set * pattern string. * The order of formats in <code>newFormats</code> thus corresponds to * the order of elements in the <code>arguments</code> array passed * to the <code>format</code> methods or the result array returned * by the <code>parse</code> methods. * <p> * If an argument index is used for more than one format element * in the pattern string, then the corresponding new format is used * for all such format elements. If an argument index is not used * for any format element in the pattern string, then the * 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. * * @param newFormats the new formats to use * @exception NullPointerException if <code>newFormats</code> is null * @since 1.4 */ public void setFormatsByArgumentIndex(Format[] newFormats) { for (int i = 0; i <= maxOffset; i++) { int j = argumentNumbers[i]; if (j < newFormats.length) { formats[i] = newFormats[j]; } } } /** * Sets the formats to use for the format elements in the * previously set pattern string. * The order of formats in <code>newFormats</code> corresponds to * the order of format elements in the pattern string. * <p> * If more formats are provided than needed by the pattern string, * the remaining ones are ignored. If fewer formats are provided * than needed, then only the first <code>newFormats.length</code> * formats are replaced. * <p> * Since the order of format elements in a pattern string often * changes during localization, it is generally better to use the * {@link #setFormatsByArgumentIndex setFormatsByArgumentIndex} * method, which assumes an order of formats corresponding to the * order of elements in the <code>arguments</code> array passed to * the <code>format</code> methods or the result array returned by * the <code>parse</code> methods. * * @param newFormats the new formats to use * @exception NullPointerException if <code>newFormats</code> is null */ public void setFormats(Format[] newFormats) { int runsToCopy = newFormats.length; if (runsToCopy > maxOffset + 1) { runsToCopy = maxOffset + 1; } for (int i = 0; i < runsToCopy; i++) { formats[i] = newFormats[i]; } } /** * Sets the format to use for the format elements within the * previously set pattern string that use the given argument * index. * The argument index is part of the format element definition and * represents an index into the <code>arguments</code> array passed * to the <code>format</code> methods or the result array returned * by the <code>parse</code> methods. * <p> * If the argument index is used for more than one format element * 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. * * @param argumentIndex the argument index for which to use the new format * @param newFormat the new format to use * @since 1.4 */ public void setFormatByArgumentIndex(int argumentIndex, Format newFormat) { for (int j = 0; j <= maxOffset; j++) { if (argumentNumbers[j] == argumentIndex) { formats[j] = newFormat; } } } /** * Sets the format to use for the format element with the given * format element index within the previously set pattern string. * The format element index is the zero-based number of the format * element counting from the start of the pattern string. * <p> * Since the order of format elements in a pattern string often * changes during localization, it is generally better to use the * {@link #setFormatByArgumentIndex setFormatByArgumentIndex} * method, which accesses format elements based on the argument * index they specify. * * @param formatElementIndex the index of a format element within the pattern * @param newFormat the format to use for the specified format element * @exception ArrayIndexOutOfBoundsException if {@code formatElementIndex} is equal to or * larger than the number of format elements in the pattern string */ public void setFormat(int formatElementIndex, Format newFormat) { formats[formatElementIndex] = newFormat; } /** * Gets the formats used for the values passed into * <code>format</code> methods or returned from <code>parse</code> * methods. The indices of elements in the returned array * correspond to the argument indices used in the previously set * pattern string. * The order of formats in the returned array thus corresponds to * the order of elements in the <code>arguments</code> array passed * to the <code>format</code> methods or the result array returned * by the <code>parse</code> methods. * <p> * If an argument index is used for more than one format element * in the pattern string, then the format used for the last such * 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. * * @return the formats used for the arguments within the pattern * @since 1.4 */ public Format[] getFormatsByArgumentIndex() { int maximumArgumentNumber = -1; for (int i = 0; i <= maxOffset; i++) { if (argumentNumbers[i] > maximumArgumentNumber) { maximumArgumentNumber = argumentNumbers[i]; } } Format[] resultArray = new Format[maximumArgumentNumber + 1]; for (int i = 0; i <= maxOffset; i++) { resultArray[argumentNumbers[i]] = formats[i]; } return resultArray; } /** * Gets the formats used for the format elements in the * previously set pattern string. * The order of formats in the returned array corresponds to * the order of format elements in the pattern string. * <p> * Since the order of format elements in a pattern string often * changes during localization, it's generally better to use the * {@link #getFormatsByArgumentIndex getFormatsByArgumentIndex} * method, which assumes an order of formats corresponding to the * order of elements in the <code>arguments</code> array passed to * the <code>format</code> methods or the result array returned by * the <code>parse</code> methods. * * @return the formats used for the format elements in the pattern */ public Format[] getFormats() { Format[] resultArray = new Format[maxOffset + 1]; System.arraycopy(formats, 0, resultArray, 0, maxOffset + 1); return resultArray; } /** * Formats an 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>. * <p> * The text substituted for the individual format elements is derived from * the current subformat of the format element and the * <code>arguments</code> element at the format element's argument index * as indicated by the first matching line of the following table. An * argument is <i>unavailable</i> if <code>arguments</code> is * <code>null</code> or has fewer than argumentIndex+1 elements. * <p> * <table border=1 summary="Examples of subformat,argument,and formatted text"> * <tr> * <th>Subformat * <th>Argument * <th>Formatted Text * <tr> * <td><i>any</i> * <td><i>unavailable</i> * <td><code>"{" + argumentIndex + "}"</code> * <tr> * <td><i>any</i> * <td><code>null</code> * <td><code>"null"</code> * <tr> * <td><code>instanceof ChoiceFormat</code> * <td><i>any</i> * <td><code>subformat.format(argument).indexOf('{') >= 0 ?<br> * (new MessageFormat(subformat.format(argument), getLocale())).format(argument) : * subformat.format(argument)</code> * <tr> * <td><code>!= null</code> * <td><i>any</i> * <td><code>subformat.format(argument)</code> * <tr> * <td><code>null</code> * <td><code>instanceof Number</code> * <td><code>NumberFormat.getInstance(getLocale()).format(argument)</code> * <tr> * <td><code>null</code> * <td><code>instanceof Date</code> * <td><code>DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, getLocale()).format(argument)</code> * <tr> * <td><code>null</code> * <td><code>instanceof String</code> * <td><code>argument</code> * <tr> * <td><code>null</code> * <td><i>any</i> * <td><code>argument.toString()</code> * </table> * <p> * If <code>pos</code> is non-null, and refers to * <code>Field.ARGUMENT</code>, the location of the first formatted * string will be returned. * * @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. * On output: the offsets of the alignment field. * @exception IllegalArgumentException if an argument in the * <code>arguments</code> array is not of the type * expected by the format element(s) that use it. */ public final StringBuffer format(Object[] arguments, StringBuffer result, 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 * <blockquote> * <code>(new {@link #MessageFormat(String) MessageFormat}(pattern)).{@link #format(java.lang.Object[], java.lang.StringBuffer, java.text.FieldPosition) format}(arguments, new StringBuffer(), null).toString()</code> * </blockquote> * * @exception IllegalArgumentException if the pattern is invalid, * or if an argument in the <code>arguments</code> array * is not of the type expected by the format element(s) * that use it. */ public static String format(String pattern, Object ... arguments) { MessageFormat temp = new MessageFormat(pattern); return temp.format(arguments); } // Overrides /** * Formats an 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 * <blockquote> * <code>{@link #format(java.lang.Object[], java.lang.StringBuffer, java.text.FieldPosition) format}((Object[]) arguments, result, pos)</code> * </blockquote> * * @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. * On output: the offsets of the alignment field. * @exception IllegalArgumentException if an argument in the * <code>arguments</code> array is not of the type * expected by the format element(s) that use it. */ public final StringBuffer format(Object arguments, StringBuffer result, FieldPosition pos) { return subformat((Object[]) arguments, result, pos, null); } /** * Formats an array of objects and inserts them into the * <code>MessageFormat</code>'s pattern, producing an * <code>AttributedCharacterIterator</code>. * You can use the returned <code>AttributedCharacterIterator</code> * to build the resulting String, as well as to determine information * about the resulting String. * <p> * The text of the returned <code>AttributedCharacterIterator</code> is * the same that would be returned by * <blockquote> * <code>{@link #format(java.lang.Object[], java.lang.StringBuffer, java.text.FieldPosition) format}(arguments, new StringBuffer(), null).toString()</code> * </blockquote> * <p> * In addition, the <code>AttributedCharacterIterator</code> contains at * least attributes indicating where text was generated from an * argument in the <code>arguments</code> array. The keys of these attributes are of * type <code>MessageFormat.Field</code>, their values are * <code>Integer</code> objects indicating the index in the <code>arguments</code> * array of the argument from which the text was generated. * <p> * The attributes/value from the underlying <code>Format</code> * instances that <code>MessageFormat</code> uses will also be * placed in the resulting <code>AttributedCharacterIterator</code>. * This allows you to not only find where an argument is placed in the * resulting String, but also which fields it contains in turn. * * @param arguments an array of objects to be formatted and substituted. * @return AttributedCharacterIterator describing the formatted value. * @exception NullPointerException if <code>arguments</code> is null. * @exception IllegalArgumentException if an argument in the * <code>arguments</code> array is not of the type * expected by the format element(s) that use it. * @since 1.4 */ public AttributedCharacterIterator formatToCharacterIterator(Object arguments) { StringBuffer result = new StringBuffer(); ArrayList iterators = new ArrayList(); if (arguments == null) { throw new NullPointerException( "formatToCharacterIterator must be passed non-null object"); } subformat((Object[]) arguments, result, null, iterators); if (iterators.size() == 0) { return createAttributedCharacterIterator(""); } return createAttributedCharacterIterator( (AttributedCharacterIterator[])iterators.toArray( new AttributedCharacterIterator[iterators.size()])); } /** * Parses the string. * * <p>Caveats: The parse may fail in a number of circumstances. * For example: * <ul> * <li>If one of the arguments does not occur in the pattern. * <li>If the format of an argument loses information, such as * with a choice format where a large number formats to "many". * <li>Does not yet handle recursion (where * the substituted strings contain {n} references.) * <li>Will not always find a match (or the correct match) * if some part of the parse is ambiguous. * For example, if the pattern "{1},{2}" is used with the * string arguments {"a,b", "c"}, it will format as "a,b,c". * When the result is parsed, it will return {"a", "b,c"}. * <li>If a single argument is parsed more than once in the string, * then the later parse wins. * </ul> * When the parse fails, use ParsePosition.getErrorIndex() to find out * where in the string the parsing failed. The returned error * index is the starting offset of the sub-patterns that the string * is comparing with. For example, if the parsing string "AAA {0} BBB" * is comparing against the pattern "AAD {0} BBB", the error index is * 0. When an error occurs, the call to this method will return null. * If the source is null, return an empty array. */ public Object[] parse(String source, ParsePosition pos) { if (source == null) { Object[] empty = {}; return empty; } int maximumArgumentNumber = -1; for (int i = 0; i <= maxOffset; i++) { if (argumentNumbers[i] > maximumArgumentNumber) { maximumArgumentNumber = argumentNumbers[i]; } } Object[] resultArray = new Object[maximumArgumentNumber + 1]; int patternOffset = 0; int sourceOffset = pos.index; ParsePosition tempStatus = new ParsePosition(0); for (int i = 0; i <= maxOffset; ++i) { // match up to format int len = offsets[i] - patternOffset; if (len == 0 || pattern.regionMatches(patternOffset, source, sourceOffset, len)) { sourceOffset += len; patternOffset += len; } else { pos.errorIndex = sourceOffset; return null; // leave index as is to signal error } // now use format if (formats[i] == null) { // string format // if at end, use longest possible match // otherwise uses first match to intervening string // does NOT recursively try all possibilities int tempLength = (i != maxOffset) ? offsets[i+1] : pattern.length(); int next; if (patternOffset >= tempLength) { next = source.length(); }else{ next = source.indexOf(pattern.substring(patternOffset, tempLength), sourceOffset); } if (next < 0) { pos.errorIndex = sourceOffset; return null; // leave index as is to signal error } else { String strValue= source.substring(sourceOffset,next); if (!strValue.equals("{"+argumentNumbers[i]+"}")) resultArray[argumentNumbers[i]] = source.substring(sourceOffset,next); sourceOffset = next; } } else { tempStatus.index = sourceOffset; resultArray[argumentNumbers[i]] = formats[i].parseObject(source,tempStatus); if (tempStatus.index == sourceOffset) {Lines 501–1000 of 1594. Previous lines Load more
break; } } } } if (braceStack == 0 && part != 0) { maxOffset = -1; throw new IllegalArgumentException("Unmatched braces in the pattern."); } this.pattern = segments[0].toString(); } /** * 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. * * @return a pattern representing the current state of the message format */ public String toPattern() { // later, make this more extensible int lastOffset = 0; StringBuilder result = new StringBuilder(); for (int i = 0; i <= maxOffset; ++i) { copyAndFixQuotes(pattern, lastOffset, offsets[i], result); lastOffset = offsets[i]; result.append('{').append(argumentNumbers[i]); Format fmt = formats[i]; if (fmt == null) { // do nothing, string format } else if (fmt instanceof NumberFormat) { if (fmt.equals(NumberFormat.getInstance(locale))) { result.append(",number"); } else if (fmt.equals(NumberFormat.getCurrencyInstance(locale))) { result.append(",number,currency"); } else if (fmt.equals(NumberFormat.getPercentInstance(locale))) { result.append(",number,percent"); } else if (fmt.equals(NumberFormat.getIntegerInstance(locale))) { result.append(",number,integer"); } else { if (fmt instanceof DecimalFormat) { result.append(",number,").append(((DecimalFormat)fmt).toPattern()); } else if (fmt instanceof ChoiceFormat) { result.append(",choice,").append(((ChoiceFormat)fmt).toPattern()); } else { // UNKNOWN } } } else if (fmt instanceof DateFormat) { int index; for (index = MODIFIER_DEFAULT; index < DATE_TIME_MODIFIERS.length; index++) { DateFormat df = DateFormat.getDateInstance(DATE_TIME_MODIFIERS[index], locale); if (fmt.equals(df)) { result.append(",date"); break; } df = DateFormat.getTimeInstance(DATE_TIME_MODIFIERS[index], locale); if (fmt.equals(df)) { result.append(",time"); break; } } if (index >= DATE_TIME_MODIFIERS.length) { if (fmt instanceof SimpleDateFormat) { result.append(",date,").append(((SimpleDateFormat)fmt).toPattern()); } else { // UNKNOWN } } else if (index != MODIFIER_DEFAULT) { result.append(',').append(DATE_TIME_MODIFIER_KEYWORDS[index]); } } else { //result.append(", unknown"); } result.append('}'); } copyAndFixQuotes(pattern, lastOffset, pattern.length(), result); return result.toString(); } /** * Sets the formats to use for the values passed into * <code>format</code> methods or returned from <code>parse</code> * methods. The indices of elements in <code>newFormats</code> * correspond to the argument indices used in the previously set * pattern string. * The order of formats in <code>newFormats</code> thus corresponds to * the order of elements in the <code>arguments</code> array passed * to the <code>format</code> methods or the result array returned * by the <code>parse</code> methods. * <p> * If an argument index is used for more than one format element * in the pattern string, then the corresponding new format is used * for all such format elements. If an argument index is not used * for any format element in the pattern string, then the * 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. * * @param newFormats the new formats to use * @exception NullPointerException if <code>newFormats</code> is null * @since 1.4 */ public void setFormatsByArgumentIndex(Format[] newFormats) { for (int i = 0; i <= maxOffset; i++) { int j = argumentNumbers[i]; if (j < newFormats.length) { formats[i] = newFormats[j]; } } } /** * Sets the formats to use for the format elements in the * previously set pattern string. * The order of formats in <code>newFormats</code> corresponds to * the order of format elements in the pattern string. * <p> * If more formats are provided than needed by the pattern string, * the remaining ones are ignored. If fewer formats are provided * than needed, then only the first <code>newFormats.length</code> * formats are replaced. * <p> * Since the order of format elements in a pattern string often * changes during localization, it is generally better to use the * {@link #setFormatsByArgumentIndex setFormatsByArgumentIndex} * method, which assumes an order of formats corresponding to the * order of elements in the <code>arguments</code> array passed to * the <code>format</code> methods or the result array returned by * the <code>parse</code> methods. * * @param newFormats the new formats to use * @exception NullPointerException if <code>newFormats</code> is null */ public void setFormats(Format[] newFormats) { int runsToCopy = newFormats.length; if (runsToCopy > maxOffset + 1) { runsToCopy = maxOffset + 1; } for (int i = 0; i < runsToCopy; i++) { formats[i] = newFormats[i]; } } /** * Sets the format to use for the format elements within the * previously set pattern string that use the given argument * index. * The argument index is part of the format element definition and * represents an index into the <code>arguments</code> array passed * to the <code>format</code> methods or the result array returned * by the <code>parse</code> methods. * <p> * If the argument index is used for more than one format element * 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. * * @param argumentIndex the argument index for which to use the new format * @param newFormat the new format to use * @since 1.4 */ public void setFormatByArgumentIndex(int argumentIndex, Format newFormat) { for (int j = 0; j <= maxOffset; j++) { if (argumentNumbers[j] == argumentIndex) { formats[j] = newFormat; } } } /** * Sets the format to use for the format element with the given * format element index within the previously set pattern string. * The format element index is the zero-based number of the format * element counting from the start of the pattern string. * <p> * Since the order of format elements in a pattern string often * changes during localization, it is generally better to use the * {@link #setFormatByArgumentIndex setFormatByArgumentIndex} * method, which accesses format elements based on the argument * index they specify. * * @param formatElementIndex the index of a format element within the pattern * @param newFormat the format to use for the specified format element * @exception ArrayIndexOutOfBoundsException if {@code formatElementIndex} is equal to or * larger than the number of format elements in the pattern string */ public void setFormat(int formatElementIndex, Format newFormat) { formats[formatElementIndex] = newFormat; } /** * Gets the formats used for the values passed into * <code>format</code> methods or returned from <code>parse</code> * methods. The indices of elements in the returned array * correspond to the argument indices used in the previously set * pattern string. * The order of formats in the returned array thus corresponds to * the order of elements in the <code>arguments</code> array passed * to the <code>format</code> methods or the result array returned * by the <code>parse</code> methods. * <p> * If an argument index is used for more than one format element * in the pattern string, then the format used for the last such * 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. * * @return the formats used for the arguments within the pattern * @since 1.4 */ public Format[] getFormatsByArgumentIndex() { int maximumArgumentNumber = -1; for (int i = 0; i <= maxOffset; i++) { if (argumentNumbers[i] > maximumArgumentNumber) { maximumArgumentNumber = argumentNumbers[i]; } } Format[] resultArray = new Format[maximumArgumentNumber + 1]; for (int i = 0; i <= maxOffset; i++) { resultArray[argumentNumbers[i]] = formats[i]; } return resultArray; } /** * Gets the formats used for the format elements in the * previously set pattern string. * The order of formats in the returned array corresponds to * the order of format elements in the pattern string. * <p> * Since the order of format elements in a pattern string often * changes during localization, it's generally better to use the * {@link #getFormatsByArgumentIndex getFormatsByArgumentIndex} * method, which assumes an order of formats corresponding to the * order of elements in the <code>arguments</code> array passed to * the <code>format</code> methods or the result array returned by * the <code>parse</code> methods. * * @return the formats used for the format elements in the pattern */ public Format[] getFormats() { Format[] resultArray = new Format[maxOffset + 1]; System.arraycopy(formats, 0, resultArray, 0, maxOffset + 1); return resultArray; } /** * Formats an 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>. * <p> * The text substituted for the individual format elements is derived from * the current subformat of the format element and the * <code>arguments</code> element at the format element's argument index * as indicated by the first matching line of the following table. An * argument is <i>unavailable</i> if <code>arguments</code> is * <code>null</code> or has fewer than argumentIndex+1 elements. * <p> * <table border=1 summary="Examples of subformat,argument,and formatted text"> * <tr> * <th>Subformat * <th>Argument * <th>Formatted Text * <tr> * <td><i>any</i> * <td><i>unavailable</i> * <td><code>"{" + argumentIndex + "}"</code> * <tr> * <td><i>any</i> * <td><code>null</code> * <td><code>"null"</code> * <tr> * <td><code>instanceof ChoiceFormat</code> * <td><i>any</i> * <td><code>subformat.format(argument).indexOf('{') >= 0 ?<br> * (new MessageFormat(subformat.format(argument), getLocale())).format(argument) : * subformat.format(argument)</code> * <tr> * <td><code>!= null</code> * <td><i>any</i> * <td><code>subformat.format(argument)</code> * <tr> * <td><code>null</code> * <td><code>instanceof Number</code> * <td><code>NumberFormat.getInstance(getLocale()).format(argument)</code> * <tr> * <td><code>null</code> * <td><code>instanceof Date</code> * <td><code>DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, getLocale()).format(argument)</code> * <tr> * <td><code>null</code> * <td><code>instanceof String</code> * <td><code>argument</code> * <tr> * <td><code>null</code> * <td><i>any</i> * <td><code>argument.toString()</code> * </table> * <p> * If <code>pos</code> is non-null, and refers to * <code>Field.ARGUMENT</code>, the location of the first formatted * string will be returned. * * @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. * On output: the offsets of the alignment field. * @exception IllegalArgumentException if an argument in the * <code>arguments</code> array is not of the type * expected by the format element(s) that use it. */ public final StringBuffer format(Object[] arguments, StringBuffer result, 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 * <blockquote> * <code>(new {@link #MessageFormat(String) MessageFormat}(pattern)).{@link #format(java.lang.Object[], java.lang.StringBuffer, java.text.FieldPosition) format}(arguments, new StringBuffer(), null).toString()</code> * </blockquote> * * @exception IllegalArgumentException if the pattern is invalid, * or if an argument in the <code>arguments</code> array * is not of the type expected by the format element(s) * that use it. */ public static String format(String pattern, Object ... arguments) { MessageFormat temp = new MessageFormat(pattern); return temp.format(arguments); } // Overrides /** * Formats an 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 * <blockquote> * <code>{@link #format(java.lang.Object[], java.lang.StringBuffer, java.text.FieldPosition) format}((Object[]) arguments, result, pos)</code> * </blockquote> * * @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. * On output: the offsets of the alignment field. * @exception IllegalArgumentException if an argument in the * <code>arguments</code> array is not of the type * expected by the format element(s) that use it. */ public final StringBuffer format(Object arguments, StringBuffer result, FieldPosition pos) { return subformat((Object[]) arguments, result, pos, null); } /** * Formats an array of objects and inserts them into the * <code>MessageFormat</code>'s pattern, producing an * <code>AttributedCharacterIterator</code>. * You can use the returned <code>AttributedCharacterIterator</code> * to build the resulting String, as well as to determine information * about the resulting String. * <p> * The text of the returned <code>AttributedCharacterIterator</code> is * the same that would be returned by * <blockquote> * <code>{@link #format(java.lang.Object[], java.lang.StringBuffer, java.text.FieldPosition) format}(arguments, new StringBuffer(), null).toString()</code> * </blockquote> * <p> * In addition, the <code>AttributedCharacterIterator</code> contains at * least attributes indicating where text was generated from an * argument in the <code>arguments</code> array. The keys of these attributes are of * type <code>MessageFormat.Field</code>, their values are * <code>Integer</code> objects indicating the index in the <code>arguments</code> * array of the argument from which the text was generated. * <p> * The attributes/value from the underlying <code>Format</code> * instances that <code>MessageFormat</code> uses will also be * placed in the resulting <code>AttributedCharacterIterator</code>. * This allows you to not only find where an argument is placed in the * resulting String, but also which fields it contains in turn. * * @param arguments an array of objects to be formatted and substituted. * @return AttributedCharacterIterator describing the formatted value. * @exception NullPointerException if <code>arguments</code> is null. * @exception IllegalArgumentException if an argument in the * <code>arguments</code> array is not of the type * expected by the format element(s) that use it. * @since 1.4 */ public AttributedCharacterIterator formatToCharacterIterator(Object arguments) { StringBuffer result = new StringBuffer(); ArrayList iterators = new ArrayList(); if (arguments == null) { throw new NullPointerException( "formatToCharacterIterator must be passed non-null object"); } subformat((Object[]) arguments, result, null, iterators); if (iterators.size() == 0) { return createAttributedCharacterIterator(""); } return createAttributedCharacterIterator( (AttributedCharacterIterator[])iterators.toArray( new AttributedCharacterIterator[iterators.size()])); } /** * Parses the string. * * <p>Caveats: The parse may fail in a number of circumstances. * For example: * <ul> * <li>If one of the arguments does not occur in the pattern. * <li>If the format of an argument loses information, such as * with a choice format where a large number formats to "many". * <li>Does not yet handle recursion (where * the substituted strings contain {n} references.) * <li>Will not always find a match (or the correct match) * if some part of the parse is ambiguous. * For example, if the pattern "{1},{2}" is used with the * string arguments {"a,b", "c"}, it will format as "a,b,c". * When the result is parsed, it will return {"a", "b,c"}. * <li>If a single argument is parsed more than once in the string, * then the later parse wins. * </ul> * When the parse fails, use ParsePosition.getErrorIndex() to find out * where in the string the parsing failed. The returned error * index is the starting offset of the sub-patterns that the string * is comparing with. For example, if the parsing string "AAA {0} BBB" * is comparing against the pattern "AAD {0} BBB", the error index is * 0. When an error occurs, the call to this method will return null. * If the source is null, return an empty array. */ public Object[] parse(String source, ParsePosition pos) { if (source == null) { Object[] empty = {}; return empty; } int maximumArgumentNumber = -1; for (int i = 0; i <= maxOffset; i++) { if (argumentNumbers[i] > maximumArgumentNumber) { maximumArgumentNumber = argumentNumbers[i]; } } Object[] resultArray = new Object[maximumArgumentNumber + 1]; int patternOffset = 0; int sourceOffset = pos.index; ParsePosition tempStatus = new ParsePosition(0); for (int i = 0; i <= maxOffset; ++i) { // match up to format int len = offsets[i] - patternOffset; if (len == 0 || pattern.regionMatches(patternOffset, source, sourceOffset, len)) { sourceOffset += len; patternOffset += len; } else { pos.errorIndex = sourceOffset; return null; // leave index as is to signal error } // now use format if (formats[i] == null) { // string format // if at end, use longest possible match // otherwise uses first match to intervening string // does NOT recursively try all possibilities int tempLength = (i != maxOffset) ? offsets[i+1] : pattern.length(); int next; if (patternOffset >= tempLength) { next = source.length(); }else{ next = source.indexOf(pattern.substring(patternOffset, tempLength), sourceOffset); } if (next < 0) { pos.errorIndex = sourceOffset; return null; // leave index as is to signal error } else { String strValue= source.substring(sourceOffset,next); if (!strValue.equals("{"+argumentNumbers[i]+"}")) resultArray[argumentNumbers[i]] = source.substring(sourceOffset,next); sourceOffset = next; } } else { tempStatus.index = sourceOffset; resultArray[argumentNumbers[i]] = formats[i].parseObject(source,tempStatus); if (tempStatus.index == sourceOffset) {