This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new a24e8e2e8e9b CAMEL-25366: camel-core - Type converter from String or
Number to BigDecimal
a24e8e2e8e9b is described below
commit a24e8e2e8e9b02ce432602878c33e191c0799336
Author: Claus Ibsen <[email protected]>
AuthorDate: Tue Oct 6 09:35:17 2026 +0200
CAMEL-25366: camel-core - Type converter from String or Number to BigDecimal
There was no type converter to BigDecimal, so converting the String
"1000.01"
returned null and simple ${bodyAs(java.math.BigDecimal)},
${convertTo(${body}, java.math.BigDecimal)} and resultType BigDecimal were
empty. Add toBigDecimal next to toBigInteger; a double or float is converted
from its decimal text.
Closes #27402
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Signed-off-by: Claus Ibsen <[email protected]>
---
.../converter/CamelBaseBulkConverterLoader.java | 16 ++++++++++++-
.../apache/camel/converter/ObjectConverter.java | 26 ++++++++++++++++++++++
.../camel/converter/ObjectConverterTest.java | 17 ++++++++++++++
.../apache/camel/language/simple/SimpleTest.java | 10 +++++++++
.../ROOT/pages/camel-4x-upgrade-guide-4_23.adoc | 4 ++++
5 files changed, 72 insertions(+), 1 deletion(-)
diff --git
a/core/camel-base/src/generated/java/org/apache/camel/converter/CamelBaseBulkConverterLoader.java
b/core/camel-base/src/generated/java/org/apache/camel/converter/CamelBaseBulkConverterLoader.java
index 5fd9e96156ac..ff3ecc3fad1a 100644
---
a/core/camel-base/src/generated/java/org/apache/camel/converter/CamelBaseBulkConverterLoader.java
+++
b/core/camel-base/src/generated/java/org/apache/camel/converter/CamelBaseBulkConverterLoader.java
@@ -41,7 +41,7 @@ public final class CamelBaseBulkConverterLoader implements
TypeConverterLoader,
@Override
public int size() {
- return 129;
+ return 130;
}
@Override
@@ -371,6 +371,15 @@ public final class CamelBaseBulkConverterLoader implements
TypeConverterLoader,
if (value instanceof java.lang.StringBuilder) {
return
org.apache.camel.converter.ObjectConverter.toString((java.lang.StringBuilder)
value);
}
+ } else if (to == java.math.BigDecimal.class) {
+ if (value instanceof java.lang.Object) {
+ Object obj =
org.apache.camel.converter.ObjectConverter.toBigDecimal(value);
+ if (obj == null) {
+ return Void.class;
+ } else {
+ return obj;
+ }
+ }
} else if (to == java.math.BigInteger.class) {
if (value instanceof java.lang.Object) {
Object obj =
org.apache.camel.converter.ObjectConverter.toBigInteger(value);
@@ -612,6 +621,7 @@ public final class CamelBaseBulkConverterLoader implements
TypeConverterLoader,
registry.addConverter(new
TypeConvertible<>(java.lang.StringBuffer.class, java.lang.String.class), this);
registry.addConverter(new
TypeConvertible<>(java.io.ByteArrayOutputStream.class, java.lang.String.class),
this);
registry.addConverter(new
TypeConvertible<>(java.lang.StringBuilder.class, java.lang.String.class), this);
+ registry.addConverter(new TypeConvertible<>(java.lang.Object.class,
java.math.BigDecimal.class), this);
registry.addConverter(new TypeConvertible<>(java.lang.Object.class,
java.math.BigInteger.class), this);
registry.addConverter(new
TypeConvertible<>(java.lang.CharSequence.class, java.net.URI.class), this);
registry.addConverter(new TypeConvertible<>(byte[].class,
java.nio.ByteBuffer.class), this);
@@ -944,6 +954,10 @@ public final class CamelBaseBulkConverterLoader implements
TypeConverterLoader,
if (from == java.lang.StringBuilder.class) {
return this;
}
+ } else if (to == java.math.BigDecimal.class) {
+ if (from == java.lang.Object.class) {
+ return this;
+ }
} else if (to == java.math.BigInteger.class) {
if (from == java.lang.Object.class) {
return this;
diff --git
a/core/camel-base/src/main/java/org/apache/camel/converter/ObjectConverter.java
b/core/camel-base/src/main/java/org/apache/camel/converter/ObjectConverter.java
index 9c3bc24cfde7..c06ed01e9a4d 100644
---
a/core/camel-base/src/main/java/org/apache/camel/converter/ObjectConverter.java
+++
b/core/camel-base/src/main/java/org/apache/camel/converter/ObjectConverter.java
@@ -353,4 +353,30 @@ public final class ObjectConverter {
return toNumber(str);
}
+ /**
+ * Returns the converted value, or null if the value is null
+ */
+ @Converter(order = 41, allowNull = true)
+ public static BigDecimal toBigDecimal(Object value) {
+ if (org.apache.camel.util.ObjectHelper.isNaN(value)) {
+ return null;
+ }
+ if (value instanceof String str) {
+ return new BigDecimal(str);
+ }
+
+ if (value instanceof BigDecimal bd) {
+ return bd;
+ } else if (value instanceof BigInteger bi) {
+ return new BigDecimal(bi);
+ } else if (value instanceof Double || value instanceof Float) {
+ // use the decimal text of the value, as the binary value of 0.1
is not exactly 0.1
+ return new BigDecimal(value.toString());
+ } else if (value instanceof Number number) {
+ return BigDecimal.valueOf(number.longValue());
+ } else {
+ return null;
+ }
+ }
+
}
diff --git
a/core/camel-core/src/test/java/org/apache/camel/converter/ObjectConverterTest.java
b/core/camel-core/src/test/java/org/apache/camel/converter/ObjectConverterTest.java
index e818aee68263..28b68040aef8 100644
---
a/core/camel-core/src/test/java/org/apache/camel/converter/ObjectConverterTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/converter/ObjectConverterTest.java
@@ -153,6 +153,23 @@ public class ObjectConverterTest {
assertEquals(BigInteger.ONE, ObjectConverter.toBigInteger(1.9d));
}
+ @Test
+ public void testToBigDecimal() {
+ assertEquals(new BigDecimal("1000.01"),
ObjectConverter.toBigDecimal("1000.01"));
+ assertEquals(new BigDecimal("4"), ObjectConverter.toBigDecimal("4"));
+ assertEquals(BigDecimal.valueOf(4),
ObjectConverter.toBigDecimal(Integer.valueOf("4")));
+ assertEquals(BigDecimal.valueOf(4),
ObjectConverter.toBigDecimal(Long.valueOf("4")));
+ assertEquals(new BigDecimal("14350442579497085228"),
+ ObjectConverter.toBigDecimal(new
BigInteger("14350442579497085228")));
+ // the decimal text of the value, not the exact binary value of the
double or float
+ assertEquals(new BigDecimal("0.1"),
ObjectConverter.toBigDecimal(0.1d));
+ assertEquals(new BigDecimal("0.1"),
ObjectConverter.toBigDecimal(0.1f));
+ assertNull(ObjectConverter.toBigDecimal(new Date()));
+ assertNull(ObjectConverter.toBigDecimal(Double.NaN));
+ assertNull(ObjectConverter.toBigDecimal(Float.NaN));
+ assertThrows(NumberFormatException.class, () ->
ObjectConverter.toBigDecimal("abc"));
+ }
+
@Test
public void testToString() {
assertEquals("ABC", ObjectConverter.toString(new StringBuffer("ABC")));
diff --git
a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
index 67f3b96d87de..3e29ee9a5e56 100644
---
a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
@@ -19,6 +19,7 @@ package org.apache.camel.language.simple;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.ArrayList;
@@ -679,6 +680,15 @@ public class SimpleTest extends LanguageTestSupport {
assertIsInstanceOf(ClassNotFoundException.class, e.getCause());
}
+ @Test
+ public void testBodyAsBigDecimal() {
+ exchange.getIn().setBody("1000.01");
+ assertExpression("${bodyAs(java.math.BigDecimal)}", new
BigDecimal("1000.01"));
+ assertExpression("${convertTo(${body}, java.math.BigDecimal)}", new
BigDecimal("1000.01"));
+ Expression expression =
context.resolveLanguage("simple").createExpression("${body}");
+ assertEquals(new BigDecimal("1000.01"), expression.evaluate(exchange,
BigDecimal.class));
+ }
+
@Test
public void testMandatoryBodyAs() {
assertExpression("${mandatoryBodyAs(String)}", "<hello
id='m123'>world!</hello>");
diff --git
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
index 9c91357c9d45..12fc32e9a85e 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
@@ -1283,6 +1283,10 @@ interfaces are tried before the super class at each
level, and `java.lang.Object
* Converting a `String` to a `Number` now returns an `Integer` for all values
within the `Integer` range
(including `Integer.MAX_VALUE`, which returned a `Long` before), and supports
exponent notation such as `1e5`.
* Converting a `BigDecimal`, or a `double` larger than a `long`, to
`BigInteger` no longer loses precision.
+* A `String` or a `Number` can now be converted to `BigDecimal`. There was no
such type converter before, so the
+conversion returned `null`: `${bodyAs(java.math.BigDecimal)}` was empty for a
body of `"1000.01"`, and a bean method
+with a `BigDecimal` parameter could not be called with a `String` body. A
`double` or `float` is converted from its
+decimal text, so `0.1` becomes `0.1`.
* Converting a `byte[]` to `char` no longer sign-extends bytes above 127.
* Converting a `String` to `ByteBuffer` now uses the charset from the
`CamelCharsetName` header or exchange
property (like the other converters), and falls back to the default charset.