| /* MessageFormat.java - Localized message formatting. | |
| Copyright (C) 1999, 2001, 2002, 2004, 2005 Free Software Foundation, Inc. | |
| This file is part of GNU Classpath. | |
| GNU Classpath is free software; you can redistribute it and/or modify | |
| it under the terms of the GNU General Public License as published by | |
| the Free Software Foundation; either version 2, or (at your option) | |
| any later version. | |
| GNU Classpath is distributed in the hope that it will be useful, but | |
| WITHOUT ANY WARRANTY; without even the implied warranty of | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| General Public License for more details. | |
| You should have received a copy of the GNU General Public License | |
| along with GNU Classpath; see the file COPYING. If not, write to the | |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | |
| 02110-1301 USA. | |
| Linking this library statically or dynamically with other modules is | |
| making a combined work based on this library. Thus, the terms and | |
| conditions of the GNU General Public License cover the whole | |
| combination. | |
| As a special exception, the copyright holders of this library give you | |
| permission to link this library with independent modules to produce an | |
| executable, regardless of the license terms of these independent | |
| modules, and to copy and distribute the resulting executable under | |
| terms of your choice, provided that you also meet, for each linked | |
| independent module, the terms and conditions of the license of that | |
| module. An independent module is a module which is not derived from | |
| or based on this library. If you modify this library, you may extend | |
| this exception to your version of the library, but you are not | |
| obligated to do so. If you do not wish to do so, delete this | |
| exception statement from your version. */ | |
| package java.text; | |
| import gnu.java.text.FormatCharacterIterator; | |
| import java.io.InvalidObjectException; | |
| import java.util.Date; | |
| import java.util.HashMap; | |
| import java.util.Locale; | |
| import java.util.Vector; | |
| public class MessageFormat extends Format | |
| { | |
| /** | |
| * @author Tom Tromey (tromey@cygnus.com) | |
| * @author Jorge Aliss (jaliss@hotmail.com) | |
| * @date March 3, 1999 | |
| */ | |
| /* Written using "Java Class Libraries", 2nd edition, plus online | |
| * API docs for JDK 1.2 from http://www.javasoft.com. | |
| * Status: Believed complete and correct to 1.2, except serialization. | |
| * and parsing. | |
| */ | |
| private static final class MessageFormatElement | |
| { | |
| // Argument number. | |
| int argNumber; | |
| // Formatter to be used. This is the format set by setFormat. | |
| Format setFormat; | |
| // Formatter to be used based on the type. | |
| Format format; | |
| // Argument will be checked to make sure it is an instance of this | |
| // class. | |
| Class formatClass; | |
| // Formatter type. | |
| String type; | |
| // Formatter style. | |
| String style; | |
| // Text to follow this element. | |
| String trailer; | |
| // Recompute the locale-based formatter. | |
| void setLocale (Locale loc) | |
| { | |
| if (type == null) | |
| ; | |
| else if (type.equals("number")) | |
| { | |
| formatClass = java.lang.Number.class; | |
| if (style == null) | |
| format = NumberFormat.getInstance(loc); | |
| else if (style.equals("currency")) | |
| format = NumberFormat.getCurrencyInstance(loc); | |
| else if (style.equals("percent")) | |
| format = NumberFormat.getPercentInstance(loc); | |
| else if (style.equals("integer")) | |
| { | |
| NumberFormat nf = NumberFormat.getNumberInstance(loc); | |
| nf.setMaximumFractionDigits(0); | |
| nf.setGroupingUsed(false); | |
| format = nf; | |
| } | |
| else | |
| { | |
| format = NumberFormat.getNumberInstance(loc); | |
| DecimalFormat df = (DecimalFormat) format; | |
| df.applyPattern(style); | |
| } | |
| } | |
| else if (type.equals("time") || type.equals("date")) | |
| { | |
| formatClass = java.util.Date.class; | |
| int val = DateFormat.DEFAULT; | |
| boolean styleIsPattern = false; | |
| if (style == null) | |
| ; | |
| else if (style.equals("short")) | |
| val = DateFormat.SHORT; | |
| else if (style.equals("medium")) | |
| val = DateFormat.MEDIUM; | |
| else if (style.equals("long")) | |
| val = DateFormat.LONG; | |
| else if (style.equals("full")) | |
| val = DateFormat.FULL; | |
| else | |
| styleIsPattern = true; | |
| if (type.equals("time")) | |
| format = DateFormat.getTimeInstance(val, loc); | |
| else | |
| format = DateFormat.getDateInstance(val, loc); | |
| if (styleIsPattern) | |
| { | |
| SimpleDateFormat sdf = (SimpleDateFormat) format; | |
| sdf.applyPattern(style); | |
| } | |
| } | |
| else if (type.equals("choice")) | |
| { | |
| formatClass = java.lang.Number.class; | |
| if (style == null) | |
| throw new | |
| IllegalArgumentException ("style required for choice format"); | |
| format = new ChoiceFormat (style); | |
| } | |
| } | |
| } | |
| private static final long serialVersionUID = 6479157306784022952L; | |
| public static class Field extends Format.Field | |
| { | |
| static final long serialVersionUID = 7899943957617360810L; | |
| /** | |
| * This is the attribute set for all characters produced | |
| * by MessageFormat during a formatting. | |
| */ | |
| public static final MessageFormat.Field ARGUMENT = new MessageFormat.Field("argument"); | |
| // For deserialization | |
| private Field() | |
| { | |
| super(""); | |
| } | |
| protected Field(String s) | |
| { | |
| super(s); | |
| } | |
| /** | |
| * invoked to resolve the true static constant by | |
| * comparing the deserialized object to know name. | |
| * | |
| * @return object constant | |
| */ | |
| protected Object readResolve() throws InvalidObjectException | |
| { | |
| if (getName().equals(ARGUMENT.getName())) | |
| return ARGUMENT; | |
| throw new InvalidObjectException("no such MessageFormat field called " + getName()); | |
| } | |
| } | |
| // Helper that returns the text up to the next format opener. The | |
| // text is put into BUFFER. Returns index of character after end of | |
| // string. Throws IllegalArgumentException on error. | |
| private static int scanString(String pat, int index, StringBuffer buffer) | |
| { | |
| int max = pat.length(); | |
| buffer.setLength(0); | |
| boolean quoted = false; | |
| for (; index < max; ++index) | |
| { | |
| char c = pat.charAt(index); | |
| if (quoted) | |
| { | |
| // In a quoted context, a single quote ends the quoting. | |
| if (c == '\'') | |
| quoted = false; | |
| else | |
| buffer.append(c); | |
| } | |
| // Check for '', which is a single quote. | |
| else if (c == '\'' && index + 1 < max && pat.charAt(index + 1) == '\'') | |
| { | |
| buffer.append(c); | |
| ++index; | |
| } | |
| else if (c == '\'') | |
| { | |
| // Start quoting. | |
| quoted = true; | |
| } | |
| else if (c == '{') | |
| break; | |
| else | |
| buffer.append(c); | |
| } | |
| // Note that we explicitly allow an unterminated quote. This is | |
| // done for compatibility. | |
| return index; | |
| } | |
| // This helper retrieves a single part of a format element. Returns | |
| // the index of the terminating character. | |
| private static int scanFormatElement(String pat, int index, | |
| StringBuffer buffer, char term) | |
| { | |
| int max = pat.length(); | |
| buffer.setLength(0); | |
| int brace_depth = 1; | |
| boolean quoted = false; | |
| for (; index < max; ++index) | |
| { | |
| char c = pat.charAt(index); | |
| // First see if we should turn off quoting. | |
| if (quoted) | |
| { | |
| if (c == '\'') | |
| quoted = false; | |
| // In both cases we fall through to inserting the | |
| // character here. | |
| } | |
| // See if we have just a plain quote to insert. | |
| else if (c == '\'' && index + 1 < max | |
| && pat.charAt(index + 1) == '\'') | |
| { | |
| buffer.append(c); | |
| ++index; | |
| } | |
| // See if quoting should turn on. | |
| else if (c == '\'') | |
| quoted = true; | |
| else if (c == '{') | |
| ++brace_depth; | |
| else if (c == '}') | |
| { | |
| if (--brace_depth == 0) | |
| break; | |
| } | |
| // Check for TERM after braces, because TERM might be `}'. | |
| else if (c == term) | |
| break; | |
| // All characters, including opening and closing quotes, are | |
| // inserted here. | |
| buffer.append(c); | |
| } | |
| return index; | |
| } | |
| // This is used to parse a format element and whatever non-format | |
| // text might trail it. | |
| private static int scanFormat(String pat, int index, StringBuffer buffer, | |
| Vector elts, Locale locale) | |
| { | |
| MessageFormatElement mfe = new MessageFormatElement (); | |
| elts.addElement(mfe); | |
| int max = pat.length(); | |
| // Skip the opening `{'. | |
| ++index; | |
| // Fetch the argument number. | |
| index = scanFormatElement (pat, index, buffer, ','); | |
| try | |
| { | |
| mfe.argNumber = Integer.parseInt(buffer.toString()); | |
| } | |
| catch (NumberFormatException nfx) | |
| { | |
| IllegalArgumentException iae = new IllegalArgumentException(pat); | |
| iae.initCause(nfx); | |
| throw iae; | |
| } | |
| // Extract the element format. | |
| if (index < max && pat.charAt(index) == ',') | |
| { | |
| index = scanFormatElement (pat, index + 1, buffer, ','); | |
| mfe.type = buffer.toString(); | |
| // Extract the style. | |
| if (index < max && pat.charAt(index) == ',') | |
| { | |
| index = scanFormatElement (pat, index + 1, buffer, '}'); | |
| mfe.style = buffer.toString (); | |
| } | |
| } | |
| // Advance past the last terminator. | |
| if (index >= max || pat.charAt(index) != '}') | |
| throw new IllegalArgumentException("Missing '}' at end of message format"); | |
| ++index; | |
| // Now fetch trailing string. | |
| index = scanString (pat, index, buffer); | |
| mfe.trailer = buffer.toString (); | |
| mfe.setLocale(locale); | |
| return index; | |
| } | |
| /** | |
| * Applies the specified pattern to this MessageFormat. | |
| * | |
| * @param newPattern The Pattern | |
| */ | |
| public void applyPattern (String newPattern) | |
| { | |
| pattern = newPattern; | |
| StringBuffer tempBuffer = new StringBuffer (); | |
| int index = scanString (newPattern, 0, tempBuffer); | |
| leader = tempBuffer.toString(); | |
| Vector elts = new Vector (); | |
| while (index < newPattern.length()) | |
| index = scanFormat (newPattern, index, tempBuffer, elts, locale); | |
| elements = new MessageFormatElement[elts.size()]; | |
| elts.copyInto(elements); | |
| } | |
| /** | |
| * Overrides Format.clone() | |
| */ | |
| public Object clone () | |
| { | |
| MessageFormat c = (MessageFormat) super.clone (); | |
| c.elements = (MessageFormatElement[]) elements.clone (); | |
| return c; | |
| } | |
| /** | |
| * Overrides Format.equals(Object obj) | |
| */ | |
| public boolean equals (Object obj) | |
| { | |
| if (! (obj instanceof MessageFormat)) | |
| return false; | |
| MessageFormat mf = (MessageFormat) obj; | |
| return (pattern.equals(mf.pattern) | |
| && locale.equals(mf.locale)); | |
| } | |
| /** | |
| * A convinience method to format patterns. | |
| * | |
| * @param arguments The array containing the objects to be formatted. | |
| */ | |
| public AttributedCharacterIterator formatToCharacterIterator (Object arguments) | |
| { | |
| Object[] arguments_array = (Object[])arguments; | |
| FormatCharacterIterator iterator = new FormatCharacterIterator(); | |
| formatInternal(arguments_array, new StringBuffer(), null, iterator); | |
| return iterator; | |
| } | |
| /** | |
| * A convinience method to format patterns. | |
| * | |
| * @param pattern The pattern used when formatting. | |
| * @param arguments The array containing the objects to be formatted. | |
| */ | |
| public static String format (String pattern, Object arguments[]) | |
| { | |
| MessageFormat mf = new MessageFormat (pattern); | |
| StringBuffer sb = new StringBuffer (); | |
| FieldPosition fp = new FieldPosition (NumberFormat.INTEGER_FIELD); | |
| return mf.formatInternal(arguments, sb, fp, null).toString(); | |
| } | |
| /** | |
| * Returns the pattern with the formatted objects. | |
| * | |
| * @param arguments The array containing the objects to be formatted. | |
| * @param appendBuf The StringBuffer where the text is appened. | |
| * @param fp A FieldPosition object (it is ignored). | |
| */ | |
| public final StringBuffer format (Object arguments[], StringBuffer appendBuf, | |
| FieldPosition fp) | |
| { | |
| return formatInternal(arguments, appendBuf, fp, null); | |
| } | |
| private StringBuffer formatInternal (Object arguments[], | |
| StringBuffer appendBuf, | |
| FieldPosition fp, | |
| FormatCharacterIterator output_iterator) | |
| { | |
| appendBuf.append(leader); | |
| if (output_iterator != null) | |
| output_iterator.append(leader); | |
| for (int i = 0; i < elements.length; ++i) | |
| { | |
| Object thisArg = null; | |
| boolean unavailable = false; | |
| if (arguments == null || elements[i].argNumber >= arguments.length) | |
| unavailable = true; | |
| else | |
| thisArg = arguments[elements[i].argNumber]; | |
| AttributedCharacterIterator iterator = null; | |
| Format formatter = null; | |
| if (fp != null && i == fp.getField() && fp.getFieldAttribute() == Field.ARGUMENT) | |
| fp.setBeginIndex(appendBuf.length()); | |
| if (unavailable) | |
| appendBuf.append("{" + elements[i].argNumber + "}"); | |
| else | |
| { | |
| if (elements[i].setFormat != null) | |
| formatter = elements[i].setFormat; | |
| else if (elements[i].format != null) | |
| { | |
| if (elements[i].formatClass != null | |
| && ! elements[i].formatClass.isInstance(thisArg)) | |
| throw new IllegalArgumentException("Wrong format class"); | |
| formatter = elements[i].format; | |
| } | |
| else if (thisArg instanceof Number) | |
| formatter = NumberFormat.getInstance(locale); | |
| else if (thisArg instanceof Date) | |
| formatter = DateFormat.getTimeInstance(DateFormat.DEFAULT, locale); | |
| else | |
| appendBuf.append(thisArg); | |
| } | |
| if (fp != null && fp.getField() == i && fp.getFieldAttribute() == Field.ARGUMENT) | |
| fp.setEndIndex(appendBuf.length()); | |
| if (formatter != null) | |
| { | |
| // Special-case ChoiceFormat. | |
| if (formatter instanceof ChoiceFormat) | |
| { | |
| StringBuffer buf = new StringBuffer (); | |
| formatter.format(thisArg, buf, fp); | |
| MessageFormat mf = new MessageFormat (); | |
| mf.setLocale(locale); | |
| mf.applyPattern(buf.toString()); | |
| mf.format(arguments, appendBuf, fp); | |
| } | |
| else | |
| { | |
| if (output_iterator != null) | |
| iterator = formatter.formatToCharacterIterator(thisArg); | |
| else | |
| formatter.format(thisArg, appendBuf, fp); | |
| } | |
| elements[i].format = formatter; | |
| } | |
| if (output_iterator != null) | |
| { | |
| HashMap hash_argument = new HashMap(); | |
| int position = output_iterator.getEndIndex(); | |
| hash_argument.put (MessageFormat.Field.ARGUMENT, | |
| new Integer(elements[i].argNumber)); | |
| if (iterator != null) | |
| { | |
| output_iterator.append(iterator); | |
| output_iterator.addAttributes(hash_argument, position, | |
| output_iterator.getEndIndex()); | |
| } | |
| else | |
| output_iterator.append(thisArg.toString(), hash_argument); | |
| output_iterator.append(elements[i].trailer); | |
| } | |
| appendBuf.append(elements[i].trailer); | |
| } | |
| return appendBuf; | |
| } | |
| /** | |
| * Returns the pattern with the formatted objects. The first argument | |
| * must be a array of Objects. | |
| * This is equivalent to format((Object[]) objectArray, appendBuf, fpos) | |
| * | |
| * @param objectArray The object array to be formatted. | |
| * @param appendBuf The StringBuffer where the text is appened. | |
| * @param fpos A FieldPosition object (it is ignored). | |
| */ | |
| public final StringBuffer format (Object objectArray, StringBuffer appendBuf, | |
| FieldPosition fpos) | |
| { | |
| return format ((Object[])objectArray, appendBuf, fpos); | |
| } | |
| /** | |
| * Returns an array with the Formats for | |
| * the arguments. | |
| */ | |
| public Format[] getFormats () | |
| { | |
| Format[] f = new Format[elements.length]; | |
| for (int i = elements.length - 1; i >= 0; --i) | |
| f[i] = elements[i].setFormat; | |
| return f; | |
| } | |
| /** | |
| * Returns the locale. | |
| */ | |
| public Locale getLocale () | |
| { | |
| return locale; | |
| } | |
| /** | |
| * Overrides Format.hashCode() | |
| */ | |
| public int hashCode () | |
| { | |
| // FIXME: not a very good hash. | |
| return pattern.hashCode() + locale.hashCode(); | |
| } | |
| private MessageFormat () | |
| { | |
| } | |
| /** | |
| * Creates a new MessageFormat object with | |
| * the specified pattern | |
| * | |
| * @param pattern The Pattern | |
| */ | |
| public MessageFormat(String pattern) | |
| { | |
| this(pattern, Locale.getDefault()); | |
| } | |
| /** | |
| * Creates a new MessageFormat object with | |
| * the specified pattern | |
| * | |
| * @param pattern The Pattern | |
| * @param locale The Locale to use | |
| * | |
| * @since 1.4 | |
| */ | |
| public MessageFormat(String pattern, Locale locale) | |
| { | |
| this.locale = locale; | |
| applyPattern (pattern); | |
| } | |
| /** | |
| * Parse a string <code>sourceStr</code> against the pattern specified | |
| * to the MessageFormat constructor. | |
| * | |
| * @param sourceStr the string to be parsed. | |
| * @param pos the current parse position (and eventually the error position). | |
| * @return the array of parsed objects sorted according to their argument number | |
| * in the pattern. | |
| */ | |
| public Object[] parse (String sourceStr, ParsePosition pos) | |
| { | |
| // Check initial text. | |
| int index = pos.getIndex(); | |
| if (! sourceStr.startsWith(leader, index)) | |
| { | |
| pos.setErrorIndex(index); | |
| return null; | |
| } | |
| index += leader.length(); | |
| Vector results = new Vector (elements.length, 1); | |
| // Now check each format. | |
| for (int i = 0; i < elements.length; ++i) | |
| { | |
| Format formatter = null; | |
| if (elements[i].setFormat != null) | |
| formatter = elements[i].setFormat; | |
| else if (elements[i].format != null) | |
| formatter = elements[i].format; | |
| Object value = null; | |
| if (formatter instanceof ChoiceFormat) | |
| { | |
| // We must special-case a ChoiceFormat because it might | |
| // have recursive formatting. | |
| ChoiceFormat cf = (ChoiceFormat) formatter; | |
| String[] formats = (String[]) cf.getFormats(); | |
| double[] limits = (double[]) cf.getLimits(); | |
| MessageFormat subfmt = new MessageFormat (); | |
| subfmt.setLocale(locale); | |
| ParsePosition subpos = new ParsePosition (index); | |
| int j; | |
| for (j = 0; value == null && j < limits.length; ++j) | |
| { | |
| subfmt.applyPattern(formats[j]); | |
| subpos.setIndex(index); | |
| value = subfmt.parse(sourceStr, subpos); | |
| } | |
| if (value != null) | |
| { | |
| index = subpos.getIndex(); | |
| value = new Double (limits[j]); | |
| } | |
| } | |
| else if (formatter != null) | |
| { | |
| pos.setIndex(index); | |
| value = formatter.parseObject(sourceStr, pos); | |
| if (value != null) | |
| index = pos.getIndex(); | |
| } | |
| else | |
| { | |
| // We have a String format. This can lose in a number | |
| // of ways, but we give it a shot. | |
| int next_index; | |
| if (elements[i].trailer.length() > 0) | |
| next_index = sourceStr.indexOf(elements[i].trailer, index); | |
| else | |
| next_index = sourceStr.length(); | |
| if (next_index == -1) | |
| { | |
| pos.setErrorIndex(index); | |
| return null; | |
| } | |
| value = sourceStr.substring(index, next_index); | |
| index = next_index; | |
| } | |
| if (value == null | |
| || ! sourceStr.startsWith(elements[i].trailer, index)) | |
| { | |
| pos.setErrorIndex(index); | |
| return null; | |
| } | |
| if (elements[i].argNumber >= results.size()) | |
| results.setSize(elements[i].argNumber + 1); | |
| results.setElementAt(value, elements[i].argNumber); | |
| index += elements[i].trailer.length(); | |
| } | |
| Object[] r = new Object[results.size()]; | |
| results.copyInto(r); | |
| return r; | |
| } | |
| public Object[] parse (String sourceStr) throws ParseException | |
| { | |
| ParsePosition pp = new ParsePosition (0); | |
| Object[] r = parse (sourceStr, pp); | |
| if (r == null) | |
| throw new ParseException ("couldn't parse string", pp.getErrorIndex()); | |
| return r; | |
| } | |
| public Object parseObject (String sourceStr, ParsePosition pos) | |
| { | |
| return parse (sourceStr, pos); | |
| } | |
| /** | |
| * Sets the format for the argument at an specified | |
| * index. | |
| * | |
| * @param variableNum The index. | |
| * @param newFormat The Format object. | |
| */ | |
| public void setFormat (int variableNum, Format newFormat) | |
| { | |
| elements[variableNum].setFormat = newFormat; | |
| } | |
| /** | |
| * Sets the formats for the arguments. | |
| * | |
| * @param newFormats An array of Format objects. | |
| */ | |
| public void setFormats (Format[] newFormats) | |
| { | |
| if (newFormats.length < elements.length) | |
| throw new IllegalArgumentException("Not enough format objects"); | |
| int len = Math.min(newFormats.length, elements.length); | |
| for (int i = 0; i < len; ++i) | |
| elements[i].setFormat = newFormats[i]; | |
| } | |
| /** | |
| * Sets the locale. | |
| * | |
| * @param loc A Locale | |
| */ | |
| public void setLocale (Locale loc) | |
| { | |
| locale = loc; | |
| if (elements != null) | |
| { | |
| for (int i = 0; i < elements.length; ++i) | |
| elements[i].setLocale(loc); | |
| } | |
| } | |
| /** | |
| * Returns the pattern. | |
| */ | |
| public String toPattern () | |
| { | |
| return pattern; | |
| } | |
| /** | |
| * Return the formatters used sorted by argument index. It uses the | |
| * internal table to fill in this array: if a format has been | |
| * set using <code>setFormat</code> or <code>setFormatByArgumentIndex</code> | |
| * then it returns it at the right index. If not it uses the detected | |
| * formatters during a <code>format</code> call. If nothing is known | |
| * about that argument index it just puts null at that position. | |
| * To get useful informations you may have to call <code>format</code> | |
| * at least once. | |
| * | |
| * @return an array of formatters sorted by argument index. | |
| */ | |
| public Format[] getFormatsByArgumentIndex() | |
| { | |
| int argNumMax = 0; | |
| // First, find the greatest argument number. | |
| for (int i=0;i<elements.length;i++) | |
| if (elements[i].argNumber > argNumMax) | |
| argNumMax = elements[i].argNumber; | |
| Format[] formats = new Format[argNumMax]; | |
| for (int i=0;i<elements.length;i++) | |
| { | |
| if (elements[i].setFormat != null) | |
| formats[elements[i].argNumber] = elements[i].setFormat; | |
| else if (elements[i].format != null) | |
| formats[elements[i].argNumber] = elements[i].format; | |
| } | |
| return formats; | |
| } | |
| /** | |
| * Set the format to used using the argument index number. | |
| * | |
| * @param argumentIndex the argument index. | |
| * @param newFormat the format to use for this argument. | |
| */ | |
| public void setFormatByArgumentIndex(int argumentIndex, | |
| Format newFormat) | |
| { | |
| for (int i=0;i<elements.length;i++) | |
| { | |
| if (elements[i].argNumber == argumentIndex) | |
| elements[i].setFormat = newFormat; | |
| } | |
| } | |
| /** | |
| * Set the format for argument using a specified array of formatters | |
| * which is sorted according to the argument index. If the number of | |
| * elements in the array is fewer than the number of arguments only | |
| * the arguments specified by the array are touched. | |
| * | |
| * @param newFormats array containing the new formats to set. | |
| * | |
| * @throws NullPointerException if newFormats is null | |
| */ | |
| public void setFormatsByArgumentIndex(Format[] newFormats) | |
| { | |
| for (int i=0;i<newFormats.length;i++) | |
| { | |
| // Nothing better than that can exist here. | |
| setFormatByArgumentIndex(i, newFormats[i]); | |
| } | |
| } | |
| // The pattern string. | |
| private String pattern; | |
| // The locale. | |
| private Locale locale; | |
| // Variables. | |
| private MessageFormatElement[] elements; | |
| // Leader text. | |
| private String leader; | |
| } |