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 798f778ed061 CAMEL-24620: Add support to enable/disable 
DatatypeFeature enums in camel-jackson3
798f778ed061 is described below

commit 798f778ed0616e54d932afb2c9ada2d96558114c
Author: Benjamin Graf <[email protected]>
AuthorDate: Mon Sep 7 20:38:57 2026 +0200

    CAMEL-24620: Add support to enable/disable DatatypeFeature enums in 
camel-jackson3
    
    Extends AbstractJacksonDataFormat in camel-jackson3 to support three
    additional Jackson 3 DatatypeFeature enum types: DateTimeFeature,
    EnumFeature, and JsonNodeFeature.
    
    - Adds enableFeature/disableFeature convenience overloads taking
      Enum<? extends DatatypeFeature> for Java-API users.
    - Extends doEnableFeatures()/doDisableFeatures() to resolve the new
      enum types via the TypeConverter, making them configurable via the
      existing enableFeatures/disableFeatures string properties — and
      therefore via the YAML/XML DSLs.
    - Fixes mock expectation ordering in existing JacksonFeaturesTest methods.
    - Adds two new tests: one using the Java-typed overload (DateTimeFeature)
      and one using the string-based model path.
    
    Closes #26103
---
 .../jackson3/AbstractJacksonDataFormat.java        | 72 ++++++++++++++++++++--
 .../component/jackson3/JacksonFeaturesTest.java    | 35 ++++++++++-
 2 files changed, 99 insertions(+), 8 deletions(-)

diff --git 
a/components/camel-jackson3/src/main/java/org/apache/camel/component/jackson3/AbstractJacksonDataFormat.java
 
b/components/camel-jackson3/src/main/java/org/apache/camel/component/jackson3/AbstractJacksonDataFormat.java
index b09f60487ef4..55344cb690de 100644
--- 
a/components/camel-jackson3/src/main/java/org/apache/camel/component/jackson3/AbstractJacksonDataFormat.java
+++ 
b/components/camel-jackson3/src/main/java/org/apache/camel/component/jackson3/AbstractJacksonDataFormat.java
@@ -55,6 +55,10 @@ import tools.jackson.databind.ObjectWriter;
 import tools.jackson.databind.PropertyNamingStrategies;
 import tools.jackson.databind.PropertyNamingStrategy;
 import tools.jackson.databind.SerializationFeature;
+import tools.jackson.databind.cfg.DatatypeFeature;
+import tools.jackson.databind.cfg.DateTimeFeature;
+import tools.jackson.databind.cfg.EnumFeature;
+import tools.jackson.databind.cfg.JsonNodeFeature;
 import tools.jackson.databind.type.CollectionType;
 
 /**
@@ -507,8 +511,10 @@ public abstract class AbstractJacksonDataFormat extends 
ServiceSupport
 
     /**
      * Set of features to enable on the Jackson {@link 
tools.jackson.databind.ObjectMapper}. The features should be a
-     * name that matches a enum from {@link 
tools.jackson.databind.SerializationFeature},
-     * {@link tools.jackson.databind.DeserializationFeature}, or {@link 
tools.jackson.databind.MapperFeature}.
+     * name that matches an enum from {@link 
tools.jackson.databind.SerializationFeature},
+     * {@link tools.jackson.databind.DeserializationFeature}, {@link 
tools.jackson.databind.MapperFeature},
+     * {@link tools.jackson.databind.cfg.DateTimeFeature}, {@link 
tools.jackson.databind.cfg.EnumFeature} or
+     * {@link tools.jackson.databind.cfg.JsonNodeFeature}.
      */
     public void setEnableFeatures(String enableFeatures) {
         this.enableFeatures = enableFeatures;
@@ -520,8 +526,10 @@ public abstract class AbstractJacksonDataFormat extends 
ServiceSupport
 
     /**
      * Set of features to disable on the Jackson {@link 
tools.jackson.databind.ObjectMapper}. The features should be a
-     * name that matches a enum from {@link 
tools.jackson.databind.SerializationFeature},
-     * {@link tools.jackson.databind.DeserializationFeature}, or {@link 
tools.jackson.databind.MapperFeature}.
+     * name that matches an enum from {@link 
tools.jackson.databind.SerializationFeature},
+     * {@link tools.jackson.databind.DeserializationFeature}, {@link 
tools.jackson.databind.MapperFeature},
+     * {@link tools.jackson.databind.cfg.DateTimeFeature}, {@link 
tools.jackson.databind.cfg.EnumFeature} or
+     * {@link tools.jackson.databind.cfg.JsonNodeFeature}.
      */
     public void setDisableFeatures(String disableFeatures) {
         this.disableFeatures = disableFeatures;
@@ -551,6 +559,14 @@ public abstract class AbstractJacksonDataFormat extends 
ServiceSupport
         }
     }
 
