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

commit 039dbed74e85a12704414bd79d91cf66de63d2be
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Oct 24 19:57:09 2026 +0200

    CAMEL-24961: Catalog body types for smb, stax, fop, flatpack, dfdl, atom, 
rss, weather and seven more components (#28417)
    
    Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../org/apache/camel/catalog/components/atom.json      |  3 +++
 .../org/apache/camel/catalog/components/citrus.json    |  4 ++++
 .../org/apache/camel/catalog/components/dfdl.json      |  4 ++++
 .../org/apache/camel/catalog/components/flatpack.json  |  5 +++++
 .../org/apache/camel/catalog/components/fop.json       |  4 ++++
 .../org/apache/camel/catalog/components/jcr.json       |  5 +++++
 .../org/apache/camel/catalog/components/jt400.json     |  5 +++++
 .../org/apache/camel/catalog/components/mapstruct.json |  4 ++++
 .../org/apache/camel/catalog/components/oaipmh.json    |  5 +++++
 .../camel/catalog/components/robotframework.json       |  5 +++++
 .../org/apache/camel/catalog/components/rss.json       |  3 +++
 .../org/apache/camel/catalog/components/smb.json       |  5 +++++
 .../apache/camel/catalog/components/spring-event.json  |  5 +++++
 .../org/apache/camel/catalog/components/stax.json      |  4 ++++
 .../org/apache/camel/catalog/components/weather.json   |  5 +++++
 .../org/apache/camel/catalog/docs/atom-component.adoc  | 10 +++++-----
 .../apache/camel/catalog/docs/flatpack-component.adoc  | 17 +++++------------
 .../apache/camel/catalog/docs/mapstruct-component.adoc |  2 +-
 .../org/apache/camel/catalog/docs/rss-component.adoc   |  2 +-
 .../META-INF/org/apache/camel/component/atom/atom.json |  3 +++
 .../camel-atom/src/main/docs/atom-component.adoc       | 10 +++++-----
 .../org/apache/camel/component/atom/AtomEndpoint.java  | 11 +++++++++++
 .../META-INF/org/apache/camel/component/dfdl/dfdl.json |  4 ++++
 .../org/apache/camel/component/dfdl/DfdlEndpoint.java  | 17 +++++++++++++++++
 .../org/apache/camel/component/flatpack/flatpack.json  |  5 +++++
 .../src/main/docs/flatpack-component.adoc              | 17 +++++------------
 .../camel/component/flatpack/FlatpackEndpoint.java     | 14 ++++++++++++++
 .../META-INF/org/apache/camel/component/fop/fop.json   |  4 ++++
 .../org/apache/camel/component/fop/FopEndpoint.java    |  9 +++++++++
 .../META-INF/org/apache/camel/component/jcr/jcr.json   |  5 +++++
 .../org/apache/camel/component/jcr/JcrEndpoint.java    | 12 ++++++++++++
 .../org/apache/camel/component/jt400/jt400.json        |  5 +++++
 .../apache/camel/component/jt400/Jt400Endpoint.java    | 18 ++++++++++++++++++
 .../apache/camel/component/mapstruct/mapstruct.json    |  4 ++++
 .../src/main/docs/mapstruct-component.adoc             |  2 +-
 .../camel/component/mapstruct/MapstructEndpoint.java   | 10 ++++++++++
 .../org/apache/camel/oaipmh/component/oaipmh.json      |  5 +++++
 .../apache/camel/oaipmh/component/OAIPMHEndpoint.java  | 13 +++++++++++++
 .../camel/component/robotframework/robotframework.json |  5 +++++
 .../robotframework/RobotFrameworkEndpoint.java         | 15 +++++++++++++++
 .../META-INF/org/apache/camel/component/rss/rss.json   |  3 +++
 components/camel-rss/src/main/docs/rss-component.adoc  |  2 +-
 .../org/apache/camel/component/rss/RssEndpoint.java    |  8 ++++++++
 .../META-INF/org/apache/camel/component/smb/smb.json   |  5 +++++
 .../org/apache/camel/component/smb/SmbEndpoint.java    | 18 ++++++++++++++++++
 .../org/apache/camel/component/event/spring-event.json |  5 +++++
 .../apache/camel/component/event/EventEndpoint.java    | 15 +++++++++++++++
 .../META-INF/org/apache/camel/component/stax/stax.json |  4 ++++
 .../org/apache/camel/component/stax/StAXEndpoint.java  | 10 ++++++++++
 .../org/apache/camel/component/citrus/citrus.json      |  4 ++++
 .../apache/camel/component/citrus/CitrusEndpoint.java  | 15 +++++++++++++++
 .../org/apache/camel/component/weather/weather.json    |  5 +++++
 .../camel/component/weather/WeatherEndpoint.java       | 15 +++++++++++++++
 .../jbang/core/commands/catalog/CatalogDocTest.java    |  4 ++--
 54 files changed, 358 insertions(+), 40 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/atom.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/atom.json
index bb4cca9e41c5..0ba3c388920d 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/atom.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/atom.json
@@ -30,6 +30,9 @@
   "headers": {
     "CamelAtomFeed": { "index": 0, "kind": "header", "displayName": "", 
"group": "consumer", "label": "", "required": false, "javaType": 
"java.util.List", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "When consuming the List object is set 
to this header.", "constantName": 
"org.apache.camel.component.atom.AtomConstants#ATOM_FEED" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "javaType": 
"com.apptasticsoftware.rssreader.Item", "byOption": [ { "option": 
"splitEntries", "value": "false", "carriers": [ "list" ], "javaType": 
"java.util.List" } ], "description": "One entry of the feed, a 
com.apptasticsoftware.rssreader.Item with its title, link, author, dates and 
content; with splitEntries=false the List of all the entries, empty for a feed 
without entries. The CamelAtomFeed header carries the List of the entries 
unless [...]
+  },
   "properties": {
     "feedUri": { "index": 0, "kind": "path", "displayName": "Feed Uri", 
"group": "consumer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The URI to the feed to 
poll." },
     "sendEmptyMessageWhenIdle": { "index": 1, "kind": "parameter", 
"displayName": "Send Empty Message When Idle", "group": "consumer", "label": 
"consumer", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
false, "description": "If the polling consumer did not poll any files, you can 
enable this option to send an empty message (no body) instead." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/citrus.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/citrus.json
index b068b5b4b76a..606d7d689b0c 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/citrus.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/citrus.json
@@ -29,6 +29,10 @@
     "autowiredEnabled": { "index": 2, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
     "exchangeFormatter": { "index": 3, "kind": "property", "displayName": 
"Exchange Formatter", "group": "advanced", "label": "advanced", "required": 
false, "type": "object", "javaType": "org.apache.camel.spi.ExchangeFormatter", 
"deprecated": false, "autowired": true, "secret": false, "description": "To use 
a custom ExchangeFormatter to format the Exchange into a String suitable for 
logging." }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "stream" ], "description": "The body 
Citrus validates, as text; a stream cache is read as text and reset. Any other 
body is compared by its toString(): bytes as a list of numbers, a file as its 
path, a Map as {key=value}, so convert it to a String first" },
+    "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": 
"operation", "value": "receive", "carriers": [ "text", "unchanged" ] } ], 
"description": "validate leaves the body as it is. receive sets the body of the 
simulated response, as text with its Citrus variables resolved (or what the 
MessagePayloadBuilder given to it builds), and leaves the body as it is when 
the response has no body or no spec matches the exchange" }
+  },
   "properties": {
     "operation": { "index": 0, "kind": "path", "displayName": "Operation", 
"group": "producer", "label": "", "required": true, "type": "enum", "javaType": 
"java.lang.String", "enum": [ "validate", "receive" ], "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
operation to perform. 'validate' validates exchanges without modifying them. 
'receive' validates exchanges and returns a simulated response." },
     "name": { "index": 1, "kind": "path", "displayName": "Name", "group": 
"producer", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "A unique name to identify this endpoint. Allows multiple Citrus 
endpoints with different validation expectations in the same route." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/dfdl.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/dfdl.json
index c22d8c144410..945255a8e264 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/dfdl.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/dfdl.json
@@ -27,6 +27,10 @@
     "lazyStartProducer": { "index": 0, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
     "autowiredEnabled": { "index": 1, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"byOption": [ { "option": "parseDirection", "value": "UNPARSE", "carriers": [ 
"text", "bytes", "stream", "file", "pojo" ] } ], "description": "Data in the 
format the DFDL schema describes, such as an EDI message, to parse. UNPARSE 
takes the XML infoset as text, bytes, a stream, a file or a DOM Document. A Map 
or no body fails" },
+    "producerOut": { "carriers": [ "pojo" ], "javaType": 
"org.w3c.dom.Document", "byOption": [ { "option": "parseDirection", "value": 
"UNPARSE", "carriers": [ "bytes" ], "javaType": "java.io.ByteArrayOutputStream" 
} ], "description": "The XML infoset as a DOM Document. UNPARSE gives the data 
in the format the DFDL schema describes as bytes, in a ByteArrayOutputStream" }
+  },
   "properties": {
     "schemaUri": { "index": 0, "kind": "path", "displayName": "Schema Uri", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The path to the DFDL 
schema file." },
     "parseDirection": { "index": 1, "kind": "parameter", "displayName": "Parse 
Direction", "group": "producer", "label": "", "required": false, "type": 
"enum", "javaType": "org.apache.camel.component.dfdl.ParseDirection", "enum": [ 
"PARSE", "UNPARSE" ], "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "defaultValue": "PARSE", "description": "Transform 
direction. Either PARSE or UNPARSE" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/flatpack.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/flatpack.json
index 3043a66c232e..85ec8dfaf75c 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/flatpack.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/flatpack.json
@@ -31,6 +31,11 @@
   "headers": {
     "CamelFlatpackCounter": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": "int", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The current row index. For splitRows=false the counter 
is the total number of rows.", "constantName": 
"org.apache.camel.component.flatpack.FlatpackConstants#FLATPACK_COUNTER" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "javaType": 
"net.sf.flatpack.DataSet", "description": "The Flatpack DataSet the producer 
parsed. With splitRows, one message per row, with the DataSet at that row: 
convert it to a Map before any asynchronous step, as the next row moves it; a 
List reads all the rows and ends the split. With splitRows=false, the whole 
DataSet: convert it to a List of Maps" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"format": "text", "description": "The fixed-width or delimited data to parse, 
such as a file from the file consumer; a java.io.File, a Map or a List fails. 
The rows go to the consumer of the same endpoint" },
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "type": { "index": 0, "kind": "path", "displayName": "Type", "group": 
"common", "label": "", "required": false, "type": "enum", "javaType": 
"org.apache.camel.component.flatpack.FlatpackType", "enum": [ "fixed", "delim" 
], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "defaultValue": "delim", "description": "Whether to use fixed or 
delimiter" },
     "resourceUri": { "index": 1, "kind": "path", "displayName": "Resource 
Uri", "group": "common", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "supportFileReference": true, 
"description": "URL for loading the flatpack mapping file from classpath or 
file system" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/fop.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/fop.json
index 16a494c7632a..38523237b1fc 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/fop.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/fop.json
@@ -30,6 +30,10 @@
   "headers": {
     "CamelFop.Output.Format": { "index": 0, "kind": "header", "displayName": 
"", "group": "producer", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The output format", "constantName": 
"org.apache.camel.component.fop.FopConstants#CAMEL_FOP_OUTPUT_FORMAT" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"format": "xml", "description": "The XSL-FO document to render, as text, bytes, 
a stream or a file. A DOM Document, a Map or no body fails" },
+    "producerOut": { "carriers": [ "bytes" ], "javaType": 
"java.io.ByteArrayOutputStream", "description": "The rendered document as 
bytes, in a ByteArrayOutputStream: PDF, or the outputType, or the format of the 
CamelFop.Output.Format header" }
+  },
   "properties": {
     "outputType": { "index": 0, "kind": "path", "displayName": "Output Type", 
"group": "producer", "label": "", "required": true, "type": "enum", "javaType": 
"org.apache.camel.component.fop.FopOutputType", "enum": [ "pdf", "ps", "pcl", 
"png", "jpeg", "svg", "xml", "mif", "rtf", "txt" ], "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
primary output format is PDF but other output formats are also supported." },
     "fopFactory": { "index": 1, "kind": "parameter", "displayName": "Fop 
Factory", "group": "producer", "label": "", "required": false, "type": 
"object", "javaType": "org.apache.fop.apps.FopFactory", "deprecated": false, 
"autowired": false, "secret": false, "description": "Allows to use a custom 
configured or implementation of org.apache.fop.apps.FopFactory." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jcr.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jcr.json
index befedd599ea5..97acf6bad235 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jcr.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jcr.json
@@ -34,6 +34,11 @@
     "CamelJcrOperation": { "index": 1, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "defaultValue": "CamelJcrInsert", "description": "The 
operation to perform. Possible values: CamelJcrInsert or CamelJcrGetById", 
"constantName": "org.apache.camel.component.jcr.JcrConstants#JCR_OPERATION" },
     "CamelJcrNodeType": { "index": 2, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The node type of the target node", 
"constantName": "org.apache.camel.component.jcr.JcrConstants#JCR_NODE_TYPE" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "list" ], "javaType": "java.util.List", 
"description": "The JCR events received in one callback: a List of 
javax.jcr.observation.Event" },
+    "producerIn": { "carriers": [ "any" ], "description": "Insert (the 
default) ignores the body and stores the headers as node properties; getById 
(CamelJcrOperation header) reads the node identifier from the body as a String" 
},
+    "producerOut": { "carriers": [ "text", "unchanged" ], "description": 
"Insert sets the identifier of the node, a String; getById leaves the body and 
sets the node properties as headers" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Name of the javax.jcr.Repository to 
lookup from the Camel registry to be used." },
     "base": { "index": 1, "kind": "path", "displayName": "Base", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Get the base node when accessing the repository" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jt400.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jt400.json
index de94380bab3e..1332a1618e71 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jt400.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jt400.json
@@ -42,6 +42,11 @@
     "CamelJt400MessageDefaultReply": { "index": 7, "kind": "header", 
"displayName": "", "group": "consumer", "label": "consumer", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The default message reply, when the 
message is an inquiry message", "constantName": 
"org.apache.camel.component.jt400.Jt400Constants#MESSAGE_DFT_RPY" },
     "CamelJt400MessageReplyToKey": { "index": 8, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "byte[]", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Consumer: The key of the message that 
will be replied to (if the sendingReply parameter is set to true). Producer: If 
set, and if the message body is not empty, a new message will not be sent to 
the provided message queue. Instead, a re [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text" ], "dependsOn": [ "objectPath" ], 
"byOption": [ { "option": "format", "value": "binary", "carriers": [ "bytes" ] 
}, { "option": "sendEmptyMessageWhenIdle", "value": "true", "carriers": [ 
"text", "bytes", "null" ] } ], "description": "The data queue entry as a 
String, or a byte array with format=binary; a message queue (.MSGQ) always 
gives the message text" },
+    "producerIn": { "carriers": [ "any" ], "dependsOn": [ "objectPath", 
"format" ], "description": "A queue writes the body converted to a String, or 
to a byte array with format=binary (text, bytes or a stream). A program call 
(.PGM, .SRVPGM) needs an Object[] of the parameters: a List fails" },
+    "producerOut": { "carriers": [ "unchanged" ], "dependsOn": [ "objectPath" 
], "description": "Unchanged for a queue. A program call sets an Object[] of 
the parameters, the output ones replaced by what the program returned: Strings, 
or byte arrays with format=binary" }
+  },
   "properties": {
     "userID": { "index": 0, "kind": "path", "displayName": "User ID", "group": 
"security", "label": "security", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.jt400.Jt400Configuration", "configurationField": 
"configuration", "description": "Returns the ID of the IBM i user." },
     "password": { "index": 1, "kind": "path", "displayName": "Password", 
"group": "security", "label": "security", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.jt400.Jt400Configuration", "configurationField": 
"configuration", "description": "Returns the password of the IBM i user." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mapstruct.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mapstruct.json
index 2d679670dbb9..3688198793a7 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mapstruct.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mapstruct.json
@@ -29,6 +29,10 @@
     "autowiredEnabled": { "index": 2, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
     "mapStructConverter": { "index": 3, "kind": "property", "displayName": 
"Map Struct Converter", "group": "advanced", "label": "advanced", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.component.mapstruct.MapStructMapperFinder", "deprecated": 
false, "autowired": true, "secret": false, "description": "To use a custom 
MapStructConverter such as adapting to a special runtime." }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "pojo", "null" ], "description": "A POJO 
that a mapper of the mapperPackageName packages maps to the className type; a 
body of that type already is left as it is. Any other body fails with an 
InvalidPayloadException, unless mandatory is false" },
+    "producerOut": { "carriers": [ "pojo", "null" ], "description": "The 
object of the className type the mapper returns, or null when there is no body. 
With mandatory=false, a body that no mapper converts becomes null" }
+  },
   "properties": {
     "className": { "index": 0, "kind": "path", "displayName": "Class Name", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The fully qualified class 
name of the POJO that mapstruct should convert to (target)" },
     "mandatory": { "index": 1, "kind": "parameter", "displayName": 
"Mandatory", "group": "producer", "label": "", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether there must exist 
a mapstruct converter to convert to the POJO." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/oaipmh.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/oaipmh.json
index 40c5335d8360..2ea471cd7e36 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/oaipmh.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/oaipmh.json
@@ -34,6 +34,11 @@
     "CamelOaimphResumptionToken": { "index": 0, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "This header is obtained when onlyFirst 
option is enable. Return resumption token of the request when data is still 
available.", "constantName": 
"org.apache.camel.oaipmh.component.model.OAIPMHConstants#RESUMPTION_TOKEN" },
     "CamelOaimphHttpHeaders": { "index": 1, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"java.util.Map<java.lang.String, java.lang.String>", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Custom HTTP headers to send with the request, overriding any httpHeader. 
endpoint parameters.", "constantName": 
"org.apache.camel.oaipmh.component.model.OAIPMHConstants#HTTP_HEADERS" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text" ], "javaType": "java.lang.String", 
"format": "xml", "description": "The XML response of one OAI-PMH request as a 
String: one message per page, following the resumption tokens until the last 
page" },
+    "producerIn": { "carriers": [ "any" ], "description": "The body is not 
read: the request comes from the options, which the CamelOaimph headers 
override" },
+    "producerOut": { "carriers": [ "list" ], "javaType": "java.util.List", 
"description": "A List of Strings, the XML response of each page of the request 
until the last; with onlyFirst only the first page, and the token for the next 
page in the CamelOaimphResumptionToken header" }
+  },
   "properties": {
     "baseUrl": { "index": 0, "kind": "path", "displayName": "Base Url", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Base URL of the repository to which the 
request is made through the OAI-PMH protocol" },
     "from": { "index": 1, "kind": "parameter", "displayName": "From", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Specifies a lower bound for datestamp-based selective 
harvesting. UTC DateTime value" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/robotframework.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/robotframework.json
index 7ccd7b4110a4..fd53b52ec4b1 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/robotframework.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/robotframework.json
@@ -81,6 +81,11 @@
     "CamelRobotReturnCode": { "index": 1, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "Integer", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The return code.", "constantName": 
"org.apache.camel.component.robotframework.RobotFrameworkCamelConstants#CAMEL_ROBOT_RETURN_CODE"
 },
     "CamelRobotResourceUri": { "index": 2, "kind": "header", "displayName": 
"", "group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The new resource URI.", "constantName": 
"org.apache.camel.component.robotframework.RobotFrameworkCamelConstants#CAMEL_ROBOT_RESOURCE_URI"
 }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "null" ], "description": "No body: each 
poll runs the test, and the outcome is in the CamelRobotReturnCode header (0 
when all tests pass)" },
+    "producerIn": { "carriers": [ "any" ], "description": "The test gets the 
body converted to a String as the body variable, and the headers and exchange 
properties as headers.name and properties.name; a null body or header value 
fails the exchange" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "The body is 
left as it is. The CamelRobotReturnCode header has the return code of the run 
(0 when all tests pass, non-zero otherwise), and CamelRobotVariables the 
variables passed to it; a failed test does not fail the exchange" }
+  },
   "properties": {
     "resourceUri": { "index": 0, "kind": "path", "displayName": "Resource 
Uri", "group": "common", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "supportFileReference": true, 
"description": "Path to the resource. You can prefix with: classpath, file, 
http, ref, or bean. classpath, file and http loads the resource using these 
protocols (classpath is default). ref will lookup [...]
     "allowContextMapAll": { "index": 1, "kind": "parameter", "displayName": 
"Allow Context Map All", "group": "common", "label": "", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": false, "configurationClass": 
"org.apache.camel.component.robotframework.RobotFrameworkCamelConfiguration", 
"configurationField": "configuration", "description": "Sets whether the context 
map should allow access to all detail [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/rss.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/rss.json
index c2546e871c7e..6284bc8b5362 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/rss.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/rss.json
@@ -30,6 +30,9 @@
   "headers": {
     "CamelRssFeed": { "index": 0, "kind": "header", "displayName": "", 
"group": "consumer", "label": "", "required": false, "javaType": "Object", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The entire SyncFeed object.", "constantName": 
"org.apache.camel.component.rss.RssConstants#RSS_FEED" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "javaType": 
"com.rometools.rome.feed.synd.SyndFeed", "description": "A ROME SyndFeed: with 
splitEntries (the default) a copy of the feed with the one entry in its 
entries, with splitEntries=false the whole feed with all its entries. The 
CamelRssFeed header carries the whole feed unless feedHeader=false" }
+  },
   "properties": {
     "feedUri": { "index": 0, "kind": "path", "displayName": "Feed Uri", 
"group": "consumer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The URI to the feed to 
poll." },
     "sendEmptyMessageWhenIdle": { "index": 1, "kind": "parameter", 
"displayName": "Send Empty Message When Idle", "group": "consumer", "label": 
"consumer", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
false, "description": "If the polling consumer did not poll any files, you can 
enable this option to send an empty message (no body) instead." },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smb.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smb.json
index 89a91c682439..55f1956e05cc 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smb.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smb.json
@@ -49,6 +49,11 @@
     "CamelSmbFileExists": { "index": 15, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"org.apache.camel.component.file.GenericFileExist", "enum": [ "Override", 
"Append", "Fail", "Ignore", "Move", "TryRename" ], "deprecated": true, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
expected behavior if the file already exists.", "constantName": 
"org.apache.camel.component.smb.SmbConstants#SMB_FIL [...]
     "CamelSmbUncPath": { "index": 16, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "UNC path to the retrieved file", 
"constantName": "org.apache.camel.component.smb.SmbConstants#SMB_UNC_PATH" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "file" ], "dependsOn": [ "preMove" ], 
"byOption": [ { "option": "streamDownload", "value": "true", "carriers": [ 
"stream" ] }, { "option": "download", "value": "false", "carriers": [ "null" ] 
} ], "description": "The file as read: an SmbFile, which converts to text, 
bytes or a stream; a stream with streamDownload; with preMove its content, a 
byte array (a stream with streamDownload)" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"byOption": [ { "option": "allowNullBody", "value": "true", "carriers": [ 
"null", "text", "bytes", "stream", "file" ] } ], "description": "What converts 
to an InputStream: text, bytes, a stream or a file. A Map or a List fails: 
marshal it first" },
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "hostname": { "index": 0, "kind": "path", "displayName": "Hostname", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.smb.SmbConfiguration", "configurationField": 
"configuration", "description": "The share hostname or IP address" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 445, 
"configurationClass": "org.apache.camel.component.smb.SmbConfiguration", 
"configurationField": "configuration", "description": "The share port number" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-event.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-event.json
index 548bc4407d51..a90da06950b1 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-event.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-event.json
@@ -28,6 +28,11 @@
     "lazyStartProducer": { "index": 1, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
     "autowiredEnabled": { "index": 2, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "javaType": 
"org.springframework.context.ApplicationEvent", "description": "The 
ApplicationEvent itself, for every event of the ApplicationContext whatever the 
name: an object published with publishEvent comes as a PayloadApplicationEvent, 
and a non-event body a spring-event producer sent as a CamelEvent, whose 
getExchange() holds the sending exchange" },
+    "producerIn": { "carriers": [ "any" ], "description": "An ApplicationEvent 
body is published as it is. Any other body, also none, is published as a 
CamelEvent that holds the exchange, so listeners read the body from its 
getExchange()" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "The body is 
left as it is. The listeners run before the producer returns, and a CamelEvent 
gives them the exchange itself" }
+  },
   "properties": {
     "name": { "index": 0, "kind": "path", "displayName": "Name", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Name of endpoint" },
     "bridgeErrorHandler": { "index": 1, "kind": "parameter", "displayName": 
"Bridge Error Handler", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Allows for bridging the consumer to the 
Camel routing Error Handler, which mean any exceptions (if possible) occurred 
while the Camel consumer is trying to pickup incoming  [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/stax.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/stax.json
index 40c81ed22a82..2d3590177b9e 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/stax.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/stax.json
@@ -27,6 +27,10 @@
     "lazyStartProducer": { "index": 0, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
     "autowiredEnabled": { "index": 1, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "stream", "file", "pojo" ], 
"format": "xml", "description": "The XML to parse: text, a stream, a file or a 
javax.xml.transform.Source. Bytes, a DOM Document, a Map or no body fail: 
convert bytes to a String first" },
+    "producerOut": { "carriers": [ "pojo" ], "dependsOn": [ 
"contentHandlerClass" ], "description": "The ContentHandler after the parse: a 
new instance of contentHandlerClass per message, or the one bean of a #bean 
reference" }
+  },
   "properties": {
     "contentHandlerClass": { "index": 0, "kind": "path", "displayName": 
"Content Handler Class", "group": "producer", "label": "", "required": true, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
FQN class name for the ContentHandler implementation to use." },
     "lazyStartProducer": { "index": 1, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produc [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/weather.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/weather.json
index 95cddc90ec1f..0aaae9f7caa9 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/weather.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/weather.json
@@ -34,6 +34,11 @@
     "CamelWeatherLocation": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Used by the producer to override the endpoint 
location and use the location from this header instead.", "constantName": 
"org.apache.camel.component.weather.WeatherConstants#WEATHER_LOCATION" },
     "CamelWeatherQuery": { "index": 1, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The original query URL sent to the Open Weather Map 
site", "constantName": 
"org.apache.camel.component.weather.WeatherConstants#WEATHER_QUERY" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text" ], "javaType": "java.lang.String", 
"format": "json", "dependsOn": [ "mode", "headerName" ], "description": "The 
OpenWeatherMap response as a String: JSON, or XML or HTML with mode. With 
headerName the response is in that header and the body is null" },
+    "producerIn": { "carriers": [ "any" ], "description": "The body is not 
read: the query comes from the options, and the CamelWeatherLocation header 
overrides the location" },
+    "producerOut": { "carriers": [ "text" ], "javaType": "java.lang.String", 
"format": "json", "dependsOn": [ "mode", "headerName" ], "description": "The 
OpenWeatherMap response as a String: JSON, or XML or HTML with mode. With 
headerName the response is in that header and the body is left unchanged" }
+  },
   "properties": {
     "name": { "index": 0, "kind": "path", "displayName": "Name", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.weather.WeatherConfiguration", 
"configurationField": "configuration", "description": "The name value is not 
used." },
     "headerName": { "index": 1, "kind": "parameter", "displayName": "Header 
Name", "group": "common", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.weather.WeatherConfiguration", 
"configurationField": "configuration", "description": "To store the weather 
result in this header instead of the message body. This is useable if you want 
to keep curren [...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/atom-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/atom-component.adoc
index 3c9cdeadd936..05999db2386d 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/atom-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/atom-component.adoc
@@ -51,20 +51,20 @@ include::partial$component-endpoint-headers.adoc[]
 
 Camel will set the In body on the returned `Exchange` with the entries.
 Depending on the `splitEntries` flag Camel will either return one
-`Entry` or a `List<Entry>`.
+entry (a `com.apptasticsoftware.rssreader.Item`) or a `List<Item>`.
 
 [width="100%",cols="10%,10%,80%",options="header",]
 |=======================================================================
 |Option |Value |Behavior
 |`splitEntries` |`true` |Only a single entry from the currently being 
processed feed is set:
-`exchange.in.body(Entry)`
+`exchange.in.body(Item)`
 
 |`splitEntries` |`false` |The entire list of entries from the feed is set:
-`exchange.in.body(List<Entry>)`
+`exchange.in.body(List<Item>)`
 |=======================================================================
 
-Camel can set the `Feed` object on the In header (see `feedHeader`
-option to disable this):
+Camel sets the `List<Item>` of all the entries of the feed on the 
`CamelAtomFeed` header (see the `feedHeader`
+option to disable this).
 
 == Usage
 
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/flatpack-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/flatpack-component.adoc
index 0140630265d1..24cf42f90647 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/flatpack-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/flatpack-component.adoc
@@ -50,8 +50,8 @@ configuration.
 
 === Message Body
 
-The component delivers the data in the IN message as a
-`org.apache.camel.component.flatpack.DataSetList` object that has
+The component delivers the data in the IN message as a Flatpack
+`net.sf.flatpack.DataSet` object that has
 converters for `java.util.Map` or `java.util.List`. +
  Usually you want the `Map` if you process one row at a time
 (`splitRows=true`). Use `List` for the entire content
@@ -68,16 +68,9 @@ For example, to get the firstname from the sample below:
   String firstName = row.get("FIRSTNAME");
 ----
 
-However, you can also always get it as a `List` (even for
-`splitRows=true`). The same example:
-
-._Java-only: accessing row data as a List from the exchange body_
-[source,java]
-----
-  List data = exchange.getIn().getBody(List.class);
-  Map row = (Map)data.get(0);
-  String firstName = row.get("FIRSTNAME");
-----
+With `splitRows=true`, every message shares the same `DataSet`, positioned at 
its row.
+Convert the body to a `Map` before any asynchronous step (such as `seda` or 
`wireTap`), as the next row moves the `DataSet`.
+Do not convert it to a `List`: that reads all the rows and the remaining rows 
are then not sent.
 
 === Header and Trailer records
 
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mapstruct-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mapstruct-component.adoc
index 05b6389d0599..bfe4b4050d2a 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mapstruct-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mapstruct-component.adoc
@@ -96,7 +96,7 @@ Where `MyFooDto` is a POJO that MapStruct is able to convert 
to/from.
 
 The same conversion can be a step of the route with the `mapstruct` endpoint, 
whose path is the fully qualified
 class name of the POJO to convert the message body to. This makes the mapping 
visible in the route, and with
-`mandatory=false` a body that no mapper can convert passes through unchanged 
instead of failing:
+`mandatory=false` a body that no mapper can convert becomes null (no body) 
instead of failing:
 
 [tabs]
 ====
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/rss-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/rss-component.adoc
index c48800d8aa5f..3d7fdeb1d784 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/rss-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/rss-component.adoc
@@ -51,7 +51,7 @@ include::partial$component-endpoint-headers.adoc[]
 
 Camel initializes the In body on the Exchange with a ROME `SyndFeed`.
 Depending on the value of the `splitEntries` flag, Camel returns either
-a `SyndFeed` with one `SyndEntry` or a `java.util.List` of `SyndEntrys`.
+a `SyndFeed` with one `SyndEntry` or the whole `SyndFeed` with all its 
`SyndEntrys`.
 
 [width="100%",cols="10%,10%,80%",options="header",]
 |=======================================================================
diff --git 
a/components/camel-atom/src/generated/resources/META-INF/org/apache/camel/component/atom/atom.json
 
b/components/camel-atom/src/generated/resources/META-INF/org/apache/camel/component/atom/atom.json
index bb4cca9e41c5..0ba3c388920d 100644
--- 
a/components/camel-atom/src/generated/resources/META-INF/org/apache/camel/component/atom/atom.json
+++ 
b/components/camel-atom/src/generated/resources/META-INF/org/apache/camel/component/atom/atom.json
@@ -30,6 +30,9 @@
   "headers": {
     "CamelAtomFeed": { "index": 0, "kind": "header", "displayName": "", 
"group": "consumer", "label": "", "required": false, "javaType": 
"java.util.List", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "When consuming the List object is set 
to this header.", "constantName": 
"org.apache.camel.component.atom.AtomConstants#ATOM_FEED" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "javaType": 
"com.apptasticsoftware.rssreader.Item", "byOption": [ { "option": 
"splitEntries", "value": "false", "carriers": [ "list" ], "javaType": 
"java.util.List" } ], "description": "One entry of the feed, a 
com.apptasticsoftware.rssreader.Item with its title, link, author, dates and 
content; with splitEntries=false the List of all the entries, empty for a feed 
without entries. The CamelAtomFeed header carries the List of the entries 
unless [...]
+  },
   "properties": {
     "feedUri": { "index": 0, "kind": "path", "displayName": "Feed Uri", 
"group": "consumer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The URI to the feed to 
poll." },
     "sendEmptyMessageWhenIdle": { "index": 1, "kind": "parameter", 
"displayName": "Send Empty Message When Idle", "group": "consumer", "label": 
"consumer", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
false, "description": "If the polling consumer did not poll any files, you can 
enable this option to send an empty message (no body) instead." },
diff --git a/components/camel-atom/src/main/docs/atom-component.adoc 
b/components/camel-atom/src/main/docs/atom-component.adoc
index 3c9cdeadd936..05999db2386d 100644
--- a/components/camel-atom/src/main/docs/atom-component.adoc
+++ b/components/camel-atom/src/main/docs/atom-component.adoc
@@ -51,20 +51,20 @@ include::partial$component-endpoint-headers.adoc[]
 
 Camel will set the In body on the returned `Exchange` with the entries.
 Depending on the `splitEntries` flag Camel will either return one
-`Entry` or a `List<Entry>`.
+entry (a `com.apptasticsoftware.rssreader.Item`) or a `List<Item>`.
 
 [width="100%",cols="10%,10%,80%",options="header",]
 |=======================================================================
 |Option |Value |Behavior
 |`splitEntries` |`true` |Only a single entry from the currently being 
processed feed is set:
-`exchange.in.body(Entry)`
+`exchange.in.body(Item)`
 
 |`splitEntries` |`false` |The entire list of entries from the feed is set:
-`exchange.in.body(List<Entry>)`
+`exchange.in.body(List<Item>)`
 |=======================================================================
 
-Camel can set the `Feed` object on the In header (see `feedHeader`
-option to disable this):
+Camel sets the `List<Item>` of all the entries of the feed on the 
`CamelAtomFeed` header (see the `feedHeader`
+option to disable this).
 
 == Usage
 
diff --git 
a/components/camel-atom/src/main/java/org/apache/camel/component/atom/AtomEndpoint.java
 
b/components/camel-atom/src/main/java/org/apache/camel/component/atom/AtomEndpoint.java
index 1806f1549f82..f0405781527b 100644
--- 
a/components/camel-atom/src/main/java/org/apache/camel/component/atom/AtomEndpoint.java
+++ 
b/components/camel-atom/src/main/java/org/apache/camel/component/atom/AtomEndpoint.java
@@ -22,6 +22,9 @@ import org.apache.camel.Processor;
 import org.apache.camel.component.feed.FeedComponent;
 import org.apache.camel.component.feed.FeedEndpoint;
 import org.apache.camel.component.feed.FeedPollingConsumer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.IdempotentRepository;
 import org.apache.camel.spi.UriEndpoint;
@@ -32,6 +35,14 @@ import org.apache.camel.spi.UriParam;
  */
 @UriEndpoint(firstVersion = "1.2.0", scheme = "atom", title = "Atom", syntax = 
"atom:feedUri", consumerOnly = true,
              category = { Category.DOCUMENT }, lenientProperties = true, 
headersClass = AtomConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.POJO, javaType = 
"com.apptasticsoftware.rssreader.Item",
+                                   byOption = @BodyType.When(option = 
"splitEntries", value = "false",
+                                                             carriers = 
Carrier.LIST, javaType = "java.util.List"),
+                                   description = "One entry of the feed, a 
com.apptasticsoftware.rssreader.Item with its"
+                                                 + " title, link, author, 
dates and content; with splitEntries=false the"
+                                                 + " List of all the entries, 
empty for a feed without entries. The"
+                                                 + " CamelAtomFeed header 
carries the List of the entries unless"
+                                                 + " feedHeader=false"))
 public class AtomEndpoint extends FeedEndpoint implements 
EndpointServiceLocation {
 
     @UriParam(label = "consumer,filter", defaultValue = "true", description = 
"Option to use the Idempotent "
diff --git 
a/components/camel-dfdl/src/generated/resources/META-INF/org/apache/camel/component/dfdl/dfdl.json
 
b/components/camel-dfdl/src/generated/resources/META-INF/org/apache/camel/component/dfdl/dfdl.json
index c22d8c144410..945255a8e264 100644
--- 
a/components/camel-dfdl/src/generated/resources/META-INF/org/apache/camel/component/dfdl/dfdl.json
+++ 
b/components/camel-dfdl/src/generated/resources/META-INF/org/apache/camel/component/dfdl/dfdl.json
@@ -27,6 +27,10 @@
     "lazyStartProducer": { "index": 0, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
     "autowiredEnabled": { "index": 1, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"byOption": [ { "option": "parseDirection", "value": "UNPARSE", "carriers": [ 
"text", "bytes", "stream", "file", "pojo" ] } ], "description": "Data in the 
format the DFDL schema describes, such as an EDI message, to parse. UNPARSE 
takes the XML infoset as text, bytes, a stream, a file or a DOM Document. A Map 
or no body fails" },
+    "producerOut": { "carriers": [ "pojo" ], "javaType": 
"org.w3c.dom.Document", "byOption": [ { "option": "parseDirection", "value": 
"UNPARSE", "carriers": [ "bytes" ], "javaType": "java.io.ByteArrayOutputStream" 
} ], "description": "The XML infoset as a DOM Document. UNPARSE gives the data 
in the format the DFDL schema describes as bytes, in a ByteArrayOutputStream" }
+  },
   "properties": {
     "schemaUri": { "index": 0, "kind": "path", "displayName": "Schema Uri", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The path to the DFDL 
schema file." },
     "parseDirection": { "index": 1, "kind": "parameter", "displayName": "Parse 
Direction", "group": "producer", "label": "", "required": false, "type": 
"enum", "javaType": "org.apache.camel.component.dfdl.ParseDirection", "enum": [ 
"PARSE", "UNPARSE" ], "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "defaultValue": "PARSE", "description": "Transform 
direction. Either PARSE or UNPARSE" },
diff --git 
a/components/camel-dfdl/src/main/java/org/apache/camel/component/dfdl/DfdlEndpoint.java
 
b/components/camel-dfdl/src/main/java/org/apache/camel/component/dfdl/DfdlEndpoint.java
index 6d835f8f7214..a432c47e2ec7 100644
--- 
a/components/camel-dfdl/src/main/java/org/apache/camel/component/dfdl/DfdlEndpoint.java
+++ 
b/components/camel-dfdl/src/main/java/org/apache/camel/component/dfdl/DfdlEndpoint.java
@@ -24,6 +24,9 @@ import org.w3c.dom.Document;
 
 import org.apache.camel.Category;
 import org.apache.camel.Exchange;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.Resource;
 import org.apache.camel.spi.UriEndpoint;
@@ -46,6 +49,20 @@ import 
org.apache.daffodil.japi.io.InputSourceDataInputStream;
  */
 @UriEndpoint(firstVersion = "4.11.0", scheme = "dfdl", title = "DFDL", syntax 
= "dfdl:schemaUri", producerOnly = true,
              category = { Category.TRANSFORMATION })
+@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE },
+                                  byOption = @BodyType.When(option = 
"parseDirection", value = "UNPARSE",
+                                                            carriers = {
+                                                                    
Carrier.TEXT, Carrier.BYTES, Carrier.STREAM,
+                                                                    
Carrier.FILE, Carrier.POJO }),
+                                  description = "Data in the format the DFDL 
schema describes, such as an EDI message, to"
+                                                + " parse. UNPARSE takes the 
XML infoset as text, bytes, a stream, a file or a"
+                                                + " DOM Document. A Map or no 
body fails"),
+           producerOut = @BodyType(value = Carrier.POJO, javaType = 
"org.w3c.dom.Document",
+                                   byOption = @BodyType.When(option = 
"parseDirection", value = "UNPARSE",
+                                                             carriers = 
Carrier.BYTES,
+                                                             javaType = 
"java.io.ByteArrayOutputStream"),
+                                   description = "The XML infoset as a DOM 
Document. UNPARSE gives the data in the format the"
+                                                 + " DFDL schema describes as 
bytes, in a ByteArrayOutputStream"))
 public class DfdlEndpoint extends ProcessorEndpoint {
 
     @UriPath
diff --git 
a/components/camel-flatpack/src/generated/resources/META-INF/org/apache/camel/component/flatpack/flatpack.json
 
b/components/camel-flatpack/src/generated/resources/META-INF/org/apache/camel/component/flatpack/flatpack.json
index 3043a66c232e..85ec8dfaf75c 100644
--- 
a/components/camel-flatpack/src/generated/resources/META-INF/org/apache/camel/component/flatpack/flatpack.json
+++ 
b/components/camel-flatpack/src/generated/resources/META-INF/org/apache/camel/component/flatpack/flatpack.json
@@ -31,6 +31,11 @@
   "headers": {
     "CamelFlatpackCounter": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": "int", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The current row index. For splitRows=false the counter 
is the total number of rows.", "constantName": 
"org.apache.camel.component.flatpack.FlatpackConstants#FLATPACK_COUNTER" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "javaType": 
"net.sf.flatpack.DataSet", "description": "The Flatpack DataSet the producer 
parsed. With splitRows, one message per row, with the DataSet at that row: 
convert it to a Map before any asynchronous step, as the next row moves it; a 
List reads all the rows and ends the split. With splitRows=false, the whole 
DataSet: convert it to a List of Maps" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"format": "text", "description": "The fixed-width or delimited data to parse, 
such as a file from the file consumer; a java.io.File, a Map or a List fails. 
The rows go to the consumer of the same endpoint" },
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "type": { "index": 0, "kind": "path", "displayName": "Type", "group": 
"common", "label": "", "required": false, "type": "enum", "javaType": 
"org.apache.camel.component.flatpack.FlatpackType", "enum": [ "fixed", "delim" 
], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "defaultValue": "delim", "description": "Whether to use fixed or 
delimiter" },
     "resourceUri": { "index": 1, "kind": "path", "displayName": "Resource 
Uri", "group": "common", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "supportFileReference": true, 
"description": "URL for loading the flatpack mapping file from classpath or 
file system" },
diff --git a/components/camel-flatpack/src/main/docs/flatpack-component.adoc 
b/components/camel-flatpack/src/main/docs/flatpack-component.adoc
index 0140630265d1..24cf42f90647 100644
--- a/components/camel-flatpack/src/main/docs/flatpack-component.adoc
+++ b/components/camel-flatpack/src/main/docs/flatpack-component.adoc
@@ -50,8 +50,8 @@ configuration.
 
 === Message Body
 
-The component delivers the data in the IN message as a
-`org.apache.camel.component.flatpack.DataSetList` object that has
+The component delivers the data in the IN message as a Flatpack
+`net.sf.flatpack.DataSet` object that has
 converters for `java.util.Map` or `java.util.List`. +
  Usually you want the `Map` if you process one row at a time
 (`splitRows=true`). Use `List` for the entire content
@@ -68,16 +68,9 @@ For example, to get the firstname from the sample below:
   String firstName = row.get("FIRSTNAME");
 ----
 
-However, you can also always get it as a `List` (even for
-`splitRows=true`). The same example:
-
-._Java-only: accessing row data as a List from the exchange body_
-[source,java]
-----
-  List data = exchange.getIn().getBody(List.class);
-  Map row = (Map)data.get(0);
-  String firstName = row.get("FIRSTNAME");
-----
+With `splitRows=true`, every message shares the same `DataSet`, positioned at 
its row.
+Convert the body to a `Map` before any asynchronous step (such as `seda` or 
`wireTap`), as the next row moves the `DataSet`.
+Do not convert it to a `List`: that reads all the rows and the remaining rows 
are then not sent.
 
 === Header and Trailer records
 
diff --git 
a/components/camel-flatpack/src/main/java/org/apache/camel/component/flatpack/FlatpackEndpoint.java
 
b/components/camel-flatpack/src/main/java/org/apache/camel/component/flatpack/FlatpackEndpoint.java
index 1190da4476b0..fa364470ad65 100644
--- 
a/components/camel-flatpack/src/main/java/org/apache/camel/component/flatpack/FlatpackEndpoint.java
+++ 
b/components/camel-flatpack/src/main/java/org/apache/camel/component/flatpack/FlatpackEndpoint.java
@@ -35,6 +35,9 @@ import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.processor.loadbalancer.LoadBalancer;
 import org.apache.camel.processor.loadbalancer.RoundRobinLoadBalancer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -50,6 +53,17 @@ import org.apache.camel.util.ObjectHelper;
  */
 @UriEndpoint(firstVersion = "1.4.0", scheme = "flatpack", title = "Flatpack", 
syntax = "flatpack:type:resourceUri",
              remote = false, category = { Category.TRANSFORMATION }, 
headersClass = FlatpackConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.POJO, javaType = 
"net.sf.flatpack.DataSet",
+                                   description = "The Flatpack DataSet the 
producer parsed. With splitRows, one message per row,"
+                                                 + " with the DataSet at that 
row: convert it to a Map before any asynchronous"
+                                                 + " step, as the next row 
moves it; a List reads all the rows and ends the"
+                                                 + " split. With 
splitRows=false, the whole DataSet: convert it to a List of"
+                                                 + " Maps"),
+           producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE }, format = "text",
+                                  description = "The fixed-width or delimited 
data to parse, such as a file from the file"
+                                                + " consumer; a java.io.File, 
a Map or a List fails. The rows go to the"
+                                                + " consumer of the same 
endpoint"),
+           producerOut = @BodyType(value = Carrier.UNCHANGED))
 public class FlatpackEndpoint extends DefaultPollingEndpoint {
 
     private LoadBalancer loadBalancer = new RoundRobinLoadBalancer();
diff --git 
a/components/camel-fop/src/generated/resources/META-INF/org/apache/camel/component/fop/fop.json
 
b/components/camel-fop/src/generated/resources/META-INF/org/apache/camel/component/fop/fop.json
index 16a494c7632a..38523237b1fc 100644
--- 
a/components/camel-fop/src/generated/resources/META-INF/org/apache/camel/component/fop/fop.json
+++ 
b/components/camel-fop/src/generated/resources/META-INF/org/apache/camel/component/fop/fop.json
@@ -30,6 +30,10 @@
   "headers": {
     "CamelFop.Output.Format": { "index": 0, "kind": "header", "displayName": 
"", "group": "producer", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The output format", "constantName": 
"org.apache.camel.component.fop.FopConstants#CAMEL_FOP_OUTPUT_FORMAT" }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"format": "xml", "description": "The XSL-FO document to render, as text, bytes, 
a stream or a file. A DOM Document, a Map or no body fails" },
+    "producerOut": { "carriers": [ "bytes" ], "javaType": 
"java.io.ByteArrayOutputStream", "description": "The rendered document as 
bytes, in a ByteArrayOutputStream: PDF, or the outputType, or the format of the 
CamelFop.Output.Format header" }
+  },
   "properties": {
     "outputType": { "index": 0, "kind": "path", "displayName": "Output Type", 
"group": "producer", "label": "", "required": true, "type": "enum", "javaType": 
"org.apache.camel.component.fop.FopOutputType", "enum": [ "pdf", "ps", "pcl", 
"png", "jpeg", "svg", "xml", "mif", "rtf", "txt" ], "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
primary output format is PDF but other output formats are also supported." },
     "fopFactory": { "index": 1, "kind": "parameter", "displayName": "Fop 
Factory", "group": "producer", "label": "", "required": false, "type": 
"object", "javaType": "org.apache.fop.apps.FopFactory", "deprecated": false, 
"autowired": false, "secret": false, "description": "Allows to use a custom 
configured or implementation of org.apache.fop.apps.FopFactory." },
diff --git 
a/components/camel-fop/src/main/java/org/apache/camel/component/fop/FopEndpoint.java
 
b/components/camel-fop/src/main/java/org/apache/camel/component/fop/FopEndpoint.java
index 420c8eec7c3b..bc7904ecc644 100644
--- 
a/components/camel-fop/src/main/java/org/apache/camel/component/fop/FopEndpoint.java
+++ 
b/components/camel-fop/src/main/java/org/apache/camel/component/fop/FopEndpoint.java
@@ -23,6 +23,9 @@ import org.apache.camel.Category;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -36,6 +39,12 @@ import org.apache.fop.apps.FopFactory;
  */
 @UriEndpoint(firstVersion = "2.10.0", scheme = "fop", title = "FOP", syntax = 
"fop:outputType", producerOnly = true,
              remote = false, category = { Category.FILE, 
Category.TRANSFORMATION }, headersClass = FopConstants.class)
+@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE }, format = "xml",
+                                  description = "The XSL-FO document to 
render, as text, bytes, a stream or a file. A DOM"
+                                                + " Document, a Map or no body 
fails"),
+           producerOut = @BodyType(value = Carrier.BYTES, javaType = 
"java.io.ByteArrayOutputStream",
+                                   description = "The rendered document as 
bytes, in a ByteArrayOutputStream: PDF, or the"
+                                                 + " outputType, or the format 
of the CamelFop.Output.Format header"))
 public class FopEndpoint extends DefaultEndpoint {
 
     @UriPath
diff --git 
a/components/camel-jcr/src/generated/resources/META-INF/org/apache/camel/component/jcr/jcr.json
 
b/components/camel-jcr/src/generated/resources/META-INF/org/apache/camel/component/jcr/jcr.json
index befedd599ea5..97acf6bad235 100644
--- 
a/components/camel-jcr/src/generated/resources/META-INF/org/apache/camel/component/jcr/jcr.json
+++ 
b/components/camel-jcr/src/generated/resources/META-INF/org/apache/camel/component/jcr/jcr.json
@@ -34,6 +34,11 @@
     "CamelJcrOperation": { "index": 1, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "defaultValue": "CamelJcrInsert", "description": "The 
operation to perform. Possible values: CamelJcrInsert or CamelJcrGetById", 
"constantName": "org.apache.camel.component.jcr.JcrConstants#JCR_OPERATION" },
     "CamelJcrNodeType": { "index": 2, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The node type of the target node", 
"constantName": "org.apache.camel.component.jcr.JcrConstants#JCR_NODE_TYPE" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "list" ], "javaType": "java.util.List", 
"description": "The JCR events received in one callback: a List of 
javax.jcr.observation.Event" },
+    "producerIn": { "carriers": [ "any" ], "description": "Insert (the 
default) ignores the body and stores the headers as node properties; getById 
(CamelJcrOperation header) reads the node identifier from the body as a String" 
},
+    "producerOut": { "carriers": [ "text", "unchanged" ], "description": 
"Insert sets the identifier of the node, a String; getById leaves the body and 
sets the node properties as headers" }
+  },
   "properties": {
     "host": { "index": 0, "kind": "path", "displayName": "Host", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Name of the javax.jcr.Repository to 
lookup from the Camel registry to be used." },
     "base": { "index": 1, "kind": "path", "displayName": "Base", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Get the base node when accessing the repository" },
diff --git 
a/components/camel-jcr/src/main/java/org/apache/camel/component/jcr/JcrEndpoint.java
 
b/components/camel-jcr/src/main/java/org/apache/camel/component/jcr/JcrEndpoint.java
index 5f2f224f2fc0..94e1c6a3c757 100644
--- 
a/components/camel-jcr/src/main/java/org/apache/camel/component/jcr/JcrEndpoint.java
+++ 
b/components/camel-jcr/src/main/java/org/apache/camel/component/jcr/JcrEndpoint.java
@@ -28,6 +28,9 @@ import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.HeaderFilterStrategy;
 import org.apache.camel.spi.HeaderFilterStrategyAware;
 import org.apache.camel.spi.Metadata;
@@ -45,6 +48,15 @@ import org.apache.camel.util.StringHelper;
 @UriEndpoint(firstVersion = "1.3.0", scheme = "jcr", title = "JCR", syntax = 
"jcr:host/base",
              alternativeSyntax = "jcr:username:password@host/base",
              category = { Category.DATABASE, Category.CMS }, headersClass = 
JcrConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.LIST, javaType = 
"java.util.List",
+                                   description = "The JCR events received in 
one callback: a List of javax.jcr.observation.Event"),
+           producerIn = @BodyType(value = Carrier.ANY,
+                                  description = "Insert (the default) ignores 
the body and stores the headers as node"
+                                                + " properties; getById 
(CamelJcrOperation header) reads the node identifier"
+                                                + " from the body as a 
String"),
+           producerOut = @BodyType(value = { Carrier.TEXT, Carrier.UNCHANGED },
+                                   description = "Insert sets the identifier 
of the node, a String; getById leaves the body"
+                                                 + " and sets the node 
properties as headers"))
 public class JcrEndpoint extends DefaultEndpoint implements 
HeaderFilterStrategyAware {
 
     private Credentials credentials;
diff --git 
a/components/camel-jt400/src/generated/resources/META-INF/org/apache/camel/component/jt400/jt400.json
 
b/components/camel-jt400/src/generated/resources/META-INF/org/apache/camel/component/jt400/jt400.json
index de94380bab3e..1332a1618e71 100644
--- 
a/components/camel-jt400/src/generated/resources/META-INF/org/apache/camel/component/jt400/jt400.json
+++ 
b/components/camel-jt400/src/generated/resources/META-INF/org/apache/camel/component/jt400/jt400.json
@@ -42,6 +42,11 @@
     "CamelJt400MessageDefaultReply": { "index": 7, "kind": "header", 
"displayName": "", "group": "consumer", "label": "consumer", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The default message reply, when the 
message is an inquiry message", "constantName": 
"org.apache.camel.component.jt400.Jt400Constants#MESSAGE_DFT_RPY" },
     "CamelJt400MessageReplyToKey": { "index": 8, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "byte[]", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Consumer: The key of the message that 
will be replied to (if the sendingReply parameter is set to true). Producer: If 
set, and if the message body is not empty, a new message will not be sent to 
the provided message queue. Instead, a re [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text" ], "dependsOn": [ "objectPath" ], 
"byOption": [ { "option": "format", "value": "binary", "carriers": [ "bytes" ] 
}, { "option": "sendEmptyMessageWhenIdle", "value": "true", "carriers": [ 
"text", "bytes", "null" ] } ], "description": "The data queue entry as a 
String, or a byte array with format=binary; a message queue (.MSGQ) always 
gives the message text" },
+    "producerIn": { "carriers": [ "any" ], "dependsOn": [ "objectPath", 
"format" ], "description": "A queue writes the body converted to a String, or 
to a byte array with format=binary (text, bytes or a stream). A program call 
(.PGM, .SRVPGM) needs an Object[] of the parameters: a List fails" },
+    "producerOut": { "carriers": [ "unchanged" ], "dependsOn": [ "objectPath" 
], "description": "Unchanged for a queue. A program call sets an Object[] of 
the parameters, the output ones replaced by what the program returned: Strings, 
or byte arrays with format=binary" }
+  },
   "properties": {
     "userID": { "index": 0, "kind": "path", "displayName": "User ID", "group": 
"security", "label": "security", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.jt400.Jt400Configuration", "configurationField": 
"configuration", "description": "Returns the ID of the IBM i user." },
     "password": { "index": 1, "kind": "path", "displayName": "Password", 
"group": "security", "label": "security", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.jt400.Jt400Configuration", "configurationField": 
"configuration", "description": "Returns the password of the IBM i user." },
diff --git 
a/components/camel-jt400/src/main/java/org/apache/camel/component/jt400/Jt400Endpoint.java
 
b/components/camel-jt400/src/main/java/org/apache/camel/component/jt400/Jt400Endpoint.java
index 1097ee7d0710..45a58baee4d2 100644
--- 
a/components/camel-jt400/src/main/java/org/apache/camel/component/jt400/Jt400Endpoint.java
+++ 
b/components/camel-jt400/src/main/java/org/apache/camel/component/jt400/Jt400Endpoint.java
@@ -30,6 +30,9 @@ import org.apache.camel.Consumer;
 import org.apache.camel.MultipleConsumersSupport;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -44,6 +47,21 @@ import org.apache.camel.util.URISupport;
 @UriEndpoint(firstVersion = "1.5.0", scheme = "jt400", title = "JT400",
              syntax = "jt400:userID:password@systemName/objectPath", category 
= { Category.MESSAGING },
              headersClass = Jt400Constants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.TEXT, dependsOn = 
"objectPath",
+                                   byOption = {
+                                           @BodyType.When(option = "format", 
value = "binary", carriers = Carrier.BYTES),
+                                           @BodyType.When(option = 
"sendEmptyMessageWhenIdle", value = "true",
+                                                          carriers = { 
Carrier.TEXT, Carrier.BYTES, Carrier.NULL }) },
+                                   description = "The data queue entry as a 
String, or a byte array with format=binary; a"
+                                                 + " message queue (.MSGQ) 
always gives the message text"),
+           producerIn = @BodyType(value = Carrier.ANY, dependsOn = { 
"objectPath", "format" },
+                                  description = "A queue writes the body 
converted to a String, or to a byte array with"
+                                                + " format=binary (text, bytes 
or a stream). A program call (.PGM, .SRVPGM)"
+                                                + " needs an Object[] of the 
parameters: a List fails"),
+           producerOut = @BodyType(value = Carrier.UNCHANGED, dependsOn = 
"objectPath",
+                                   description = "Unchanged for a queue. A 
program call sets an Object[] of the parameters,"
+                                                 + " the output ones replaced 
by what the program returned: Strings, or byte"
+                                                 + " arrays with 
format=binary"))
 public class Jt400Endpoint extends ScheduledPollEndpoint implements 
MultipleConsumersSupport, EndpointServiceLocation {
 
     public static final String KEY = Jt400Constants.KEY;
diff --git 
a/components/camel-mapstruct/src/generated/resources/META-INF/org/apache/camel/component/mapstruct/mapstruct.json
 
b/components/camel-mapstruct/src/generated/resources/META-INF/org/apache/camel/component/mapstruct/mapstruct.json
index 2d679670dbb9..3688198793a7 100644
--- 
a/components/camel-mapstruct/src/generated/resources/META-INF/org/apache/camel/component/mapstruct/mapstruct.json
+++ 
b/components/camel-mapstruct/src/generated/resources/META-INF/org/apache/camel/component/mapstruct/mapstruct.json
@@ -29,6 +29,10 @@
     "autowiredEnabled": { "index": 2, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
     "mapStructConverter": { "index": 3, "kind": "property", "displayName": 
"Map Struct Converter", "group": "advanced", "label": "advanced", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.component.mapstruct.MapStructMapperFinder", "deprecated": 
false, "autowired": true, "secret": false, "description": "To use a custom 
MapStructConverter such as adapting to a special runtime." }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "pojo", "null" ], "description": "A POJO 
that a mapper of the mapperPackageName packages maps to the className type; a 
body of that type already is left as it is. Any other body fails with an 
InvalidPayloadException, unless mandatory is false" },
+    "producerOut": { "carriers": [ "pojo", "null" ], "description": "The 
object of the className type the mapper returns, or null when there is no body. 
With mandatory=false, a body that no mapper converts becomes null" }
+  },
   "properties": {
     "className": { "index": 0, "kind": "path", "displayName": "Class Name", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The fully qualified class 
name of the POJO that mapstruct should convert to (target)" },
     "mandatory": { "index": 1, "kind": "parameter", "displayName": 
"Mandatory", "group": "producer", "label": "", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether there must exist 
a mapstruct converter to convert to the POJO." },
diff --git a/components/camel-mapstruct/src/main/docs/mapstruct-component.adoc 
b/components/camel-mapstruct/src/main/docs/mapstruct-component.adoc
index 05b6389d0599..bfe4b4050d2a 100644
--- a/components/camel-mapstruct/src/main/docs/mapstruct-component.adoc
+++ b/components/camel-mapstruct/src/main/docs/mapstruct-component.adoc
@@ -96,7 +96,7 @@ Where `MyFooDto` is a POJO that MapStruct is able to convert 
to/from.
 
 The same conversion can be a step of the route with the `mapstruct` endpoint, 
whose path is the fully qualified
 class name of the POJO to convert the message body to. This makes the mapping 
visible in the route, and with
-`mandatory=false` a body that no mapper can convert passes through unchanged 
instead of failing:
+`mandatory=false` a body that no mapper can convert becomes null (no body) 
instead of failing:
 
 [tabs]
 ====
diff --git 
a/components/camel-mapstruct/src/main/java/org/apache/camel/component/mapstruct/MapstructEndpoint.java
 
b/components/camel-mapstruct/src/main/java/org/apache/camel/component/mapstruct/MapstructEndpoint.java
index 3c0fdb169ef2..ffb11260dc98 100644
--- 
a/components/camel-mapstruct/src/main/java/org/apache/camel/component/mapstruct/MapstructEndpoint.java
+++ 
b/components/camel-mapstruct/src/main/java/org/apache/camel/component/mapstruct/MapstructEndpoint.java
@@ -21,6 +21,9 @@ import org.apache.camel.Component;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -31,6 +34,13 @@ import org.apache.camel.util.ObjectHelper;
 @UriEndpoint(firstVersion = "3.19.0", scheme = "mapstruct", title = 
"MapStruct", syntax = "mapstruct:className",
              remote = false, producerOnly = true,
              category = { Category.TRANSFORMATION })
+@BodyTypes(producerIn = @BodyType(value = { Carrier.POJO, Carrier.NULL },
+                                  description = "A POJO that a mapper of the 
mapperPackageName packages maps to the className"
+                                                + " type; a body of that type 
already is left as it is. Any other body fails"
+                                                + " with an 
InvalidPayloadException, unless mandatory is false"),
+           producerOut = @BodyType(value = { Carrier.POJO, Carrier.NULL },
+                                   description = "The object of the className 
type the mapper returns, or null when there is"
+                                                 + " no body. With 
mandatory=false, a body that no mapper converts becomes null"))
 public class MapstructEndpoint extends DefaultEndpoint {
 
     @UriPath
diff --git 
a/components/camel-oaipmh/src/generated/resources/META-INF/org/apache/camel/oaipmh/component/oaipmh.json
 
b/components/camel-oaipmh/src/generated/resources/META-INF/org/apache/camel/oaipmh/component/oaipmh.json
index 40c5335d8360..2ea471cd7e36 100644
--- 
a/components/camel-oaipmh/src/generated/resources/META-INF/org/apache/camel/oaipmh/component/oaipmh.json
+++ 
b/components/camel-oaipmh/src/generated/resources/META-INF/org/apache/camel/oaipmh/component/oaipmh.json
@@ -34,6 +34,11 @@
     "CamelOaimphResumptionToken": { "index": 0, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "This header is obtained when onlyFirst 
option is enable. Return resumption token of the request when data is still 
available.", "constantName": 
"org.apache.camel.oaipmh.component.model.OAIPMHConstants#RESUMPTION_TOKEN" },
     "CamelOaimphHttpHeaders": { "index": 1, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"java.util.Map<java.lang.String, java.lang.String>", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Custom HTTP headers to send with the request, overriding any httpHeader. 
endpoint parameters.", "constantName": 
"org.apache.camel.oaipmh.component.model.OAIPMHConstants#HTTP_HEADERS" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text" ], "javaType": "java.lang.String", 
"format": "xml", "description": "The XML response of one OAI-PMH request as a 
String: one message per page, following the resumption tokens until the last 
page" },
+    "producerIn": { "carriers": [ "any" ], "description": "The body is not 
read: the request comes from the options, which the CamelOaimph headers 
override" },
+    "producerOut": { "carriers": [ "list" ], "javaType": "java.util.List", 
"description": "A List of Strings, the XML response of each page of the request 
until the last; with onlyFirst only the first page, and the token for the next 
page in the CamelOaimphResumptionToken header" }
+  },
   "properties": {
     "baseUrl": { "index": 0, "kind": "path", "displayName": "Base Url", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Base URL of the repository to which the 
request is made through the OAI-PMH protocol" },
     "from": { "index": 1, "kind": "parameter", "displayName": "From", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Specifies a lower bound for datestamp-based selective 
harvesting. UTC DateTime value" },
diff --git 
a/components/camel-oaipmh/src/main/java/org/apache/camel/oaipmh/component/OAIPMHEndpoint.java
 
b/components/camel-oaipmh/src/main/java/org/apache/camel/oaipmh/component/OAIPMHEndpoint.java
index 872d6f7e41ad..9de2126bdad1 100644
--- 
a/components/camel-oaipmh/src/main/java/org/apache/camel/oaipmh/component/OAIPMHEndpoint.java
+++ 
b/components/camel-oaipmh/src/main/java/org/apache/camel/oaipmh/component/OAIPMHEndpoint.java
@@ -25,6 +25,9 @@ import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.oaipmh.component.model.OAIPMHConstants;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
@@ -39,6 +42,16 @@ import org.joda.time.format.ISODateTimeFormat;
  */
 @UriEndpoint(firstVersion = "3.5.0", scheme = "oaipmh", title = "OAI-PMH", 
syntax = "oaipmh:baseUrl", lenientProperties = true,
              category = { Category.SEARCH }, headersClass = 
OAIPMHConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.TEXT, javaType = 
"java.lang.String", format = "xml",
+                                   description = "The XML response of one 
OAI-PMH request as a String: one message per"
+                                                 + " page, following the 
resumption tokens until the last page"),
+           producerIn = @BodyType(value = Carrier.ANY,
+                                  description = "The body is not read: the 
request comes from the options, which the"
+                                                + " CamelOaimph headers 
override"),
+           producerOut = @BodyType(value = Carrier.LIST, javaType = 
"java.util.List",
+                                   description = "A List of Strings, the XML 
response of each page of the request until"
+                                                 + " the last; with onlyFirst 
only the first page, and the token for the next"
+                                                 + " page in the 
CamelOaimphResumptionToken header"))
 public class OAIPMHEndpoint extends ScheduledPollEndpoint implements 
EndpointServiceLocation {
 
     private transient URI url;
diff --git 
a/components/camel-robotframework/src/generated/resources/META-INF/org/apache/camel/component/robotframework/robotframework.json
 
b/components/camel-robotframework/src/generated/resources/META-INF/org/apache/camel/component/robotframework/robotframework.json
index 7ccd7b4110a4..fd53b52ec4b1 100644
--- 
a/components/camel-robotframework/src/generated/resources/META-INF/org/apache/camel/component/robotframework/robotframework.json
+++ 
b/components/camel-robotframework/src/generated/resources/META-INF/org/apache/camel/component/robotframework/robotframework.json
@@ -81,6 +81,11 @@
     "CamelRobotReturnCode": { "index": 1, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "Integer", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The return code.", "constantName": 
"org.apache.camel.component.robotframework.RobotFrameworkCamelConstants#CAMEL_ROBOT_RETURN_CODE"
 },
     "CamelRobotResourceUri": { "index": 2, "kind": "header", "displayName": 
"", "group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The new resource URI.", "constantName": 
"org.apache.camel.component.robotframework.RobotFrameworkCamelConstants#CAMEL_ROBOT_RESOURCE_URI"
 }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "null" ], "description": "No body: each 
poll runs the test, and the outcome is in the CamelRobotReturnCode header (0 
when all tests pass)" },
+    "producerIn": { "carriers": [ "any" ], "description": "The test gets the 
body converted to a String as the body variable, and the headers and exchange 
properties as headers.name and properties.name; a null body or header value 
fails the exchange" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "The body is 
left as it is. The CamelRobotReturnCode header has the return code of the run 
(0 when all tests pass, non-zero otherwise), and CamelRobotVariables the 
variables passed to it; a failed test does not fail the exchange" }
+  },
   "properties": {
     "resourceUri": { "index": 0, "kind": "path", "displayName": "Resource 
Uri", "group": "common", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "supportFileReference": true, 
"description": "Path to the resource. You can prefix with: classpath, file, 
http, ref, or bean. classpath, file and http loads the resource using these 
protocols (classpath is default). ref will lookup [...]
     "allowContextMapAll": { "index": 1, "kind": "parameter", "displayName": 
"Allow Context Map All", "group": "common", "label": "", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": false, "configurationClass": 
"org.apache.camel.component.robotframework.RobotFrameworkCamelConfiguration", 
"configurationField": "configuration", "description": "Sets whether the context 
map should allow access to all detail [...]
diff --git 
a/components/camel-robotframework/src/main/java/org/apache/camel/component/robotframework/RobotFrameworkEndpoint.java
 
b/components/camel-robotframework/src/main/java/org/apache/camel/component/robotframework/RobotFrameworkEndpoint.java
index 5720ca440dbd..51dbd1886611 100644
--- 
a/components/camel-robotframework/src/main/java/org/apache/camel/component/robotframework/RobotFrameworkEndpoint.java
+++ 
b/components/camel-robotframework/src/main/java/org/apache/camel/component/robotframework/RobotFrameworkEndpoint.java
@@ -23,6 +23,9 @@ import org.apache.camel.Category;
 import org.apache.camel.Exchange;
 import org.apache.camel.ExchangePattern;
 import org.apache.camel.component.ResourceEndpoint;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -36,6 +39,18 @@ import org.robotframework.RobotFramework;
              syntax = "robotframework:resourceUri", category = { 
Category.TESTING },
              remote = false, headersClass = RobotFrameworkCamelConstants.class)
 @Metadata(excludeProperties = "contentCache")
+@BodyTypes(consumerOut = @BodyType(value = Carrier.NULL,
+                                   description = "No body: each poll runs the 
test, and the outcome is in the"
+                                                 + " CamelRobotReturnCode 
header (0 when all tests pass)"),
+           producerIn = @BodyType(value = Carrier.ANY,
+                                  description = "The test gets the body 
converted to a String as the body variable, and the"
+                                                + " headers and exchange 
properties as headers.name and properties.name; a"
+                                                + " null body or header value 
fails the exchange"),
+           producerOut = @BodyType(value = Carrier.UNCHANGED,
+                                   description = "The body is left as it is. 
The CamelRobotReturnCode header has the return"
+                                                 + " code of the run (0 when 
all tests pass, non-zero"
+                                                 + " otherwise), and 
CamelRobotVariables the variables passed to it; a failed"
+                                                 + " test does not fail the 
exchange"))
 public class RobotFrameworkEndpoint extends ResourceEndpoint {
 
     @UriParam
diff --git 
a/components/camel-rss/src/generated/resources/META-INF/org/apache/camel/component/rss/rss.json
 
b/components/camel-rss/src/generated/resources/META-INF/org/apache/camel/component/rss/rss.json
index c2546e871c7e..6284bc8b5362 100644
--- 
a/components/camel-rss/src/generated/resources/META-INF/org/apache/camel/component/rss/rss.json
+++ 
b/components/camel-rss/src/generated/resources/META-INF/org/apache/camel/component/rss/rss.json
@@ -30,6 +30,9 @@
   "headers": {
     "CamelRssFeed": { "index": 0, "kind": "header", "displayName": "", 
"group": "consumer", "label": "", "required": false, "javaType": "Object", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The entire SyncFeed object.", "constantName": 
"org.apache.camel.component.rss.RssConstants#RSS_FEED" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "javaType": 
"com.rometools.rome.feed.synd.SyndFeed", "description": "A ROME SyndFeed: with 
splitEntries (the default) a copy of the feed with the one entry in its 
entries, with splitEntries=false the whole feed with all its entries. The 
CamelRssFeed header carries the whole feed unless feedHeader=false" }
+  },
   "properties": {
     "feedUri": { "index": 0, "kind": "path", "displayName": "Feed Uri", 
"group": "consumer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The URI to the feed to 
poll." },
     "sendEmptyMessageWhenIdle": { "index": 1, "kind": "parameter", 
"displayName": "Send Empty Message When Idle", "group": "consumer", "label": 
"consumer", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
false, "description": "If the polling consumer did not poll any files, you can 
enable this option to send an empty message (no body) instead." },
diff --git a/components/camel-rss/src/main/docs/rss-component.adoc 
b/components/camel-rss/src/main/docs/rss-component.adoc
index c48800d8aa5f..3d7fdeb1d784 100644
--- a/components/camel-rss/src/main/docs/rss-component.adoc
+++ b/components/camel-rss/src/main/docs/rss-component.adoc
@@ -51,7 +51,7 @@ include::partial$component-endpoint-headers.adoc[]
 
 Camel initializes the In body on the Exchange with a ROME `SyndFeed`.
 Depending on the value of the `splitEntries` flag, Camel returns either
-a `SyndFeed` with one `SyndEntry` or a `java.util.List` of `SyndEntrys`.
+a `SyndFeed` with one `SyndEntry` or the whole `SyndFeed` with all its 
`SyndEntrys`.
 
 [width="100%",cols="10%,10%,80%",options="header",]
 |=======================================================================
diff --git 
a/components/camel-rss/src/main/java/org/apache/camel/component/rss/RssEndpoint.java
 
b/components/camel-rss/src/main/java/org/apache/camel/component/rss/RssEndpoint.java
index fef1db7d13f7..922204db4b5c 100644
--- 
a/components/camel-rss/src/main/java/org/apache/camel/component/rss/RssEndpoint.java
+++ 
b/components/camel-rss/src/main/java/org/apache/camel/component/rss/RssEndpoint.java
@@ -27,6 +27,9 @@ import org.apache.camel.Producer;
 import org.apache.camel.component.feed.FeedComponent;
 import org.apache.camel.component.feed.FeedEndpoint;
 import org.apache.camel.component.feed.FeedPollingConsumer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.UriEndpoint;
 import org.slf4j.Logger;
@@ -38,6 +41,11 @@ import org.slf4j.LoggerFactory;
 @UriEndpoint(firstVersion = "2.0.0", scheme = "rss", extendsScheme = "atom", 
title = "RSS",
              syntax = "rss:feedUri", consumerOnly = true, category = { 
Category.DOCUMENT }, lenientProperties = true,
              headersClass = RssConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.POJO, javaType = 
"com.rometools.rome.feed.synd.SyndFeed",
+                                   description = "A ROME SyndFeed: with 
splitEntries (the default) a copy of the feed with"
+                                                 + " the one entry in its 
entries, with splitEntries=false the whole feed"
+                                                 + " with all its entries. The 
CamelRssFeed header carries the whole feed"
+                                                 + " unless feedHeader=false"))
 public class RssEndpoint extends FeedEndpoint implements 
EndpointServiceLocation {
     protected static final Logger LOG = 
LoggerFactory.getLogger(RssEndpoint.class);
 
diff --git 
a/components/camel-smb/src/generated/resources/META-INF/org/apache/camel/component/smb/smb.json
 
b/components/camel-smb/src/generated/resources/META-INF/org/apache/camel/component/smb/smb.json
index 89a91c682439..55f1956e05cc 100644
--- 
a/components/camel-smb/src/generated/resources/META-INF/org/apache/camel/component/smb/smb.json
+++ 
b/components/camel-smb/src/generated/resources/META-INF/org/apache/camel/component/smb/smb.json
@@ -49,6 +49,11 @@
     "CamelSmbFileExists": { "index": 15, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"org.apache.camel.component.file.GenericFileExist", "enum": [ "Override", 
"Append", "Fail", "Ignore", "Move", "TryRename" ], "deprecated": true, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
expected behavior if the file already exists.", "constantName": 
"org.apache.camel.component.smb.SmbConstants#SMB_FIL [...]
     "CamelSmbUncPath": { "index": 16, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "UNC path to the retrieved file", 
"constantName": "org.apache.camel.component.smb.SmbConstants#SMB_UNC_PATH" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "file" ], "dependsOn": [ "preMove" ], 
"byOption": [ { "option": "streamDownload", "value": "true", "carriers": [ 
"stream" ] }, { "option": "download", "value": "false", "carriers": [ "null" ] 
} ], "description": "The file as read: an SmbFile, which converts to text, 
bytes or a stream; a stream with streamDownload; with preMove its content, a 
byte array (a stream with streamDownload)" },
+    "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], 
"byOption": [ { "option": "allowNullBody", "value": "true", "carriers": [ 
"null", "text", "bytes", "stream", "file" ] } ], "description": "What converts 
to an InputStream: text, bytes, a stream or a file. A Map or a List fails: 
marshal it first" },
+    "producerOut": { "carriers": [ "unchanged" ] }
+  },
   "properties": {
     "hostname": { "index": 0, "kind": "path", "displayName": "Hostname", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.smb.SmbConfiguration", "configurationField": 
"configuration", "description": "The share hostname or IP address" },
     "port": { "index": 1, "kind": "path", "displayName": "Port", "group": 
"common", "label": "", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 445, 
"configurationClass": "org.apache.camel.component.smb.SmbConfiguration", 
"configurationField": "configuration", "description": "The share port number" },
diff --git 
a/components/camel-smb/src/main/java/org/apache/camel/component/smb/SmbEndpoint.java
 
b/components/camel-smb/src/main/java/org/apache/camel/component/smb/SmbEndpoint.java
index a7f76fdeab77..1adf7a705575 100644
--- 
a/components/camel-smb/src/main/java/org/apache/camel/component/smb/SmbEndpoint.java
+++ 
b/components/camel-smb/src/main/java/org/apache/camel/component/smb/SmbEndpoint.java
@@ -35,6 +35,9 @@ import 
org.apache.camel.component.file.GenericFileProcessStrategy;
 import org.apache.camel.component.file.GenericFileProducer;
 import org.apache.camel.component.file.strategy.FileMoveExistingStrategy;
 import org.apache.camel.component.smb.strategy.SmbProcessStrategyFactory;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
@@ -54,6 +57,21 @@ import org.slf4j.LoggerFactory;
                               + 
"directoryMustExist,extendedAttributes,probeContentType,"
                               + 
"startingDirectoryMustHaveAccess,chmodDirectory,forceWrites,"
                               + "synchronous")
+@BodyTypes(consumerOut = @BodyType(value = Carrier.FILE, dependsOn = "preMove",
+                                   byOption = {
+                                           @BodyType.When(option = 
"streamDownload", value = "true", carriers = Carrier.STREAM),
+                                           @BodyType.When(option = "download", 
value = "false", carriers = Carrier.NULL) },
+                                   description = "The file as read: an 
SmbFile, which converts to text, bytes or a stream; a"
+                                                 + " stream with 
streamDownload; with preMove its content, a byte array (a stream with"
+                                                 + " streamDownload)"),
+           producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, 
Carrier.STREAM, Carrier.FILE },
+                                  byOption = @BodyType.When(option = 
"allowNullBody", value = "true",
+                                                            carriers = {
+                                                                    
Carrier.NULL, Carrier.TEXT, Carrier.BYTES,
+                                                                    
Carrier.STREAM, Carrier.FILE }),
+                                  description = "What converts to an 
InputStream: text, bytes, a stream or a file. A Map or"
+                                                + " a List fails: marshal it 
first"),
+           producerOut = @BodyType(Carrier.UNCHANGED))
 public class SmbEndpoint extends 
GenericFileEndpoint<FileIdBothDirectoryInformation> implements 
EndpointServiceLocation {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(SmbEndpoint.class);
diff --git 
a/components/camel-spring-parent/camel-spring/src/generated/resources/META-INF/org/apache/camel/component/event/spring-event.json
 
b/components/camel-spring-parent/camel-spring/src/generated/resources/META-INF/org/apache/camel/component/event/spring-event.json
index 548bc4407d51..a90da06950b1 100644
--- 
a/components/camel-spring-parent/camel-spring/src/generated/resources/META-INF/org/apache/camel/component/event/spring-event.json
+++ 
b/components/camel-spring-parent/camel-spring/src/generated/resources/META-INF/org/apache/camel/component/event/spring-event.json
@@ -28,6 +28,11 @@
     "lazyStartProducer": { "index": 1, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
     "autowiredEnabled": { "index": 2, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "pojo" ], "javaType": 
"org.springframework.context.ApplicationEvent", "description": "The 
ApplicationEvent itself, for every event of the ApplicationContext whatever the 
name: an object published with publishEvent comes as a PayloadApplicationEvent, 
and a non-event body a spring-event producer sent as a CamelEvent, whose 
getExchange() holds the sending exchange" },
+    "producerIn": { "carriers": [ "any" ], "description": "An ApplicationEvent 
body is published as it is. Any other body, also none, is published as a 
CamelEvent that holds the exchange, so listeners read the body from its 
getExchange()" },
+    "producerOut": { "carriers": [ "unchanged" ], "description": "The body is 
left as it is. The listeners run before the producer returns, and a CamelEvent 
gives them the exchange itself" }
+  },
   "properties": {
     "name": { "index": 0, "kind": "path", "displayName": "Name", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Name of endpoint" },
     "bridgeErrorHandler": { "index": 1, "kind": "parameter", "displayName": 
"Bridge Error Handler", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Allows for bridging the consumer to the 
Camel routing Error Handler, which mean any exceptions (if possible) occurred 
while the Camel consumer is trying to pickup incoming  [...]
diff --git 
a/components/camel-spring-parent/camel-spring/src/main/java/org/apache/camel/component/event/EventEndpoint.java
 
b/components/camel-spring-parent/camel-spring/src/main/java/org/apache/camel/component/event/EventEndpoint.java
index 811ff8fc0a92..4337c59e4719 100644
--- 
a/components/camel-spring-parent/camel-spring/src/main/java/org/apache/camel/component/event/EventEndpoint.java
+++ 
b/components/camel-spring-parent/camel-spring/src/main/java/org/apache/camel/component/event/EventEndpoint.java
@@ -22,6 +22,9 @@ import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.processor.loadbalancer.LoadBalancer;
 import org.apache.camel.processor.loadbalancer.TopicLoadBalancer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriPath;
 import org.apache.camel.support.DefaultEndpoint;
@@ -39,6 +42,18 @@ import static 
org.apache.camel.RuntimeCamelException.wrapRuntimeCamelException;
  */
 @UriEndpoint(firstVersion = "1.4.0", scheme = "spring-event", title = "Spring 
Event", syntax = "spring-event:name",
              remote = false, category = { Category.MESSAGING })
+@BodyTypes(consumerOut = @BodyType(value = Carrier.POJO, javaType = 
"org.springframework.context.ApplicationEvent",
+                                   description = "The ApplicationEvent itself, 
for every event of the ApplicationContext"
+                                                 + " whatever the name: an 
object published with publishEvent comes as a"
+                                                 + " PayloadApplicationEvent, 
and a non-event body a spring-event producer"
+                                                 + " sent as a CamelEvent, 
whose getExchange() holds the sending exchange"),
+           producerIn = @BodyType(value = Carrier.ANY,
+                                  description = "An ApplicationEvent body is 
published as it is. Any other body, also none,"
+                                                + " is published as a 
CamelEvent that holds the exchange, so listeners read the"
+                                                + " body from its 
getExchange()"),
+           producerOut = @BodyType(value = Carrier.UNCHANGED,
+                                   description = "The body is left as it is. 
The listeners run before the producer returns,"
+                                                 + " and a CamelEvent gives 
them the exchange itself"))
 public class EventEndpoint extends DefaultEndpoint implements 
ApplicationContextAware {
     private LoadBalancer loadBalancer;
     private ApplicationContext applicationContext;
diff --git 
a/components/camel-stax/src/generated/resources/META-INF/org/apache/camel/component/stax/stax.json
 
b/components/camel-stax/src/generated/resources/META-INF/org/apache/camel/component/stax/stax.json
index 40c81ed22a82..2d3590177b9e 100644
--- 
a/components/camel-stax/src/generated/resources/META-INF/org/apache/camel/component/stax/stax.json
+++ 
b/components/camel-stax/src/generated/resources/META-INF/org/apache/camel/component/stax/stax.json
@@ -27,6 +27,10 @@
     "lazyStartProducer": { "index": 0, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
     "autowiredEnabled": { "index": 1, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "stream", "file", "pojo" ], 
"format": "xml", "description": "The XML to parse: text, a stream, a file or a 
javax.xml.transform.Source. Bytes, a DOM Document, a Map or no body fail: 
convert bytes to a String first" },
+    "producerOut": { "carriers": [ "pojo" ], "dependsOn": [ 
"contentHandlerClass" ], "description": "The ContentHandler after the parse: a 
new instance of contentHandlerClass per message, or the one bean of a #bean 
reference" }
+  },
   "properties": {
     "contentHandlerClass": { "index": 0, "kind": "path", "displayName": 
"Content Handler Class", "group": "producer", "label": "", "required": true, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
FQN class name for the ContentHandler implementation to use." },
     "lazyStartProducer": { "index": 1, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produc [...]
diff --git 
a/components/camel-stax/src/main/java/org/apache/camel/component/stax/StAXEndpoint.java
 
b/components/camel-stax/src/main/java/org/apache/camel/component/stax/StAXEndpoint.java
index 2febe79b83e8..2cd8f142cc94 100644
--- 
a/components/camel-stax/src/main/java/org/apache/camel/component/stax/StAXEndpoint.java
+++ 
b/components/camel-stax/src/main/java/org/apache/camel/component/stax/StAXEndpoint.java
@@ -21,6 +21,9 @@ import org.xml.sax.ContentHandler;
 import org.apache.camel.Category;
 import org.apache.camel.Component;
 import org.apache.camel.Processor;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriPath;
@@ -32,6 +35,13 @@ import org.apache.camel.support.ProcessorEndpoint;
  */
 @UriEndpoint(firstVersion = "2.9.0", scheme = "stax", title = "StAX", syntax = 
"stax:contentHandlerClass", producerOnly = true,
              remote = false, category = { Category.TRANSFORMATION })
+@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.STREAM, 
Carrier.FILE, Carrier.POJO }, format = "xml",
+                                  description = "The XML to parse: text, a 
stream, a file or a javax.xml.transform.Source."
+                                                + " Bytes, a DOM Document, a 
Map or no body fail: convert bytes to a String"
+                                                + " first"),
+           producerOut = @BodyType(value = Carrier.POJO, dependsOn = 
"contentHandlerClass",
+                                   description = "The ContentHandler after the 
parse: a new instance of contentHandlerClass"
+                                                 + " per message, or the one 
bean of a #bean reference"))
 public class StAXEndpoint extends ProcessorEndpoint {
 
     @UriPath
diff --git 
a/components/camel-test/camel-test-citrus/src/generated/resources/META-INF/org/apache/camel/component/citrus/citrus.json
 
b/components/camel-test/camel-test-citrus/src/generated/resources/META-INF/org/apache/camel/component/citrus/citrus.json
index b068b5b4b76a..606d7d689b0c 100644
--- 
a/components/camel-test/camel-test-citrus/src/generated/resources/META-INF/org/apache/camel/component/citrus/citrus.json
+++ 
b/components/camel-test/camel-test-citrus/src/generated/resources/META-INF/org/apache/camel/component/citrus/citrus.json
@@ -29,6 +29,10 @@
     "autowiredEnabled": { "index": 2, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
     "exchangeFormatter": { "index": 3, "kind": "property", "displayName": 
"Exchange Formatter", "group": "advanced", "label": "advanced", "required": 
false, "type": "object", "javaType": "org.apache.camel.spi.ExchangeFormatter", 
"deprecated": false, "autowired": true, "secret": false, "description": "To use 
a custom ExchangeFormatter to format the Exchange into a String suitable for 
logging." }
   },
+  "bodyTypes": {
+    "producerIn": { "carriers": [ "text", "stream" ], "description": "The body 
Citrus validates, as text; a stream cache is read as text and reset. Any other 
body is compared by its toString(): bytes as a list of numbers, a file as its 
path, a Map as {key=value}, so convert it to a String first" },
+    "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": 
"operation", "value": "receive", "carriers": [ "text", "unchanged" ] } ], 
"description": "validate leaves the body as it is. receive sets the body of the 
simulated response, as text with its Citrus variables resolved (or what the 
MessagePayloadBuilder given to it builds), and leaves the body as it is when 
the response has no body or no spec matches the exchange" }
+  },
   "properties": {
     "operation": { "index": 0, "kind": "path", "displayName": "Operation", 
"group": "producer", "label": "", "required": true, "type": "enum", "javaType": 
"java.lang.String", "enum": [ "validate", "receive" ], "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
operation to perform. 'validate' validates exchanges without modifying them. 
'receive' validates exchanges and returns a simulated response." },
     "name": { "index": 1, "kind": "path", "displayName": "Name", "group": 
"producer", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "A unique name to identify this endpoint. Allows multiple Citrus 
endpoints with different validation expectations in the same route." },
diff --git 
a/components/camel-test/camel-test-citrus/src/main/java/org/apache/camel/component/citrus/CitrusEndpoint.java
 
b/components/camel-test/camel-test-citrus/src/main/java/org/apache/camel/component/citrus/CitrusEndpoint.java
index efcdfc354e20..949af01e2d4a 100644
--- 
a/components/camel-test/camel-test-citrus/src/main/java/org/apache/camel/component/citrus/CitrusEndpoint.java
+++ 
b/components/camel-test/camel-test-citrus/src/main/java/org/apache/camel/component/citrus/CitrusEndpoint.java
@@ -21,6 +21,9 @@ import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.camel.Category;
 import org.apache.camel.Exchange;
 import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -32,6 +35,18 @@ import 
org.citrusframework.validation.context.ValidationContext;
 
 @UriEndpoint(firstVersion = "4.24.0", scheme = "citrus", title = "Citrus", 
syntax = "citrus:operation/name",
              producerOnly = true, remote = false, category = { 
Category.TESTING })
+@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.STREAM },
+                                  description = "The body Citrus validates, as 
text; a stream cache is read as text and"
+                                                + " reset. Any other body is 
compared by its toString(): bytes as a list of"
+                                                + " numbers, a file as its 
path, a Map as {key=value}, so convert it to a String"
+                                                + " first"),
+           producerOut = @BodyType(value = Carrier.UNCHANGED,
+                                   byOption = @BodyType.When(option = 
"operation", value = "receive",
+                                                             carriers = { 
Carrier.TEXT, Carrier.UNCHANGED }),
+                                   description = "validate leaves the body as 
it is. receive sets the body of the simulated"
+                                                 + " response, as text with 
its Citrus variables resolved (or what the"
+                                                 + " MessagePayloadBuilder 
given to it builds), and leaves the body as it is"
+                                                 + " when the response has no 
body or no spec matches the exchange"))
 public class CitrusEndpoint extends MockEndpoint {
 
     @UriPath(description = "The operation to perform. 'validate' validates 
exchanges without modifying them."
diff --git 
a/components/camel-weather/src/generated/resources/META-INF/org/apache/camel/component/weather/weather.json
 
b/components/camel-weather/src/generated/resources/META-INF/org/apache/camel/component/weather/weather.json
index 95cddc90ec1f..0aaae9f7caa9 100644
--- 
a/components/camel-weather/src/generated/resources/META-INF/org/apache/camel/component/weather/weather.json
+++ 
b/components/camel-weather/src/generated/resources/META-INF/org/apache/camel/component/weather/weather.json
@@ -34,6 +34,11 @@
     "CamelWeatherLocation": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Used by the producer to override the endpoint 
location and use the location from this header instead.", "constantName": 
"org.apache.camel.component.weather.WeatherConstants#WEATHER_LOCATION" },
     "CamelWeatherQuery": { "index": 1, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The original query URL sent to the Open Weather Map 
site", "constantName": 
"org.apache.camel.component.weather.WeatherConstants#WEATHER_QUERY" }
   },
+  "bodyTypes": {
+    "consumerOut": { "carriers": [ "text" ], "javaType": "java.lang.String", 
"format": "json", "dependsOn": [ "mode", "headerName" ], "description": "The 
OpenWeatherMap response as a String: JSON, or XML or HTML with mode. With 
headerName the response is in that header and the body is null" },
+    "producerIn": { "carriers": [ "any" ], "description": "The body is not 
read: the query comes from the options, and the CamelWeatherLocation header 
overrides the location" },
+    "producerOut": { "carriers": [ "text" ], "javaType": "java.lang.String", 
"format": "json", "dependsOn": [ "mode", "headerName" ], "description": "The 
OpenWeatherMap response as a String: JSON, or XML or HTML with mode. With 
headerName the response is in that header and the body is left unchanged" }
+  },
   "properties": {
     "name": { "index": 0, "kind": "path", "displayName": "Name", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.weather.WeatherConfiguration", 
"configurationField": "configuration", "description": "The name value is not 
used." },
     "headerName": { "index": 1, "kind": "parameter", "displayName": "Header 
Name", "group": "common", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.weather.WeatherConfiguration", 
"configurationField": "configuration", "description": "To store the weather 
result in this header instead of the message body. This is useable if you want 
to keep curren [...]
diff --git 
a/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherEndpoint.java
 
b/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherEndpoint.java
index 712f740f354e..b6a690255c02 100644
--- 
a/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherEndpoint.java
+++ 
b/components/camel-weather/src/main/java/org/apache/camel/component/weather/WeatherEndpoint.java
@@ -20,6 +20,9 @@ import org.apache.camel.Category;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.BodyType;
+import org.apache.camel.spi.BodyType.Carrier;
+import org.apache.camel.spi.BodyTypes;
 import org.apache.camel.spi.EndpointServiceLocation;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
@@ -31,6 +34,18 @@ import 
org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
  */
 @UriEndpoint(firstVersion = "2.12.0", scheme = "weather", title = "Weather", 
syntax = "weather:name",
              category = { Category.API }, headersClass = 
WeatherConstants.class)
+@BodyTypes(consumerOut = @BodyType(value = Carrier.TEXT, javaType = 
"java.lang.String", format = "json",
+                                   dependsOn = { "mode", "headerName" },
+                                   description = "The OpenWeatherMap response 
as a String: JSON, or XML or HTML with mode."
+                                                 + " With headerName the 
response is in that header and the body is null"),
+           producerIn = @BodyType(value = Carrier.ANY,
+                                  description = "The body is not read: the 
query comes from the options, and the"
+                                                + " CamelWeatherLocation 
header overrides the location"),
+           producerOut = @BodyType(value = Carrier.TEXT, javaType = 
"java.lang.String", format = "json",
+                                   dependsOn = { "mode", "headerName" },
+                                   description = "The OpenWeatherMap response 
as a String: JSON, or XML or HTML with mode."
+                                                 + " With headerName the 
response is in that header and the body is left"
+                                                 + " unchanged"))
 public class WeatherEndpoint extends DefaultPollingEndpoint implements 
EndpointServiceLocation {
 
     @UriParam
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogDocTest.java
 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogDocTest.java
index b114ed5532b8..4eb8b9118902 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogDocTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogDocTest.java
@@ -207,9 +207,9 @@ class CatalogDocTest extends CamelCommandBaseTestSupport {
         Assertions.assertEquals(0, command.doCall());
         Assertions.assertTrue(printer.getOutput().contains("Unmarshal 
output"), printer.getOutput());
 
-        // a component whose body types are not in the catalog has no such 
table
+        // an EIP has no body types in the catalog, so it has no such table
         printer = new StringPrinter();
-        command = createCommand("weather", false);
+        command = createCommand("eip:split", false);
         Assertions.assertEquals(0, command.doCall());
         Assertions.assertFalse(printer.getOutput().contains("Message body"), 
printer.getOutput());
     }

Reply via email to