This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch allow-null in repository https://gitbox.apache.org/repos/asf/camel.git
commit 04eb0bda269157cadd4157b75df647efdd3fecc6 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Thu Apr 10 18:22:17 2025 +0200 CAMEL-21949: camel-core - Type converter with allowNull should be a valid response for ConvertBodyTo --- .../InstanceMethodFallbackTypeConverter.java | 6 +++- .../converter/InstanceMethodTypeConverter.java | 6 +++- .../StaticMethodFallbackTypeConverter.java | 6 +++- .../impl/converter/StaticMethodTypeConverter.java | 6 +++- .../converter/ConvertBodyAllowNullTest.java | 35 +++++++++++++++++++++- .../processor/converter/custom/MyConverter.java | 7 ++++- .../org/apache/camel/main/scan/MyConverter.java | 1 + 7 files changed, 61 insertions(+), 6 deletions(-) diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/converter/InstanceMethodFallbackTypeConverter.java b/core/camel-base/src/main/java/org/apache/camel/impl/converter/InstanceMethodFallbackTypeConverter.java index 755f90fc4fb..5f99f9dac3d 100644 --- a/core/camel-base/src/main/java/org/apache/camel/impl/converter/InstanceMethodFallbackTypeConverter.java +++ b/core/camel-base/src/main/java/org/apache/camel/impl/converter/InstanceMethodFallbackTypeConverter.java @@ -61,9 +61,13 @@ public class InstanceMethodFallbackTypeConverter extends TypeConverterSupport { if (instance == null) { throw new RuntimeCamelException("Could not instantiate an instance of: " + type.getCanonicalName()); } - return useExchange + Object answer = useExchange ? (T) ObjectHelper.invokeMethod(method, instance, type, exchange, value, registry) : (T) ObjectHelper .invokeMethod(method, instance, type, value, registry); + if (answer == null && allowNull) { + answer = Void.class; + } + return (T) answer; } } diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/converter/InstanceMethodTypeConverter.java b/core/camel-base/src/main/java/org/apache/camel/impl/converter/InstanceMethodTypeConverter.java index c4f4d71c011..30c273757c6 100644 --- a/core/camel-base/src/main/java/org/apache/camel/impl/converter/InstanceMethodTypeConverter.java +++ b/core/camel-base/src/main/java/org/apache/camel/impl/converter/InstanceMethodTypeConverter.java @@ -60,9 +60,13 @@ public class InstanceMethodTypeConverter extends TypeConverterSupport { if (instance == null) { throw new RuntimeCamelException("Could not instantiate an instance of: " + type.getCanonicalName()); } - return useExchange + Object answer = useExchange ? (T) ObjectHelper.invokeMethod(method, instance, value, exchange) : (T) ObjectHelper .invokeMethod(method, instance, value); + if (answer == null && allowNull) { + answer = Void.class; + } + return (T) answer; } } diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/converter/StaticMethodFallbackTypeConverter.java b/core/camel-base/src/main/java/org/apache/camel/impl/converter/StaticMethodFallbackTypeConverter.java index 73ac6bacf0a..4a5e4f92d50 100644 --- a/core/camel-base/src/main/java/org/apache/camel/impl/converter/StaticMethodFallbackTypeConverter.java +++ b/core/camel-base/src/main/java/org/apache/camel/impl/converter/StaticMethodFallbackTypeConverter.java @@ -53,9 +53,13 @@ public class StaticMethodFallbackTypeConverter extends TypeConverterSupport { @Override @SuppressWarnings("unchecked") public <T> T convertTo(Class<T> type, Exchange exchange, Object value) { - return useExchange + Object answer = useExchange ? (T) ObjectHelper.invokeMethod(method, null, type, exchange, value, registry) : (T) ObjectHelper.invokeMethod(method, null, type, value, registry); + if (answer == null && allowNull) { + answer = Void.class; + } + return (T) answer; } } diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/converter/StaticMethodTypeConverter.java b/core/camel-base/src/main/java/org/apache/camel/impl/converter/StaticMethodTypeConverter.java index 81d5ab90696..9d6385f2f0a 100644 --- a/core/camel-base/src/main/java/org/apache/camel/impl/converter/StaticMethodTypeConverter.java +++ b/core/camel-base/src/main/java/org/apache/camel/impl/converter/StaticMethodTypeConverter.java @@ -50,9 +50,13 @@ public class StaticMethodTypeConverter extends TypeConverterSupport { @Override @SuppressWarnings("unchecked") public <T> T convertTo(Class<T> type, Exchange exchange, Object value) { - return useExchange + Object answer = useExchange ? (T) ObjectHelper.invokeMethod(method, null, value, exchange) : (T) ObjectHelper.invokeMethod(method, null, value); + if (answer == null && allowNull) { + answer = Void.class; + } + return (T) answer; } } diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/converter/ConvertBodyAllowNullTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/converter/ConvertBodyAllowNullTest.java index 4336d94de3c..9af723f7601 100644 --- a/core/camel-core/src/test/java/org/apache/camel/processor/converter/ConvertBodyAllowNullTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/processor/converter/ConvertBodyAllowNullTest.java @@ -20,12 +20,42 @@ import org.apache.camel.ContextTestSupport; import org.apache.camel.Exchange; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.processor.converter.custom.MyBean; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; public class ConvertBodyAllowNullTest extends ContextTestSupport { - // TODO: custom type converter with allow null + @Test + public void testConvertMyBean() throws Exception { + MyBean custom = context.getTypeConverter().convertTo(MyBean.class, "1:2"); + Assertions.assertNotNull(custom); + + custom = context.getTypeConverter().convertTo(MyBean.class, ""); + Assertions.assertNull(custom); + } + + @Test + public void testCustomConvertToAllowNullOptional() throws Exception { + MockEndpoint result = getMockEndpoint("mock:result"); + result.expectedMessageCount(1); + result.message(0).body().isInstanceOf(MyBean.class); + + template.sendBody("direct:custom-optional", "1:2"); + + assertMockEndpointsSatisfied(); + } + + @Test + public void testCustomConvertToAllowNull() throws Exception { + MockEndpoint result = getMockEndpoint("mock:result"); + result.expectedMessageCount(1); + result.message(0).body().isNull(); + + template.sendBody("direct:custom-mandatory", ""); + + assertMockEndpointsSatisfied(); + } @Test public void testConvertAllowNull() throws Exception { @@ -143,6 +173,9 @@ public class ConvertBodyAllowNullTest extends ContextTestSupport { from("direct:var-optional").convertVariableTo("foo", Integer.class, false).to("mock:result"); from("direct:var-mandatory").convertVariableTo("foo", Integer.class).to("mock:result"); + + from("direct:custom-optional").convertBodyTo(MyBean.class, false).to("mock:result"); + from("direct:custom-mandatory").convertBodyTo(MyBean.class).to("mock:result"); } }; } diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/converter/custom/MyConverter.java b/core/camel-core/src/test/java/org/apache/camel/processor/converter/custom/MyConverter.java index 753b85f751e..aa2d0ba8052 100644 --- a/core/camel-core/src/test/java/org/apache/camel/processor/converter/custom/MyConverter.java +++ b/core/camel-core/src/test/java/org/apache/camel/processor/converter/custom/MyConverter.java @@ -21,9 +21,14 @@ import org.apache.camel.util.StringHelper; @Converter public class MyConverter { - @Converter + + @Converter(allowNull = true) public MyBean fromString(String text) { + if (text.isBlank()) { + return null; + } String[] values = StringHelper.splitOnCharacter(text, ":", 2); return new MyBean(values[0], values[1]); } + } diff --git a/core/camel-main/src/test/java/org/apache/camel/main/scan/MyConverter.java b/core/camel-main/src/test/java/org/apache/camel/main/scan/MyConverter.java index 013bd75f6bc..ec840e1646d 100644 --- a/core/camel-main/src/test/java/org/apache/camel/main/scan/MyConverter.java +++ b/core/camel-main/src/test/java/org/apache/camel/main/scan/MyConverter.java @@ -29,4 +29,5 @@ public final class MyConverter { public static MyFoo toFoo(String name) { return new MyFoo(name); } + }