diff --git a/.gitattributes b/.gitattributes index 4dea60aa2d..39f2a65a1b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -265,7 +265,7 @@ icu4j/main/classes/core/.settings/edu.umd.cs.findbugs.core.prefs -text icu4j/main/classes/core/.settings/org.eclipse.core.resources.prefs -text icu4j/main/classes/core/.settings/org.eclipse.jdt.core.prefs -text icu4j/main/classes/core/manifest.stub -text -icu4j/main/classes/core/src/com/ibm/icu/impl/Template.java -text +icu4j/main/classes/core/src/com/ibm/icu/impl/SimplePatternFormatter.java -text icu4j/main/classes/currdata/.externalToolBuilders/copy-data-currdata.launch -text icu4j/main/classes/currdata/.settings/org.eclipse.core.resources.prefs -text icu4j/main/classes/currdata/.settings/org.eclipse.jdt.core.prefs -text @@ -554,7 +554,7 @@ icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_52.1/com.ib icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_52.1/com.ibm.icu.util.ULocale.dat -text icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_52.1/com.ibm.icu.util.UResourceTypeMismatchException.dat -text icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_52.1/com.ibm.icu.util.VTimeZone.dat -text -icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/TemplateTest.java -text +icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/SimplePatternFormatterTest.java -text icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/Trie2Test.setRanges1.16.tri2 -text icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/Trie2Test.setRanges1.32.tri2 -text icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/Trie2Test.setRanges2.16.tri2 -text diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/Template.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/SimplePatternFormatter.java similarity index 74% rename from icu4j/main/classes/core/src/com/ibm/icu/impl/Template.java rename to icu4j/main/classes/core/src/com/ibm/icu/impl/SimplePatternFormatter.java index a46ce81b76..8f3b877813 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/Template.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/SimplePatternFormatter.java @@ -10,9 +10,9 @@ import java.util.ArrayList; import java.util.List; /** - * Compiled version of a template such as "{1} was born in {0}". + * Compiled version of a pattern such as "{1} was born in {0}". *

- * Using Template objects is both faster and safer than adhoc replacement + * Using SimplePatternFormatter objects is both faster and safer than adhoc replacement * such as pattern.replace("{0}", "Colorado").replace("{1} "Fred");. * They are faster because they are precompiled; they are safer because they * account for curly braces escaped by apostrophe ('). @@ -21,17 +21,17 @@ import java.util.List; * by a single quote, it becomes a curly brace instead of the start of a * placeholder. Two single quotes resolve to one single quote. *

- * Template objects are immutable and can be safely cached like strings. + * SimplePatternFormatter objects are immutable and can be safely cached like strings. *

* Example: *

- * Template template = Template.compile("{1} '{born} in {0}");
+ * SimplePatternFormatter fmt = SimplePatternFormatter.compile("{1} '{born} in {0}");
  * 
  * // Output: "paul {born} in england"
- * System.out.println(template.evaluate("england", "paul"));
+ * System.out.println(fmt.format("england", "paul"));
  * 
*/ -public class Template { +public class SimplePatternFormatter { private final String patternWithoutPlaceholders; private final int placeholderCount; @@ -39,7 +39,7 @@ public class Template { // [3] second placeholderId etc. private final int[] placeholderIdsOrderedByOffset; - private Template(String pattern, PlaceholdersBuilder builder) { + private SimplePatternFormatter(String pattern, PlaceholdersBuilder builder) { this.patternWithoutPlaceholders = pattern; this.placeholderIdsOrderedByOffset = builder.getPlaceholderIdsOrderedByOffset(); @@ -47,11 +47,11 @@ public class Template { } /** - * Compiles a string into a template. + * Compiles a string. * @param pattern The string. - * @return the new template object. + * @return the new SimplePatternFormatter object. */ - public static Template compile(String pattern) { + public static SimplePatternFormatter compile(String pattern) { PlaceholdersBuilder placeholdersBuilder = new PlaceholdersBuilder(); PlaceholderIdBuilder idBuilder = new PlaceholderIdBuilder(); StringBuilder newPattern = new StringBuilder(); @@ -110,35 +110,59 @@ public class Template { default: throw new IllegalStateException(); } - return new Template(newPattern.toString(), placeholdersBuilder); + return new SimplePatternFormatter(newPattern.toString(), placeholdersBuilder); } /** - * Evaluates this template with given values. The first value - * corresponds to {0}; the second to {1} etc. - * @param values the values. - * @return The result. - * @throws IllegalArgumentException if the number of arguments is - * insufficient to match all the placeholders. + * Formats given value. + * @throws UnsupportedOperationException if this object's pattern expects + * more than one value */ - public String evaluate(Object... values) { + public String format(Object arg0) { StringResultBuilder builder = new StringResultBuilder(); - evaluatePrivate(values, builder); + if (!formatPrivate(new Object[] {arg0}, builder)) { + throw new UnsupportedOperationException(); + } return builder.build(); } /** - * Evaluates this template with given values. The first value - * corresponds to {0}; the second to {1} etc. - * @param values the values. - * @return The result of the evaluation. - * @throws IllegalArgumentException if the number of arguments is - * insufficient to match all the placeholders. + * Formats given values. + * @throws UnsupportedOperationException if this object's pattern expects more than two + * values. */ - public Evaluation evaluateFull(Object... values) { - EvaluationResultBuilder builder = new EvaluationResultBuilder(); - evaluatePrivate(values, builder); + public String format(Object arg0, Object arg1) { + StringResultBuilder builder = new StringResultBuilder(); + if (!formatPrivate(new Object[] {arg0, arg1}, builder)) { + throw new UnsupportedOperationException(); + } + return builder.build(); + } + + /** + * Formats given values. + * @throws UnsupportedOperationException if this object's pattern expects more than three + * values. + */ + public String format(Object arg0, Object arg1, Object arg2) { + StringResultBuilder builder = new StringResultBuilder(); + if (!formatPrivate(new Object[] {arg0, arg1, arg2}, builder)) { + throw new UnsupportedOperationException(); + } + return builder.build(); + } + + /** + * Formats given values. + * @throws IllegalArgumentException if args.length < this.getPlaceholderCount() + * values. + */ + public Formatted formatValues(Object[] args) { + FormattedResultBuilder builder = new FormattedResultBuilder(); + if (!formatPrivate(args, builder)) { + throw new IllegalArgumentException(); + } return builder.build(); } @@ -150,8 +174,8 @@ public class Template { } /** - * Evaluates this template using values {0}, {1} etc. Note that this is - * not the same as the original pattern string used to build the template. + * Formats this object using values {0}, {1} etc. Note that this is + * not the same as the original pattern string used to build this object. */ @Override public String toString() { @@ -159,26 +183,25 @@ public class Template { for (int i = 0; i < values.length; i++) { values[i] = String.format("{%d}", i); } - return evaluate((Object[]) values); + return formatValues(values).toString(); } /** - * The immutable evaluation of a template. + * The immutable representation of a formatted value. */ - public static class Evaluation { + public static class Formatted { private final String result; private final int[] offsets; - private Evaluation(String result, int[] placeholderOffsets) { + private Formatted(String result, int[] placeholderOffsets) { this.result = result; this.offsets = placeholderOffsets; } /** - * Returns the offset of a particular placeholder in the evaluated - * string. Returns -1 if the placeholder did not exist in the - * corresponding template. + * Returns the offset of a particular placeholder in this formatted + * value. Returns -1 if the placeholder does not exist. * @throws IndexOutOfBoundsException if placeholderId is negative. */ public int getOffset(int placeholderId) { @@ -192,7 +215,7 @@ public class Template { } /** - * Returns the evaluated string. + * Returns the formatted string */ public String toString() { return result; @@ -200,15 +223,14 @@ public class Template { } - private void evaluatePrivate(Object[] values, ResultBuilder builder) { + private boolean formatPrivate(Object[] values, ResultBuilder builder) { if (values.length < placeholderCount) { - throw new IllegalArgumentException( - "There must be at least as values as placeholders."); + return false; } builder.setPlaceholderCount(placeholderCount); if (placeholderIdsOrderedByOffset.length == 0) { builder.setResult(patternWithoutPlaceholders); - return; + return true; } StringBuilder result = new StringBuilder(); result.append( @@ -232,6 +254,7 @@ public class Template { placeholderIdsOrderedByOffset[placeholderIdsOrderedByOffset.length - 2], patternWithoutPlaceholders.length()); builder.setResult(result.toString()); + return true; } private static enum State { @@ -319,7 +342,7 @@ public class Template { } } - private static class EvaluationResultBuilder implements ResultBuilder { + private static class FormattedResultBuilder implements ResultBuilder { private int[] placeholderOffsets; private String result; @@ -338,8 +361,8 @@ public class Template { this.result = result; } - public Evaluation build() { - return new Evaluation(this.result, this.placeholderOffsets); + public Formatted build() { + return new Formatted(this.result, this.placeholderOffsets); } } diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/ListFormatter.java b/icu4j/main/classes/core/src/com/ibm/icu/text/ListFormatter.java index 07a9eefc86..fc1bf3eda9 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/text/ListFormatter.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/text/ListFormatter.java @@ -18,7 +18,7 @@ import java.util.MissingResourceException; import com.ibm.icu.impl.ICUCache; import com.ibm.icu.impl.ICUResourceBundle; import com.ibm.icu.impl.SimpleCache; -import com.ibm.icu.impl.Template; +import com.ibm.icu.impl.SimplePatternFormatter; import com.ibm.icu.util.ULocale; import com.ibm.icu.util.UResourceBundle; @@ -31,10 +31,10 @@ import com.ibm.icu.util.UResourceBundle; * @provisional This API might change or be removed in a future release. */ final public class ListFormatter { - private final Template two; - private final Template start; - private final Template middle; - private final Template end; + private final SimplePatternFormatter two; + private final SimplePatternFormatter start; + private final SimplePatternFormatter middle; + private final SimplePatternFormatter end; private final ULocale locale; /** @@ -104,15 +104,15 @@ final public class ListFormatter { */ public ListFormatter(String two, String start, String middle, String end) { this( - Template.compile(two), - Template.compile(start), - Template.compile(middle), - Template.compile(end), + SimplePatternFormatter.compile(two), + SimplePatternFormatter.compile(start), + SimplePatternFormatter.compile(middle), + SimplePatternFormatter.compile(end), null); } - private ListFormatter(Template two, Template start, Template middle, Template end, ULocale locale) { + private ListFormatter(SimplePatternFormatter two, SimplePatternFormatter start, SimplePatternFormatter middle, SimplePatternFormatter end, ULocale locale) { this.two = two; this.start = start; this.middle = middle; @@ -267,14 +267,14 @@ final public class ListFormatter { // added in relation to the rest of the list. {0} represents the rest of the list; {1} // represents the new object in pattern. next is the object to be added. If recordOffset // is true, records the offset of next in the formatted string. - public FormattedListBuilder append(Template pattern, Object next, boolean recordOffset) { + public FormattedListBuilder append(SimplePatternFormatter pattern, Object next, boolean recordOffset) { if (pattern.getPlaceholderCount() != 2) { throw new IllegalArgumentException("Need {0} and {1} only in pattern " + pattern); } if (recordOffset || offsetRecorded()) { - Template.Evaluation evaluation = pattern.evaluateFull(current, next); - int oneOffset = evaluation.getOffset(1); - int zeroOffset = evaluation.getOffset(0); + SimplePatternFormatter.Formatted formatted = pattern.formatValues(new Object[]{current, next}); + int oneOffset = formatted.getOffset(1); + int zeroOffset = formatted.getOffset(0); if (zeroOffset == -1 || oneOffset == -1) { throw new IllegalArgumentException("{0} or {1} missing from pattern " + pattern); } @@ -283,9 +283,9 @@ final public class ListFormatter { } else { offset += zeroOffset; } - current = evaluation.toString(); + current = formatted.toString(); } else { - current = pattern.evaluate(current, next); + current = pattern.format(current, next); } return this; } @@ -336,17 +336,17 @@ final public class ListFormatter { // for listPattern/duration and listPattern/duration-narrow in root.txt. try { return new ListFormatter( - Template.compile(r.getWithFallback("listPattern/" + style + "/2").getString()), - Template.compile(r.getWithFallback("listPattern/" + style + "/start").getString()), - Template.compile(r.getWithFallback("listPattern/" + style + "/middle").getString()), - Template.compile(r.getWithFallback("listPattern/" + style + "/end").getString()), + SimplePatternFormatter.compile(r.getWithFallback("listPattern/" + style + "/2").getString()), + SimplePatternFormatter.compile(r.getWithFallback("listPattern/" + style + "/start").getString()), + SimplePatternFormatter.compile(r.getWithFallback("listPattern/" + style + "/middle").getString()), + SimplePatternFormatter.compile(r.getWithFallback("listPattern/" + style + "/end").getString()), ulocale); } catch (MissingResourceException e) { return new ListFormatter( - Template.compile(r.getWithFallback("listPattern/standard/2").getString()), - Template.compile(r.getWithFallback("listPattern/standard/start").getString()), - Template.compile(r.getWithFallback("listPattern/standard/middle").getString()), - Template.compile(r.getWithFallback("listPattern/standard/end").getString()), + SimplePatternFormatter.compile(r.getWithFallback("listPattern/standard/2").getString()), + SimplePatternFormatter.compile(r.getWithFallback("listPattern/standard/start").getString()), + SimplePatternFormatter.compile(r.getWithFallback("listPattern/standard/middle").getString()), + SimplePatternFormatter.compile(r.getWithFallback("listPattern/standard/end").getString()), ulocale); } } diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/QuantityFormatter.java b/icu4j/main/classes/core/src/com/ibm/icu/text/QuantityFormatter.java index 2898c5f368..9f04fc5aea 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/text/QuantityFormatter.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/text/QuantityFormatter.java @@ -9,7 +9,7 @@ package com.ibm.icu.text; import java.util.HashMap; import java.util.Map; -import com.ibm.icu.impl.Template; +import com.ibm.icu.impl.SimplePatternFormatter; /** * QuantityFormatter represents an unknown quantity of something and formats a known quantity @@ -45,7 +45,7 @@ class QuantityFormatter { */ static class Builder { - private Template[] templates; + private SimplePatternFormatter[] templates; /** * Adds a template. @@ -63,7 +63,7 @@ class QuantityFormatter { if (idx == null) { throw new IllegalArgumentException(variant); } - Template newT = Template.compile(template); + SimplePatternFormatter newT = SimplePatternFormatter.compile(template); if (newT.getPlaceholderCount() > 1) { throw new IllegalArgumentException( "Extra placeholders: " + template); @@ -74,7 +74,7 @@ class QuantityFormatter { private void ensureCapacity() { if (templates == null) { - templates = new Template[MAX_INDEX]; + templates = new SimplePatternFormatter[MAX_INDEX]; } } @@ -97,9 +97,9 @@ class QuantityFormatter { } - private final Template[] templates; + private final SimplePatternFormatter[] templates; - private QuantityFormatter(Template[] templates) { + private QuantityFormatter(SimplePatternFormatter[] templates) { this.templates = templates; } @@ -119,12 +119,12 @@ class QuantityFormatter { } else { variant = pluralRules.select(quantity); } - return getByVariant(variant).evaluate(formatStr); + return getByVariant(variant).format(formatStr); } - private Template getByVariant(String variant) { + private SimplePatternFormatter getByVariant(String variant) { Integer idxObj = INDEX_MAP.get(variant); - Template template = templates[idxObj == null ? 0 : idxObj.intValue()]; + SimplePatternFormatter template = templates[idxObj == null ? 0 : idxObj.intValue()]; return template == null ? templates[0] : template; } } diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/impl/TestAll.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/impl/TestAll.java index 71ecbd2a50..7a4cd1e4f5 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/impl/TestAll.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/impl/TestAll.java @@ -22,7 +22,7 @@ public class TestAll extends TestGroup { "ICUServiceTest", "ICUServiceThreadTest", "ICUBinaryTest", - "TemplateTest", + "SimplePatternFormatterTest", "TextTrieMapTest" }, "Test miscellaneous implementation utilities"); diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/TemplateTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/SimplePatternFormatterTest.java similarity index 58% rename from icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/TemplateTest.java rename to icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/SimplePatternFormatterTest.java index b1315995d4..4d38585d17 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/TemplateTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/SimplePatternFormatterTest.java @@ -7,18 +7,14 @@ package com.ibm.icu.dev.test.util; import com.ibm.icu.dev.test.TestFmwk; -import com.ibm.icu.impl.Template; +import com.ibm.icu.impl.SimplePatternFormatter; -/** - * @author rocketman - * - */ -public class TemplateTest extends TestFmwk { +public class SimplePatternFormatterTest extends TestFmwk { /** * Constructor */ - public TemplateTest() + public SimplePatternFormatterTest() { } @@ -26,87 +22,94 @@ public class TemplateTest extends TestFmwk { public static void main(String arg[]) { - TemplateTest test = new TemplateTest(); + SimplePatternFormatterTest test = new SimplePatternFormatterTest(); try { test.run(arg); } catch (Exception e) { - test.errln("Error testing templatetest"); + test.errln("Error testing SimplePatternFormatterTest"); } } public void TestWithNoPlaceholders() { - Template t = Template.compile("This doesn''t have templates '{0}"); + SimplePatternFormatter fmt = SimplePatternFormatter.compile("This doesn''t have templates '{0}"); assertEquals( "getPlaceholderCount", 0, - t.getPlaceholderCount()); + fmt.getPlaceholderCount()); assertEquals( "evaluate", "This doesn't have templates {0}", - t.evaluate()); + fmt.format("unused")); assertEquals( "toString", "This doesn't have templates {0}", - t.toString()); - Template.Evaluation eval = t.evaluateFull(); + fmt.toString()); + SimplePatternFormatter.Formatted formatted = fmt.formatValues(new Object[] {}); assertEquals( "toString2", "This doesn't have templates {0}", - eval.toString()); + formatted.toString()); assertEquals( "getOffset(0)", -1, - eval.getOffset(0)); - t = Template.compile("Some {} messed {12d up stuff."); + formatted.getOffset(0)); + fmt = SimplePatternFormatter.compile("Some {} messed {12d up stuff."); assertEquals( "getPlaceholderCount", 0, - t.getPlaceholderCount()); + fmt.getPlaceholderCount()); assertEquals( "evaluate", "Some {} messed {12d up stuff.", - t.evaluate("to")); + fmt.format("to")); } public void TestOnePlaceholder() { assertEquals("TestOnePlaceholder", "1 meter", - Template.compile("{0} meter").evaluate(1)); + SimplePatternFormatter.compile("{0} meter").format(1)); } public void TestWithPlaceholders() { - Template t = Template.compile( + SimplePatternFormatter fmt = SimplePatternFormatter.compile( "Templates {2}{1} and {4} are out of order."); assertEquals( "getPlaceholderCount", 5, - t.getPlaceholderCount()); + fmt.getPlaceholderCount()); try { - t.evaluate("freddy", "tommy", "frog", "leg"); + fmt.format("freddy", "tommy", "frog"); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException e) { + // Expected + } + try { + fmt.formatValues(new String[] {"freddy", "tommy", "frog", "leg"}); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException e) { // Expected } - assertEquals( + String[] args = new String[] {"freddy", "tommy", "frog", "leg", "{0}"}; + assertEquals( "evaluate", "Templates frogtommy and {0} are out of order.", - t.evaluate("freddy", "tommy", "frog", "leg", "{0}")); + fmt.formatValues(args).toString()); assertEquals( "toString", "Templates {2}{1} and {4} are out of order.", - t.toString()); - Template.Evaluation eval = - t.evaluateFull("freddy", "tommy", "frog", "leg", "{0}"); + fmt.toString()); + SimplePatternFormatter.Formatted formatted = + fmt.formatValues(args); int[] offsets = {-1, 14, 10, -1, 24, -1}; for (int i = 0; i < offsets.length; i++) { - if (offsets[i] != eval.getOffset(i)) { + if (offsets[i] != formatted.getOffset(i)) { fail("getOffset() returned wrong value for " + i); } } assertEquals( "toString2", "Templates frogtommy and {0} are out of order.", - eval.toString()); + formatted.toString()); } }