From 1f6461426733ebf74be8e451c0b4d5b72710e800 Mon Sep 17 00:00:00 2001 From: Guilhem Lavaux Date: Tue, 4 May 2004 22:05:25 +0000 Subject: [PATCH] MessageFormat.java: (class Field): New class. 2004-05-05 Guilhem Lavaux * java/text/MessageFormat.java: (class Field): New class. (formatToCharacterIterator): New method. (format): Use formatInternal now. (formatInternal): New method. String formatter should be done here (with attributes). Attributes merging supported. (parse): More documentation. (getFormatsByArgumentIndex): New method. (setFormatByArgumentIndex): New method. (setFormatsByArgumentIndex): New method. From-SVN: r81492 --- libjava/ChangeLog | 13 ++ libjava/java/text/MessageFormat.java | 195 +++++++++++++++++++++++++-- 2 files changed, 199 insertions(+), 9 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 91080fffb80..ad5a349306a 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,16 @@ +2004-05-05 Guilhem Lavaux + + * java/text/MessageFormat.java: + (class Field): New class. + (formatToCharacterIterator): New method. + (format): Use formatInternal now. + (formatInternal): New method. String formatter should + be done here (with attributes). Attributes merging supported. + (parse): More documentation. + (getFormatsByArgumentIndex): New method. + (setFormatByArgumentIndex): New method. + (setFormatsByArgumentIndex): New method. + 2004-05-05 Guilhem Lavaux * java/text/DecimalFormat.java diff --git a/libjava/java/text/MessageFormat.java b/libjava/java/text/MessageFormat.java index 7bb7760c90e..2e1786da986 100644 --- a/libjava/java/text/MessageFormat.java +++ b/libjava/java/text/MessageFormat.java @@ -38,7 +38,11 @@ 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; @@ -145,6 +149,43 @@ public class MessageFormat extends Format { 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 Field("argument"); + + // For deserialization + private Field() + { + super(""); + } + + private 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. @@ -320,6 +361,22 @@ public class MessageFormat extends Format && 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. * @@ -331,7 +388,7 @@ public class MessageFormat extends Format MessageFormat mf = new MessageFormat (pattern); StringBuffer sb = new StringBuffer (); FieldPosition fp = new FieldPosition (NumberFormat.INTEGER_FIELD); - return mf.format(arguments, sb, fp).toString(); + return mf.formatInternal(arguments, sb, fp, null).toString(); } /** @@ -342,9 +399,18 @@ public class MessageFormat extends Format * @param fp A FieldPosition object (it is ignored). */ public final StringBuffer format (Object arguments[], StringBuffer appendBuf, - FieldPosition ignore) + FieldPosition fp) + { + return formatInternal(arguments, appendBuf, fp, null); + } + + protected final 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) { @@ -352,8 +418,13 @@ public class MessageFormat extends Format throw new IllegalArgumentException("Not enough arguments given"); Object 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 (elements[i].setFormat != null) formatter = elements[i].setFormat; else if (elements[i].format != null) @@ -371,25 +442,56 @@ public class MessageFormat extends Format 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, ignore); + formatter.format(thisArg, buf, fp); MessageFormat mf = new MessageFormat (); mf.setLocale(locale); mf.applyPattern(buf.toString()); - mf.format(arguments, appendBuf, ignore); + mf.format(arguments, appendBuf, fp); } else - formatter.format(thisArg, appendBuf, ignore); + { + 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; } @@ -398,10 +500,10 @@ public class MessageFormat extends Format * * @param source The object to be formatted. * @param result The StringBuffer where the text is appened. - * @param fp A FieldPosition object (it is ignored). + * @param fpos A FieldPosition object (it is ignored). */ public final StringBuffer format (Object singleArg, StringBuffer appendBuf, - FieldPosition ignore) + FieldPosition fpos) { Object[] args; @@ -416,7 +518,7 @@ public class MessageFormat extends Format args = new Object[1]; args[0] = singleArg; } - return format (args, appendBuf, ignore); + return format (args, appendBuf, fpos); } /** @@ -478,6 +580,15 @@ public class MessageFormat extends Format applyPattern (pattern); } + /** + * Parse a string sourceStr 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. @@ -628,6 +739,72 @@ public class MessageFormat extends Format 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 setFormat or setFormatByArgumentIndex + * then it returns it at the right index. If not it uses the detected + * formatters during a format 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 format + * 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 argNumMax) + argNumMax = elements[i].argNumber; + + Format[] formats = new Format[argNumMax]; + for (int i=0;i