+    public void enableFeature(Enum<? extends DatatypeFeature> feature) {
+        if (enableFeatures == null) {
+            enableFeatures = feature.name();
+        } else {
+            enableFeatures += "," + feature.name();
+        }
+    }
+
     public void disableFeature(SerializationFeature feature) {
         if (disableFeatures == null) {
             disableFeatures = feature.name();
@@ -575,6 +591,14 @@ public abstract class AbstractJacksonDataFormat extends 
ServiceSupport
         }
     }
 
+    public void disableFeature(Enum<? extends DatatypeFeature> feature) {
+        if (disableFeatures == null) {
+            disableFeatures = feature.name();
+        } else {
+            disableFeatures += "," + feature.name();
+        }
+    }
+
     @Override
     protected void doInit() throws Exception {
         if (unmarshalTypeName != null && (unmarshalType == null || 
unmarshalType == Object.class)) {
@@ -702,9 +726,27 @@ public abstract class AbstractJacksonDataFormat extends 
ServiceSupport
                 setObjectMapper(om);
                 continue;
             }
+            DateTimeFeature dtf = 
getCamelContext().getTypeConverter().tryConvertTo(DateTimeFeature.class, 
enable);
+            if (dtf != null) {
+                ObjectMapper om = objectMapper.rebuild().enable(dtf).build();
+                setObjectMapper(om);
+                continue;
+            }
+            EnumFeature ef = 
getCamelContext().getTypeConverter().tryConvertTo(EnumFeature.class, enable);
+            if (ef != null) {
+                ObjectMapper om = objectMapper.rebuild().enable(ef).build();
+                setObjectMapper(om);
+                continue;
+            }
+            JsonNodeFeature jnf = 
getCamelContext().getTypeConverter().tryConvertTo(JsonNodeFeature.class, 
enable);
+            if (jnf != null) {
+                ObjectMapper om = objectMapper.rebuild().enable(jnf).build();
+                setObjectMapper(om);
+                continue;
+            }
             throw new IllegalArgumentException(
                     "Enable feature: " + enable
-                                               + " cannot be converted to an 
accepted enum of types 
[SerializationFeature,DeserializationFeature,MapperFeature]");
+                                               + " cannot be converted to an 
accepted enum of types 
[SerializationFeature,DeserializationFeature,MapperFeature,DateTimeFeature,EnumFeature,JsonNodeFeature]");
         }
     }
 
@@ -803,9 +845,27 @@ public abstract class AbstractJacksonDataFormat extends 
ServiceSupport
                 setObjectMapper(om);
                 continue;
             }
