You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2015/09/16 19:59:13 UTC
[13/15] incubator-freemarker git commit: FTL now uses the
ExtendedDecimalFormatParser. Some cleanups in the code.
FTL now uses the ExtendedDecimalFormatParser. Some cleanups in the code.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/25f3b824
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/25f3b824
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/25f3b824
Branch: refs/heads/2.3
Commit: 25f3b824b263713dc48e32f05546a8a19e92f57d
Parents: 9ca1a71
Author: ddekany <dd...@apache.org>
Authored: Wed Sep 16 19:23:12 2015 +0200
Committer: ddekany <dd...@apache.org>
Committed: Wed Sep 16 19:23:12 2015 +0200
----------------------------------------------------------------------
.../core/ExtendedDecimalFormatParser.java | 86 ++++++++++++++------
.../core/JavaTemplateNumberFormatFactory.java | 7 +-
.../core/ExtendedDecimalFormatTest.java | 37 +++++++--
3 files changed, 96 insertions(+), 34 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/25f3b824/src/main/java/freemarker/core/ExtendedDecimalFormatParser.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/ExtendedDecimalFormatParser.java b/src/main/java/freemarker/core/ExtendedDecimalFormatParser.java
index b3f218f..76484cf 100644
--- a/src/main/java/freemarker/core/ExtendedDecimalFormatParser.java
+++ b/src/main/java/freemarker/core/ExtendedDecimalFormatParser.java
@@ -31,30 +31,53 @@ import java.util.Set;
import freemarker.template.utility.StringUtil;
class ExtendedDecimalFormatParser {
-
+
+ private static final String PARAM_ROUNDING_MODE = "rnd";
+ private static final String PARAM_MULTIPIER = "mul";
+ private static final String PARAM_DECIMAL_SEPARATOR = "dec";
+ private static final String PARAM_MONETARY_DECIMAL_SEPARATOR = "mdec";
+ private static final String PARAM_GROUP_SEPARATOR = "grp";
+ private static final String PARAM_EXPONENT_SEPARATOR = "exp";
+ private static final String PARAM_MINUS_SIGN = "min";
+ private static final String PARAM_INFINITY = "inf";
+ private static final String PARAM_NAN = "nan";
+ private static final String PARAM_PERCENT = "prc";
+ private static final String PARAM_PER_MILL = "prm";
+ private static final String PARAM_ZERO_DIGIT = "zero";
+ private static final String PARAM_CURRENCY_CODE = "curc";
+ private static final String PARAM_CURRENCY_SYMBOL = "curs";
+
+ private static final String PARAM_VALUE_RND_UP = "u";
+ private static final String PARAM_VALUE_RND_DOWN = "d";
+ private static final String PARAM_VALUE_RND_CEILING = "c";
+ private static final String PARAM_VALUE_RND_FLOOR = "f";
+ private static final String PARAM_VALUE_RND_HALF_DOWN = "hd";
+ private static final String PARAM_VALUE_RND_HALF_EVEN = "he";
+ private static final String PARAM_VALUE_RND_HALF_UP = "hu";
+ private static final String PARAM_VALUE_RND_UNNECESSARY = "un";
+
private static final HashMap<String, ? extends ParameterHandler> PARAM_HANDLERS;
-
static {
HashMap<String, ParameterHandler> m = new HashMap<String, ParameterHandler>();
- m.put("rnd", new ParameterHandler() {
+ m.put(PARAM_ROUNDING_MODE, new ParameterHandler() {
public void handle(ExtendedDecimalFormatParser parser, String value)
throws InvalidParameterValueException {
RoundingMode parsedValue;
- if (value.equals("u")) {
+ if (value.equals(PARAM_VALUE_RND_UP)) {
parsedValue = RoundingMode.UP;
- } else if (value.equals("d")) {
+ } else if (value.equals(PARAM_VALUE_RND_DOWN)) {
parsedValue = RoundingMode.DOWN;
- } else if (value.equals("c")) {
+ } else if (value.equals(PARAM_VALUE_RND_CEILING)) {
parsedValue = RoundingMode.CEILING;
- } else if (value.equals("f")) {
+ } else if (value.equals(PARAM_VALUE_RND_FLOOR)) {
parsedValue = RoundingMode.FLOOR;
- } else if (value.equals("hd")) {
+ } else if (value.equals(PARAM_VALUE_RND_HALF_DOWN)) {
parsedValue = RoundingMode.HALF_DOWN;
- } else if (value.equals("he")) {
+ } else if (value.equals(PARAM_VALUE_RND_HALF_EVEN)) {
parsedValue = RoundingMode.HALF_EVEN;
- } else if (value.equals("hu")) {
+ } else if (value.equals(PARAM_VALUE_RND_HALF_UP)) {
parsedValue = RoundingMode.HALF_UP;
- } else if (value.equals("un")) {
+ } else if (value.equals(PARAM_VALUE_RND_UNNECESSARY)) {
parsedValue = RoundingMode.UNNECESSARY;
} else {
throw new InvalidParameterValueException("Should be one of: u, d, c, f, hd, he, hu, un");
@@ -67,7 +90,7 @@ class ExtendedDecimalFormatParser {
parser.roundingMode = parsedValue;
}
});
- m.put("mul", new ParameterHandler() {
+ m.put(PARAM_MULTIPIER, new ParameterHandler() {
public void handle(ExtendedDecimalFormatParser parser, String value)
throws InvalidParameterValueException {
try {
@@ -77,7 +100,7 @@ class ExtendedDecimalFormatParser {
}
}
});
- m.put("dec", new ParameterHandler() {
+ m.put(PARAM_DECIMAL_SEPARATOR, new ParameterHandler() {
public void handle(ExtendedDecimalFormatParser parser, String value)
throws InvalidParameterValueException {
if (value.length() != 1) {
@@ -86,7 +109,7 @@ class ExtendedDecimalFormatParser {
parser.symbols.setDecimalSeparator(value.charAt(0));
}
});
- m.put("mdec", new ParameterHandler() {
+ m.put(PARAM_MONETARY_DECIMAL_SEPARATOR, new ParameterHandler() {
public void handle(ExtendedDecimalFormatParser parser, String value)
throws InvalidParameterValueException {
if (value.length() != 1) {
@@ -95,7 +118,7 @@ class ExtendedDecimalFormatParser {
parser.symbols.setMonetaryDecimalSeparator(value.charAt(0));
}
});
- m.put("grp", new ParameterHandler() {
+ m.put(PARAM_GROUP_SEPARATOR, new ParameterHandler() {
public void handle(ExtendedDecimalFormatParser parser, String value)
throws InvalidParameterValueException {
if (value.length() != 1) {
@@ -104,7 +127,7 @@ class ExtendedDecimalFormatParser {
parser.symbols.setGroupingSeparator(value.charAt(0));
}
});
- m.put("exp", new ParameterHandler() {
+ m.put(PARAM_EXPONENT_SEPARATOR, new ParameterHandler() {
public void handle(ExtendedDecimalFormatParser parser, String value)
throws InvalidParameterValueException {
if (_JavaVersions.JAVA_6 == null) {
@@ -114,7 +137,7 @@ class ExtendedDecimalFormatParser {
_JavaVersions.JAVA_6.setExponentSeparator(parser.symbols, value);
}
});
- m.put("min", new ParameterHandler() {
+ m.put(PARAM_MINUS_SIGN, new ParameterHandler() {
public void handle(ExtendedDecimalFormatParser parser, String value)
throws InvalidParameterValueException {
if (value.length() != 1) {
@@ -123,19 +146,19 @@ class ExtendedDecimalFormatParser {
parser.symbols.setMinusSign(value.charAt(0));
}
});
- m.put("inf", new ParameterHandler() {
+ m.put(PARAM_INFINITY, new ParameterHandler() {
public void handle(ExtendedDecimalFormatParser parser, String value)
throws InvalidParameterValueException {
parser.symbols.setInfinity(value);
}
});
- m.put("nan", new ParameterHandler() {
+ m.put(PARAM_NAN, new ParameterHandler() {
public void handle(ExtendedDecimalFormatParser parser, String value)
throws InvalidParameterValueException {
parser.symbols.setNaN(value);
}
});
- m.put("prc", new ParameterHandler() {
+ m.put(PARAM_PERCENT, new ParameterHandler() {
public void handle(ExtendedDecimalFormatParser parser, String value)
throws InvalidParameterValueException {
if (value.length() != 1) {
@@ -144,7 +167,7 @@ class ExtendedDecimalFormatParser {
parser.symbols.setPercent(value.charAt(0));
}
});
- m.put("prm", new ParameterHandler() {
+ m.put(PARAM_PER_MILL, new ParameterHandler() {
public void handle(ExtendedDecimalFormatParser parser, String value)
throws InvalidParameterValueException {
if (value.length() != 1) {
@@ -153,7 +176,7 @@ class ExtendedDecimalFormatParser {
parser.symbols.setPerMill(value.charAt(0));
}
});
- m.put("zero", new ParameterHandler() {
+ m.put(PARAM_ZERO_DIGIT, new ParameterHandler() {
public void handle(ExtendedDecimalFormatParser parser, String value)
throws InvalidParameterValueException {
if (value.length() != 1) {
@@ -162,7 +185,7 @@ class ExtendedDecimalFormatParser {
parser.symbols.setZeroDigit(value.charAt(0));
}
});
- m.put("curc", new ParameterHandler() {
+ m.put(PARAM_CURRENCY_CODE, new ParameterHandler() {
public void handle(ExtendedDecimalFormatParser parser, String value)
throws InvalidParameterValueException {
Currency currency;
@@ -196,7 +219,20 @@ class ExtendedDecimalFormatParser {
skipWS();
parseFormatStringExtension();
- DecimalFormat decimalFormat = new DecimalFormat(stdPattern, symbols);
+ DecimalFormat decimalFormat;
+ try {
+ decimalFormat = new DecimalFormat(stdPattern, symbols);
+ } catch (IllegalArgumentException e) {
+ ParseException pe = new ParseException(e.getMessage(), 0);
+ if (e.getCause() != null) {
+ try {
+ e.initCause(e.getCause());
+ } catch (Exception e2) {
+ // Supress
+ }
+ }
+ throw pe;
+ }
if (roundingMode != null) {
if (_JavaVersions.JAVA_6 == null) {
@@ -244,7 +280,7 @@ class ExtendedDecimalFormatParser {
ParameterHandler handler = PARAM_HANDLERS.get(name);
if (handler == null) {
- if (name.equals("curs")) {
+ if (name.equals(PARAM_CURRENCY_SYMBOL)) {
currencySymbol = value;
} else {
throw newUnknownParameterException(name, namePos);
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/25f3b824/src/main/java/freemarker/core/JavaTemplateNumberFormatFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/JavaTemplateNumberFormatFactory.java b/src/main/java/freemarker/core/JavaTemplateNumberFormatFactory.java
index 21db3af..330d4f6 100644
--- a/src/main/java/freemarker/core/JavaTemplateNumberFormatFactory.java
+++ b/src/main/java/freemarker/core/JavaTemplateNumberFormatFactory.java
@@ -18,9 +18,8 @@
*/
package freemarker.core;
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
+import java.text.ParseException;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
@@ -59,8 +58,8 @@ class JavaTemplateNumberFormatFactory extends TemplateNumberFormatFactory {
jFormat = env.getCNumberFormat();
} else {
try {
- jFormat = new DecimalFormat(params, new DecimalFormatSymbols(locale));
- } catch (IllegalArgumentException e) {
+ jFormat = ExtendedDecimalFormatParser.parse(params, locale);
+ } catch (ParseException e) {
String msg = e.getMessage();
throw new InvalidFormatParametersException(
msg != null ? msg : "Invalid DecimalFormat pattern", e);
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/25f3b824/src/test/java/freemarker/core/ExtendedDecimalFormatTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/ExtendedDecimalFormatTest.java b/src/test/java/freemarker/core/ExtendedDecimalFormatTest.java
index acd8f8b..0c5c9f2 100644
--- a/src/test/java/freemarker/core/ExtendedDecimalFormatTest.java
+++ b/src/test/java/freemarker/core/ExtendedDecimalFormatTest.java
@@ -22,13 +22,18 @@ import static freemarker.test.hamcerst.Matchers.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
+import java.io.IOException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.Locale;
import org.junit.Test;
-public class ExtendedDecimalFormatTest {
+import freemarker.template.Configuration;
+import freemarker.template.TemplateException;
+import freemarker.test.TemplateTest;
+
+public class ExtendedDecimalFormatTest extends TemplateTest {
private static final Locale LOC = Locale.US;
@@ -47,7 +52,7 @@ public class ExtendedDecimalFormatTest {
}
try {
ExtendedDecimalFormatParser.parse(";", LOC);
- } catch (IllegalArgumentException e) {
+ } catch (ParseException e) {
// Expected
}
}
@@ -81,19 +86,19 @@ public class ExtendedDecimalFormatTest {
try {
ExtendedDecimalFormatParser.parse("; ;", LOC);
fail();
- } catch (IllegalArgumentException e) {
+ } catch (ParseException e) {
// Expected
}
try {
ExtendedDecimalFormatParser.parse(";m", LOC);
fail();
- } catch (IllegalArgumentException e) {
+ } catch (ParseException e) {
// Expected
}
try {
ExtendedDecimalFormatParser.parse(";m;", LOC);
fail();
- } catch (IllegalArgumentException e) {
+ } catch (ParseException e) {
// Expected
}
}
@@ -255,6 +260,28 @@ public class ExtendedDecimalFormatTest {
assertEquals("1_000,0", ExtendedDecimalFormatParser.parse(",000.0;;grp=_", Locale.FRANCE).format(1000));
}
+ @Test
+ public void testTemplates() throws IOException, TemplateException {
+ Configuration cfg = getConfiguration();
+ cfg.setLocale(Locale.US);
+
+ cfg.setNumberFormat(",000.#");
+ assertOutput("${1000.15} ${1000.25}", "1,000.2 1,000.2");
+ cfg.setNumberFormat(",000.#;; rnd=hu grp=_");
+ assertOutput("${1000.15} ${1000.25}", "1_000.2 1_000.3");
+ cfg.setLocale(Locale.GERMANY);
+ assertOutput("${1000.15} ${1000.25}", "1_000,2 1_000,3");
+ cfg.setLocale(Locale.US);
+ assertOutput(
+ "${1000.15}; "
+ + "${1000.15?string(',##.#;;grp=\" \"')}; "
+ + "<#setting locale='de_DE'>${1000.15}; "
+ + "<#setting numberFormat='0.0;;rnd=d'>${1000.15}",
+ "1_000.2; 10 00.2; 1_000,2; 1000,1");
+ assertErrorContains("${1?string('#E')}", "\"#E\"", "format string", "exponential");
+ assertErrorContains("<#setting numberFormat='#E'>${1}", "\"#E\"", "format string", "exponential");
+ assertErrorContains("<#setting numberFormat=';;foo=bar'>${1}", "\"foo\"", "supported");
+ }
private void assertFormatted(String formatString, Object... numberAndExpectedOutput) throws ParseException {
assertFormatted(LOC, formatString, numberAndExpectedOutput);