freemarker-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ddek...@apache.org
Subject [12/15] incubator-freemarker git commit: Extended decimal format strings now support options "curc" for CURrency Code (ISO 4217), "curs" for CURency Symbol, and "mdec" for the monetary version of "dec". Just like the other extended format options, these
Date Wed, 16 Sep 2015 17:59:12 GMT
Extended decimal format strings now support options "curc" for CURrency Code (ISO 4217), "curs"
for CURency Symbol, and "mdec" for the monetary version of "dec". Just like the other extended
format options, these just make long existing DecimalFormat capabilities accessible. Examples:
"0.## ¤;;curs=bucks"  prints something like "10 bucks", "¤0.##;;curc=USD" prints "$10" (at
least if locale is US).


Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/9ca1a710
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/9ca1a710
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/9ca1a710

Branch: refs/heads/2.3
Commit: 9ca1a710efd7a2a8d7e399c10cffa9d6dbb4e5a1
Parents: be9500d
Author: ddekany <ddekany@apache.org>
Authored: Wed Sep 16 17:38:44 2015 +0200
Committer: ddekany <ddekany@apache.org>
Committed: Wed Sep 16 17:41:46 2015 +0200

----------------------------------------------------------------------
 .../core/ExtendedDecimalFormatParser.java       | 102 ++++++++++++-------
 .../core/ExtendedDecimalFormatTest.java         |  27 ++++-
 2 files changed, 90 insertions(+), 39 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9ca1a710/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 0a14126..b3f218f 100644
--- a/src/main/java/freemarker/core/ExtendedDecimalFormatParser.java
+++ b/src/main/java/freemarker/core/ExtendedDecimalFormatParser.java
@@ -23,6 +23,7 @@ import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
 import java.text.ParseException;
 import java.util.Arrays;
