You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2017/05/18 13:29:44 UTC
[2/7] struts git commit: WW-3650 Supports double conversion for
different locale
WW-3650 Supports double conversion for different locale
Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/266d78d3
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/266d78d3
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/266d78d3
Branch: refs/heads/master
Commit: 266d78d32c786276f37ae701267f6719ea9f8a75
Parents: f874f9c
Author: Lukasz Lenart <lu...@apache.org>
Authored: Fri May 12 13:48:14 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Fri May 12 13:48:14 2017 +0200
----------------------------------------------------------------------
.../xwork2/conversion/impl/NumberConverter.java | 69 ++++++++++++++++----
.../conversion/impl/NumberConverterTest.java | 27 ++++++++
.../conversion/impl/XWorkConverterTest.java | 24 +++----
3 files changed, 94 insertions(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/struts/blob/266d78d3/core/src/main/java/com/opensymphony/xwork2/conversion/impl/NumberConverter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/NumberConverter.java b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/NumberConverter.java
index 16bbd49..c4a2a1d 100644
--- a/core/src/main/java/com/opensymphony/xwork2/conversion/impl/NumberConverter.java
+++ b/core/src/main/java/com/opensymphony/xwork2/conversion/impl/NumberConverter.java
@@ -1,6 +1,7 @@
package com.opensymphony.xwork2.conversion.impl;
import com.opensymphony.xwork2.XWorkException;
+import com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.message.ParameterizedMessage;
@@ -28,6 +29,8 @@ public class NumberConverter extends DefaultTypeConverter {
return convertToBigDecimal(context, value);
} else if (toType == BigInteger.class) {
return new BigInteger((String) value);
+ } else if (toType == Double.class || toType == double.class) {
+ return convertToDouble(context, value);
} else if (toType.isPrimitive()) {
Object convertedValue = super.convertValue(context, value, toType);
String stringValue = (String) value;
@@ -74,27 +77,65 @@ public class NumberConverter extends DefaultTypeConverter {
Locale locale = getLocale(context);
String strValue = String.valueOf(value);
- NumberFormat format = NumberFormat.getNumberInstance(locale);
- format.setGroupingUsed(true);
+ NumberFormat format = getNumberFormat(locale);
if (format instanceof DecimalFormat) {
((DecimalFormat) format).setParseBigDecimal(true);
char separator = ((DecimalFormat) format).getDecimalFormatSymbols().getGroupingSeparator();
+ strValue = normalize(strValue, separator);
+ }
- // this is a hack as \160 isn't the same as " " (an empty space)
- if (separator == 160) {
- strValue = strValue.replaceAll(" ", "");
- } else {
- strValue = strValue.replaceAll(String.valueOf(separator), "");
- }
+ LOG.debug("Trying to convert a value {} with locale {} to BigDecimal", strValue, locale);
+ ParsePosition parsePosition = new ParsePosition(0);
+ Number number = format.parse(strValue, parsePosition);
+
+ if (parsePosition.getIndex() != strValue.length()) {
+ throw new XWorkException("Unparseable number: \"" + strValue + "\" at position " + parsePosition.getIndex());
}
- try {
- LOG.info("Trying parse value {} with locale {}", strValue, locale);
- return format.parse(strValue);
- } catch (ParseException e) {
- LOG.warn(new ParameterizedMessage("Cannot convert value {} to BigDecimal, trying with default converter", value, e));
- return super.convertValue(context, value, BigDecimal.class);
+ return number;
+ }
+
+ protected Object convertToDouble(Map<String, Object> context, Object value) {
+ Locale locale = getLocale(context);
+ String strValue = String.valueOf(value);
+
+ NumberFormat format = getNumberFormat(locale);
+ if (format instanceof DecimalFormat) {
+ char separator = ((DecimalFormat) format).getDecimalFormatSymbols().getGroupingSeparator();
+ strValue = normalize(strValue, separator);
+ }
+
+ LOG.debug("Trying to convert a value {} with locale {} to Double", strValue, locale);
+ ParsePosition parsePosition = new ParsePosition(0);
+ Number number = format.parse(strValue, parsePosition);
+
+ if (parsePosition.getIndex() != strValue.length()) {
+ throw new XWorkException("Unparseable number: \"" + strValue + "\" at position " + parsePosition.getIndex());
+ }
+
+ if (!isInRange(number, strValue, Double.class)) {
+ throw new XWorkException("Overflow or underflow converting: \"" + strValue + "\" into class " + number.getClass().getName());
+ }
+
+ if (number != null) {
+ return number.doubleValue();
+ }
+
+ return null;
+ }
+
+ protected NumberFormat getNumberFormat(Locale locale) {
+ NumberFormat format = NumberFormat.getNumberInstance(locale);
+ format.setGroupingUsed(true);
+ return format;
+ }
+
+ protected String normalize(String strValue, char separator) {
+ // this is a hack as \160 isn't the same as " " (an empty space)
+ if (separator == 160) {
+ strValue = strValue.replaceAll(" ", String.valueOf(separator));
}
+ return strValue;
}
protected boolean isInRange(Number value, String stringValue, Class toType) {
http://git-wip-us.apache.org/repos/asf/struts/blob/266d78d3/core/src/test/java/com/opensymphony/xwork2/conversion/impl/NumberConverterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/conversion/impl/NumberConverterTest.java b/core/src/test/java/com/opensymphony/xwork2/conversion/impl/NumberConverterTest.java
index ca87aae..8143b00 100644
--- a/core/src/test/java/com/opensymphony/xwork2/conversion/impl/NumberConverterTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/conversion/impl/NumberConverterTest.java
@@ -81,4 +81,31 @@ public class NumberConverterTest extends XWorkTestCase {
assertEquals(BigDecimal.valueOf(100234.4), value);
}
+ public void testStringToDoubleConversionPL() throws Exception {
+ // given
+ NumberConverter converter = new NumberConverter();
+ Map<String, Object> context = new HashMap<>();
+ context.put(ActionContext.LOCALE, new Locale("pl", "PL"));
+
+ // when
+ Object value = converter.convertValue(context, null, null, null, "1234,4567", Double.class);
+
+ // then
+ assertEquals(1234.4567, value);
+ }
+
+ public void testStringToDoubleConversionWithDotsPL() throws Exception {
+ // given
+ NumberConverter converter = new NumberConverter();
+ Map<String, Object> context = new HashMap<>();
+ context.put(ActionContext.LOCALE, new Locale("pl", "PL"));
+
+ // when
+ Object value = converter.convertValue(context, null, null, null, "1 234,4", Double.class);
+
+ // then
+ assertEquals(1234.4, value);
+ }
+
+
}
http://git-wip-us.apache.org/repos/asf/struts/blob/266d78d3/core/src/test/java/com/opensymphony/xwork2/conversion/impl/XWorkConverterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/conversion/impl/XWorkConverterTest.java b/core/src/test/java/com/opensymphony/xwork2/conversion/impl/XWorkConverterTest.java
index be96416..4607805 100644
--- a/core/src/test/java/com/opensymphony/xwork2/conversion/impl/XWorkConverterTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/conversion/impl/XWorkConverterTest.java
@@ -519,30 +519,30 @@ public class XWorkConverterTest extends XWorkTestCase {
}
public void testStringToPrimitiveDouble() {
- assertEquals(new Double(123), converter.convertValue(context, null, null, null, "123", double.class));
+ assertEquals(123d, converter.convertValue(context, null, null, null, "123", double.class));
context.put(ActionContext.LOCALE, Locale.US);
- assertEquals(new Double(123.12), converter.convertValue(context, null, null, null, "123.12", double.class));
+ assertEquals(123.12, converter.convertValue(context, null, null, null, "123.12", double.class));
assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "123aa", double.class));
assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "aa123", double.class));
- assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,234", double.class));
- assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,234.12", double.class));
- assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,23", double.class));
- assertEquals(new Double(1.234), converter.convertValue(context, null, null, null, "1.234", double.class));
+ assertEquals(1234d, converter.convertValue(context, null, null, null, "1,234", double.class));
+ assertEquals(1234.12, converter.convertValue(context, null, null, null, "1,234.12", double.class));
+ assertEquals(123d, converter.convertValue(context, null, null, null, "1,23", double.class));
+ assertEquals(1.234, converter.convertValue(context, null, null, null, "1.234", double.class));
assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1.234,12", double.class));
context.put(ActionContext.LOCALE, Locale.GERMANY);
- assertEquals(new Double(123.12), converter.convertValue(context, null, null, null, "123.12", double.class));
+ assertEquals(12312d, converter.convertValue(context, null, null, null, "123.12", double.class));
assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "123aa", double.class));
assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "aa123", double.class));
- assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,234", double.class));
+ assertEquals(1.234, converter.convertValue(context, null, null, null, "1,234", double.class));
assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,234.12", double.class));
- assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1,23", double.class));
- assertEquals(new Double(1.234), converter.convertValue(context, null, null, null, "1.234", double.class));
- assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1.234,12", double.class));
+ assertEquals(1.23, converter.convertValue(context, null, null, null, "1,23", double.class));
+ assertEquals(1234d, converter.convertValue(context, null, null, null, "1.234", double.class));
+ assertEquals(1234.12, converter.convertValue(context, null, null, null, "1.234,12", double.class));
}
public void testStringToDouble() {
- assertEquals(new Double(123), converter.convertValue(context, null, null, null, "123", Double.class));
+ assertEquals(123d, converter.convertValue(context, null, null, null, "123", Double.class));
context.put(ActionContext.LOCALE, Locale.US);
assertEquals(new Double(123.12), converter.convertValue(context, null, null, null, "123.12", Double.class));
assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "123aa", Double.class));