+            DateTimeFeature dtf = 
getCamelContext().getTypeConverter().tryConvertTo(DateTimeFeature.class, 
disable);
+            if (dtf != null) {
+                ObjectMapper om = objectMapper.rebuild().disable(dtf).build();
+                setObjectMapper(om);
+                continue;
+            }
+            EnumFeature ef = 
getCamelContext().getTypeConverter().tryConvertTo(EnumFeature.class, disable);
+            if (ef != null) {
+                ObjectMapper om = objectMapper.rebuild().disable(ef).build();
+                setObjectMapper(om);
+                continue;
+            }
+            JsonNodeFeature jnf = 
getCamelContext().getTypeConverter().tryConvertTo(JsonNodeFeature.class, 
disable);
+            if (jnf != null) {
+                ObjectMapper om = objectMapper.rebuild().disable(jnf).build();
+                setObjectMapper(om);
+                continue;
+            }
             throw new IllegalArgumentException(
                     "Disable feature: " + disable
-                                               + " cannot be converted to an 
accepted enum of types 
[SerializationFeature,DeserializationFeature,MapperFeature]");
+                                               + " cannot be converted to an 
accepted enum of types 
[SerializationFeature,DeserializationFeature,MapperFeature,DateTimeFeature,EnumFeature,JsonNodeFeature]");
         }
     }
 
diff --git 
a/components/camel-jackson3/src/test/java/org/apache/camel/component/jackson3/JacksonFeaturesTest.java
 
b/components/camel-jackson3/src/test/java/org/apache/camel/component/jackson3/JacksonFeaturesTest.java
index 8207ebf1c07a..2657e75aa44a 100644
--- 
a/components/camel-jackson3/src/test/java/org/apache/camel/component/jackson3/JacksonFeaturesTest.java
+++ 
b/components/camel-jackson3/src/test/java/org/apache/camel/component/jackson3/JacksonFeaturesTest.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.component.jackson3;
 
+import java.util.Date;
+
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.test.junit6.CamelTestSupport;
@@ -23,29 +25,51 @@ import org.junit.jupiter.api.Test;
 import tools.jackson.databind.DeserializationFeature;
 import tools.jackson.databind.MapperFeature;
 import tools.jackson.databind.SerializationFeature;
+import tools.jackson.databind.cfg.DateTimeFeature;
 
 public class JacksonFeaturesTest extends CamelTestSupport {
 
     @Test
     public void testEnableDeserializationFeature() throws Exception {
         MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
         mock.message(0).body().isNull();
 
         template.send("direct:format", exchange -> 
exchange.getIn().setBody("[]"));
 
-        mock.expectedMessageCount(1);
-
         mock.assertIsSatisfied();
     }
 
     @Test
     public void testEnableMapperFeature() throws Exception {
         MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
         mock.message(0).body().isInstanceOf(TestPojo.class);
 
         template.send("direct:format", exchange -> 
exchange.getIn().setBody("{\"nAmE\": \"test\"}"));
 
+        mock.assertIsSatisfied();
+    }
+
+    @Test
+    public void testEnableDatatypeFeature() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+        mock.message(0).body(String.class).isEqualTo("123");
+
+        template.send("direct:unformat", exchange -> 
exchange.getIn().setBody(new Date(123)));
+
+        mock.assertIsSatisfied();
+    }
+
+    @Test
+    public void testEnableDatatypeFeatureViaModelString() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
         mock.expectedMessageCount(1);
+        mock.message(0).body(String.class).isEqualTo("123");
+
+        template.send("direct:unformat-model", exchange -> 
exchange.getIn().setBody(new Date(123)));
+
         mock.assertIsSatisfied();
     }
 
@@ -61,8 +85,15 @@ public class JacksonFeaturesTest extends CamelTestSupport {
                 format.disableFeature(SerializationFeature.INDENT_OUTPUT);
                 
format.disableFeature(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
                 format.disableFeature(MapperFeature.APPLY_DEFAULT_VALUES);
+                
format.enableFeature(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS);
 
                 from("direct:format").unmarshal(format).to("mock:result");
+                from("direct:unformat").marshal(format).to("mock:result");
+
+                JacksonDataFormat formatModel = new JacksonDataFormat();
+                formatModel.setEnableFeatures("WRITE_DATES_AS_TIMESTAMPS");
+
+                
from("direct:unformat-model").marshal(formatModel).to("mock:result");
             }
         };
     }

Reply via email to