+import java.util.Currency;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Set;
@@ -36,7 +37,6 @@ class ExtendedDecimalFormatParser {
     static {
         HashMap<String, ParameterHandler> m = new HashMap<String, ParameterHandler>();
         m.put("rnd", new ParameterHandler() {
-
             public void handle(ExtendedDecimalFormatParser parser, String value)
                     throws InvalidParameterValueException {
                 RoundingMode parsedValue;
@@ -68,7 +68,6 @@ class ExtendedDecimalFormatParser {
             }
         });
         m.put("mul", new ParameterHandler() {
-
             public void handle(ExtendedDecimalFormatParser parser, String value)
                     throws InvalidParameterValueException {
                 try {
@@ -79,7 +78,6 @@ class ExtendedDecimalFormatParser {
             }
         });
         m.put("dec", new ParameterHandler() {
-
             public void handle(ExtendedDecimalFormatParser parser, String value)
                     throws InvalidParameterValueException {
                 if (value.length() != 1) {
@@ -88,8 +86,16 @@ class ExtendedDecimalFormatParser {
                 parser.symbols.setDecimalSeparator(value.charAt(0));
             }
         });
+        m.put("mdec", new ParameterHandler() {
+            public void handle(ExtendedDecimalFormatParser parser, String value)
+                    throws InvalidParameterValueException {
+                if (value.length() != 1) {
+                    throw new InvalidParameterValueException("Must contain exactly 1 character.");
+                }
+                parser.symbols.setMonetaryDecimalSeparator(value.charAt(0));
+            }
+        });
         m.put("grp", new ParameterHandler() {
-
             public void handle(ExtendedDecimalFormatParser parser, String value)
                     throws InvalidParameterValueException {
                 if (value.length() != 1) {
@@ -99,7 +105,6 @@ class ExtendedDecimalFormatParser {
             }
         });
         m.put("exp", new ParameterHandler() {
-
             public void handle(ExtendedDecimalFormatParser parser, String value)
                     throws InvalidParameterValueException {
                 if (_JavaVersions.JAVA_6 == null) {
@@ -110,7 +115,6 @@ class ExtendedDecimalFormatParser {
             }
         });
         m.put("min", new ParameterHandler() {
-
             public void handle(ExtendedDecimalFormatParser parser, String value)
                     throws InvalidParameterValueException {
                 if (value.length() != 1) {
@@ -120,21 +124,18 @@ class ExtendedDecimalFormatParser {
             }
         });
         m.put("inf", new ParameterHandler() {
-
             public void handle(ExtendedDecimalFormatParser parser, String value)
                     throws InvalidParameterValueException {
                 parser.symbols.setInfinity(value);
             }
         });
         m.put("nan", new ParameterHandler() {
-
             public void handle(ExtendedDecimalFormatParser parser, String value)
                     throws InvalidParameterValueException {
                 parser.symbols.setNaN(value);
             }
         });
         m.put("prc", new ParameterHandler() {
-
             public void handle(ExtendedDecimalFormatParser parser, String value)
                     throws InvalidParameterValueException {
                 if (value.length() != 1) {
@@ -144,7 +145,6 @@ class ExtendedDecimalFormatParser {
             }
         });
         m.put("prm", new ParameterHandler() {
-
             public void handle(ExtendedDecimalFormatParser parser, String value)
                     throws InvalidParameterValueException {
                 if (value.length() != 1) {
@@ -154,7 +154,6 @@ class ExtendedDecimalFormatParser {
             }
         });
         m.put("zero", new ParameterHandler() {
-
             public void handle(ExtendedDecimalFormatParser parser, String value)
                     throws InvalidParameterValueException {
                 if (value.length() != 1) {
@@ -163,6 +162,18 @@ class ExtendedDecimalFormatParser {
                 parser.symbols.setZeroDigit(value.charAt(0));
             }
         });
+        m.put("curc", new ParameterHandler() {
+            public void handle(ExtendedDecimalFormatParser parser, String value)
+                    throws InvalidParameterValueException {
+                Currency currency;
+                try {
+                    currency = Currency.getInstance(value);
+                } catch (IllegalArgumentException e) {
+                    throw new InvalidParameterValueException("Not a known ISO 4217 code.");
+                }
+                parser.symbols.setCurrency(currency);
+            }
+        });
         PARAM_HANDLERS = m;
     }
 
@@ -208,7 +219,8 @@ class ExtendedDecimalFormatParser {
             return;
         }
 
-        do {
+        String currencySymbol = null;  // Exceptional, as must be applied after "currency
code"
+        fetchParamters: do {
             int namePos = pos;
             String name = fetchName();
             if (name == null) {
@@ -230,7 +242,20 @@ class ExtendedDecimalFormatParser {
             }
             int paramEndPos = pos;
 
-            applyFormatStringExtensionParameter(name, namePos, value, valuePos);
+            ParameterHandler handler = PARAM_HANDLERS.get(name);
+            if (handler == null) {
+                if (name.equals("curs")) {
+                    currencySymbol = value;
+                } else {
+                    throw newUnknownParameterException(name, namePos);
+                }
+            } else {
+                try {
+                    handler.handle(this, value);
+                } catch (InvalidParameterValueException e) {
+                    throw newInvalidParameterValueException(name, value, valuePos, e);
+                }
+            }
 
             skipWS();
 
@@ -239,41 +264,42 @@ class ExtendedDecimalFormatParser {
                 skipWS();
             } else {
                 if (pos == ln) {
-                    return;
+                    break fetchParamters;
                 }
                 if (pos == paramEndPos) {
                     throw newExpectedSgParseException("parameter separator whitespace or
comma");
                 }
             }
         } while (true);
+        
+        // This is brought out to here to ensure that it's applied after "currency code":
+        if (currencySymbol != null) {
+            symbols.setCurrencySymbol(currencySymbol);
+        }
     }
 
-    private void applyFormatStringExtensionParameter(
-            String name, int namePos, String value, int valuePos) throws ParseException {
-        ParameterHandler handler = PARAM_HANDLERS.get(name);
-        if (handler == null) {
-            StringBuilder sb = new StringBuilder(128);
-            sb.append("Unsupported parameter name, ").append(StringUtil.jQuote(name));
-            sb.append(". The supported names are: ");
-            Set<String> legalNames = PARAM_HANDLERS.keySet();
-            String[] legalNameArr = legalNames.toArray(new String[legalNames.size()]);
-            Arrays.sort(legalNameArr);
-            for (int i = 0; i < legalNameArr.length; i++) {
-                if (i != 0) {
-                    sb.append(", ");
-                }
-                sb.append(legalNameArr[i]);
-            }
-            throw new java.text.ParseException(sb.toString(), namePos);
-        }
+    private ParseException newInvalidParameterValueException(String name, String value, int
valuePos,
+            InvalidParameterValueException e) {
+        return new java.text.ParseException(
+                StringUtil.jQuote(value) + " is an invalid value for the \"" + name + "\"
parameter: "
+                + e.message,
+                valuePos);
+    }
 
-        try {
-            handler.handle(this, value);
-        } catch (InvalidParameterValueException e) {
-            throw new java.text.ParseException(
-                    StringUtil.jQuote(value) + " is an invalid value for the \"" + name +
"\" parameter: " + e.message,
-                    valuePos);
+    private ParseException newUnknownParameterException(String name, int namePos) throws
ParseException {
+        StringBuilder sb = new StringBuilder(128);
+        sb.append("Unsupported parameter name, ").append(StringUtil.jQuote(name));
+        sb.append(". The supported names are: ");
+        Set<String> legalNames = PARAM_HANDLERS.keySet();
+        String[] legalNameArr = legalNames.toArray(new String[legalNames.size()]);
+        Arrays.sort(legalNameArr);
+        for (int i = 0; i < legalNameArr.length; i++) {
+            if (i != 0) {
+                sb.append(", ");
+            }
+            sb.append(legalNameArr[i]);
         }
+        return new java.text.ParseException(sb.toString(), namePos);
     }
 
     private void skipWS() {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/9ca1a710/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 b632069..acd8f8b 100644
--- a/src/test/java/freemarker/core/ExtendedDecimalFormatTest.java
+++ b/src/test/java/freemarker/core/ExtendedDecimalFormatTest.java
@@ -224,6 +224,27 @@ public class ExtendedDecimalFormatTest {
         assertFormatted("0\u2030;; prm='m'", 0.75, "750m");
         
         assertFormatted("0.00;; zero='@'", 10.5, "A@.E@");
+        
+        assertFormatted("0;; curc=USD", 10, "10");
+        assertFormatted("0 \u00A4;; curc=USD", 10, "10 $");
+        assertFormatted("0 \u00A4\u00A4;; curc=USD", 10, "10 USD");
+        assertFormatted(Locale.GERMANY, "0 \u00A4;; curc=EUR", 10, "10 \u20AC");
+        assertFormatted(Locale.GERMANY, "0 \u00A4\u00A4;; curc=EUR", 10, "10 EUR");
+        try {
+            assertFormatted("0;; curc=USDX", 10, "10");
+        } catch (ParseException e) {
+            assertThat(e.getMessage(), containsString("ISO 4217"));
+        }
+        assertFormatted("0 \u00A4;; curc=USD curs=bucks", 10, "10 bucks");
+        assertFormatted("0 \u00A4;; curs=bucks curc=USD", 10, "10 bucks"); // Order doesn't
mater
+        assertFormatted("0 \u00A4\u00A4;; curc=USD curs=bucks", 10, "10 USD"); // International
symbol isn't affected
+        
+        assertFormatted("0.0 \u00A4;; mdec=m", 10.5, "10m5 $");
+        assertFormatted("0.0 kg;; mdec=m", 10.5, "10.5 kg");
+        assertFormatted("0.0 \u00A4;; dec=d", 10.5, "10.5 $");
+        assertFormatted("0.0 kg;; dec=d", 10.5, "10d5 kg");
+        assertFormatted("0.0 \u00A4;; mdec=m dec=d", 10.5, "10m5 $");
+        assertFormatted("0.0 kg;; mdec=m dec=d", 10.5, "10d5 kg");
     }
     
     @Test
@@ -236,11 +257,15 @@ public class ExtendedDecimalFormatTest {
     
 
     private void assertFormatted(String formatString, Object... numberAndExpectedOutput)
throws ParseException {
+        assertFormatted(LOC, formatString, numberAndExpectedOutput);
+    }
+    
+    private void assertFormatted(Locale loc, String formatString, Object... numberAndExpectedOutput)
throws ParseException {
         if (numberAndExpectedOutput.length % 2 != 0) {
             throw new IllegalArgumentException();
         }
         
-        DecimalFormat df = ExtendedDecimalFormatParser.parse(formatString, LOC);
+        DecimalFormat df = ExtendedDecimalFormatParser.parse(formatString, loc);
         Number num = null;
         for (int i = 0; i < numberAndExpectedOutput.length; i++) {
             if (i % 2 == 0) {


Mime
View raw message