You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2020/03/19 12:01:46 UTC

[camel] branch master updated: CAMEL-14679: Support DROP_ROOT_MODE in XStream JSON dataformat

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/master by this push:
     new 82f8b67  CAMEL-14679: Support DROP_ROOT_MODE in XStream JSON dataformat
82f8b67 is described below

commit 82f8b67f23b34664995edd21e95ced86ffd58548
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Mar 19 12:59:22 2020 +0100

    CAMEL-14679: Support DROP_ROOT_MODE in XStream JSON dataformat
---
 .../xstream/JsonDataFormatConfigurer.java          |  2 +
 .../camel/dataformat/xstream/json-xstream.json     |  1 +
 .../src/main/docs/json-xstream-dataformat.adoc     |  3 +-
 .../dataformat/xstream/AbstractXStreamWrapper.java |  4 +-
 .../camel/dataformat/xstream/JsonDataFormat.java   | 46 +++++++++----
 .../MarshalDomainObjectJSONDropRootNodeTest.java   | 79 ++++++++++++++++++++++
 .../org/apache/camel/model/dataformat/json.json    |  1 +
 .../camel/model/dataformat/JsonDataFormat.java     | 25 +++++++
 .../reifier/dataformat/JsonDataFormatReifier.java  | 12 +++-
 .../java/org/apache/camel/xml/in/ModelParser.java  |  1 +
 .../dataformats/pages/json-xstream-dataformat.adoc |  3 +-
 11 files changed, 156 insertions(+), 21 deletions(-)

diff --git a/components/camel-xstream/src/generated/java/org/apache/camel/dataformat/xstream/JsonDataFormatConfigurer.java b/components/camel-xstream/src/generated/java/org/apache/camel/dataformat/xstream/JsonDataFormatConfigurer.java
index b5f8358..a29ed97 100644
--- a/components/camel-xstream/src/generated/java/org/apache/camel/dataformat/xstream/JsonDataFormatConfigurer.java
+++ b/components/camel-xstream/src/generated/java/org/apache/camel/dataformat/xstream/JsonDataFormatConfigurer.java
@@ -20,6 +20,8 @@ public class JsonDataFormatConfigurer extends PropertyConfigurerSupport implemen
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "prettyprint":
         case "prettyPrint": dataformat.setPrettyPrint(property(camelContext, boolean.class, value)); return true;
+        case "droprootnode":
+        case "dropRootNode": dataformat.setDropRootNode(property(camelContext, boolean.class, value)); return true;
         case "permissions": dataformat.setPermissions(property(camelContext, java.lang.String.class, value)); return true;
         default: return false;
         }
diff --git a/components/camel-xstream/src/generated/resources/org/apache/camel/dataformat/xstream/json-xstream.json b/components/camel-xstream/src/generated/resources/org/apache/camel/dataformat/xstream/json-xstream.json
index 41dbaad..3b197e8 100644
--- a/components/camel-xstream/src/generated/resources/org/apache/camel/dataformat/xstream/json-xstream.json
+++ b/components/camel-xstream/src/generated/resources/org/apache/camel/dataformat/xstream/json-xstream.json
@@ -35,6 +35,7 @@
     "allowUnmarshallType": { "kind": "attribute", "displayName": "Allow Unmarshall Type", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "If enabled then Jackson is allowed to attempt to use the CamelJacksonUnmarshalType header during the unmarshalling. This should only be enabled when desired to be used." },
     "timezone": { "kind": "attribute", "displayName": "Timezone", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "If set then Jackson will use the Timezone when marshalling\/unmarshalling. This option will have no effect on the others Json DataFormat, like gson, fastjson and xstream." },
     "autoDiscoverObjectMapper": { "kind": "attribute", "displayName": "Auto Discover Object Mapper", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "If set to true then Jackson will lookup for an objectMapper into the registry" },
