Skip to content

Commit 04020d7

Browse files
authored
Fixed: Support non-breaking spaces in string to be converted to numeric types (OFBIZ-13168) (#845)
1 parent 10529c3 commit 04020d7

File tree

2 files changed

+18
-0
lines changed

2 files changed

+18
-0
lines changed

framework/base/src/main/java/org/apache/ofbiz/base/util/ObjectType.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import java.io.Serializable;
2222
import java.lang.reflect.InvocationTargetException;
23+
import java.math.BigDecimal;
2324
import java.util.Collection;
2425
import java.util.HashMap;
2526
import java.util.List;
@@ -330,6 +331,15 @@ public static Object simpleTypeOrObjectConvert(Object obj, String type, String f
330331
}
331332

332333
if (converter != null) {
334+
// numeric types : replace non-breaking spaces (which break parsing) by normal spaces
335+
List<?> numericClasses = UtilMisc.toList(BigDecimal.class, Double.class, Float.class);
336+
if (obj instanceof String && numericClasses.contains(targetClass)) {
337+
final String[] tmp = {String.valueOf(obj)};
338+
List<Character> nonBreakingWhitespaces = UtilMisc.toList('\u00A0', '\u202F', '\u2007');
339+
nonBreakingWhitespaces.forEach(character -> tmp[0] = tmp[0].replace(character, ' '));
340+
obj = tmp[0];
341+
}
342+
333343
if (converter instanceof LocalizedConverter) {
334344
LocalizedConverter<Object, Object> localizedConverter = UtilGenerics.cast(converter);
335345
if (timeZone == null) {
@@ -345,6 +355,7 @@ public static Object simpleTypeOrObjectConvert(Object obj, String type, String f
345355
throw new GeneralException(e.getMessage(), e);
346356
}
347357
}
358+
348359
try {
349360
return converter.convert(obj);
350361
} catch (ConversionException e) {

framework/base/src/test/java/org/apache/ofbiz/base/util/ObjectTypeTests.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public class ObjectTypeTests {
4848
// These numbers are all based on 1 / 128, which is a binary decimal
4949
// that can be represented by both float and double
5050
private final BigDecimal dcml = new BigDecimal("781.25");
51+
private final BigDecimal largeBigDecimal = new BigDecimal("29000");
5152
private final Double dbl = Double.valueOf("7.8125E2");
5253
private final Float flt = Float.valueOf("7.8125E2");
5354
private final Long lng = Long.valueOf("781");
@@ -385,6 +386,12 @@ public void testString() throws GeneralException, Exception {
385386
new String[] {"TimeDuration", "org.apache.ofbiz.base.util.TimeDuration"}, duration);
386387
simpleTypeOrObjectConvertTestError("String->error-TimeDuration", "o",
387388
new String[] {"TimeDuration", "org.apache.ofbiz.base.util.TimeDuration"});
389+
390+
// usual pattern assumes that the String->BigDecimal conversion will break with bad timezone/locale
391+
// which is not the case for this particular test
392+
assertEquals("String->BigDecimal supports NBSP",
393+
simpleTypeOrObjectConvert("29 000", "BigDecimal", null, LOCALE_DATA.goodTimeZone,
394+
LOCALE_DATA.goodLocale, false), largeBigDecimal);
388395
}
389396

390397
@Test

0 commit comments

Comments
 (0)