1594 lines · 66.6 KB · Java
RawDownload
                            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