You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by st...@apache.org on 2011/02/05 18:52:30 UTC
svn commit: r1067470 - in /myfaces/core/trunk/api/src:
main/java/javax/faces/convert/DoubleConverter.java
test/java/javax/faces/convert/DoubleConverterTest.java
Author: struberg
Date: Sat Feb 5 17:52:29 2011
New Revision: 1067470
URL: http://svn.apache.org/viewvc?rev=1067470&view=rev
Log:
MYFACES-3029 fix non-Locale.US decimal seperators in DoubleConverter
Added:
myfaces/core/trunk/api/src/test/java/javax/faces/convert/DoubleConverterTest.java
Modified:
myfaces/core/trunk/api/src/main/java/javax/faces/convert/DoubleConverter.java
Modified: myfaces/core/trunk/api/src/main/java/javax/faces/convert/DoubleConverter.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/convert/DoubleConverter.java?rev=1067470&r1=1067469&r2=1067470&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/convert/DoubleConverter.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/convert/DoubleConverter.java Sat Feb 5 17:52:29 2011
@@ -23,6 +23,12 @@ import javax.faces.context.FacesContext;
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFConverter;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.util.Locale;
+
/**
* see Javadoc of <a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/index.html">JSF Specification</a>
*
@@ -56,7 +62,8 @@ public class DoubleConverter
{
try
{
- return Double.valueOf(value);
+ value = fixLocale(facesContext, value);
+ return this.stringToDouble(value);
}
catch (NumberFormatException e)
{
@@ -64,11 +71,67 @@ public class DoubleConverter
DOUBLE_ID,
new Object[]{value,"4214",_MessageUtils.getLabel(facesContext, uiComponent)}), e);
}
+
}
}
return null;
}
+ /**
+ * Since Double.valueOf is not Locale aware, and NumberFormatter
+ * cannot parse E values correctly, we need to make a US Locale
+ * string from our input value.
+ * E.g. '34,383e3' will be translated to '34.383e3' if Locale.DE
+ * is set in the {@link javax.faces.component.UIViewRoot#getLocale()}
+ *
+ * @param facesContext
+ * @param value
+ * @return the 'fixed' value String
+ */
+ private String fixLocale(FacesContext facesContext, String value)
+ {
+ Locale loc = facesContext.getViewRoot().getLocale();
+ if (loc == null || loc == Locale.US)
+ {
+ // nothing to fix if we are already using the US Locale
+ return value;
+ }
+
+
+ DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(loc);
+
+ char decSep = dfs.getDecimalSeparator();
+
+
+ // replace decimal separators which are different to '.'
+ if (decSep != '.' && value.lastIndexOf(decSep) >= 0)
+ {
+ StringBuffer sbVal = new StringBuffer();
+
+ // remove all groupSeperators and change the decimalSeperator
+ for (int i = 0; i < value.length(); i++)
+ {
+ if (value.charAt(i) == decSep)
+ {
+ sbVal.append('.'); // we append the Locale.US decimal separator
+ continue;
+ }
+
+ // just append all other characters as usual
+ sbVal.append(value.charAt(i));
+ }
+
+ value = sbVal.toString();
+ }
+
+ // we need the formatter with the correct Locale of the user
+ return value;
+ }
+
+ private Double stringToDouble(String value) {
+ return Double.valueOf(value);
+ }
+
public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object value)
{
if (facesContext == null) throw new NullPointerException("facesContext");
Added: myfaces/core/trunk/api/src/test/java/javax/faces/convert/DoubleConverterTest.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/test/java/javax/faces/convert/DoubleConverterTest.java?rev=1067470&view=auto
==============================================================================
--- myfaces/core/trunk/api/src/test/java/javax/faces/convert/DoubleConverterTest.java (added)
+++ myfaces/core/trunk/api/src/test/java/javax/faces/convert/DoubleConverterTest.java Sat Feb 5 17:52:29 2011
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 javax.faces.convert;
+
+import org.apache.myfaces.test.base.AbstractJsfTestCase;
+import org.junit.Test;
+
+import javax.faces.component.UIInput;
+import javax.faces.context.FacesContext;
+import java.util.Locale;
+
+/**
+ * Test the {@link DoubleConverter}.
+ */
+public class DoubleConverterTest extends AbstractJsfTestCase {
+
+ private DoubleConverter mock;
+
+ public DoubleConverterTest(String name)
+ {
+ super(name);
+ }
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ mock = new DoubleConverter();
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ super.tearDown();
+
+ mock = null;
+ }
+
+ /**
+ * the focus here is on the comma separator ',' in germany.
+ */
+ @Test(timeout = 2000L)
+ public void testDoubleParsingGermany()
+ {
+ FacesContext.getCurrentInstance().getViewRoot().setLocale(Locale.GERMANY);
+ UIInput input = new UIInput();
+
+ {
+ Double d = (Double) mock.getAsObject(FacesContext.getCurrentInstance(), input, "47,3443");
+ assertNotNull(d);
+ assertEquals(47.3443d, d.doubleValue());
+ }
+
+ {
+ Double d = (Double) mock.getAsObject(FacesContext.getCurrentInstance(), input, "0,3443e3");
+ assertNotNull(d);
+ assertEquals(344.3d, d.doubleValue());
+ }
+
+ {
+ // values with a dot as decimal seperator should still work...
+ Double d = (Double) mock.getAsObject(FacesContext.getCurrentInstance(), input, "0.3443e3");
+ assertNotNull(d);
+ assertEquals(344.3d, d.doubleValue());
+ }
+
+ }
+
+ /**
+ * the focus here is on the comma separator '.' in the US.
+ */
+ @Test(timeout = 2000L)
+ public void testDoubleParsingUS()
+ {
+ FacesContext.getCurrentInstance().getViewRoot().setLocale(Locale.US);
+ UIInput input = new UIInput();
+
+ {
+ Double d = (Double) mock.getAsObject(FacesContext.getCurrentInstance(), input, "47.3443");
+ assertNotNull(d);
+ assertEquals(47.3443d, d.doubleValue());
+ }
+
+ {
+ // german decimal separators are not expected to work here ;)
+ try
+ {
+ Double d = (Double) mock.getAsObject(FacesContext.getCurrentInstance(), input, "47,3443");
+ fail();
+ }
+ catch (ConverterException cev)
+ {
+ // all is well, that was expected ;)
+ }
+
+ }
+
+ }
+
+
+}