Supports string to float conversion based on locale
Project: http://git-wip-us.apache.org/repos/asf/struts/repo Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/51afa631 Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/51afa631 Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/51afa631 Branch: refs/heads/master Commit: 51afa631835ac603da7bce234aeff0b0154e6296 Parents: 45aae9c Author: Lukasz Lenart <lukaszlen...@apache.org> Authored: Wed May 17 07:18:22 2017 +0200 Committer: Lukasz Lenart <lukaszlen...@apache.org> Committed: Wed May 17 07:18:22 2017 +0200 ---------------------------------------------------------------------- .../xwork2/conversion/impl/NumberConverter.java | 71 ++++++++++++++------ .../conversion/impl/NumberConverterTest.java | 26 +++++++ 2 files changed, 76 insertions(+), 21 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/struts/blob/51afa631/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 6e7d231..1fa2512 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 @@ -19,21 +19,24 @@ public class NumberConverter extends DefaultTypeConverter { public Object convertValue(Map<String, Object> context, Object target, Member member, String propertyName, Object value, Class toType) { if (value instanceof String) { + String stringValue = String.valueOf(value); + if (toType == BigDecimal.class) { - return convertToBigDecimal(context, value); + return convertToBigDecimal(context, stringValue); } else if (toType == BigInteger.class) { - return new BigInteger((String) value); + return new BigInteger(stringValue); } else if (toType == Double.class || toType == double.class) { - return convertToDouble(context, value); + return convertToDouble(context, stringValue); + } else if (toType == Float.class || toType == float.class) { + return convertToFloat(context, stringValue); } else if (toType.isPrimitive()) { Object convertedValue = super.convertValue(context, value, toType); - String stringValue = (String) value; + if (!isInRange((Number) convertedValue, stringValue, toType)) throw new XWorkException("Overflow or underflow casting: \"" + stringValue + "\" into class " + convertedValue.getClass().getName()); return convertedValue; } else { - String stringValue = (String) value; if (!toType.isPrimitive() && stringValue.isEmpty()) { return null; } @@ -67,48 +70,46 @@ public class NumberConverter extends DefaultTypeConverter { return super.convertValue(context, value, toType); } - protected Object convertToBigDecimal(Map<String, Object> context, Object value) { + protected Object convertToBigDecimal(Map<String, Object> context, String stringValue) { Locale locale = getLocale(context); - String strValue = String.valueOf(value); NumberFormat format = getNumberFormat(locale); if (format instanceof DecimalFormat) { ((DecimalFormat) format).setParseBigDecimal(true); char separator = ((DecimalFormat) format).getDecimalFormatSymbols().getGroupingSeparator(); - strValue = normalize(strValue, separator); + stringValue = normalize(stringValue, separator); } - LOG.debug("Trying to convert a value {} with locale {} to BigDecimal", strValue, locale); + LOG.debug("Trying to convert a value {} with locale {} to BigDecimal", stringValue, locale); ParsePosition parsePosition = new ParsePosition(0); - Number number = format.parse(strValue, parsePosition); + Number number = format.parse(stringValue, parsePosition); - if (parsePosition.getIndex() != strValue.length()) { - throw new XWorkException("Unparseable number: \"" + strValue + "\" at position " + parsePosition.getIndex()); + if (parsePosition.getIndex() != stringValue.length()) { + throw new XWorkException("Unparseable number: \"" + stringValue + "\" at position " + parsePosition.getIndex()); } return number; } - protected Object convertToDouble(Map<String, Object> context, Object value) { + protected Object convertToDouble(Map<String, Object> context, String stringValue) { 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); + stringValue = normalize(stringValue, separator); } - LOG.debug("Trying to convert a value {} with locale {} to Double", strValue, locale); + LOG.debug("Trying to convert a value {} with locale {} to Double", stringValue, locale); ParsePosition parsePosition = new ParsePosition(0); - Number number = format.parse(strValue, parsePosition); + Number number = format.parse(stringValue, parsePosition); - if (parsePosition.getIndex() != strValue.length()) { - throw new XWorkException("Unparseable number: \"" + strValue + "\" at position " + parsePosition.getIndex()); + if (parsePosition.getIndex() != stringValue.length()) { + throw new XWorkException("Unparseable number: \"" + stringValue + "\" at position " + parsePosition.getIndex()); } - if (!isInRange(number, strValue, Double.class)) { - throw new XWorkException("Overflow or underflow converting: \"" + strValue + "\" into class " + number.getClass().getName()); + if (!isInRange(number, stringValue, Double.class)) { + throw new XWorkException("Overflow or underflow converting: \"" + stringValue + "\" into class " + number.getClass().getName()); } if (number != null) { @@ -118,6 +119,34 @@ public class NumberConverter extends DefaultTypeConverter { return null; } + protected Object convertToFloat(Map<String, Object> context, String stringValue) { + Locale locale = getLocale(context); + + NumberFormat format = getNumberFormat(locale); + if (format instanceof DecimalFormat) { + char separator = ((DecimalFormat) format).getDecimalFormatSymbols().getGroupingSeparator(); + stringValue = normalize(stringValue, separator); + } + + LOG.debug("Trying to convert a value {} with locale {} to Float", stringValue, locale); + ParsePosition parsePosition = new ParsePosition(0); + Number number = format.parse(stringValue, parsePosition); + + if (parsePosition.getIndex() != stringValue.length()) { + throw new XWorkException("Unparseable number: \"" + stringValue + "\" at position " + parsePosition.getIndex()); + } + + if (!isInRange(number, stringValue, Float.class)) { + throw new XWorkException("Overflow or underflow converting: \"" + stringValue + "\" into class " + number.getClass().getName()); + } + + if (number != null) { + return number.floatValue(); + } + + return null; + } + protected NumberFormat getNumberFormat(Locale locale) { NumberFormat format = NumberFormat.getNumberInstance(locale); format.setGroupingUsed(true); http://git-wip-us.apache.org/repos/asf/struts/blob/51afa631/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 8143b00..4ffa684 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 @@ -107,5 +107,31 @@ public class NumberConverterTest extends XWorkTestCase { assertEquals(1234.4, value); } + public void testStringToFloatConversionPL() 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", Float.class); + + // then + assertEquals(1234.4567F, value); + } + + public void testStringToFloatConversionWithDotsPL() 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", Float.class); + + // then + assertEquals(1234.4F, value); + } + }