You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2009/03/05 01:08:10 UTC

svn commit: r750246 - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry5/internal/translator/ main/java/org/apache/tapestry5/services/ test/java/org/apache/tapestry5/internal/services/

Author: hlship
Date: Thu Mar  5 00:08:09 2009
New Revision: 750246

URL: http://svn.apache.org/viewvc?rev=750246&view=rev
Log:
TAP5-540: Allow exact parsing of numeric client input by creating a BigDecimal Translator and enabling parseBigDecimal in DecimalFormat

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/BigDecimalNumericFormatter.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/BigIntegerNumericFormatter.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/BigTypesFormatter.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericFormatter.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericFormatterImpl.java
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericTranslator.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericTranslatorSupport.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericTranslatorSupportImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TranslatorSourceImplTest.java

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/BigDecimalNumericFormatter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/BigDecimalNumericFormatter.java?rev=750246&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/BigDecimalNumericFormatter.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/BigDecimalNumericFormatter.java Thu Mar  5 00:08:09 2009
@@ -0,0 +1,31 @@
+// Copyright 2009 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.internal.translator;
+
+import java.math.BigDecimal;
+import java.text.DecimalFormatSymbols;
+
+public class BigDecimalNumericFormatter extends BigTypesFormatter
+{
+    public BigDecimalNumericFormatter(DecimalFormatSymbols symbols)
+    {
+        super(symbols);
+    }
+
+    protected Number parseConvertedValue(String converted)
+    {
+        return new BigDecimal(converted);
+    }
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/BigIntegerNumericFormatter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/BigIntegerNumericFormatter.java?rev=750246&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/BigIntegerNumericFormatter.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/BigIntegerNumericFormatter.java Thu Mar  5 00:08:09 2009
@@ -0,0 +1,32 @@
+// Copyright 2009 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.internal.translator;
+
+import java.math.BigInteger;
+import java.text.DecimalFormatSymbols;
+
+public class BigIntegerNumericFormatter extends BigTypesFormatter
+{
+    public BigIntegerNumericFormatter(DecimalFormatSymbols symbols)
+    {
+        super(symbols);
+    }
+
+
+    protected Number parseConvertedValue(String fixedNeg)
+    {
+        return new BigInteger(fixedNeg);
+    }
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/BigTypesFormatter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/BigTypesFormatter.java?rev=750246&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/BigTypesFormatter.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/BigTypesFormatter.java Thu Mar  5 00:08:09 2009
@@ -0,0 +1,65 @@
+// Copyright 2009 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.internal.translator;
+
+import java.text.DecimalFormatSymbols;
+import java.text.ParseException;
+
+/**
+ * Base class for parsing/formatting BigInteger and BigDecimal.
+ *
+ * @since 5.1.0.1
+ */
+public abstract class BigTypesFormatter implements NumericFormatter
+{
+    protected final DecimalFormatSymbols symbols;
+
+    public BigTypesFormatter(DecimalFormatSymbols symbols)
+    {
+        this.symbols = symbols;
+    }
+
+    protected String toString(char ch)
+    {
+        return String.valueOf(ch);
+    }
+
+    public String toClient(Number value)
+    {
+        String normal = value.toString();
+
+        // When formatting integers, we don't use the grouping seperator.
+
+        return normal.replace('-', symbols.getMinusSign()).replace('.', symbols.getDecimalSeparator());
+    }
+
+    public Number parse(String clientValue) throws ParseException
+    {
+        String noGroups = clientValue.replace(toString(symbols.getGroupingSeparator()), "");
+        String fixedNeg = noGroups.replace(symbols.getMinusSign(), '-');
+        String fixedDec = fixedNeg.replace(symbols.getDecimalSeparator(), '.');
+
+        try
+        {
+            return parseConvertedValue(fixedDec);
+        }
+        catch (NumberFormatException ex)
+        {
+            throw new ParseException(ex.getMessage(), 0);
+        }
+    }
+
+    protected abstract Number parseConvertedValue(String converted);
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericFormatter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericFormatter.java?rev=750246&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericFormatter.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericFormatter.java Thu Mar  5 00:08:09 2009
@@ -0,0 +1,36 @@
+// Copyright 2009 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.internal.translator;
+
+import java.text.ParseException;
+
+/**
+ * Interface for defining the basic parse and toClient operations. The typical implementation is based on {@link
+ * java.text.NumberFormat} but alternate implementations are used for BigInteger and BigDecimal.
+ *
+ * @since 5.1.0.1
+ */
+public interface NumericFormatter
+{
+    /**
+     * Parses a value from the client in a locale-specific way.
+     */
+    Number parse(String clientValue) throws ParseException;
+
+    /**
+     * Formats a value for the client in a locale-specific way.
+     */
+    String toClient(Number value);
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericFormatterImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericFormatterImpl.java?rev=750246&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericFormatterImpl.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericFormatterImpl.java Thu Mar  5 00:08:09 2009
@@ -0,0 +1,43 @@
+// Copyright 2009 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.internal.translator;
+
+import java.text.NumberFormat;
+import java.text.ParseException;
+
+/**
+ * A wrapper around NumberFormat.
+ *
+ * @since 5.1.0.1
+ */
+public class NumericFormatterImpl implements NumericFormatter
+{
+    private final NumberFormat format;
+
+    public NumericFormatterImpl(NumberFormat format)
+    {
+        this.format = format;
+    }
+
+    public Number parse(String clientValue) throws ParseException
+    {
+        return format.parse(clientValue);
+    }
+
+    public String toClient(Number value)
+    {
+        return format.format(value);
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericTranslator.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericTranslator.java?rev=750246&r1=750245&r2=750246&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericTranslator.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericTranslator.java Thu Mar  5 00:08:09 2009
@@ -21,7 +21,13 @@
 
 import java.text.ParseException;
 
-public class NumericTranslator<T> extends AbstractTranslator<T>
+/**
+ * Uses a {@link org.apache.tapestry5.internal.translator.NumericTranslatorSupport} to provide proper locale-aware
+ * support for all the built-in numeric types.
+ *
+ * @since 5.1.0.1
+ */
+public class NumericTranslator<T extends Number> extends AbstractTranslator<T>
 {
     private final NumericTranslatorSupport support;
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericTranslatorSupport.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericTranslatorSupport.java?rev=750246&r1=750245&r2=750246&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericTranslatorSupport.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericTranslatorSupport.java Thu Mar  5 00:08:09 2009
@@ -36,7 +36,7 @@
      * @throws ParseException
      * @see org.apache.tapestry5.Translator#parseClient(org.apache.tapestry5.Field, String, String)
      */
-    <T> T parseClient(Class<T> type, String clientValue) throws ParseException;
+    <T extends Number> T parseClient(Class<T> type, String clientValue) throws ParseException;
 
     /**
      * Converts a server-side value to a client-side string. Integer types are formatted simply; decimal types may be
@@ -47,7 +47,7 @@
      * @param <T>
      * @return value formatted
      */
-    <T> String toClient(Class<T> type, T value);
+    <T extends Number> String toClient(Class<T> type, T value);
 
     /**
      * Returns the default message key for parse failures for the indicated type.
@@ -56,7 +56,7 @@
      * @param <T>
      * @return a message key: either "integer-format-exception" or "number-format-exception"
      */
-    <T> String getMessageKey(Class<T> type);
+    <T extends Number> String getMessageKey(Class<T> type);
 
     /**
      * Adds client-side format validation for the field, appropriate to the indicated type.
@@ -66,5 +66,5 @@
      * @param message message if the client-side value can't be parsed as a number
      * @param <T>
      */
-    <T> void addValidation(Class<T> type, Field field, String message);
+    <T extends Number> void addValidation(Class<T> type, Field field, String message);
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericTranslatorSupportImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericTranslatorSupportImpl.java?rev=750246&r1=750245&r2=750246&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericTranslatorSupportImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericTranslatorSupportImpl.java Thu Mar  5 00:08:09 2009
@@ -23,6 +23,7 @@
 import org.apache.tapestry5.services.ClientBehaviorSupport;
 import org.apache.tapestry5.services.Request;
 
+import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
@@ -68,7 +69,7 @@
 
     }
 
-    public <T> void addValidation(Class<T> type, Field field, String message)
+    public <T extends Number> void addValidation(Class<T> type, Field field, String message)
     {
         if (request.getAttribute(DECIMAL_FORMAT_SYMBOLS_PROVIDED) == null)
         {
@@ -113,52 +114,81 @@
         return integerTypes.contains(type);
     }
 
-    public <T> T parseClient(Class<T> type, String clientValue) throws ParseException
+    public <T extends Number> T parseClient(Class<T> type, String clientValue) throws ParseException
     {
-        NumberFormat formatter = getParseFormatter(type);
+        NumericFormatter formatter = getParseFormatter(type);
 
         Number number = formatter.parse(clientValue.trim());
 
         return typeCoercer.coerce(number, type);
     }
 
-    private NumberFormat getParseFormatter(Class type)
+    private NumericFormatter getParseFormatter(Class type)
     {
         Locale locale = threadLocale.getLocale();
+        DecimalFormatSymbols symbols = getSymbols(locale);
+
+        if (type.equals(BigInteger.class))
+            return new BigIntegerNumericFormatter(symbols);
 
-        boolean isInteger = isIntegerType(type);
+        if (type.equals(BigDecimal.class))
+            return new BigDecimalNumericFormatter(symbols);
 
         // We don't cache NumberFormat instances because they are not thread safe.
         // Perhaps we should turn this service into a perthread so that we can cache
         // (for the duration of a request)?
 
-        return isInteger ? NumberFormat.getIntegerInstance(locale)
-                         : NumberFormat.getNumberInstance(locale);
+        // We don't cache the rest of these, because they are built on DecimalFormat which is
+        // not thread safe.
+
+        if (isIntegerType(type))
+        {
+            NumberFormat format = NumberFormat.getIntegerInstance(locale);
+            return new NumericFormatterImpl(format);
+        }
 
+        DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(locale);
+
+        if (type.equals(BigDecimal.class))
+            df.setParseBigDecimal(true);
+
+        return new NumericFormatterImpl(df);
     }
 
-    private NumberFormat getOutputFormatter(Class type)
+    private NumericFormatter getOutputFormatter(Class type)
     {
         Locale locale = threadLocale.getLocale();
 
-        boolean isInteger = isIntegerType(type);
+        DecimalFormatSymbols symbols = getSymbols(locale);
 
-        if (!isInteger) return NumberFormat.getNumberInstance(locale);
+        if (type.equals(BigInteger.class))
+            return new BigIntegerNumericFormatter(symbols);
 
-        DecimalFormatSymbols symbols = getSymbols(locale);
+        if (type.equals(BigDecimal.class))
+            return new BigDecimalNumericFormatter(symbols);
 
-        return new DecimalFormat(toString(symbols.getZeroDigit()), symbols);
+
+        // We don't cache the rest of these, because they are built on DecimalFormat which is
+        // not thread safe.
+
+        if (!isIntegerType(type))
+        {
+            NumberFormat format = NumberFormat.getNumberInstance(locale);
+
+            return new NumericFormatterImpl(format);
+        }
+
+        DecimalFormat df = new DecimalFormat(toString(symbols.getZeroDigit()), symbols);
+
+        return new NumericFormatterImpl(df);
     }
 
-    public <T> String toClient(Class<T> type, T value)
+    public <T extends Number> String toClient(Class<T> type, T value)
     {
-        // TODO: The default includes the comma (thousands grouping) seperators.
-        // I don't think most people want that!
-
-        return getOutputFormatter(type).format(value);
+        return getOutputFormatter(type).toClient(value);
     }
 
-    public <T> String getMessageKey(Class<T> type)
+    public <T extends Number> String getMessageKey(Class<T> type)
     {
         return isIntegerType(type)
                ? "integer-format-exception"

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java?rev=750246&r1=750245&r2=750246&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java Thu Mar  5 00:08:09 2009
@@ -58,6 +58,8 @@
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.lang.annotation.Annotation;
+import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.net.URL;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
@@ -783,7 +785,7 @@
 
     /**
      * Contributes the basic set of translators: <ul>  <li>string</li>  <li>byte</li> <li>short</li> <li>integer</li>
-     * <li>long</li> <li>float</li> <li>double</li>  </ul>
+     * <li>long</li> <li>float</li> <li>double</li>  <li>BigInteger</li> <li>BigDecimal</li></ul>
      */
     public static void contributeTranslatorSource(Configuration<Translator> configuration,
                                                   NumericTranslatorSupport support)
@@ -791,7 +793,8 @@
 
         configuration.add(new StringTranslator());
 
-        Class[] types = new Class[] { Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class };
+        Class[] types = new Class[] { Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class,
+                BigInteger.class, BigDecimal.class };
 
         for (Class type : types)
         {

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TranslatorSourceImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TranslatorSourceImplTest.java?rev=750246&r1=750245&r2=750246&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TranslatorSourceImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/TranslatorSourceImplTest.java Thu Mar  5 00:08:09 2009
@@ -18,6 +18,8 @@
 import org.apache.tapestry5.Translator;
 import org.apache.tapestry5.ValidationException;
 import org.apache.tapestry5.internal.test.InternalBaseTestCase;
+import org.apache.tapestry5.internal.translator.BigDecimalNumericFormatter;
+import org.apache.tapestry5.internal.translator.BigIntegerNumericFormatter;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry5.ioc.services.ThreadLocale;
 import org.apache.tapestry5.services.TranslatorSource;
@@ -25,6 +27,10 @@
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.text.DecimalFormatSymbols;
+import java.text.ParseException;
 import java.util.Collection;
 import java.util.Locale;
 
@@ -94,13 +100,23 @@
 
                 { Long.class, 12345l, "12345" },
 
-                { Double.class, 123.45d, "123.45" },
+                // Is this a bug?  We seem to be using a JDK- or locale-defined level of precision.
+                // Maybe translators need room for configuration just like validators, so that
+                // the correct decimal format string could be specified in the message catalog.
+
+                { Double.class, 3.1428571429d, "3.143" },
 
                 { String.class, "abcd", "abcd" },
 
                 { Short.class, (short) 95, "95" },
 
-                { Float.class, (float) -22.7, "-22.7" }
+                { Float.class, (float) -22.7, "-22.7" },
+
+                { BigInteger.class, new BigInteger("123456789012345678901234567890"),
+                        "123456789012345678901234567890" },
+
+                { BigDecimal.class, new BigDecimal("-9876543219876543321987654321.12345123451234512345"),
+                        "-9876543219876543321987654321.12345123451234512345" }
         };
     }
 
@@ -129,11 +145,17 @@
 
                 { Long.class, "  -1234567 ", -1234567l },
 
-                { Double.class, " 3.14 ", 3.14d },
+                { Double.class, "3.1428571429", 3.1428571429d },
 
                 { String.class, " abcdef ", " abcdef " },
 
                 { Float.class, " 28.95 ", (float) 28.95 },
+
+                { BigInteger.class, " -123456789012345678901234567890",
+                        new BigInteger("-123456789012345678901234567890") },
+
+                { BigDecimal.class, "-9,876,543,219,876,543,321,987,654,321.12345123451234512345",
+                        new BigDecimal("-9876543219876543321987654321.12345123451234512345") }
         };
     }
 
@@ -232,4 +254,39 @@
 
         verify();
     }
+
+    @Test
+    public void biginteger_with_localized_symbols() throws ParseException
+    {
+        DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.ENGLISH);
+        symbols.setGroupingSeparator('_');
+        symbols.setMinusSign('*');
+
+        BigIntegerNumericFormatter f = new BigIntegerNumericFormatter(symbols);
+
+        BigInteger big = new BigInteger("-123456");
+
+        assertEquals(f.parse("*123_456"), big);
+
+        assertEquals(f.toClient(big), "*123456");
+    }
+
+    @Test
+    public void bigdecimal_with_localized_symbols() throws ParseException
+    {
+        DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.ENGLISH);
+        symbols.setGroupingSeparator('_');
+        symbols.setMinusSign('*');
+        symbols.setDecimalSeparator('#');
+
+        BigDecimalNumericFormatter f = new BigDecimalNumericFormatter(symbols);
+
+        BigDecimal big = new BigDecimal("-123456.797956563434");
+
+        assertEquals(f.parse("*123_456#797956563434"), big);
+
+        assertEquals(f.toClient(big), "*123456#797956563434");
+    }
+
+
 }