diff --git a/src/java/org/apache/commons/lang/text/ChoiceMetaFormat.java b/src/java/org/apache/commons/lang/text/ChoiceMetaFormat.java index 4a36ac3c0..ed8cf3054 100644 --- a/src/java/org/apache/commons/lang/text/ChoiceMetaFormat.java +++ b/src/java/org/apache/commons/lang/text/ChoiceMetaFormat.java @@ -43,11 +43,8 @@ public class ChoiceMetaFormat extends MetaFormatSupport { super(); } - /* - * (non-Javadoc) - * - * @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer, - * java.text.FieldPosition) + /** + * {@inheritDoc} */ public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { @@ -57,11 +54,8 @@ public class ChoiceMetaFormat extends MetaFormatSupport { throw new IllegalArgumentException(String.valueOf(obj)); } - /* - * (non-Javadoc) - * - * @see java.text.Format#parseObject(java.lang.String, - * java.text.ParsePosition) + /** + * {@inheritDoc} */ public Object parseObject(String source, ParsePosition pos) { int start = pos.getIndex(); diff --git a/src/java/org/apache/commons/lang/text/CompositeFormat.java b/src/java/org/apache/commons/lang/text/CompositeFormat.java index 36a0ef1da..569b8b963 100644 --- a/src/java/org/apache/commons/lang/text/CompositeFormat.java +++ b/src/java/org/apache/commons/lang/text/CompositeFormat.java @@ -56,8 +56,15 @@ public class CompositeFormat extends Format { } /** - * Uses the formatter Format instance. - * + * Uses the formatter Format instance. + * + * @param obj + * the object to format + * @param toAppendTo + * the {@link StringBuffer} to append to + * @param pos + * the FieldPosition to use (or ignore). + * @return toAppendTo * @see Format#format(Object, StringBuffer, FieldPosition) */ public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { @@ -65,8 +72,15 @@ public class CompositeFormat extends Format { } /** - * Uses the parser Format instance. - * + * Uses the parser Format instance. + * + * @param source + * the String source + * @param pos + * the ParsePosition containing the position to parse from, will + * be updated according to parsing success (index) or failure + * (error index) + * @return the parsed Object * @see Format#parseObject(String, ParsePosition) */ public Object parseObject(String source, ParsePosition pos) { diff --git a/src/java/org/apache/commons/lang/text/DateMetaFormat.java b/src/java/org/apache/commons/lang/text/DateMetaFormat.java index a135b4519..c7dcdfc97 100644 --- a/src/java/org/apache/commons/lang/text/DateMetaFormat.java +++ b/src/java/org/apache/commons/lang/text/DateMetaFormat.java @@ -40,17 +40,13 @@ public class DateMetaFormat extends DateMetaFormatSupport { /** * Create a new DateMetaFormat. * - * @param locale + * @param locale the Locale to use */ public DateMetaFormat(Locale locale) { super(locale); } - /* - * (non-Javadoc) - * - * @see org.apache.commons.lang.text.AbstractDateMetaFormat#createSubformatInstance(int) - */ + /** {@inheritDoc} */ protected DateFormat createSubformatInstance(int style) { return DateFormat.getDateInstance(style, getLocale()); } diff --git a/src/java/org/apache/commons/lang/text/DateMetaFormatSupport.java b/src/java/org/apache/commons/lang/text/DateMetaFormatSupport.java index 82cd6ce66..d7de5268b 100644 --- a/src/java/org/apache/commons/lang/text/DateMetaFormatSupport.java +++ b/src/java/org/apache/commons/lang/text/DateMetaFormatSupport.java @@ -29,6 +29,7 @@ import java.util.Map; /** * date/time metaFormat support. + * * @see ExtendedMessageFormat * @author Matt Benson * @since 2.4 @@ -70,18 +71,15 @@ public abstract class DateMetaFormatSupport extends MetaFormatSupport { /** * Create a new AbstractDateMetaFormat. * - * @param locale + * @param locale Locale */ public DateMetaFormatSupport(Locale locale) { super(); this.locale = locale; } - /* - * (non-Javadoc) - * - * @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer, - * java.text.FieldPosition) + /** + * {@inheritDoc} */ public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { @@ -98,6 +96,12 @@ public abstract class DateMetaFormatSupport extends MetaFormatSupport { throw new IllegalArgumentException(String.valueOf(obj)); } + /** + * Get the subformat name for the given object. + * + * @param subformat Object + * @return subformat name. + */ private String getSubformatName(Object subformat) { initialize(); if (reverseSubformats.containsKey(subformat)) { @@ -107,11 +111,8 @@ public abstract class DateMetaFormatSupport extends MetaFormatSupport { return null; } - /* - * (non-Javadoc) - * - * @see java.text.Format#parseObject(java.lang.String, - * java.text.ParsePosition) + /** + * {@inheritDoc} */ public Object parseObject(String source, ParsePosition pos) { int start = pos.getIndex(); @@ -131,6 +132,12 @@ public abstract class DateMetaFormatSupport extends MetaFormatSupport { return null; } + /** + * Get the named subformat. + * + * @param subformat name + * @return Format designated by name, if any + */ private Format getSubformat(String subformat) { initialize(); if (!styleMap.containsKey(subformat)) { @@ -141,7 +148,7 @@ public abstract class DateMetaFormatSupport extends MetaFormatSupport { } /** - * Get the locale in use by this {@link DateMetaFormatSupport}. + * Get the locale in use by this DateMetaFormatSupport. * * @return Locale */ @@ -149,6 +156,9 @@ public abstract class DateMetaFormatSupport extends MetaFormatSupport { return locale; } + /** + * Initialize this DateMetaFormatSupport. + */ private synchronized void initialize() { if (!initialized) { styleMap = createStyleMap(); @@ -175,7 +185,7 @@ public abstract class DateMetaFormatSupport extends MetaFormatSupport { * Create a subformat for the given DateFormat style * constant. * - * @param style + * @param style DateFormat style constant * @return a DateFormat instance. */ protected abstract DateFormat createSubformatInstance(int style); @@ -194,8 +204,7 @@ public abstract class DateMetaFormatSupport extends MetaFormatSupport { * Set whether this metaformat can parse date/time pattern formats in * addition to named formats. * - * @param handlePatterns - * the boolean handlePatterns to set. + * @param handlePatterns the boolean handlePatterns to set. * @return this for fluent usage. */ public DateMetaFormatSupport setHandlePatterns(boolean handlePatterns) { diff --git a/src/java/org/apache/commons/lang/text/DefaultMetaFormatFactory.java b/src/java/org/apache/commons/lang/text/DefaultMetaFormatFactory.java index 6922fedf2..c834bf11d 100644 --- a/src/java/org/apache/commons/lang/text/DefaultMetaFormatFactory.java +++ b/src/java/org/apache/commons/lang/text/DefaultMetaFormatFactory.java @@ -34,7 +34,8 @@ import org.apache.commons.lang.Validate; * * @author Matt Benson * @since 2.4 - * @version $Id$ + * @version $Id: DefaultMetaFormatFactory.java 592077 2007-11-05 16:47:10Z + * mbenson $ */ class DefaultMetaFormatFactory { @@ -59,16 +60,32 @@ class DefaultMetaFormatFactory { private static final String[] PATTERN_KEYS = new String[] { DATE_KEY, TIME_KEY }; + /** + * Ordered NameKeyedMetaFormat + */ private static class OrderedNameKeyedMetaFormat extends NameKeyedMetaFormat { private static final long serialVersionUID = -7688772075239431055L; private List keys; + /** + * Construct a new OrderedNameKeyedMetaFormat. + * + * @param names String[] + * @param formats Format[] + */ private OrderedNameKeyedMetaFormat(String[] names, Format[] formats) { super(createMap(names, formats)); this.keys = Arrays.asList(names); } + /** + * Create a map from the specified key/value parameters. + * + * @param names keys + * @param formats values + * @return Map + */ private static Map createMap(String[] names, Format[] formats) { Validate.isTrue(ArrayUtils.isSameLength(names, formats)); HashMap result = new HashMap(names.length); @@ -78,6 +95,9 @@ class DefaultMetaFormatFactory { return result; } + /** + * {@inheritDoc} + */ protected Iterator iterateKeys() { return keys.iterator(); } @@ -86,8 +106,7 @@ class DefaultMetaFormatFactory { /** * Get a default metaformat for the specified Locale. * - * @param locale - * the Locale for the resulting Format instance. + * @param locale the Locale for the resulting Format instance. * @return Format */ public static Format getFormat(final Locale locale) { @@ -106,6 +125,12 @@ class DefaultMetaFormatFactory { new TimeMetaFormat(locale) }) }); } + /** + * Get the default format supported by a given metaformat. + * + * @param metaformat Format to handle parsing. + * @return the default format, if any. + */ private static Format getDefaultFormat(Format metaformat) { ParsePosition pos = new ParsePosition(0); Object o = metaformat.parseObject("", pos); diff --git a/src/java/org/apache/commons/lang/text/ExtendedMessageFormat.java b/src/java/org/apache/commons/lang/text/ExtendedMessageFormat.java index d2035a9a9..95e0126c7 100644 --- a/src/java/org/apache/commons/lang/text/ExtendedMessageFormat.java +++ b/src/java/org/apache/commons/lang/text/ExtendedMessageFormat.java @@ -22,13 +22,16 @@ import java.text.ParsePosition; import java.util.ArrayList; import java.util.Locale; +import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; /** * Extends MessageFormat to allow pluggable/additional formatting * options for embedded format elements; requires a "meta-format", i.e. a * Format capable of parsing and formatting other - * Formats. + * Formats. One shortcoming is that recursive choice formats do + * not inherit knowledge of the extended formatters and are limited to those + * available with java.text.MessageFormat (patches welcome). * * @author Matt Benson * @since 2.4 @@ -53,14 +56,16 @@ public class ExtendedMessageFormat extends MessageFormat { * behavior identical to a java.lang.MessageFormat using * locale. * - * @param locale - * the Locale for the resulting Format instance. + * @param locale the Locale for the resulting Format instance. * @return Format */ public static Format createDefaultMetaFormat(Locale locale) { return DefaultMetaFormatFactory.getFormat(locale); } + /** + * Conceptual demarcation of methods to parse the pattern. + */ private static class Parser { private static final String ESCAPED_QUOTE = "''"; private static final char START_FMT = ','; @@ -68,6 +73,12 @@ public class ExtendedMessageFormat extends MessageFormat { private static final char START_FE = '{'; private static final char QUOTE = '\''; + /** + * Strip all formats from the pattern. + * + * @param pattern String to strip + * @return stripped pattern + */ private String stripFormats(String pattern) { StringBuffer sb = new StringBuffer(pattern.length()); ParsePosition pos = new ParsePosition(0); @@ -98,6 +109,14 @@ public class ExtendedMessageFormat extends MessageFormat { return sb.toString(); } + /** + * Insert formats back into the pattern for toPattern() support. + * + * @param pattern source + * @param formats the Formats to insert + * @param metaFormat Format to format the Formats + * @return full pattern + */ private String insertFormats(String pattern, Format[] formats, Format metaFormat) { if (formats == null || formats.length == 0) { @@ -117,8 +136,10 @@ public class ExtendedMessageFormat extends MessageFormat { sb.append(START_FE).append( readArgumentIndex(pattern, next(pos))); if (formats[fe] != null) { - sb.append(START_FMT).append( - metaFormat.format(formats[fe])); + String formatName = metaFormat.format(formats[fe]); + if (StringUtils.isNotEmpty(formatName)) { + sb.append(START_FMT).append(formatName); + } } break; default: @@ -129,6 +150,13 @@ public class ExtendedMessageFormat extends MessageFormat { return sb.toString(); } + /** + * Parse the formats from the given pattern. + * + * @param pattern String to parse + * @param metaFormat Format to parse the Formats + * @return array of parsed Formats + */ private Format[] parseFormats(String pattern, Format metaFormat) { ArrayList result = new ArrayList(); ParsePosition pos = new ParsePosition(0); @@ -142,8 +170,8 @@ public class ExtendedMessageFormat extends MessageFormat { readArgumentIndex(pattern, next(pos)); if (pattern.charAt(pos.getIndex()) == START_FMT) { seekNonWs(pattern, next(pos)); - result.add(metaFormat.parseObject(pattern, pos)); } + result.add(metaFormat.parseObject(pattern, pos)); seekNonWs(pattern, pos); if (pattern.charAt(pos.getIndex()) != END_FE) { throw new IllegalArgumentException( @@ -158,6 +186,12 @@ public class ExtendedMessageFormat extends MessageFormat { return (Format[]) result.toArray(new Format[result.size()]); } + /** + * Consume whitespace from the current parse position. + * + * @param pattern String to read + * @param pos current position + */ private void seekNonWs(String pattern, ParsePosition pos) { int len = 0; char[] buffer = pattern.toCharArray(); @@ -167,11 +201,24 @@ public class ExtendedMessageFormat extends MessageFormat { } while (len > 0 && pos.getIndex() < pattern.length()); } + /** + * Convenience method to advance parse position by 1 + * + * @param pos ParsePosition + * @return pos + */ private ParsePosition next(ParsePosition pos) { pos.setIndex(pos.getIndex() + 1); return pos; } + /** + * Read the argument index from the current format element + * + * @param pattern pattern to parse + * @param pos current parse position + * @return argument index as string + */ private String readArgumentIndex(String pattern, ParsePosition pos) { int start = pos.getIndex(); for (; pos.getIndex() < pattern.length(); next(pos)) { @@ -189,6 +236,16 @@ public class ExtendedMessageFormat extends MessageFormat { "Unterminated format element at position " + start); } + /** + * Consume a quoted string, adding it to appendTo if + * specified. + * + * @param pattern pattern to parse + * @param pos current parse position + * @param appendTo optional StringBuffer to append + * @param escapingOn whether to process escaped quotes + * @return appendTo + */ private StringBuffer appendQuotedString(String pattern, ParsePosition pos, StringBuffer appendTo, boolean escapingOn) { int start = pos.getIndex(); @@ -200,8 +257,8 @@ public class ExtendedMessageFormat extends MessageFormat { for (int i = pos.getIndex(); i < pattern.length(); i++) { if (escapingOn && pattern.substring(i).startsWith(ESCAPED_QUOTE)) { - appendTo.append(c, lastHold, pos.getIndex() - lastHold).append( - QUOTE); + appendTo.append(c, lastHold, pos.getIndex() - lastHold) + .append(QUOTE); pos.setIndex(i + ESCAPED_QUOTE.length()); lastHold = pos.getIndex(); continue; @@ -219,11 +276,24 @@ public class ExtendedMessageFormat extends MessageFormat { "Unterminated quoted string at position " + start); } + /** + * Consume quoted string only + * + * @param pattern pattern to parse + * @param pos current parse position + * @param escapingOn whether to process escaped quotes + */ private void getQuotedString(String pattern, ParsePosition pos, boolean escapingOn) { appendQuotedString(pattern, pos, null, escapingOn); } + /** + * Consume the entire format found at the current position. + * + * @param pattern string to parse + * @param pos current parse position + */ private void eatFormat(String pattern, ParsePosition pos) { int start = pos.getIndex(); int depth = 1; @@ -254,15 +324,28 @@ public class ExtendedMessageFormat extends MessageFormat { private String strippedPattern; /** - * Create a new ExtendedMessageFormat. + * Create a new ExtendedMessageFormat for the default locale. * - * @param pattern - * @param metaFormat - * @throws IllegalArgumentException - * if metaFormat is null or in - * case of a bad pattern. + * @param pattern String + * @param metaFormat Format + * @throws IllegalArgumentException if metaFormat is + * null or in case of a bad pattern. */ public ExtendedMessageFormat(String pattern, Format metaFormat) { + this(pattern, Locale.getDefault(), metaFormat); + } + + /** + * Create a new ExtendedMessageFormat. + * + * @param pattern String + * @param locale Locale + * @param metaFormat Format + * @throws IllegalArgumentException if metaFormat is + * null or in case of a bad pattern. + */ + public ExtendedMessageFormat(String pattern, Locale locale, + Format metaFormat) { /* * We have to do some acrobatics here: the call to the super constructor * will invoke applyPattern(), but we don't want to apply the pattern @@ -270,7 +353,7 @@ public class ExtendedMessageFormat extends MessageFormat { * our (final) applyPattern implementation, and re-call at the end of * this constructor. */ - super(pattern); + super(pattern, locale); setMetaFormat(metaFormat); applyPattern(pattern); } @@ -278,8 +361,7 @@ public class ExtendedMessageFormat extends MessageFormat { /** * Apply the specified pattern. * - * @param pattern - * pattern String + * @param pattern String */ public final void applyPattern(String pattern) { if (metaFormat == null) { @@ -293,20 +375,20 @@ public class ExtendedMessageFormat extends MessageFormat { } /** - * Pre-execution hook that allows subclasses to customize the behavior of - * the final applyPattern implementation. + * Pre-execution hook by means of which a subclass can customize the + * behavior of the final applyPattern implementation. * - * @param pattern + * @param pattern String */ protected void applyPatternPre(String pattern) { // noop } /** - * Post-execution hook that allows subclasses to customize the behavior of - * the final applyPattern implementation. + * Post-execution hook by means of which a subclass can customize the + * behavior of the final applyPattern implementation. * - * @param pattern + * @param pattern String */ protected void applyPatternPost(String pattern) { // noop @@ -335,8 +417,7 @@ public class ExtendedMessageFormat extends MessageFormat { * Set the meta-format. Has no effect until a subsequent call to * {@link #applyPattern(String)}. * - * @param metaFormat - * the Format metaFormat to set. + * @param metaFormat the Format metaFormat to set. */ public synchronized void setMetaFormat(Format metaFormat) { Validate.notNull(metaFormat, "metaFormat is null"); diff --git a/src/java/org/apache/commons/lang/text/MetaFormatSupport.java b/src/java/org/apache/commons/lang/text/MetaFormatSupport.java index d409e2ede..a7574577c 100644 --- a/src/java/org/apache/commons/lang/text/MetaFormatSupport.java +++ b/src/java/org/apache/commons/lang/text/MetaFormatSupport.java @@ -24,7 +24,8 @@ import java.util.Iterator; import java.util.Map; /** - * metaFormat support. + * Support class for implementing Formats that parse/format other Formats, with + * specific support for interoperability with ExtendedMessageFormat. * * @see ExtendedMessageFormat * @author Matt Benson @@ -40,11 +41,9 @@ public abstract class MetaFormatSupport extends Format { /** * Invert the specified Map. * - * @param map - * the Map to invert. + * @param map the Map to invert. * @return a new Map instance. - * @throws NullPointerException - * if map is null. + * @throws NullPointerException if map is null. */ protected Map invert(Map map) { Map result = new HashMap(map.size()); @@ -58,8 +57,8 @@ public abstract class MetaFormatSupport extends Format { /** * Find the end of the subformat. * - * @param source - * @param pos + * @param source String + * @param pos current parse position */ protected void seekFormatElementEnd(String source, ParsePosition pos) { int depth = 1; @@ -85,8 +84,7 @@ public abstract class MetaFormatSupport extends Format { /** * Advance the parse index by 1. * - * @param pos - * the ParsePosition to advance. + * @param pos the ParsePosition to advance. * @return pos */ protected ParsePosition next(ParsePosition pos) { @@ -100,10 +98,8 @@ public abstract class MetaFormatSupport extends Format { * occurs pos.getErrorIndex() will contain a value >= zero, * indicating the index at which the parse error occurred. * - * @param source - * String to parse - * @param pos - * ParsePosition marking index into source + * @param source String to parse + * @param pos ParsePosition marking index into source * @return Object parsed */ public abstract Object parseObject(String source, ParsePosition pos); @@ -112,19 +108,14 @@ public abstract class MetaFormatSupport extends Format { * Format the specified object, appending to the given StringBuffer, and * optionally respecting the specified FieldPosition. * - * @param obj - * the object to format - * @param toAppendTo - * the StringBuffer to which the formatted object should be - * appended - * @param pos - * FieldPosition associated with obj + * @param obj the object to format + * @param toAppendTo the StringBuffer to which the formatted object should + * be appended + * @param pos FieldPosition associated with obj * @return toAppendTo - * @throws NullPointerException - * if toAppendTo or pos is - * null - * @throws IllegalArgumentException - * if unable to format obj + * @throws NullPointerException if toAppendTo or + * pos is null + * @throws IllegalArgumentException if unable to format obj */ public abstract StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos); diff --git a/src/java/org/apache/commons/lang/text/MultiFormat.java b/src/java/org/apache/commons/lang/text/MultiFormat.java index fb102a45f..9714275cd 100644 --- a/src/java/org/apache/commons/lang/text/MultiFormat.java +++ b/src/java/org/apache/commons/lang/text/MultiFormat.java @@ -50,7 +50,7 @@ public class MultiFormat extends Format { /** * Add a delegate format. * - * @param delegate + * @param delegate Format * @return the builder */ public Builder add(Format delegate) { @@ -82,17 +82,19 @@ public class MultiFormat extends Format { /** * Create a new MultiFormat. * - * @param delegates + * @param delegates Formats */ public MultiFormat(Format[] delegates) { setDelegates(delegates); } - /* - * (non-Javadoc) + /** + * Format obj; append to toAppendTo. * - * @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer, - * java.text.FieldPosition) + * @param obj Object to format + * @param toAppendTo StringBuffer to append to + * @param pos FieldPosition + * @return toAppendTo */ public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { @@ -108,11 +110,13 @@ public class MultiFormat extends Format { + obj); } - /* - * (non-Javadoc) + /** + * Parse an object by trying each delegate. * - * @see java.text.Format#parseObject(java.lang.String, - * java.text.ParsePosition) + * @param source string + * @param pos current parse position + * @return value returned from first delegate that does not encounter an + * error. */ public Object parseObject(String source, ParsePosition pos) { int start = pos.getIndex(); @@ -133,8 +137,7 @@ public class MultiFormat extends Format { /** * Set the delegates. * - * @param delegates - * the Format[] delegates to set. + * @param delegates the Format[] delegates to set. */ public void setDelegates(Format[] delegates) { Validate.noNullElements(delegates, @@ -151,6 +154,11 @@ public class MultiFormat extends Format { return delegates; } + /** + * Validate and return our delegates. + * + * @return delegate Formats, not null + */ private Format[] getValidDelegates() { Format[] result = getDelegates(); Validate.notEmpty(result, "No delegate Formats configured"); diff --git a/src/java/org/apache/commons/lang/text/NameKeyedMetaFormat.java b/src/java/org/apache/commons/lang/text/NameKeyedMetaFormat.java index a54e7b2f7..b22401c8c 100644 --- a/src/java/org/apache/commons/lang/text/NameKeyedMetaFormat.java +++ b/src/java/org/apache/commons/lang/text/NameKeyedMetaFormat.java @@ -57,8 +57,8 @@ public class NameKeyedMetaFormat extends MetaFormatSupport { /** * Add the specified format with the specified string key. * - * @param key - * @param format + * @param key String + * @param format Format * @return Builder reference to this object */ public Builder put(String key, Format format) { @@ -80,16 +80,15 @@ public class NameKeyedMetaFormat extends MetaFormatSupport { /** * Create a new NameKeyedMetaFormat. + * + * @param keyedFormats String->Format map. */ public NameKeyedMetaFormat(Map keyedFormats) { this.keyedFormats = keyedFormats; } - /* - * (non-Javadoc) - * - * @see org.apache.commons.lang.text.MetaFormatSupport#format(java.lang.Object, - * java.lang.StringBuffer, java.text.FieldPosition) + /** + * {@inheritDoc} */ public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { @@ -117,11 +116,8 @@ public class NameKeyedMetaFormat extends MetaFormatSupport { throw new IllegalArgumentException("Cannot format " + obj); } - /* - * (non-Javadoc) - * - * @see org.apache.commons.lang.text.MetaFormatSupport#parseObject(java.lang.String, - * java.text.ParsePosition) + /** + * {@inheritDoc} */ public Object parseObject(String source, ParsePosition pos) { int start = pos.getIndex(); diff --git a/src/java/org/apache/commons/lang/text/NumberMetaFormat.java b/src/java/org/apache/commons/lang/text/NumberMetaFormat.java index 7851e820a..87e3a11ad 100644 --- a/src/java/org/apache/commons/lang/text/NumberMetaFormat.java +++ b/src/java/org/apache/commons/lang/text/NumberMetaFormat.java @@ -56,18 +56,15 @@ public class NumberMetaFormat extends MetaFormatSupport { /** * Create a new NumberMetaFormat. * - * @param locale + * @param locale Locale */ public NumberMetaFormat(Locale locale) { super(); this.locale = locale; } - /* - * (non-Javadoc) - * - * @see org.apache.commons.lang.text.AbstractMetaFormat#format(java.lang.Object, - * java.lang.StringBuffer, java.text.FieldPosition) + /** + * {@inheritDoc} */ public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { @@ -85,11 +82,8 @@ public class NumberMetaFormat extends MetaFormatSupport { throw new IllegalArgumentException(); } - /* - * (non-Javadoc) - * - * @see java.text.Format#parseObject(java.lang.String, - * java.text.ParsePosition) + /** + * {@inheritDoc} */ public Object parseObject(String source, ParsePosition pos) { int start = pos.getIndex(); @@ -115,6 +109,9 @@ public class NumberMetaFormat extends MetaFormatSupport { return locale; } + /** + * Initialize this NumberMetaFormat. + */ private synchronized void initialize() { if (subformats == null) { subformats = new HashMap(); diff --git a/src/java/org/apache/commons/lang/text/TimeMetaFormat.java b/src/java/org/apache/commons/lang/text/TimeMetaFormat.java index e212e9e14..a0091dda3 100644 --- a/src/java/org/apache/commons/lang/text/TimeMetaFormat.java +++ b/src/java/org/apache/commons/lang/text/TimeMetaFormat.java @@ -41,30 +41,28 @@ public class TimeMetaFormat extends DateMetaFormatSupport { /** * Create a new NumberMetaFormat. * - * @param locale + * @param locale Locale */ public TimeMetaFormat(Locale locale) { super(locale); } - /* - * (non-Javadoc) - * - * @see org.apache.commons.lang.text.AbstractDateMetaFormat#createSubformatInstance(int) - */ + /** {@inheritDoc} */ protected DateFormat createSubformatInstance(int style) { return DateFormat.getTimeInstance(style, getLocale()); } - /* - * (non-Javadoc) - * - * @see org.apache.commons.lang.text.AbstractDateMetaFormat#createReverseStyleMap() - */ + /** {@inheritDoc} */ protected Map createInverseStyleMap() { Map invertMe = createStyleMap(); invertMe.remove(DEFAULT); - invertMe.remove(FULL); + DateFormat longDf = DateFormat.getTimeInstance(DateFormat.LONG, + getLocale()); + DateFormat fullDf = DateFormat.getTimeInstance(DateFormat.FULL, + getLocale()); + if (fullDf.equals(longDf)) { + invertMe.remove(FULL); + } return invert(invertMe); } } diff --git a/src/test/org/apache/commons/lang/text/AbstractMessageFormatTest.java b/src/test/org/apache/commons/lang/text/AbstractMessageFormatTest.java index 0457bdfea..ef8a9e398 100644 --- a/src/test/org/apache/commons/lang/text/AbstractMessageFormatTest.java +++ b/src/test/org/apache/commons/lang/text/AbstractMessageFormatTest.java @@ -16,10 +16,18 @@ */ package org.apache.commons.lang.text; +import java.text.ChoiceFormat; import java.text.DateFormat; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.text.FieldPosition; +import java.text.Format; import java.text.MessageFormat; +import java.text.NumberFormat; +import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.GregorianCalendar; +import java.util.Locale; import junit.framework.TestCase; @@ -32,7 +40,7 @@ import junit.framework.TestCase; * @version $Id$ */ public abstract class AbstractMessageFormatTest extends TestCase { - protected static final Object[] NUMBERS = { new Double(0.1), + protected static final Double[] NUMBERS = { new Double(0.1), new Double(1.1), new Double(2.1) }; protected static final Object[] DATES = { @@ -43,18 +51,30 @@ public abstract class AbstractMessageFormatTest extends TestCase { new GregorianCalendar(1970, Calendar.MARCH, 03, 18, 45, 50) .getTime() }; - /* - * (non-Javadoc) - * - * @see junit.framework.TestCase#setUp() + protected Locale locale; + + /** + * {@inheritDoc} */ protected void setUp() throws Exception { super.setUp(); - // tests depend on Locale.US - java.util.Locale.setDefault(java.util.Locale.US); + this.locale = getLocale(); } - protected abstract MessageFormat createMessageFormat(String pattern); + /** + * Create a MessageFormat. + * @param pattern + * @param locale + * @return + */ + protected abstract MessageFormat createMessageFormat(String pattern, + Locale locale); + + /** + * Get the Locale to use. + * @return + */ + protected abstract Locale getLocale(); protected void doAssertions(String expected, String pattern, Object[] args) { doAssertions(expected, pattern, args, pattern); @@ -62,235 +82,213 @@ public abstract class AbstractMessageFormatTest extends TestCase { protected void doAssertions(String expected, String pattern, Object[] args, String toPattern) { - MessageFormat f = createMessageFormat(pattern); + MessageFormat f = createMessageFormat(pattern, locale); assertEquals(expected, f.format(args)); assertEquals(toPattern, f.toPattern()); } - public void testPlain() { + protected void doAssertions(Format format, Object[] args) { + doAssertions(format, args, null); + } + + protected void doAssertions(Format format, Object[] args, String formatName) { + doAssertions(format, args, formatName, null); + } + + protected void doAssertions(Format format, Object[] args, + String formatName, String decodeFormatName) { + StringBuffer pattern = new StringBuffer(); + StringBuffer expected = new StringBuffer(); + StringBuffer decodePattern = new StringBuffer(); + for (int i = 0; i < args.length; i++) { + pattern.append(i).append(": {").append(i); + if (formatName != null) { + pattern.append(',').append(formatName); + } + pattern.append("}; "); + expected.append(i).append(": "); + if (format != null) { + format.format(args[i], expected, new FieldPosition(0)); + } else { + expected.append(String.valueOf(args[i])); + } + expected.append("; "); + decodePattern.append(i).append(": {").append(i); + if (decodeFormatName != null || formatName != null) { + decodePattern.append(',').append( + decodeFormatName == null ? formatName + : decodeFormatName); + } + decodePattern.append("}; "); + } + doAssertions(expected.toString(), pattern.toString(), args, + decodePattern.toString()); + } + + public void testNoFormatElements() { StringBuffer pattern = new StringBuffer(); for (int i = 0; i < NUMBERS.length; i++) { if (i > 0) { pattern.append("; "); } - pattern.append("Object ").append(i).append(": ").append(NUMBERS[i]); + pattern.append(i).append(": ").append(NUMBERS[i]); } String p = pattern.toString(); - doAssertions(p, p, NUMBERS); + doAssertions(p, p, null); } - public void testSimple() { - doAssertions("Object 0: 0.1; Object 1: 1.1; Object 2: 2.1", - "Object 0: {0}; Object 1: {1}; Object 2: {2}", NUMBERS); + public void testSimpleStrings() { + doAssertions(null, new Object[] { "foo", "bar", "baz"}, null); + } + + public void testSimpleNumbers() { + doAssertions(NumberFormat.getInstance(locale), NUMBERS, null); + } + + public void testSimpleDates() { + doAssertions(DateFormat.getDateTimeInstance(DateFormat.SHORT, + DateFormat.SHORT, locale), DATES, null); } public void testNumber() { - doAssertions( - "Number 0: 0.1; Number 1: 1.1; Number 2: 2.1", - "Number 0: {0,number}; Number 1: {1,number}; Number 2: {2,number}", - NUMBERS); + doAssertions(NumberFormat.getInstance(locale), NUMBERS, "number"); } public void testNumberLooseFormatting() { - doAssertions( - "Number 0: 0.1; Number 1: 1.1; Number 2: 2.1", - "Number 0: {0, number }; Number 1: {1, number }; Number 2: {2, number }", - NUMBERS, - "Number 0: {0,number}; Number 1: {1,number}; Number 2: {2,number}"); + doAssertions(NumberFormat.getInstance(locale), NUMBERS, " number ", + "number"); } public void testInteger() { - doAssertions( - "Number 0: 0; Number 1: 1; Number 2: 2", - "Number 0: {0,number,integer}; Number 1: {1,number,integer}; Number 2: {2,number,integer}", - NUMBERS); + doAssertions(NumberFormat.getIntegerInstance(locale), NUMBERS, + "number,integer"); } public void testIntegerLooseFormatting() { - doAssertions( - "Number 0: 0; Number 1: 1; Number 2: 2", - "Number 0: {0, number , integer }; Number 1: {1, number , integer }; Number 2: {2, number , integer }", - NUMBERS, - "Number 0: {0,number,integer}; Number 1: {1,number,integer}; Number 2: {2,number,integer}"); + doAssertions(NumberFormat.getIntegerInstance(locale), NUMBERS, + " number , integer ", "number,integer"); } public void testCurrency() { - doAssertions( - "Number 0: $0.10; Number 1: $1.10; Number 2: $2.10", - "Number 0: {0,number,currency}; Number 1: {1,number,currency}; Number 2: {2,number,currency}", - NUMBERS); + doAssertions(NumberFormat.getCurrencyInstance(locale), NUMBERS, + "number,currency"); } public void testPercent() { - doAssertions( - "Number 0: 10%; Number 1: 110%; Number 2: 210%", - "Number 0: {0,number,percent}; Number 1: {1,number,percent}; Number 2: {2,number,percent}", - NUMBERS); + doAssertions(NumberFormat.getPercentInstance(locale), NUMBERS, + "number,percent"); } public void testNumberPattern() { - doAssertions( - "Number 0: 000.100; Number 1: 001.100; Number 2: 002.100", - "Number 0: {0,number,#000.000}; Number 1: {1,number,#000.000}; Number 2: {2,number,#000.000}", - NUMBERS); + doAssertions(new DecimalFormat("#000.000", new DecimalFormatSymbols( + locale)), NUMBERS, "number,#000.000"); } public void testDate() { - doAssertions( - "Date 0: Jan 1, 1970; Date 1: Feb 2, 1970; Date 2: Mar 3, 1970", - "Date 0: {0,date}; Date 1: {1,date}; Date 2: {2,date}", DATES); + doAssertions(DateFormat.getDateInstance(DateFormat.DEFAULT, locale), + DATES, "date"); } public void testDateLooseFormatting() { - doAssertions( - "Date 0: Jan 1, 1970; Date 1: Feb 2, 1970; Date 2: Mar 3, 1970", - "Date 0: {0, date }; Date 1: {1, date }; Date 2: {2, date }", - DATES, "Date 0: {0,date}; Date 1: {1,date}; Date 2: {2,date}"); + doAssertions(DateFormat.getDateInstance(DateFormat.DEFAULT, locale), + DATES, " date ", "date"); } public void testShortDate() { - doAssertions( - "Date 0: 1/1/70; Date 1: 2/2/70; Date 2: 3/3/70", - "Date 0: {0,date,short}; Date 1: {1,date,short}; Date 2: {2,date,short}", - DATES); + DateFormat shortDf = DateFormat.getDateInstance(DateFormat.SHORT, locale); + DateFormat defaultDf = DateFormat.getDateInstance(DateFormat.DEFAULT, locale); + doAssertions(shortDf, DATES, "date,short", + shortDf.equals(defaultDf) ? "date" : "date,short"); } public void testShortDateLooseFormatting() { - doAssertions( - "Date 0: 1/1/70; Date 1: 2/2/70; Date 2: 3/3/70", - "Date 0: {0, date , short }; Date 1: {1, date , short }; Date 2: {2, date , short }", - DATES, - "Date 0: {0,date,short}; Date 1: {1,date,short}; Date 2: {2,date,short}"); + DateFormat shortDf = DateFormat.getDateInstance(DateFormat.SHORT, locale); + DateFormat defaultDf = DateFormat.getDateInstance(DateFormat.DEFAULT, locale); + doAssertions(shortDf, DATES, " date , short ", + shortDf.equals(defaultDf) ? "date" : "date,short"); } public void testMediumDate() { - doAssertions( - "Date 0: Jan 1, 1970; Date 1: Feb 2, 1970; Date 2: Mar 3, 1970", - "Date 0: {0,date,medium}; Date 1: {1,date,medium}; Date 2: {2,date,medium}", - DATES, "Date 0: {0,date}; Date 1: {1,date}; Date 2: {2,date}"); + doAssertions(DateFormat.getDateInstance(DateFormat.MEDIUM, locale), + DATES, "date,medium", "date"); } public void testLongDate() { - doAssertions( - "Date 0: January 1, 1970; Date 1: February 2, 1970; Date 2: March 3, 1970", - "Date 0: {0,date,long}; Date 1: {1,date,long}; Date 2: {2,date,long}", - DATES); + DateFormat longDf = DateFormat.getDateInstance(DateFormat.LONG, locale); + DateFormat defaultDf = DateFormat.getDateInstance(DateFormat.DEFAULT, + locale); + doAssertions(longDf, DATES, "date,long", + longDf.equals(defaultDf) ? "date" : "date,long"); } public void testFullDate() { - doAssertions( - "Date 0: Thursday, January 1, 1970; Date 1: Monday, February 2, 1970; Date 2: Tuesday, March 3, 1970", - "Date 0: {0,date,full}; Date 1: {1,date,full}; Date 2: {2,date,full}", - DATES); + DateFormat fullDf = DateFormat.getDateInstance(DateFormat.FULL, locale); + DateFormat longDf = DateFormat.getDateInstance(DateFormat.LONG, locale); + doAssertions(fullDf, DATES, "date,full", + fullDf.equals(longDf) ? "date,long" : "date,full"); } public void testDatePattern() { - doAssertions( - "Date 0: AD1970.1; Date 1: AD1970.33; Date 2: AD1970.62", - "Date 0: {0,date,Gyyyy.D}; Date 1: {1,date,Gyyyy.D}; Date 2: {2,date,Gyyyy.D}", - DATES); + doAssertions(new SimpleDateFormat("Gyyyy.D", locale), DATES, + "date,Gyyyy.D"); } public void testTime() { - doAssertions( - "Time 0: 12:15:20 AM; Time 1: 12:30:35 PM; Time 2: 6:45:50 PM", - "Time 0: {0,time}; Time 1: {1,time}; Time 2: {2,time}", DATES); + doAssertions(DateFormat.getTimeInstance(DateFormat.DEFAULT, locale), + DATES, "time"); } public void testShortTime() { - doAssertions( - "Time 0: 12:15 AM; Time 1: 12:30 PM; Time 2: 6:45 PM", - "Time 0: {0,time,short}; Time 1: {1,time,short}; Time 2: {2,time,short}", - DATES); + doAssertions(DateFormat.getTimeInstance(DateFormat.SHORT, locale), + DATES, "time,short"); } public void testMediumTime() { - doAssertions( - "Time 0: 12:15:20 AM; Time 1: 12:30:35 PM; Time 2: 6:45:50 PM", - "Time 0: {0,time,medium}; Time 1: {1,time,medium}; Time 2: {2,time,medium}", - DATES, "Time 0: {0,time}; Time 1: {1,time}; Time 2: {2,time}"); + doAssertions(DateFormat.getTimeInstance(DateFormat.MEDIUM, locale), + DATES, "time,medium", "time"); } public void testLongTime() { - DateFormat df = DateFormat.getTimeInstance(DateFormat.LONG); - StringBuffer expected = new StringBuffer(); - for (int i = 0; i < DATES.length; i++) { - if (i > 0) { - expected.append("; "); - } - expected.append("Time ").append(i).append(": ").append( - df.format(DATES[i])); - } - doAssertions( - expected.toString(), - "Time 0: {0,time,long}; Time 1: {1,time,long}; Time 2: {2,time,long}", - DATES); + doAssertions(DateFormat.getTimeInstance(DateFormat.LONG, locale), + DATES, "time,long"); } public void testFullTime() { - DateFormat df = DateFormat.getTimeInstance(DateFormat.FULL); - StringBuffer expected = new StringBuffer(); - for (int i = 0; i < DATES.length; i++) { - if (i > 0) { - expected.append("; "); - } - expected.append("Time ").append(i).append(": ").append( - df.format(DATES[i])); - } - doAssertions( - expected.toString(), - "Time 0: {0,time,full}; Time 1: {1,time,full}; Time 2: {2,time,full}", - DATES, - "Time 0: {0,time,long}; Time 1: {1,time,long}; Time 2: {2,time,long}"); + DateFormat fullDf = DateFormat.getTimeInstance(DateFormat.FULL, locale); + DateFormat longDf = DateFormat.getTimeInstance(DateFormat.LONG, locale); + doAssertions(fullDf, DATES, "time,full", + fullDf.equals(longDf) ? "time,long" : "time,full"); } public void testTimePattern() { - doAssertions( - "Time 0: AM01520; Time 1: PM123035; Time 2: PM184550", - "Time 0: {0,time,aHms}; Time 1: {1,time,aHms}; Time 2: {2,time,aHms}", - DATES, - "Time 0: {0,date,aHms}; Time 1: {1,date,aHms}; Time 2: {2,date,aHms}"); + doAssertions(new SimpleDateFormat("aHms", locale), DATES, "date,aHms"); } public void testChoice() { - String choice = "0.0#x|1.0#y|2.0#z"; - StringBuffer pattern = new StringBuffer(); - for (int i = 0; i < 3; i++) { - if (i > 0) { - pattern.append("; "); - } - pattern.append("Choice ").append(i).append(": {").append(i).append( - ",choice,").append(choice).append("}"); - } - doAssertions("Choice 0: x; Choice 1: y; Choice 2: z", pattern - .toString(), NUMBERS); + doAssertions(new ChoiceFormat("0.0#x|1.0#y|2.0#z"), NUMBERS, + "choice,0.0#x|1.0#y|2.0#z"); } public void testChoiceLooseFormatting() { - String choice = "0.0#x |1.0#y |2.0#z "; - StringBuffer pattern = new StringBuffer(); - for (int i = 0; i < 3; i++) { - if (i > 0) { - pattern.append("; "); - } - pattern.append("Choice ").append(i).append(": {").append(i).append( - ",choice,").append(choice).append("}"); - } - doAssertions("Choice 0: x ; Choice 1: y ; Choice 2: z ", pattern - .toString(), NUMBERS); + doAssertions(new ChoiceFormat("0.0#x |1.0#y |2.0#z "), NUMBERS, + "choice,0.0#x |1.0#y |2.0#z "); } public void testChoiceRecursive() { - String choice = "0.0#{0}|1.0#{1}|2.0#{2}"; - StringBuffer pattern = new StringBuffer(); - for (int i = 0; i < 3; i++) { + NumberFormat nf = NumberFormat.getInstance(locale); + StringBuffer choice = new StringBuffer(); + StringBuffer format = new StringBuffer("choice,"); + for (int i = 0; i < NUMBERS.length; i++) { + Double d = new Double(Math.floor(NUMBERS[i].doubleValue())); if (i > 0) { - pattern.append("; "); + choice.append('|'); + format.append('|'); } - pattern.append("Choice ").append(i).append(": {").append(i).append( - ",choice,").append(choice).append("}"); + choice.append(d).append('#').append( + nf.format(NUMBERS[i].doubleValue())); + format.append(d).append('#').append('{').append(i).append('}'); } - doAssertions("Choice 0: 0.1; Choice 1: 1.1; Choice 2: 2.1", pattern - .toString(), NUMBERS); + doAssertions(new ChoiceFormat(choice.toString()), NUMBERS, format + .toString()); } } diff --git a/src/test/org/apache/commons/lang/text/ExtendedMessageFormatBaselineTest.java b/src/test/org/apache/commons/lang/text/ExtendedMessageFormatBaselineTest.java index 9c3bdb6e4..d52c595bf 100644 --- a/src/test/org/apache/commons/lang/text/ExtendedMessageFormatBaselineTest.java +++ b/src/test/org/apache/commons/lang/text/ExtendedMessageFormatBaselineTest.java @@ -20,21 +20,161 @@ import java.text.MessageFormat; import java.util.Locale; /** - * Baseline tests for {@link ExtendedMessageFormat} + * Baseline tests for ExtendedMessageFormat * * @author Matt Benson * @since 2.4 * @version $Id$ */ -public class ExtendedMessageFormatBaselineTest extends AbstractMessageFormatTest { +public abstract class ExtendedMessageFormatBaselineTest extends + AbstractMessageFormatTest { - /* - * (non-Javadoc) + /** + * Tests for Locale.US * - * @see org.apache.commons.lang.text.AbstractMessageFormatTest#createMessageFormat(java.lang.String) + * @author mbenson */ - protected MessageFormat createMessageFormat(String pattern) { - return new ExtendedMessageFormat(pattern, ExtendedMessageFormat.createDefaultMetaFormat(Locale.US)); + public static class US extends ExtendedMessageFormatBaselineTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.US; + } + } + + /** + * Tests for Locale.UK + * + * @author mbenson + */ + public static class UK extends ExtendedMessageFormatBaselineTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.UK; + } + } + + /** + * Tests for Locale.GERMANY + * + * @author mbenson + */ + public static class DE extends ExtendedMessageFormatBaselineTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.GERMANY; + } + } + + /** + * Tests for Locale.ITALY + * + * @author mbenson + */ + public static class IT extends ExtendedMessageFormatBaselineTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.ITALY; + } + } + + /** + * Tests for Locale.JAPAN + * + * @author mbenson + */ + public static class JP extends ExtendedMessageFormatBaselineTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.JAPAN; + } + } + + /** + * Tests for Locale.CHINA + * + * @author mbenson + */ + public static class CN extends ExtendedMessageFormatBaselineTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.CHINA; + } + } + + /** + * Tests for Locale.CANADA + * + * @author mbenson + */ + public static class CA extends ExtendedMessageFormatBaselineTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.CANADA; + } + } + + /** + * Tests for Locale.FRANCE + * + * @author mbenson + */ + public static class FR extends ExtendedMessageFormatBaselineTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.FRANCE; + } + } + + /** + * Tests for Locale.KOREA + * + * @author mbenson + */ + public static class KR extends ExtendedMessageFormatBaselineTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.KOREA; + } + } + + /** + * Tests for Locale.TAIWAN + * + * @author mbenson + */ + public static class TW extends ExtendedMessageFormatBaselineTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.TAIWAN; + } + } + + /** + * {@inheritDoc} + */ + protected MessageFormat createMessageFormat(String pattern, Locale locale) { + return new ExtendedMessageFormat(pattern, locale, ExtendedMessageFormat + .createDefaultMetaFormat(locale)); } } diff --git a/src/test/org/apache/commons/lang/text/MessageFormatExtensionTest.java b/src/test/org/apache/commons/lang/text/MessageFormatExtensionTest.java index e842bf3b5..6512ba3e2 100644 --- a/src/test/org/apache/commons/lang/text/MessageFormatExtensionTest.java +++ b/src/test/org/apache/commons/lang/text/MessageFormatExtensionTest.java @@ -16,11 +16,13 @@ */ package org.apache.commons.lang.text; +import java.text.DateFormat; import java.text.FieldPosition; import java.text.Format; import java.text.MessageFormat; import java.text.ParsePosition; import java.util.Calendar; +import java.util.Date; import java.util.GregorianCalendar; import java.util.Locale; @@ -31,22 +33,162 @@ import java.util.Locale; * @since 2.4 * @version $Id$ */ -public class MessageFormatExtensionTest extends AbstractMessageFormatTest { +public abstract class MessageFormatExtensionTest extends + AbstractMessageFormatTest { + /** + * Tests for Locale.US + * + * @author mbenson + */ + public static class US extends MessageFormatExtensionTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.US; + } + } + + /** + * Tests for Locale.UK + * + * @author mbenson + */ + public static class UK extends MessageFormatExtensionTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.UK; + } + } + + /** + * Tests for Locale.GERMANY + * + * @author mbenson + */ + public static class DE extends MessageFormatExtensionTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.GERMANY; + } + } + + /** + * Tests for Locale.ITALY + * + * @author mbenson + */ + public static class IT extends MessageFormatExtensionTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.ITALY; + } + } + + /** + * Tests for Locale.JAPAN + * + * @author mbenson + */ + public static class JP extends MessageFormatExtensionTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.JAPAN; + } + } + + /** + * Tests for Locale.CHINA + * + * @author mbenson + */ + public static class CN extends MessageFormatExtensionTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.CHINA; + } + } + + /** + * Tests for Locale.CANADA + * + * @author mbenson + */ + public static class CA extends MessageFormatExtensionTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.CANADA; + } + } + + /** + * Tests for Locale.FRANCE + * + * @author mbenson + */ + public static class FR extends MessageFormatExtensionTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.FRANCE; + } + } + + /** + * Tests for Locale.KOREA + * + * @author mbenson + */ + public static class KR extends MessageFormatExtensionTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.KOREA; + } + } + + /** + * Tests for Locale.TAIWAN + * + * @author mbenson + */ + public static class TW extends MessageFormatExtensionTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.TAIWAN; + } + } static class ProperNameCapitalizationFormat extends Format { private static final long serialVersionUID = -6081911520622186866L; private static final StrMatcher MATCH = StrMatcher .charSetMatcher(" ,."); - /* - * (non-Javadoc) - * - * @see java.text.Format#format(java.lang.Object, - * java.lang.StringBuffer, java.text.FieldPosition) + /** + * {@inheritDoc} */ public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition fpos) { - char[] buffer = String.valueOf(obj).toCharArray(); + if (!(obj instanceof String)) { + throw new IllegalArgumentException(); + } + char[] buffer = ((String) obj).toCharArray(); ParsePosition pos = new ParsePosition(0); while (pos.getIndex() < buffer.length) { char c = buffer[pos.getIndex()]; @@ -91,17 +233,17 @@ public class MessageFormatExtensionTest extends AbstractMessageFormatTest { } } - /* - * (non-Javadoc) - * - * @see org.apache.commons.lang.text.AbstractMessageFormatTest#createMessageFormat(java.lang.String) + /** + * {@inheritDoc} */ - protected MessageFormat createMessageFormat(String pattern) { - return new ExtendedMessageFormat(pattern, new MultiFormat.Builder() - .add(ExtendedMessageFormat.createDefaultMetaFormat(Locale.US)).add( + protected MessageFormat createMessageFormat(String pattern, Locale locale) { + return new ExtendedMessageFormat(pattern, locale, + new MultiFormat.Builder().add( new NameKeyedMetaFormat.Builder().put("properName", new ProperNameCapitalizationFormat()) - .toNameKeyedMetaFormat()).toMultiFormat()); + .toNameKeyedMetaFormat()).add( + ExtendedMessageFormat.createDefaultMetaFormat(locale)) + .toMultiFormat()); } public void testProperName() { @@ -111,10 +253,23 @@ public class MessageFormatExtensionTest extends AbstractMessageFormatTest { } public void testMixed() { - doAssertions("John Q. Public was born on Thursday, January 1, 1970.", - "{0,properName} was born on {1,date,full}.", new Object[] { + StringBuffer expected = new StringBuffer("John Q. Public was born on "); + Date dob = new GregorianCalendar(1970, Calendar.JANUARY, 01, 0, 15, 20) + .getTime(); + DateFormat longDf = DateFormat.getDateInstance(DateFormat.LONG, locale); + longDf.format(dob, expected, new FieldPosition(0)); + expected.append('.'); + String pattern = "{0,properName} was born on {1,date,long}."; + StringBuffer toPattern = new StringBuffer(pattern); + if (longDf.equals(DateFormat.getDateInstance(DateFormat.DEFAULT, locale))) { + int idx = pattern.indexOf(",long"); + toPattern.delete(idx, idx + ",long".length()); + } + doAssertions(expected.toString(), + pattern, new Object[] { "john q. public", new GregorianCalendar(1970, Calendar.JANUARY, 01, 0, - 15, 20).getTime() }); + 15, 20).getTime() }, toPattern.toString()); } + } diff --git a/src/test/org/apache/commons/lang/text/MessageFormatTest.java b/src/test/org/apache/commons/lang/text/MessageFormatTest.java index 4836001fc..82964f361 100644 --- a/src/test/org/apache/commons/lang/text/MessageFormatTest.java +++ b/src/test/org/apache/commons/lang/text/MessageFormatTest.java @@ -10,13 +10,152 @@ import java.util.Locale; * @since 2.4 * @version $Id$ */ -public class MessageFormatTest extends AbstractMessageFormatTest { - /* - * (non-Javadoc) +public abstract class MessageFormatTest extends AbstractMessageFormatTest { + + /** + * Tests for Locale.US * - * @see org.apache.commons.lang.text.AbstractMessageFormatTest#createMessageFormat(java.lang.String) + * @author mbenson */ - protected MessageFormat createMessageFormat(String pattern) { - return new MessageFormat(pattern, Locale.US); + public static class US extends MessageFormatTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.US; + } + } + + /** + * Tests for Locale.UK + * + * @author mbenson + */ + public static class UK extends MessageFormatTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.UK; + } + } + + /** + * Tests for Locale.GERMANY + * + * @author mbenson + */ + public static class DE extends MessageFormatTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.GERMANY; + } + } + + /** + * Tests for Locale.ITALY + * + * @author mbenson + */ + public static class IT extends MessageFormatTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.ITALY; + } + } + + /** + * Tests for Locale.JAPAN + * + * @author mbenson + */ + public static class JP extends MessageFormatTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.JAPAN; + } + } + + /** + * Tests for Locale.CHINA + * + * @author mbenson + */ + public static class CN extends MessageFormatTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.CHINA; + } + } + + /** + * Tests for Locale.CANADA + * + * @author mbenson + */ + public static class CA extends MessageFormatTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.CANADA; + } + } + + /** + * Tests for Locale.FRANCE + * + * @author mbenson + */ + public static class FR extends MessageFormatTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.FRANCE; + } + } + + /** + * Tests for Locale.KOREA + * + * @author mbenson + */ + public static class KR extends MessageFormatTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.KOREA; + } + } + + /** + * Tests for Locale.TAIWAN + * + * @author mbenson + */ + public static class TW extends MessageFormatTest { + /** + * {@inheritDoc} + */ + protected Locale getLocale() { + return Locale.TAIWAN; + } + } + + /** + * {@inheritDoc} + */ + protected MessageFormat createMessageFormat(String pattern, Locale locale) { + return new MessageFormat(pattern, locale); } } diff --git a/src/test/org/apache/commons/lang/text/TextTestSuite.java b/src/test/org/apache/commons/lang/text/TextTestSuite.java index b0c8dbdc8..af6765cac 100644 --- a/src/test/org/apache/commons/lang/text/TextTestSuite.java +++ b/src/test/org/apache/commons/lang/text/TextTestSuite.java @@ -57,9 +57,36 @@ public class TextTestSuite extends TestCase { suite.addTest(StrSubstitutorTest.suite()); suite.addTest(StrTokenizerTest.suite()); suite.addTestSuite(MultiFormatTest.class); - suite.addTestSuite(MessageFormatTest.class); - suite.addTestSuite(ExtendedMessageFormatBaselineTest.class); - suite.addTestSuite(MessageFormatExtensionTest.class); + suite.addTestSuite(MessageFormatTest.US.class); + suite.addTestSuite(MessageFormatTest.UK.class); + suite.addTestSuite(MessageFormatTest.DE.class); + suite.addTestSuite(MessageFormatTest.IT.class); + suite.addTestSuite(MessageFormatTest.JP.class); + suite.addTestSuite(MessageFormatTest.CA.class); + suite.addTestSuite(MessageFormatTest.CN.class); + suite.addTestSuite(MessageFormatTest.FR.class); + suite.addTestSuite(MessageFormatTest.KR.class); + suite.addTestSuite(MessageFormatTest.TW.class); + suite.addTestSuite(ExtendedMessageFormatBaselineTest.US.class); + suite.addTestSuite(ExtendedMessageFormatBaselineTest.UK.class); + suite.addTestSuite(ExtendedMessageFormatBaselineTest.DE.class); + suite.addTestSuite(ExtendedMessageFormatBaselineTest.IT.class); + suite.addTestSuite(ExtendedMessageFormatBaselineTest.JP.class); + suite.addTestSuite(ExtendedMessageFormatBaselineTest.CA.class); + suite.addTestSuite(ExtendedMessageFormatBaselineTest.CN.class); + suite.addTestSuite(ExtendedMessageFormatBaselineTest.FR.class); + suite.addTestSuite(ExtendedMessageFormatBaselineTest.KR.class); + suite.addTestSuite(ExtendedMessageFormatBaselineTest.TW.class); + suite.addTestSuite(MessageFormatExtensionTest.US.class); + suite.addTestSuite(MessageFormatExtensionTest.UK.class); + suite.addTestSuite(MessageFormatExtensionTest.DE.class); + suite.addTestSuite(MessageFormatExtensionTest.IT.class); + suite.addTestSuite(MessageFormatExtensionTest.JP.class); + suite.addTestSuite(MessageFormatExtensionTest.CA.class); + suite.addTestSuite(MessageFormatExtensionTest.CN.class); + suite.addTestSuite(MessageFormatExtensionTest.FR.class); + suite.addTestSuite(MessageFormatExtensionTest.KR.class); + suite.addTestSuite(MessageFormatExtensionTest.TW.class); return suite; }