+    "dropRootNode": { "kind": "attribute", "displayName": "Drop Root Node", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Whether XStream will drop the root node in the generated JSon. You may want to enable this when using POJOs; as then the written object will include the class name as root node, which is often not intended to be written in the JSon output." },
     "contentTypeHeader": { "kind": "attribute", "displayName": "Content Type Header", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Whether the data format should set the Content-Type header with the type from the data format if the data format is capable of doing so. For example application\/xml for data formats marshalling to XML, or application\/json for data formats marshalling to JS [...]
     "id": { "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "The id of this node" }
   }
diff --git a/components/camel-xstream/src/main/docs/json-xstream-dataformat.adoc b/components/camel-xstream/src/main/docs/json-xstream-dataformat.adoc
index 6447c2c..916d414 100644
--- a/components/camel-xstream/src/main/docs/json-xstream-dataformat.adoc
+++ b/components/camel-xstream/src/main/docs/json-xstream-dataformat.adoc
@@ -28,7 +28,7 @@ Maven users will need to add the following dependency to their
 == Options
 
 // dataformat options: START
-The JSon XStream dataformat supports 20 options, which are listed below.
+The JSon XStream dataformat supports 21 options, which are listed below.
 
 
 
@@ -54,6 +54,7 @@ The JSon XStream dataformat supports 20 options, which are listed below.
 | allowUnmarshallType | false | Boolean | If enabled then Jackson is allowed to attempt to use the CamelJacksonUnmarshalType header during the unmarshalling. This should only be enabled when desired to be used.
 | timezone |  | String | If set then Jackson will use the Timezone when marshalling/unmarshalling. This option will have no effect on the others Json DataFormat, like gson, fastjson and xstream.
 | autoDiscoverObjectMapper | false | Boolean | If set to true then Jackson will lookup for an objectMapper into the registry
+| dropRootNode | false | Boolean | Whether XStream will drop the root node in the generated JSon. You may want to enable this when using POJOs; as then the written object will include the class name as root node, which is often not intended to be written in the JSon output.
 | contentTypeHeader | false | Boolean | Whether the data format should set the Content-Type header with the type from the data format if the data format is capable of doing so. For example application/xml for data formats marshalling to XML, or application/json for data formats marshalling to JSon etc.
 |===
 // dataformat options: END
diff --git a/components/camel-xstream/src/main/java/org/apache/camel/dataformat/xstream/AbstractXStreamWrapper.java b/components/camel-xstream/src/main/java/org/apache/camel/dataformat/xstream/AbstractXStreamWrapper.java
index ec2d4ec..7bf9b43 100644
--- a/components/camel-xstream/src/main/java/org/apache/camel/dataformat/xstream/AbstractXStreamWrapper.java
+++ b/components/camel-xstream/src/main/java/org/apache/camel/dataformat/xstream/AbstractXStreamWrapper.java
@@ -16,16 +16,14 @@
  */
 package org.apache.camel.dataformat.xstream;
 
+import javax.xml.stream.XMLStreamException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
-import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 
-import javax.xml.stream.XMLStreamException;
-
 import com.thoughtworks.xstream.XStream;
 import com.thoughtworks.xstream.converters.Converter;
 import com.thoughtworks.xstream.core.util.CompositeClassLoader;
diff --git a/components/camel-xstream/src/main/java/org/apache/camel/dataformat/xstream/JsonDataFormat.java b/components/camel-xstream/src/main/java/org/apache/camel/dataformat/xstream/JsonDataFormat.java
index bb5bebe..2697f5a 100644
--- a/components/camel-xstream/src/main/java/org/apache/camel/dataformat/xstream/JsonDataFormat.java
+++ b/components/camel-xstream/src/main/java/org/apache/camel/dataformat/xstream/JsonDataFormat.java
@@ -16,18 +16,16 @@
  */
 package org.apache.camel.dataformat.xstream;
 
+import javax.xml.stream.XMLStreamException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
-import java.io.UnsupportedEncodingException;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.xml.stream.XMLStreamException;
+import java.nio.charset.StandardCharsets;
 
 import com.thoughtworks.xstream.XStream;
 import com.thoughtworks.xstream.io.HierarchicalStreamReader;
 import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+import com.thoughtworks.xstream.io.json.AbstractJsonWriter;
 import com.thoughtworks.xstream.io.json.JsonWriter;
 import com.thoughtworks.xstream.io.xml.QNameMap;
 import com.thoughtworks.xstream.io.xml.StaxReader;
@@ -35,6 +33,7 @@ import com.thoughtworks.xstream.io.xml.StaxWriter;
 import org.apache.camel.Exchange;
 import org.apache.camel.spi.ClassResolver;
 import org.apache.camel.spi.annotations.Dataformat;
+import org.codehaus.jettison.mapped.Configuration;
 import org.codehaus.jettison.mapped.MappedXMLInputFactory;
 import org.codehaus.jettison.mapped.MappedXMLOutputFactory;
 
@@ -44,14 +43,12 @@ import org.codehaus.jettison.mapped.MappedXMLOutputFactory;
  */
 @Dataformat("json-xstream")
 public class JsonDataFormat extends AbstractXStreamWrapper {
-    private final MappedXMLOutputFactory mof;
-    private final MappedXMLInputFactory mif;
+    private MappedXMLOutputFactory mof;
+    private MappedXMLInputFactory mif;
     private boolean prettyPrint;
+    private boolean dropRootNode;
 
     public JsonDataFormat() {
-        final Map<?, ?> nstjsons = new HashMap<>();
-        mof = new MappedXMLOutputFactory(nstjsons);
-        mif = new MappedXMLInputFactory(nstjsons);
     }
 
     @Override
@@ -67,6 +64,14 @@ public class JsonDataFormat extends AbstractXStreamWrapper {
         this.prettyPrint = prettyPrint;
     }
 
+    public boolean isDropRootNode() {
+        return dropRootNode;
+    }
+
+    public void setDropRootNode(boolean dropRootNode) {
+        this.dropRootNode = dropRootNode;
+    }
+
     @Override
     public void marshal(Exchange exchange, Object body, OutputStream stream) throws Exception {
         super.marshal(exchange, body, stream);
@@ -94,11 +99,11 @@ public class JsonDataFormat extends AbstractXStreamWrapper {
     @Override
     protected HierarchicalStreamWriter createHierarchicalStreamWriter(Exchange exchange, Object body, OutputStream stream) throws XMLStreamException {
         if (isPrettyPrint()) {
-            try {
-                // the json spec. expects UTF-8 as the default encoding
-                return new JsonWriter(new OutputStreamWriter(stream, "UTF-8"));
-            } catch (UnsupportedEncodingException uee) {
-                throw new XMLStreamException(uee);
+            // the json spec. expects UTF-8 as the default encoding
+            if (isDropRootNode()) {
+                return new JsonWriter(new OutputStreamWriter(stream, StandardCharsets.UTF_8), AbstractJsonWriter.DROP_ROOT_MODE);
+            } else {
+                return new JsonWriter(new OutputStreamWriter(stream, StandardCharsets.UTF_8));
             }
         }
 
@@ -109,4 +114,15 @@ public class JsonDataFormat extends AbstractXStreamWrapper {
     protected HierarchicalStreamReader createHierarchicalStreamReader(Exchange exchange, InputStream stream) throws XMLStreamException {
         return new StaxReader(new QNameMap(), mif.createXMLStreamReader(stream));
     }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+
+        Configuration config = new Configuration();
+        config.setDropRootElement(dropRootNode);
+
+        mof = new MappedXMLOutputFactory(config);
+        mif = new MappedXMLInputFactory(config);
+    }
 }
diff --git a/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/MarshalDomainObjectJSONDropRootNodeTest.java b/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/MarshalDomainObjectJSONDropRootNodeTest.java
new file mode 100644
index 0000000..a64b95e
--- /dev/null
+++ b/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/MarshalDomainObjectJSONDropRootNodeTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dataformat.xstream;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.model.dataformat.JsonDataFormat;
+import org.apache.camel.model.dataformat.JsonLibrary;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class MarshalDomainObjectJSONDropRootNodeTest extends CamelTestSupport {
+    
+    @Test
+    public void testMarshalAndUnmarshalWithPrettyPrint() throws Exception {
+        PurchaseOrder order = new PurchaseOrder();
+        order.setName("pretty printed Camel");
+        order.setAmount(1);
+        order.setPrice(7.91);
+
+        MockEndpoint mock = getMockEndpoint("mock:reverse");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(PurchaseOrder.class);
+        mock.message(0).body().isEqualTo(order);
+
+        Object marshalled = template.requestBody("direct:inPretty", order);
+        String marshalledAsString = context.getTypeConverter().convertTo(String.class, marshalled);
+        // the line-separator used by JsonWriter is "\n", even on windows
+        String expected = "{\n"
+                          + "  \"name\": \"pretty printed Camel\",\n" 
+                          + "  \"price\": 7.91,\n"
+                          + "  \"amount\": 1.0\n" 
+                          + "}";
+        assertEquals(expected, marshalledAsString);
+
+        // must include class type when reversing
+        String back = "{\"org.apache.camel.dataformat.xstream.PurchaseOrder\": {\n"
+                + "  \"name\": \"pretty printed Camel\",\n"
+                + "  \"price\": 7.91,\n"
+                + "  \"amount\": 1.0\n"
+                + "}}";
+
+        template.sendBody("direct:backPretty", back);
+
+        mock.assertIsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() throws Exception {
+                from("direct:reverse").unmarshal().json(JsonLibrary.XStream, PurchaseOrder.class).to("mock:reverse");
+
+                JsonDataFormat df = new JsonDataFormat().library(JsonLibrary.XStream).dropRootNode(true).prettyPrint(true);
+                from("direct:inPretty").marshal(df);
+
+                from("direct:backPretty").unmarshal().json(JsonLibrary.XStream, PurchaseOrder.class, true).to("mock:reverse");
+            }
+        };
+    }
+
+}
diff --git a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/dataformat/json.json b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/dataformat/json.json
index 3a54d05..5b4e283 100644
--- a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/dataformat/json.json
+++ b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/dataformat/json.json
@@ -30,6 +30,7 @@
     "allowUnmarshallType": { "kind": "attribute", "displayName": "Allow Unmarshall Type", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "If enabled then Jackson is allowed to attempt to use the CamelJacksonUnmarshalType header during the unmarshalling. This should only be enabled when desired to be used." },
     "timezone": { "kind": "attribute", "displayName": "Timezone", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "If set then Jackson will use the Timezone when marshalling\/unmarshalling. This option will have no effect on the others Json DataFormat, like gson, fastjson and xstream." },
     "autoDiscoverObjectMapper": { "kind": "attribute", "displayName": "Auto Discover Object Mapper", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "If set to true then Jackson will lookup for an objectMapper into the registry" },
+    "dropRootNode": { "kind": "attribute", "displayName": "Drop Root Node", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Whether XStream will drop the root node in the generated JSon. You may want to enable this when using POJOs; as then the written object will include the class name as root node, which is often not intended to be written in the JSon output." },
     "contentTypeHeader": { "kind": "attribute", "displayName": "Content Type Header", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Whether the data format should set the Content-Type header with the type from the data format if the data format is capable of doing so. For example application\/xml for data formats marshalling to XML, or application\/json for data formats marshalling to JS [...]
     "id": { "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "The id of this node" }
   }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/JsonDataFormat.java b/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/JsonDataFormat.java
index b99ce64..fbda282 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/JsonDataFormat.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/JsonDataFormat.java
@@ -84,6 +84,9 @@ public class JsonDataFormat extends DataFormatDefinition {
     @XmlAttribute
     @Metadata(javaType = "java.lang.Boolean", defaultValue = "false")
     private String autoDiscoverObjectMapper;
+    @XmlAttribute
+    @Metadata(javaType = "java.lang.Boolean", defaultValue = "false")
+    private String dropRootNode;
 
     public JsonDataFormat() {
         super("json");
@@ -386,6 +389,19 @@ public class JsonDataFormat extends DataFormatDefinition {
         this.autoDiscoverObjectMapper = autoDiscoverObjectMapper;
     }
 
+    public String getDropRootNode() {
+        return dropRootNode;
+    }
+
+    /**
+     * Whether XStream will drop the root node in the generated JSon.
+     * You may want to enable this when using POJOs; as then the written object will include the class name
+     * as root node, which is often not intended to be written in the JSon output.
+     */
+    public void setDropRootNode(String dropRootNode) {
+        this.dropRootNode = dropRootNode;
+    }
+
     @Override
     public String getDataFormatName() {
         // json data format is special as the name can be from different bundles
@@ -529,4 +545,13 @@ public class JsonDataFormat extends DataFormatDefinition {
         return this;
     }
 
+    public JsonDataFormat dropRootNode(boolean dropRootNode) {
+        return dropRootNode(Boolean.toString(dropRootNode));
+    }
+
+    public JsonDataFormat dropRootNode(String dropRootNode) {
+        this.dropRootNode = dropRootNode;
+        return this;
+    }
+
 }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/dataformat/JsonDataFormatReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/dataformat/JsonDataFormatReifier.java
index b56c302..a934b03 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/dataformat/JsonDataFormatReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/dataformat/JsonDataFormatReifier.java
@@ -32,7 +32,14 @@ public class JsonDataFormatReifier extends DataFormatReifier<JsonDataFormat> {
     @Override
     protected void prepareDataFormatConfig(Map<String, Object> properties) {
         properties.put("objectMapper", asRef(definition.getObjectMapper()));
-        properties.put("useDefaultObjectMapper", definition.getUseDefaultObjectMapper());
+        if (definition.getLibrary() != JsonLibrary.XStream) {
+            if (definition.getUseDefaultObjectMapper() == null) {
+                // default true
+                properties.put("useDefaultObjectMapper", "true");
+            } else {
+                properties.put("useDefaultObjectMapper", definition.getUseDefaultObjectMapper());
+            }
+        }
         properties.put("unmarshalType", or(definition.getUnmarshalType(), definition.getUnmarshalTypeName()));
         properties.put("prettyPrint", definition.getPrettyPrint());
         properties.put("jsonView", definition.getJsonView());
@@ -46,6 +53,9 @@ public class JsonDataFormatReifier extends DataFormatReifier<JsonDataFormat> {
         properties.put("enableFeatures", definition.getEnableFeatures());
         properties.put("disableFeatures", definition.getDisableFeatures());
         properties.put("allowUnmarshallType", definition.getAllowUnmarshallType());
+        if (definition.getLibrary() == JsonLibrary.XStream) {
+            properties.put("dropRootNode", definition.getDropRootNode());
+        }
         if (definition.getLibrary() == JsonLibrary.XStream && definition.getPermissions() == null) {
             // if we have the unmarshal type, but no permission set, then use it to be allowed
             String type = definition.getUnmarshalTypeName();
diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
index 0cf7eaa..33f3b43 100644
--- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
+++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
@@ -1941,6 +1941,7 @@ public class ModelParser extends BaseParser {
                 case "autoDiscoverObjectMapper": def.setAutoDiscoverObjectMapper(val); break;
                 case "collectionTypeName": def.setCollectionTypeName(val); break;
                 case "disableFeatures": def.setDisableFeatures(val); break;
+                case "dropRootNode": def.setDropRootNode(val); break;
                 case "enableFeatures": def.setEnableFeatures(val); break;
                 case "enableJaxbAnnotationModule": def.setEnableJaxbAnnotationModule(val); break;
                 case "include": def.setInclude(val); break;
diff --git a/docs/components/modules/dataformats/pages/json-xstream-dataformat.adoc b/docs/components/modules/dataformats/pages/json-xstream-dataformat.adoc
index 7068854..a90a7c3 100644
--- a/docs/components/modules/dataformats/pages/json-xstream-dataformat.adoc
+++ b/docs/components/modules/dataformats/pages/json-xstream-dataformat.adoc
@@ -29,7 +29,7 @@ Maven users will need to add the following dependency to their
 == Options
 
 // dataformat options: START
-The JSon XStream dataformat supports 20 options, which are listed below.
+The JSon XStream dataformat supports 21 options, which are listed below.
 
 
 
@@ -55,6 +55,7 @@ The JSon XStream dataformat supports 20 options, which are listed below.
 | allowUnmarshallType | false | Boolean | If enabled then Jackson is allowed to attempt to use the CamelJacksonUnmarshalType header during the unmarshalling. This should only be enabled when desired to be used.
 | timezone |  | String | If set then Jackson will use the Timezone when marshalling/unmarshalling. This option will have no effect on the others Json DataFormat, like gson, fastjson and xstream.
 | autoDiscoverObjectMapper | false | Boolean | If set to true then Jackson will lookup for an objectMapper into the registry
+| dropRootNode | false | Boolean | Whether XStream will drop the root node in the generated JSon. You may want to enable this when using POJOs; as then the written object will include the class name as root node, which is often not intended to be written in the JSon output.
 | contentTypeHeader | false | Boolean | Whether the data format should set the Content-Type header with the type from the data format if the data format is capable of doing so. For example application/xml for data formats marshalling to XML, or application/json for data formats marshalling to JSon etc.
 |===
 // dataformat options: END