diff --git a/framework/base/src/main/java/org/apache/ofbiz/base/util/ObjectType.java b/framework/base/src/main/java/org/apache/ofbiz/base/util/ObjectType.java index 6e98f5bd66..74b54b8032 100644 --- a/framework/base/src/main/java/org/apache/ofbiz/base/util/ObjectType.java +++ b/framework/base/src/main/java/org/apache/ofbiz/base/util/ObjectType.java @@ -20,6 +20,7 @@ import java.io.Serializable; import java.lang.reflect.InvocationTargetException; +import java.math.BigDecimal; import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -330,6 +331,15 @@ public static Object simpleTypeOrObjectConvert(Object obj, String type, String f } if (converter != null) { + // numeric types : replace non-breaking spaces (which break parsing) by normal spaces + List numericClasses = UtilMisc.toList(BigDecimal.class, Double.class, Float.class); + if (obj instanceof String && numericClasses.contains(targetClass)) { + final String[] tmp = {String.valueOf(obj)}; + List nonBreakingWhitespaces = UtilMisc.toList('\u00A0', '\u202F', '\u2007'); + nonBreakingWhitespaces.forEach(character -> tmp[0] = tmp[0].replace(character, ' ')); + obj = tmp[0]; + } + if (converter instanceof LocalizedConverter) { LocalizedConverter localizedConverter = UtilGenerics.cast(converter); if (timeZone == null) { @@ -345,6 +355,7 @@ public static Object simpleTypeOrObjectConvert(Object obj, String type, String f throw new GeneralException(e.getMessage(), e); } } + try { return converter.convert(obj); } catch (ConversionException e) { diff --git a/framework/base/src/test/java/org/apache/ofbiz/base/util/ObjectTypeTests.java b/framework/base/src/test/java/org/apache/ofbiz/base/util/ObjectTypeTests.java index c6308597fd..0afdd88b73 100644 --- a/framework/base/src/test/java/org/apache/ofbiz/base/util/ObjectTypeTests.java +++ b/framework/base/src/test/java/org/apache/ofbiz/base/util/ObjectTypeTests.java @@ -48,6 +48,7 @@ public class ObjectTypeTests { // These numbers are all based on 1 / 128, which is a binary decimal // that can be represented by both float and double private final BigDecimal dcml = new BigDecimal("781.25"); + private final BigDecimal largeBigDecimal = new BigDecimal("29000"); private final Double dbl = Double.valueOf("7.8125E2"); private final Float flt = Float.valueOf("7.8125E2"); private final Long lng = Long.valueOf("781"); @@ -385,6 +386,12 @@ public void testString() throws GeneralException, Exception { new String[] {"TimeDuration", "org.apache.ofbiz.base.util.TimeDuration"}, duration); simpleTypeOrObjectConvertTestError("String->error-TimeDuration", "o", new String[] {"TimeDuration", "org.apache.ofbiz.base.util.TimeDuration"}); + + // usual pattern assumes that the String->BigDecimal conversion will break with bad timezone/locale + // which is not the case for this particular test + assertEquals("String->BigDecimal supports NBSP", + simpleTypeOrObjectConvert("29 000", "BigDecimal", null, LOCALE_DATA.goodTimeZone, + LOCALE_DATA.goodLocale, false), largeBigDecimal); } @Test