diff options
Diffstat (limited to 'libjava/java/text/MessageFormat.java')
-rw-r--r-- | libjava/java/text/MessageFormat.java | 832 |
1 files changed, 0 insertions, 832 deletions
diff --git a/libjava/java/text/MessageFormat.java b/libjava/java/text/MessageFormat.java deleted file mode 100644 index f7a9f1687a6..00000000000 --- a/libjava/java/text/MessageFormat.java +++ /dev/null @@ -1,832 +0,0 @@ -/* 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 aPattern 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 aPattern The pattern used when formatting. - * @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 aPattern 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 source The array containing the objects to be formatted. - * @param result 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 index The index. - * @format The Format object. - */ - public void setFormat (int variableNum, Format newFormat) - { - elements[variableNum].setFormat = newFormat; - } - - /** - * Sets the formats for the arguments. - * - * @param formats 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 locale 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; -} |