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

davsclaus pushed a commit to branch feature/CAMEL-25182-doc-java-examples
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 95bc4460cc700271b4a48ef25eeb7ab1b80ea415
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Sep 30 15:08:22 2026 +0200

    CAMEL-25182: Check the Java DSL examples of the documentation with the Java 
DSL parser
    
    - CatalogDocJavaExamplesTest reads the Java route examples of the catalog 
docs
      and the user manual with LwJavaParser and fails on DSL calls that do not 
exist
    - fix the documentation examples that call the Java DSL wrongly; the jq 
header
      input uses the source option, the keycloak policy closes with endDoTry, 
the
      xmlSecurity namespace example has a passPhrase, the removed
      exceptionPolicyStrategy section is gone, and the redelivery example is a 
route
    - DataFormatClause: univocityCsv(), univocityFixed(), univocityTsv() and 
yaml(),
      as the documentation of these data formats shows them
    - parser: char literals, Map.of/List.of/Set.of/Arrays.asList, JDK constants 
in
      snippets without imports, enum name()/toString() and TimeUnit conversions,
      null stands in for objects of a class the parser cannot create, model
      methods named configure/configuration are no longer denied
    - endpoint DSL: only calls whose arguments are paths and whose scheme is a
      known component are endpoints (and(user, admin) and stax(Record.class) 
are not)
    
    Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../camel/catalog/docs/aws2-ses-component.adoc     |   2 +-
 .../camel/catalog/docs/aws2-sqs-component.adoc     |   2 +-
 .../catalog/docs/aws2-translate-component.adoc     |   2 +-
 .../camel/catalog/docs/dead-letter-channel.adoc    |   2 +-
 .../camel/catalog/docs/disruptor-component.adoc    |   2 +-
 .../catalog/docs/google-bigquery-component.adoc    |   2 +-
 .../camel/catalog/docs/hwcloud-dms-component.adoc  |   8 +-
 .../camel/catalog/docs/hwcloud-iam-component.adoc  |   4 +-
 .../camel/catalog/docs/hwcloud-obs-component.adoc  |   4 +-
 .../org/apache/camel/catalog/docs/intercept.adoc   |   2 +-
 .../apache/camel/catalog/docs/jdbc-component.adoc  |   2 +-
 .../org/apache/camel/catalog/docs/jq-language.adoc |   6 +-
 .../camel/catalog/docs/keycloak-security.adoc      |   3 +-
 .../camel/catalog/docs/olingo2-component.adoc      |   2 +-
 .../camel/catalog/docs/olingo4-component.adoc      |   2 +-
 .../apache/camel/catalog/docs/resumable-eip.adoc   |   2 +-
 .../camel/catalog/docs/resume-strategies.adoc      |   2 +-
 .../apache/camel/catalog/docs/seda-component.adoc  |   4 +-
 .../apache/camel/catalog/docs/validate-eip.adoc    |   2 +-
 .../camel/catalog/docs/xmlSecurity-dataformat.adoc |   8 +-
 .../src/main/docs/aws2-ses-component.adoc          |   2 +-
 .../src/main/docs/aws2-sqs-component.adoc          |   2 +-
 .../src/main/docs/aws2-translate-component.adoc    |   2 +-
 .../src/main/docs/disruptor-component.adoc         |   2 +-
 .../src/main/docs/google-bigquery-component.adoc   |   2 +-
 .../src/main/docs/hwcloud-dms-component.adoc       |   8 +-
 .../src/main/docs/hwcloud-iam-component.adoc       |   4 +-
 .../src/main/docs/hwcloud-obs-component.adoc       |   4 +-
 .../camel-jdbc/src/main/docs/jdbc-component.adoc   |   2 +-
 components/camel-jq/src/main/docs/jq-language.adoc |   6 +-
 .../src/main/docs/keycloak-security.adoc           |   3 +-
 .../src/main/docs/olingo2-component.adoc           |   2 +-
 .../src/main/docs/olingo4-component.adoc           |   2 +-
 .../camel-seda/src/main/docs/seda-component.adoc   |   4 +-
 .../snakeyaml/SnakeYAMLDataFormatClauseTest.java   |  49 ++++++++
 .../univocity/UniVocityDataFormatClauseTest.java   |  63 ++++++++++
 .../src/main/docs/xmlSecurity-dataformat.adoc      |   8 +-
 .../modules/eips/pages/dead-letter-channel.adoc    |   2 +-
 .../main/docs/modules/eips/pages/intercept.adoc    |   2 +-
 .../docs/modules/eips/pages/resumable-eip.adoc     |   2 +-
 .../docs/modules/eips/pages/resume-strategies.adoc |   2 +-
 .../main/docs/modules/eips/pages/validate-eip.adoc |   2 +-
 .../org/apache/camel/builder/DataFormatClause.java |  31 +++++
 .../org/apache/camel/java/in/ChainReplayer.java    | 127 ++++++++++++++++++++-
 .../org/apache/camel/java/in/JavaChainParser.java  |  10 +-
 .../org/apache/camel/java/in/LwJavaParserTest.java |  66 +++++++++++
 .../modules/ROOT/pages/exception-advanced.adoc     |  33 ------
 .../ROOT/pages/exception-handling-patterns.adoc    |   2 +-
 .../modules/ROOT/pages/exception-redelivery.adoc   |   6 +-
 .../modules/ROOT/pages/rest-dsl-openapi.adoc       |   6 +-
 .../modules/ROOT/pages/route-template.adoc         |   2 +-
 .../commands/ai/CatalogEndpointDslResolver.java    |   7 +-
 .../commands/ai/CatalogDocJavaExamplesTest.java    | 124 ++++++++++++++++++++
 53 files changed, 542 insertions(+), 110 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-ses-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-ses-component.adoc
index 7ab6c2dbe639..4368831ee4cb 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-ses-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-ses-component.adoc
@@ -121,7 +121,7 @@ Java::
 ----
 from("direct:start")
     .setHeader(SesConstants.SUBJECT, constant("This is my subject"))
-    .setHeader(SesConstants.TO, 
constant(Collections.singletonList("[email protected]"))
+    .setHeader(SesConstants.TO, 
constant(Collections.singletonList("[email protected]")))
     .setBody(constant("This is my message text."))
     .to("aws2-ses://[email protected]?accessKey=xxx&secretKey=yyy");
 ----
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-sqs-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-sqs-component.adoc
index 89fa5105095b..0b355120b900 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-sqs-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-sqs-component.adoc
@@ -138,7 +138,7 @@ Java::
 [source,java]
 ----
 
from("aws2-sqs://MyQueue?amazonSQSClient=#client&defaultVisibilityTimeout=5000&deleteIfFiltered=false&deleteAfterRead=false")
-.filter("${header.login} == true")
+.filter(simple("${header.login} == true"))
   .setProperty("CamelAwsSqsDeleteFiltered", constant(true))
   .to("mock:filter");
 ----
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-translate-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-translate-component.adoc
index 8c976e072bc7..bb6cf7ae4179 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-translate-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/aws2-translate-component.adoc
@@ -84,7 +84,7 @@ Camel-AWS Translate component provides the following 
operation on the producer s
 from("direct:start")
   .setHeader(TranslateConstants.SOURCE_LANGUAGE, TranslateLanguageEnum.ITALIAN)
   .setHeader(TranslateConstants.TARGET_LANGUAGE, TranslateLanguageEnum.GERMAN)
-  .setBody("Ciao")
+  .setBody(constant("Ciao"))
   
.to("aws2-translate://test?translateClient=#amazonTranslateClient&operation=translateText");
 ----
 
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/dead-letter-channel.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/dead-letter-channel.adoc
index 93e755f663a7..2df230324a93 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/dead-letter-channel.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/dead-letter-channel.adoc
@@ -324,7 +324,7 @@ Java::
 ----
 errorHandler(deadLetterChannel("jms:queue:dead")
   .maximumRedeliveries(3)
-  .onRedeliver(new MyOnRedeliveryProcessor());
+  .onRedelivery(new MyOnRedeliveryProcessor()));
 ----
 
 Spring XML::
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/disruptor-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/disruptor-component.adoc
index a864a33aff77..4fb1d1e7c904 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/disruptor-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/disruptor-component.adoc
@@ -196,7 +196,7 @@ something like:
 ._Java-only: incomplete route (thread pool example)_
 [source,java]
 ----
-from("disruptor:stageName").thread(5).process(...)
+from("disruptor:stageName").threads(5).process(...)
 ----
 
 Can wind up with adding a normal
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/google-bigquery-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/google-bigquery-component.adoc
index 6685537b880a..965789ea0996 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/google-bigquery-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/google-bigquery-component.adoc
@@ -109,7 +109,7 @@ I.e. the following route will create tables and insert 
records sharded on a per-
 [source,java]
 ----
 from("direct:start")
-  .header(GoogleBigQueryConstants.TABLE_SUFFIX, "_${date:now:yyyyMMdd}")
+  .setHeader(GoogleBigQueryConstants.TABLE_SUFFIX, 
simple("_${date:now:yyyyMMdd}"))
   .to("google-bigquery:sampleDataset:sampleTable")
 ----
 Note it is recommended to use partitioning for this use case.
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hwcloud-dms-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hwcloud-dms-component.adoc
index f747c4dabadf..e1264510d92a 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hwcloud-dms-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hwcloud-dms-component.adoc
@@ -119,7 +119,7 @@ To create an instance, you can pass the parameters through 
the endpoint, the exc
 [source,java]
 ----
 from("direct:triggerRoute")
- .setBody(new 
CreateInstanceRequestBody().withName("new-instance").withDescription("description").with*)
 // add remaining options
+ .setBody(constant(new 
CreateInstanceRequestBody().withName("new-instance").withDescription("description").with*))
 // add remaining options
  
.to("hwcloud-dms:createInstance?region=cn-north-4&accessKey=********&secretKey=********&projectId=*******")
 ----
 
@@ -130,7 +130,7 @@ Java::
 [source,java]
 ----
 from("direct:triggerRoute")
- .setBody("{\"name\":\"new-instance\",\"description\":\"description\"}") // 
add remaining options
+ 
.setBody(constant("{\"name\":\"new-instance\",\"description\":\"description\"}"))
 // add remaining options
  
.to("hwcloud-dms:createInstance?region=cn-north-4&accessKey=********&secretKey=********&projectId=*******")
 ----
 
@@ -175,7 +175,7 @@ To update an instance, you must pass the parameters through 
the exchange body as
 [source,java]
 ----
 from("direct:triggerRoute")
- .setBody(new 
UpdateInstanceRequestBody().withName("new-instance").withDescription("description").with*)
 // add remaining options
+ .setBody(constant(new 
UpdateInstanceRequestBody().withName("new-instance").withDescription("description").with*))
 // add remaining options
  
.to("hwcloud-dms:updateInstance?instanceId=******&region=cn-north-4&accessKey=********&secretKey=********&projectId=*******")
 ----
 
@@ -186,7 +186,7 @@ Java::
 [source,java]
 ----
 from("direct:triggerRoute")
- .setBody("{\"name\":\"new-instance\",\"description\":\"description\"}") // 
add remaining options
+ 
.setBody(constant("{\"name\":\"new-instance\",\"description\":\"description\"}"))
 // add remaining options
  
.to("hwcloud-dms:updateInstance?instanceId=******&region=cn-north-4&accessKey=********&secretKey=********&projectId=*******")
 ----
 
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hwcloud-iam-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hwcloud-iam-component.adoc
index b6b0dc845cdd..6a160eea888d 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hwcloud-iam-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hwcloud-iam-component.adoc
@@ -89,7 +89,7 @@ Java::
 [source,java]
 ----
 from("direct:triggerRoute")
- 
.setBody("{\"name\":\"user\",\"description\":\"employee\",\"email\":\"[email protected]\"}")
+ 
.setBody(constant("{\"name\":\"user\",\"description\":\"employee\",\"email\":\"[email protected]\"}"))
  
.to("hwcloud-iam:updateUser?userId=********&region=cn-north-4&accessKey=********&secretKey=********")
 ----
 
@@ -144,7 +144,7 @@ Java::
 [source,java]
 ----
 from("direct:triggerRoute")
- 
.setBody("{\"name\":\"group\",\"description\":\"employees\",\"domain_id\":\"1234\"}")
+ 
.setBody(constant("{\"name\":\"group\",\"description\":\"employees\",\"domain_id\":\"1234\"}"))
  
.to("hwcloud-iam:updateUser?groupId=********&region=cn-north-4&accessKey=********&secretKey=********")
 ----
 
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hwcloud-obs-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hwcloud-obs-component.adoc
index 14b0c984a363..49f3fa4b0750 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hwcloud-obs-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/hwcloud-obs-component.adoc
@@ -104,7 +104,7 @@ Java::
 [source,java]
 ----
 from("direct:triggerRoute")
- .setBody("{\"bucketName\":\"Bucket name\",\"location\":\"Bucket location\"}")
+ .setBody(constant("{\"bucketName\":\"Bucket name\",\"location\":\"Bucket 
location\"}"))
  
.to("hwcloud-obs:createBucket?region=cn-north-4&accessKey=********&secretKey=********")
 ----
 
@@ -158,7 +158,7 @@ Java::
 [source,java]
 ----
 from("direct:triggerRoute")
- .setBody("{\"bucketName\":\"Bucket name\",\"maxKeys\":1000}")
+ .setBody(constant("{\"bucketName\":\"Bucket name\",\"maxKeys\":1000}"))
  
.to("hwcloud-obs:listObjects?region=cn-north-4&accessKey=********&secretKey=********")
 ----
 
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/intercept.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/intercept.adoc
index 8211ded75f3c..e023a41d1ad3 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/intercept.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/intercept.adoc
@@ -640,7 +640,7 @@ Java::
 [source,java]
 ----
 interceptSendToEndpoint("kafka*").skipSendToOriginalEndpoint()
-  .onWhen(simple("${header.biztype} == 'TEST'")
+  .onWhen(simple("${header.biztype} == 'TEST'"))
   .log("TEST message detected - is NOT send to kafka");
 
 from("jms:queue:order")
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jdbc-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jdbc-component.adoc
index 8ada1f09e9d0..d9c4efcd0e19 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jdbc-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jdbc-component.adoc
@@ -93,7 +93,7 @@ Java::
 from("direct:projects")
     .setHeader("lic", constant("ASF"))
     .setHeader("min", constant(123))
-    .setBody("select * from projects where license = :?lic and id > :?min 
order by id")
+    .setBody(constant("select * from projects where license = :?lic and id > 
:?min order by id"))
     .to("jdbc:myDataSource?useHeadersAsParameters=true");
 ----
 
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jq-language.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jq-language.adoc
index d0199d69c8ec..b98597ad069a 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jq-language.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jq-language.adoc
@@ -27,7 +27,7 @@ To enable camel-jackson POJO type conversion, refer to the 
Camel Jackson documen
 
 === Using header as input
 
-By default, JQ uses the message body as the input source. However, you can 
also use a header as input by specifying the `headerName` option.
+By default, JQ uses the message body as the input source. However, you can 
also use a header, property or variable as input by specifying the `source` 
option, such as `header:books`.
 
 For example, to count the number of books from a JSON document that was stored 
in a header named `books` you can do:
 
@@ -35,8 +35,8 @@ For example, to count the number of books from a JSON 
document that was stored i
 [source,java]
 ----
 from("direct:start")
-    .setHeader("numberOfBooks")
-        .jq(".store.books | length", int.class, "books")
+    .setHeader("numberOfBooks",
+        expression().jq(".store.books | 
length").resultType(int.class).source("header:books").end())
     .to("mock:result");
 ----
 
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/keycloak-security.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/keycloak-security.adoc
index 3791f75263be..9a4a7c65df64 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/keycloak-security.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/keycloak-security.adoc
@@ -990,7 +990,8 @@ onException(CamelAuthorizationException.class)
 from("rest:post:/secure-data")
     .doTry()
         .policy(keycloakPolicy)
-        .to("bean:dataProcessor")
+            .to("bean:dataProcessor")
+        .endDoTry() // the policy wraps the steps after it, until the end of 
the doTry
     .doCatch(CamelAuthorizationException.class)
         .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(403))
         .transform().constant("Access denied")
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/olingo2-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/olingo2-component.adoc
index a02cf1fb73e4..5fcdfdf8f378 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/olingo2-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/olingo2-component.adoc
@@ -128,7 +128,7 @@ ordered by ascending Name property.
 [source,java]
 ----
 from("direct:...")
-    .setHeader("CamelOlingo2.$top", "5");
+    .setHeader("CamelOlingo2.$top", constant("5"))
     .to("olingo2://read/Manufacturers?orderBy=Name%20asc");
 ----
 
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/olingo4-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/olingo4-component.adoc
index 2792b2f1ba8a..5e125800872a 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/olingo4-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/olingo4-component.adoc
@@ -118,7 +118,7 @@ ordered by ascending FirstName property.
 [source,java]
 ----
 from("direct:...")
-    .setHeader("CamelOlingo4.$top", "5");
+    .setHeader("CamelOlingo4.$top", constant("5"))
     .to("olingo4://read/People?orderBy=FirstName%20asc");
 ----
 
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/resumable-eip.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/resumable-eip.adoc
index 702e92e4970a..cd2c2c679afb 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/resumable-eip.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/resumable-eip.adoc
@@ -46,7 +46,7 @@ Enable intermittent mode to avoid updating the offset for 
every exchange:
 [source,java]
 ----
 from("some:component")
-    .resumable(new MyTestResumeStrategy()).intermittent(true)
+    .resumable().resumeStrategy(new MyTestResumeStrategy()).intermittent(true)
     .process(this::process);
 ----
 
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/resume-strategies.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/resume-strategies.adoc
index 8bfdcdb7434d..569e0b61619e 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/resume-strategies.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/resume-strategies.adoc
@@ -98,7 +98,7 @@ You can enable the intermittent mode to modify the route 
behavior so that missin
 [source,java]
 ----
 from("some:component")
-.resumable(new MyTestResumeStrategy()).intermittent(true)
+.resumable().resumeStrategy(new MyTestResumeStrategy()).intermittent(true)
 .process(this::process)
 ----
 
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/seda-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/seda-component.adoc
index b9b9befc43ec..53b298cfe7fc 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/seda-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/seda-component.adoc
@@ -199,7 +199,7 @@ like:
 ._Java-only: thread pool added to SEDA endpoint_
 [source,java]
 ----
-from("seda:stageName").thread(5).process(...)
+from("seda:stageName").threads(5).process(...)
 ----
 
 Can wind up with two `BlockQueues`: one from the SEDA endpoint, and one
@@ -211,7 +211,7 @@ asynchronously. For example:
 ._Java-only: thread pool on a Direct endpoint_
 [source,java]
 ----
-from("direct:stageName").thread(5).process(...)
+from("direct:stageName").threads(5).process(...)
 ----
 
 You can also directly configure number of threads that process messages
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/validate-eip.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/validate-eip.adoc
index 06fd3bfa3c87..e694bf9c56de 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/validate-eip.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/validate-eip.adoc
@@ -38,7 +38,7 @@ Java::
 [source,java]
 ----
 from("file:inbox")
-  .validate(body(String.class).regex("^\\w{10}\\,\\d{2}\\,\\w{24}$"))
+  .validate(bodyAs(String.class).regex("^\\w{10}\\,\\d{2}\\,\\w{24}$"))
   .to("bean:myServiceBean.processLine");
 ----
 
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/xmlSecurity-dataformat.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/xmlSecurity-dataformat.adoc
index ced411c85754..e7b53ee5d873 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/xmlSecurity-dataformat.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/xmlSecurity-dataformat.adoc
@@ -89,7 +89,7 @@ Key key = keyGenerator.generateKey();
 
 from("direct:start")
     .marshal().xmlSecurity(key.getEncoded())
-    .unmarshal().xmlSecurity(key.getEncoded()
+    .unmarshal().xmlSecurity(key.getEncoded())
     .to("direct:end");
 ----
 
@@ -160,7 +160,7 @@ Java::
 [source,java]
 ----
 from("direct:start")
-    .marshal().xmlSecurity("//cheese:cheesesites/italy", true)
+    .marshal().xmlSecurity("//cheese:cheesesites/italy", true, "Just another 
32 Byte key for AES")
     .to("...");
 ----
 
@@ -175,7 +175,8 @@ XML::
         <from uri="direct://start"/>
             <marshal>
                 <xmlSecurity secureTag="//cheese:cheesesites/italy"
-                           secureTagContents="true"/>
+                           secureTagContents="true"
+                           passPhrase="Just another 32 Byte key for AES"/>
             </marshal>
             ...
 ----
@@ -192,6 +193,7 @@ YAML::
             xmlSecurity:
               secureTag: "//cheese:cheesesites/italy"
               secureTagContents: true
+              passPhrase: "Just another 32 Byte key for AES"
 ----
 ====
 
diff --git 
a/components/camel-aws/camel-aws2-ses/src/main/docs/aws2-ses-component.adoc 
b/components/camel-aws/camel-aws2-ses/src/main/docs/aws2-ses-component.adoc
index 7ab6c2dbe639..4368831ee4cb 100644
--- a/components/camel-aws/camel-aws2-ses/src/main/docs/aws2-ses-component.adoc
+++ b/components/camel-aws/camel-aws2-ses/src/main/docs/aws2-ses-component.adoc
@@ -121,7 +121,7 @@ Java::
 ----
 from("direct:start")
     .setHeader(SesConstants.SUBJECT, constant("This is my subject"))
-    .setHeader(SesConstants.TO, 
constant(Collections.singletonList("[email protected]"))
+    .setHeader(SesConstants.TO, 
constant(Collections.singletonList("[email protected]")))
     .setBody(constant("This is my message text."))
     .to("aws2-ses://[email protected]?accessKey=xxx&secretKey=yyy");
 ----
diff --git 
a/components/camel-aws/camel-aws2-sqs/src/main/docs/aws2-sqs-component.adoc 
b/components/camel-aws/camel-aws2-sqs/src/main/docs/aws2-sqs-component.adoc
index 89fa5105095b..0b355120b900 100644
--- a/components/camel-aws/camel-aws2-sqs/src/main/docs/aws2-sqs-component.adoc
+++ b/components/camel-aws/camel-aws2-sqs/src/main/docs/aws2-sqs-component.adoc
@@ -138,7 +138,7 @@ Java::
 [source,java]
 ----
 
from("aws2-sqs://MyQueue?amazonSQSClient=#client&defaultVisibilityTimeout=5000&deleteIfFiltered=false&deleteAfterRead=false")
-.filter("${header.login} == true")
+.filter(simple("${header.login} == true"))
   .setProperty("CamelAwsSqsDeleteFiltered", constant(true))
   .to("mock:filter");
 ----
diff --git 
a/components/camel-aws/camel-aws2-translate/src/main/docs/aws2-translate-component.adoc
 
b/components/camel-aws/camel-aws2-translate/src/main/docs/aws2-translate-component.adoc
index 8c976e072bc7..bb6cf7ae4179 100644
--- 
a/components/camel-aws/camel-aws2-translate/src/main/docs/aws2-translate-component.adoc
+++ 
b/components/camel-aws/camel-aws2-translate/src/main/docs/aws2-translate-component.adoc
@@ -84,7 +84,7 @@ Camel-AWS Translate component provides the following 
operation on the producer s
 from("direct:start")
   .setHeader(TranslateConstants.SOURCE_LANGUAGE, TranslateLanguageEnum.ITALIAN)
   .setHeader(TranslateConstants.TARGET_LANGUAGE, TranslateLanguageEnum.GERMAN)
-  .setBody("Ciao")
+  .setBody(constant("Ciao"))
   
.to("aws2-translate://test?translateClient=#amazonTranslateClient&operation=translateText");
 ----
 
diff --git a/components/camel-disruptor/src/main/docs/disruptor-component.adoc 
b/components/camel-disruptor/src/main/docs/disruptor-component.adoc
index a864a33aff77..4fb1d1e7c904 100644
--- a/components/camel-disruptor/src/main/docs/disruptor-component.adoc
+++ b/components/camel-disruptor/src/main/docs/disruptor-component.adoc
@@ -196,7 +196,7 @@ something like:
 ._Java-only: incomplete route (thread pool example)_
 [source,java]
 ----
-from("disruptor:stageName").thread(5).process(...)
+from("disruptor:stageName").threads(5).process(...)
 ----
 
 Can wind up with adding a normal
diff --git 
a/components/camel-google/camel-google-bigquery/src/main/docs/google-bigquery-component.adoc
 
b/components/camel-google/camel-google-bigquery/src/main/docs/google-bigquery-component.adoc
index 6685537b880a..965789ea0996 100644
--- 
a/components/camel-google/camel-google-bigquery/src/main/docs/google-bigquery-component.adoc
+++ 
b/components/camel-google/camel-google-bigquery/src/main/docs/google-bigquery-component.adoc
@@ -109,7 +109,7 @@ I.e. the following route will create tables and insert 
records sharded on a per-
 [source,java]
 ----
 from("direct:start")
-  .header(GoogleBigQueryConstants.TABLE_SUFFIX, "_${date:now:yyyyMMdd}")
+  .setHeader(GoogleBigQueryConstants.TABLE_SUFFIX, 
simple("_${date:now:yyyyMMdd}"))
   .to("google-bigquery:sampleDataset:sampleTable")
 ----
 Note it is recommended to use partitioning for this use case.
diff --git 
a/components/camel-huawei/camel-huaweicloud-dms/src/main/docs/hwcloud-dms-component.adoc
 
b/components/camel-huawei/camel-huaweicloud-dms/src/main/docs/hwcloud-dms-component.adoc
index f747c4dabadf..e1264510d92a 100644
--- 
a/components/camel-huawei/camel-huaweicloud-dms/src/main/docs/hwcloud-dms-component.adoc
+++ 
b/components/camel-huawei/camel-huaweicloud-dms/src/main/docs/hwcloud-dms-component.adoc
@@ -119,7 +119,7 @@ To create an instance, you can pass the parameters through 
the endpoint, the exc
 [source,java]
 ----
 from("direct:triggerRoute")
- .setBody(new 
CreateInstanceRequestBody().withName("new-instance").withDescription("description").with*)
 // add remaining options
+ .setBody(constant(new 
CreateInstanceRequestBody().withName("new-instance").withDescription("description").with*))
 // add remaining options
  
.to("hwcloud-dms:createInstance?region=cn-north-4&accessKey=********&secretKey=********&projectId=*******")
 ----
 
@@ -130,7 +130,7 @@ Java::
 [source,java]
 ----
 from("direct:triggerRoute")
- .setBody("{\"name\":\"new-instance\",\"description\":\"description\"}") // 
add remaining options
+ 
.setBody(constant("{\"name\":\"new-instance\",\"description\":\"description\"}"))
 // add remaining options
  
.to("hwcloud-dms:createInstance?region=cn-north-4&accessKey=********&secretKey=********&projectId=*******")
 ----
 
@@ -175,7 +175,7 @@ To update an instance, you must pass the parameters through 
the exchange body as
 [source,java]
 ----
 from("direct:triggerRoute")
- .setBody(new 
UpdateInstanceRequestBody().withName("new-instance").withDescription("description").with*)
 // add remaining options
+ .setBody(constant(new 
UpdateInstanceRequestBody().withName("new-instance").withDescription("description").with*))
 // add remaining options
  
.to("hwcloud-dms:updateInstance?instanceId=******&region=cn-north-4&accessKey=********&secretKey=********&projectId=*******")
 ----
 
@@ -186,7 +186,7 @@ Java::
 [source,java]
 ----
 from("direct:triggerRoute")
- .setBody("{\"name\":\"new-instance\",\"description\":\"description\"}") // 
add remaining options
+ 
.setBody(constant("{\"name\":\"new-instance\",\"description\":\"description\"}"))
 // add remaining options
  
.to("hwcloud-dms:updateInstance?instanceId=******&region=cn-north-4&accessKey=********&secretKey=********&projectId=*******")
 ----
 
diff --git 
a/components/camel-huawei/camel-huaweicloud-iam/src/main/docs/hwcloud-iam-component.adoc
 
b/components/camel-huawei/camel-huaweicloud-iam/src/main/docs/hwcloud-iam-component.adoc
index b6b0dc845cdd..6a160eea888d 100644
--- 
a/components/camel-huawei/camel-huaweicloud-iam/src/main/docs/hwcloud-iam-component.adoc
+++ 
b/components/camel-huawei/camel-huaweicloud-iam/src/main/docs/hwcloud-iam-component.adoc
@@ -89,7 +89,7 @@ Java::
 [source,java]
 ----
 from("direct:triggerRoute")
- 
.setBody("{\"name\":\"user\",\"description\":\"employee\",\"email\":\"[email protected]\"}")
+ 
.setBody(constant("{\"name\":\"user\",\"description\":\"employee\",\"email\":\"[email protected]\"}"))
  
.to("hwcloud-iam:updateUser?userId=********&region=cn-north-4&accessKey=********&secretKey=********")
 ----
 
@@ -144,7 +144,7 @@ Java::
 [source,java]
 ----
 from("direct:triggerRoute")
- 
.setBody("{\"name\":\"group\",\"description\":\"employees\",\"domain_id\":\"1234\"}")
+ 
.setBody(constant("{\"name\":\"group\",\"description\":\"employees\",\"domain_id\":\"1234\"}"))
  
.to("hwcloud-iam:updateUser?groupId=********&region=cn-north-4&accessKey=********&secretKey=********")
 ----
 
diff --git 
a/components/camel-huawei/camel-huaweicloud-obs/src/main/docs/hwcloud-obs-component.adoc
 
b/components/camel-huawei/camel-huaweicloud-obs/src/main/docs/hwcloud-obs-component.adoc
index 14b0c984a363..49f3fa4b0750 100644
--- 
a/components/camel-huawei/camel-huaweicloud-obs/src/main/docs/hwcloud-obs-component.adoc
+++ 
b/components/camel-huawei/camel-huaweicloud-obs/src/main/docs/hwcloud-obs-component.adoc
@@ -104,7 +104,7 @@ Java::
 [source,java]
 ----
 from("direct:triggerRoute")
- .setBody("{\"bucketName\":\"Bucket name\",\"location\":\"Bucket location\"}")
+ .setBody(constant("{\"bucketName\":\"Bucket name\",\"location\":\"Bucket 
location\"}"))
  
.to("hwcloud-obs:createBucket?region=cn-north-4&accessKey=********&secretKey=********")
 ----
 
@@ -158,7 +158,7 @@ Java::
 [source,java]
 ----
 from("direct:triggerRoute")
- .setBody("{\"bucketName\":\"Bucket name\",\"maxKeys\":1000}")
+ .setBody(constant("{\"bucketName\":\"Bucket name\",\"maxKeys\":1000}"))
  
.to("hwcloud-obs:listObjects?region=cn-north-4&accessKey=********&secretKey=********")
 ----
 
diff --git a/components/camel-jdbc/src/main/docs/jdbc-component.adoc 
b/components/camel-jdbc/src/main/docs/jdbc-component.adoc
index 8ada1f09e9d0..d9c4efcd0e19 100644
--- a/components/camel-jdbc/src/main/docs/jdbc-component.adoc
+++ b/components/camel-jdbc/src/main/docs/jdbc-component.adoc
@@ -93,7 +93,7 @@ Java::
 from("direct:projects")
     .setHeader("lic", constant("ASF"))
     .setHeader("min", constant(123))
-    .setBody("select * from projects where license = :?lic and id > :?min 
order by id")
+    .setBody(constant("select * from projects where license = :?lic and id > 
:?min order by id"))
     .to("jdbc:myDataSource?useHeadersAsParameters=true");
 ----
 
diff --git a/components/camel-jq/src/main/docs/jq-language.adoc 
b/components/camel-jq/src/main/docs/jq-language.adoc
index d0199d69c8ec..b98597ad069a 100644
--- a/components/camel-jq/src/main/docs/jq-language.adoc
+++ b/components/camel-jq/src/main/docs/jq-language.adoc
@@ -27,7 +27,7 @@ To enable camel-jackson POJO type conversion, refer to the 
Camel Jackson documen
 
 === Using header as input
 
-By default, JQ uses the message body as the input source. However, you can 
also use a header as input by specifying the `headerName` option.
+By default, JQ uses the message body as the input source. However, you can 
also use a header, property or variable as input by specifying the `source` 
option, such as `header:books`.
 
 For example, to count the number of books from a JSON document that was stored 
in a header named `books` you can do:
 
@@ -35,8 +35,8 @@ For example, to count the number of books from a JSON 
document that was stored i
 [source,java]
 ----
 from("direct:start")
-    .setHeader("numberOfBooks")
-        .jq(".store.books | length", int.class, "books")
+    .setHeader("numberOfBooks",
+        expression().jq(".store.books | 
length").resultType(int.class).source("header:books").end())
     .to("mock:result");
 ----
 
diff --git a/components/camel-keycloak/src/main/docs/keycloak-security.adoc 
b/components/camel-keycloak/src/main/docs/keycloak-security.adoc
index 3791f75263be..9a4a7c65df64 100644
--- a/components/camel-keycloak/src/main/docs/keycloak-security.adoc
+++ b/components/camel-keycloak/src/main/docs/keycloak-security.adoc
@@ -990,7 +990,8 @@ onException(CamelAuthorizationException.class)
 from("rest:post:/secure-data")
     .doTry()
         .policy(keycloakPolicy)
-        .to("bean:dataProcessor")
+            .to("bean:dataProcessor")
+        .endDoTry() // the policy wraps the steps after it, until the end of 
the doTry
     .doCatch(CamelAuthorizationException.class)
         .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(403))
         .transform().constant("Access denied")
diff --git 
a/components/camel-olingo2/camel-olingo2-component/src/main/docs/olingo2-component.adoc
 
b/components/camel-olingo2/camel-olingo2-component/src/main/docs/olingo2-component.adoc
index a02cf1fb73e4..5fcdfdf8f378 100644
--- 
a/components/camel-olingo2/camel-olingo2-component/src/main/docs/olingo2-component.adoc
+++ 
b/components/camel-olingo2/camel-olingo2-component/src/main/docs/olingo2-component.adoc
@@ -128,7 +128,7 @@ ordered by ascending Name property.
 [source,java]
 ----
 from("direct:...")
-    .setHeader("CamelOlingo2.$top", "5");
+    .setHeader("CamelOlingo2.$top", constant("5"))
     .to("olingo2://read/Manufacturers?orderBy=Name%20asc");
 ----
 
diff --git 
a/components/camel-olingo4/camel-olingo4-component/src/main/docs/olingo4-component.adoc
 
b/components/camel-olingo4/camel-olingo4-component/src/main/docs/olingo4-component.adoc
index 2792b2f1ba8a..5e125800872a 100644
--- 
a/components/camel-olingo4/camel-olingo4-component/src/main/docs/olingo4-component.adoc
+++ 
b/components/camel-olingo4/camel-olingo4-component/src/main/docs/olingo4-component.adoc
@@ -118,7 +118,7 @@ ordered by ascending FirstName property.
 [source,java]
 ----
 from("direct:...")
-    .setHeader("CamelOlingo4.$top", "5");
+    .setHeader("CamelOlingo4.$top", constant("5"))
     .to("olingo4://read/People?orderBy=FirstName%20asc");
 ----
 
diff --git a/components/camel-seda/src/main/docs/seda-component.adoc 
b/components/camel-seda/src/main/docs/seda-component.adoc
index b9b9befc43ec..53b298cfe7fc 100644
--- a/components/camel-seda/src/main/docs/seda-component.adoc
+++ b/components/camel-seda/src/main/docs/seda-component.adoc
@@ -199,7 +199,7 @@ like:
 ._Java-only: thread pool added to SEDA endpoint_
 [source,java]
 ----
-from("seda:stageName").thread(5).process(...)
+from("seda:stageName").threads(5).process(...)
 ----
 
 Can wind up with two `BlockQueues`: one from the SEDA endpoint, and one
@@ -211,7 +211,7 @@ asynchronously. For example:
 ._Java-only: thread pool on a Direct endpoint_
 [source,java]
 ----
-from("direct:stageName").thread(5).process(...)
+from("direct:stageName").threads(5).process(...)
 ----
 
 You can also directly configure number of threads that process messages
diff --git 
a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLDataFormatClauseTest.java
 
b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLDataFormatClauseTest.java
new file mode 100644
index 000000000000..e841a6c8f1c5
--- /dev/null
+++ 
b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLDataFormatClauseTest.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.snakeyaml;
+
+import java.util.Map;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * The YAML data format from the data format clause: {@code 
.marshal().yaml()}, as the documentation shows.
+ */
+public class SnakeYAMLDataFormatClauseTest extends CamelTestSupport {
+
+    @Test
+    public void marshalAndUnmarshal() {
+        String yaml = template.requestBody("direct:marshal", Map.of("name", 
"Camel"), String.class);
+        assertEquals("{name: Camel}", yaml.trim());
+        assertEquals(Map.of("name", "Camel"), 
template.requestBody("direct:unmarshal", yaml, Map.class));
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                from("direct:marshal").marshal().yaml();
+                from("direct:unmarshal").unmarshal().yaml();
+            }
+        };
+    }
+}
diff --git 
a/components/camel-univocity-parsers/src/test/java/org/apache/camel/dataformat/univocity/UniVocityDataFormatClauseTest.java
 
b/components/camel-univocity-parsers/src/test/java/org/apache/camel/dataformat/univocity/UniVocityDataFormatClauseTest.java
new file mode 100644
index 000000000000..c0a665efadcf
--- /dev/null
+++ 
b/components/camel-univocity-parsers/src/test/java/org/apache/camel/dataformat/univocity/UniVocityDataFormatClauseTest.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dataformat.univocity;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.model.MarshalDefinition;
+import org.apache.camel.model.dataformat.UniVocityFixedDataFormat;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.camel.dataformat.univocity.UniVocityTestHelper.asMap;
+import static org.apache.camel.dataformat.univocity.UniVocityTestHelper.join;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+
+/**
+ * The uniVocity data formats from the data format clause: {@code 
.marshal().univocityCsv()}, as the documentation
+ * shows.
+ */
+public class UniVocityDataFormatClauseTest extends CamelTestSupport {
+
+    @Test
+    public void marshalCsv() {
+        assertEquals(join("1,2,3"), template.requestBody("direct:csv", 
asMap("A", "1", "B", "2", "C", "3"), String.class));
+    }
+
+    @Test
+    public void marshalTsv() {
+        assertEquals(join("1\t2\t3"), template.requestBody("direct:tsv", 
asMap("A", "1", "B", "2", "C", "3"), String.class));
+    }
+
+    @Test
+    public void fixedInTheModel() {
+        MarshalDefinition marshal = (MarshalDefinition) 
context.getRouteDefinition("fixed").getOutputs().get(0);
+        assertInstanceOf(UniVocityFixedDataFormat.class, 
marshal.getDataFormatType());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                from("direct:csv").marshal().univocityCsv();
+                from("direct:tsv").marshal().univocityTsv();
+                
from("direct:fixed").routeId("fixed").marshal().univocityFixed();
+            }
+        };
+    }
+}
diff --git 
a/components/camel-xmlsecurity/src/main/docs/xmlSecurity-dataformat.adoc 
b/components/camel-xmlsecurity/src/main/docs/xmlSecurity-dataformat.adoc
index ced411c85754..e7b53ee5d873 100644
--- a/components/camel-xmlsecurity/src/main/docs/xmlSecurity-dataformat.adoc
+++ b/components/camel-xmlsecurity/src/main/docs/xmlSecurity-dataformat.adoc
@@ -89,7 +89,7 @@ Key key = keyGenerator.generateKey();
 
 from("direct:start")
     .marshal().xmlSecurity(key.getEncoded())
-    .unmarshal().xmlSecurity(key.getEncoded()
+    .unmarshal().xmlSecurity(key.getEncoded())
     .to("direct:end");
 ----
 
@@ -160,7 +160,7 @@ Java::
 [source,java]
 ----
 from("direct:start")
-    .marshal().xmlSecurity("//cheese:cheesesites/italy", true)
+    .marshal().xmlSecurity("//cheese:cheesesites/italy", true, "Just another 
32 Byte key for AES")
     .to("...");
 ----
 
@@ -175,7 +175,8 @@ XML::
         <from uri="direct://start"/>
             <marshal>
                 <xmlSecurity secureTag="//cheese:cheesesites/italy"
-                           secureTagContents="true"/>
+                           secureTagContents="true"
+                           passPhrase="Just another 32 Byte key for AES"/>
             </marshal>
             ...
 ----
@@ -192,6 +193,7 @@ YAML::
             xmlSecurity:
               secureTag: "//cheese:cheesesites/italy"
               secureTagContents: true
+              passPhrase: "Just another 32 Byte key for AES"
 ----
 ====
 
diff --git 
a/core/camel-core-engine/src/main/docs/modules/eips/pages/dead-letter-channel.adoc
 
b/core/camel-core-engine/src/main/docs/modules/eips/pages/dead-letter-channel.adoc
index 93e755f663a7..2df230324a93 100644
--- 
a/core/camel-core-engine/src/main/docs/modules/eips/pages/dead-letter-channel.adoc
+++ 
b/core/camel-core-engine/src/main/docs/modules/eips/pages/dead-letter-channel.adoc
@@ -324,7 +324,7 @@ Java::
 ----
 errorHandler(deadLetterChannel("jms:queue:dead")
   .maximumRedeliveries(3)
-  .onRedeliver(new MyOnRedeliveryProcessor());
+  .onRedelivery(new MyOnRedeliveryProcessor()));
 ----
 
 Spring XML::
diff --git 
a/core/camel-core-engine/src/main/docs/modules/eips/pages/intercept.adoc 
b/core/camel-core-engine/src/main/docs/modules/eips/pages/intercept.adoc
index 8211ded75f3c..e023a41d1ad3 100644
--- a/core/camel-core-engine/src/main/docs/modules/eips/pages/intercept.adoc
+++ b/core/camel-core-engine/src/main/docs/modules/eips/pages/intercept.adoc
@@ -640,7 +640,7 @@ Java::
 [source,java]
 ----
 interceptSendToEndpoint("kafka*").skipSendToOriginalEndpoint()
-  .onWhen(simple("${header.biztype} == 'TEST'")
+  .onWhen(simple("${header.biztype} == 'TEST'"))
   .log("TEST message detected - is NOT send to kafka");
 
 from("jms:queue:order")
diff --git 
a/core/camel-core-engine/src/main/docs/modules/eips/pages/resumable-eip.adoc 
b/core/camel-core-engine/src/main/docs/modules/eips/pages/resumable-eip.adoc
index 702e92e4970a..cd2c2c679afb 100644
--- a/core/camel-core-engine/src/main/docs/modules/eips/pages/resumable-eip.adoc
+++ b/core/camel-core-engine/src/main/docs/modules/eips/pages/resumable-eip.adoc
@@ -46,7 +46,7 @@ Enable intermittent mode to avoid updating the offset for 
every exchange:
 [source,java]
 ----
 from("some:component")
-    .resumable(new MyTestResumeStrategy()).intermittent(true)
+    .resumable().resumeStrategy(new MyTestResumeStrategy()).intermittent(true)
     .process(this::process);
 ----
 
diff --git 
a/core/camel-core-engine/src/main/docs/modules/eips/pages/resume-strategies.adoc
 
b/core/camel-core-engine/src/main/docs/modules/eips/pages/resume-strategies.adoc
index 8bfdcdb7434d..569e0b61619e 100644
--- 
a/core/camel-core-engine/src/main/docs/modules/eips/pages/resume-strategies.adoc
+++ 
b/core/camel-core-engine/src/main/docs/modules/eips/pages/resume-strategies.adoc
@@ -98,7 +98,7 @@ You can enable the intermittent mode to modify the route 
behavior so that missin
 [source,java]
 ----
 from("some:component")
-.resumable(new MyTestResumeStrategy()).intermittent(true)
+.resumable().resumeStrategy(new MyTestResumeStrategy()).intermittent(true)
 .process(this::process)
 ----
 
diff --git 
a/core/camel-core-engine/src/main/docs/modules/eips/pages/validate-eip.adoc 
b/core/camel-core-engine/src/main/docs/modules/eips/pages/validate-eip.adoc
index 06fd3bfa3c87..e694bf9c56de 100644
--- a/core/camel-core-engine/src/main/docs/modules/eips/pages/validate-eip.adoc
+++ b/core/camel-core-engine/src/main/docs/modules/eips/pages/validate-eip.adoc
@@ -38,7 +38,7 @@ Java::
 [source,java]
 ----
 from("file:inbox")
-  .validate(body(String.class).regex("^\\w{10}\\,\\d{2}\\,\\w{24}$"))
+  .validate(bodyAs(String.class).regex("^\\w{10}\\,\\d{2}\\,\\w{24}$"))
   .to("bean:myServiceBean.processLine");
 ----
 
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/builder/DataFormatClause.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/builder/DataFormatClause.java
index a1549752cd10..8fc664634ad7 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/builder/DataFormatClause.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/builder/DataFormatClause.java
@@ -66,6 +66,9 @@ import org.apache.camel.model.dataformat.TarFileDataFormat;
 import org.apache.camel.model.dataformat.ThriftDataFormat;
 import org.apache.camel.model.dataformat.ToonDataFormat;
 import org.apache.camel.model.dataformat.UblDataFormat;
+import org.apache.camel.model.dataformat.UniVocityCsvDataFormat;
+import org.apache.camel.model.dataformat.UniVocityFixedDataFormat;
+import org.apache.camel.model.dataformat.UniVocityTsvDataFormat;
 import org.apache.camel.model.dataformat.XMLSecurityDataFormat;
 import org.apache.camel.model.dataformat.YAMLDataFormat;
 import org.apache.camel.model.dataformat.YAMLLibrary;
@@ -1121,6 +1124,34 @@ public class DataFormatClause<T extends 
ProcessorDefinition<?>> {
         return dataFormat(ublDataFormat);
     }
 
+    /**
+     * Uses the uniVocity CSV data format
+     */
+    public T univocityCsv() {
+        return dataFormat(new UniVocityCsvDataFormat());
+    }
+
+    /**
+     * Uses the uniVocity fixed-length data format
+     */
+    public T univocityFixed() {
+        return dataFormat(new UniVocityFixedDataFormat());
+    }
+
+    /**
+     * Uses the uniVocity TSV data format
+     */
+    public T univocityTsv() {
+        return dataFormat(new UniVocityTsvDataFormat());
+    }
+
+    /**
+     * Uses the YAML data format with the SnakeYAML library
+     */
+    public T yaml() {
+        return dataFormat(new YAMLDataFormat());
+    }
+
     /**
      * Uses the YAML data format
      *
diff --git 
a/core/camel-java-io/src/main/java/org/apache/camel/java/in/ChainReplayer.java 
b/core/camel-java-io/src/main/java/org/apache/camel/java/in/ChainReplayer.java
index 6276d223d68b..59e7272e6623 100644
--- 
a/core/camel-java-io/src/main/java/org/apache/camel/java/in/ChainReplayer.java
+++ 
b/core/camel-java-io/src/main/java/org/apache/camel/java/in/ChainReplayer.java
@@ -32,11 +32,13 @@ import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.IllegalFormatException;
 import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
+import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -51,6 +53,7 @@ import org.apache.camel.java.in.JavaChainParser.BinOp;
 import org.apache.camel.java.in.JavaChainParser.Bool;
 import org.apache.camel.java.in.JavaChainParser.Call;
 import org.apache.camel.java.in.JavaChainParser.Chain;
+import org.apache.camel.java.in.JavaChainParser.Chr;
 import org.apache.camel.java.in.JavaChainParser.ClassLit;
 import org.apache.camel.java.in.JavaChainParser.ClassName;
 import org.apache.camel.java.in.JavaChainParser.Concat;
@@ -112,7 +115,7 @@ final class ChainReplayer {
     private static final Set<String> READABLE_JDK = Set.of(
             "java.lang.Integer", "java.lang.Long", "java.lang.Short", 
"java.lang.Byte", "java.lang.Double",
             "java.lang.Float", "java.lang.Boolean", "java.lang.Character", 
"java.util.concurrent.TimeUnit",
-            "java.nio.charset.StandardCharsets");
+            "java.nio.charset.StandardCharsets", "java.util.zip.Deflater");
 
     /** Classes whose static DSL methods a route may call, qualified or 
statically imported: language(...), and(...). */
     private static final List<Class<?>> STATIC_DSL
@@ -129,12 +132,13 @@ final class ChainReplayer {
 
     private static final Set<String> DENIED_METHODS = Set.of(
             "getContext", "getCamelContext", "setContext", "setCamelContext", 
"addRoutesToCamelContext",
-            "addRouteConfigurationsToCamelContext", 
"addTemplatedRoutesToCamelContext", "configure", "configuration",
+            "addRouteConfigurationsToCamelContext", 
"addTemplatedRoutesToCamelContext",
             "includeRoutes", "bindToRegistry", "propertyInject", "endpoint", 
"getClass", "wait", "notify", "notifyAll");
 
     /** The life cycle of a route builder, which a parse never runs: only the 
DSL it offers is called. */
     private static final List<String> BUILDER_LIFE_CYCLE = List.of(
-            "populate", "configure", "prepare", "update", "initialize", "set", 
"check", "add", "remove", "customize");
+            "populate", "configure", "configuration", "prepare", "update", 
"initialize", "set", "check", "add", "remove",
+            "customize");
 
     /** The builder of the configure() being replayed. */
     private ReplayBuilder builder;
@@ -241,6 +245,8 @@ final class ChainReplayer {
     private Object evaluate(Node node) {
         if (node instanceof Str s) {
             return s.value();
+        } else if (node instanceof Chr c) {
+            return c.value();
         } else if (node instanceof Num n) {
             return number(n.text());
         } else if (node instanceof Bool b) {
@@ -540,6 +546,12 @@ final class ChainReplayer {
             for (String pkg : CAMEL_PACKAGES) {
                 candidates.add(pkg + name);
             }
+            // a snippet without its imports: TimeUnit.SECONDS, 
Deflater.BEST_COMPRESSION
+            for (String jdk : READABLE_JDK) {
+                if (jdk.endsWith("." + first)) {
+                    candidates.add(jdk + name.substring(first.length()));
+                }
+            }
         }
         for (String candidate : candidates) {
             String binary = candidate;
@@ -604,6 +616,11 @@ final class ChainReplayer {
             String text = formatText(c.calls().get(0).args());
             return text != null ? text : new Unknown(c, "a format the parser 
cannot work out");
         }
+        if (c.qualifier() != null && c.calls().size() == 1
+                && COLLECTIONS.contains(c.qualifier() + "." + 
c.calls().get(0).name())) {
+            // setHeaders(Map.of("foo", constant("ABC"))): a collection of 
values the parser works out
+            return collection(c);
+        }
         if (c.qualifier() != null && c.qualifier().equals(builderParameter)) {
             // rb.simple(...) in a builder lambda: the builder
             target = builder;
@@ -662,6 +679,36 @@ final class ChainReplayer {
         return target;
     }
 
+    /** Factories of JDK collections a route passes values in: only data, 
nothing of the project runs. */
+    private static final Set<String> COLLECTIONS = Set.of(
+            "Map.of", "java.util.Map.of", "List.of", "java.util.List.of", 
"Set.of", "java.util.Set.of",
+            "Arrays.asList", "java.util.Arrays.asList", 
"Collections.singletonList", "java.util.Collections.singletonList");
+
+    private Object collection(Chain c) {
+        Call call = c.calls().get(0);
+        List<Object> values = new ArrayList<>();
+        for (Node arg : call.args()) {
+            Object v = evaluate(arg);
+            if (v instanceof Unknown || v == null) {
+                return new Unknown(c, "a collection of values the parser 
cannot work out");
+            }
+            values.add(v);
+        }
+        String qualifier = 
c.qualifier().substring(c.qualifier().lastIndexOf('.') + 1);
+        if (qualifier.equals("Map")) {
+            if (values.size() % 2 != 0) {
+                return new Unknown(c, "a collection of values the parser 
cannot work out");
+            }
+            // in the order of the source, which Map.of does not keep but the 
model and a dump should
+            Map<Object, Object> map = new LinkedHashMap<>();
+            for (int i = 0; i < values.size(); i += 2) {
+                map.put(values.get(i), values.get(i + 1));
+            }
+            return map;
+        }
+        return qualifier.equals("Set") ? new LinkedHashSet<>(values) : values;
+    }
+
     /** Why a statement that sets up the CamelContext (components, beans, 
properties) is not read: it is not a route. */
     static final String CONFIGURES_THE_CONTEXT = "configures the CamelContext, 
not a route";
 
@@ -788,9 +835,21 @@ final class ChainReplayer {
     /** The URI of an endpoint DSL chain, or null when the resolver does not 
know its factory. */
     private String endpoint(Chain c) {
         Call factory = c.calls().get(0);
-        List<String> args = new ArrayList<>();
+        if (factory.args().size() > 2) {
+            return null;
+        }
+        List<Object> paths = new ArrayList<>();
         for (Node arg : factory.args()) {
-            args.add(uriValue(arg));
+            Object v = evaluate(arg);
+            if (!(v instanceof String) && !(v instanceof Unknown)) {
+                // a factory of the endpoint DSL takes the path as text: 
split(stax(Record.class)) is StAXBuilder
+                return null;
+            }
+            paths.add(v);
+        }
+        List<String> args = new ArrayList<>();
+        for (int i = 0; i < paths.size(); i++) {
+            args.add(uriValue(factory.args().get(i), paths.get(i)));
         }
         List<EndpointDslResolver.Option> options = new ArrayList<>();
         for (int i = 1; i < c.calls().size(); i++) {
@@ -813,7 +872,10 @@ final class ChainReplayer {
 
     /** A value in an endpoint URI as the endpoint DSL writes it; a marked 
placeholder when unknown (reported). */
     private String uriValue(Node node) {
-        Object v = evaluate(node);
+        return uriValue(node, evaluate(node));
+    }
+
+    private String uriValue(Node node, Object v) {
         if (v instanceof Unknown u) {
             report(node, u.reason());
             return LwJavaParser.UNRESOLVED_PREFIX + text(node) + "}";
@@ -845,6 +907,10 @@ final class ChainReplayer {
     }
 
     private Object invoke(Object target, Call call) {
+        Object value = valueCall(target, call);
+        if (value != null) {
+            return value;
+        }
         List<Method> candidates = candidates(target.getClass(), call.name(), 
call.args().size());
         if (candidates.isEmpty()) {
             String reason = target == builder
@@ -855,6 +921,31 @@ final class ChainReplayer {
         return call(target, candidates, call);
     }
 
+    /**
+     * A call on a JDK value that only computes a value: {@code 
TimeUnit.MILLISECONDS.toString()},
+     * {@code TimeUnit.SECONDS.toMillis(5)}; null for anything else.
+     */
+    private Object valueCall(Object target, Call call) {
+        if (target instanceof Enum<?> e && call.args().isEmpty()
+                && (call.name().equals("name") || 
call.name().equals("toString"))) {
+            return e.name();
+        }
+        if (target instanceof TimeUnit unit && call.args().size() == 1 && 
call.name().startsWith("to")
+                && evaluate(call.args().get(0)) instanceof Number n) {
+            return switch (call.name()) {
+                case "toNanos" -> unit.toNanos(n.longValue());
+                case "toMicros" -> unit.toMicros(n.longValue());
+                case "toMillis" -> unit.toMillis(n.longValue());
+                case "toSeconds" -> unit.toSeconds(n.longValue());
+                case "toMinutes" -> unit.toMinutes(n.longValue());
+                case "toHours" -> unit.toHours(n.longValue());
+                case "toDays" -> unit.toDays(n.longValue());
+                default -> null;
+            };
+        }
+        return null;
+    }
+
     /** Calls the overload the arguments fit best; a static one when {@code 
target} is null. */
     private Object call(Object target, List<Method> candidates, Call call) {
         Object[] values = new Object[call.args().size()];
@@ -905,6 +996,11 @@ final class ChainReplayer {
         } catch (InvocationTargetException e) {
             Throwable cause = e.getCause() != null ? e.getCause() : e;
             String message = String.valueOf(cause.getMessage());
+            if (standsIn(values)) {
+                // the DSL checks or uses right away what stands in for a 
value: configuration(builder) calls
+                // builder.build(), setHeaders(headerMap) needs the map; the 
source is not wrong
+                return new Unknown(call, "needs a value the parser cannot 
see");
+            }
             if (cause instanceof NullPointerException && 
message.contains("CamelContext")) {
                 // the replay builder never has a context: whatever needs one 
is not done in a parse
                 return new Unknown(call, "needs a running CamelContext, which 
a parse does not have");
@@ -915,6 +1011,16 @@ final class ChainReplayer {
         }
     }
 
+    /** Whether something stands in for a value the parser does not know, in 
the arguments of a call. */
+    private static boolean standsIn(Object[] values) {
+        for (Object v : values) {
+            if (v instanceof Unknown) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /** How well a method's parameter types match the values: exactly the 
value's type counts most, Object least. */
     private static int specificity(Method m, Object[] values) {
         Class<?>[] types = m.getParameterTypes();
@@ -1143,6 +1249,13 @@ final class ChainReplayer {
                 default -> defaultValue(method.getReturnType());
             });
         }
+        if (!type.isPrimitive() && !type.isEnum() && type != Class.class) {
+            // an object of a class, such as xpath("/c:n", ns) with Namespaces 
ns built in the method: null stands
+            // in, as the parser creates no objects of a route
+            cost[0] += 30;
+            reports.add(new JavaParseResult.Unresolved(node.line(), text, 
u.reason()));
+            return null;
+        }
         return NO;
     }
 
@@ -1199,6 +1312,8 @@ final class ChainReplayer {
     static String text(Node node) {
         if (node instanceof Str s) {
             return "\"" + s.value() + "\"";
+        } else if (node instanceof Chr c) {
+            return "'" + c.value() + "'";
         } else if (node instanceof Num n) {
             return n.text();
         } else if (node instanceof Bool b) {
diff --git 
a/core/camel-java-io/src/main/java/org/apache/camel/java/in/JavaChainParser.java
 
b/core/camel-java-io/src/main/java/org/apache/camel/java/in/JavaChainParser.java
index 8b37fc25cdb9..fa4381fcb792 100644
--- 
a/core/camel-java-io/src/main/java/org/apache/camel/java/in/JavaChainParser.java
+++ 
b/core/camel-java-io/src/main/java/org/apache/camel/java/in/JavaChainParser.java
@@ -45,6 +45,10 @@ final class JavaChainParser {
     record Num(String text, int line) implements Node {
     }
 
+    /** A char literal: {@code 'i'}. */
+    record Chr(char value, int line) implements Node {
+    }
+
     record Bool(boolean value, int line) implements Node {
     }
 
@@ -428,10 +432,14 @@ final class JavaChainParser {
         Token t = peek();
         int line = t.line();
         switch (t.kind()) {
-            case STRING, CHAR -> {
+            case STRING -> {
                 pos++;
                 return new Str(t.text(), line);
             }
+            case CHAR -> {
+                pos++;
+                return t.text().length() == 1 ? new Chr(t.text().charAt(0), 
line) : new Str(t.text(), line);
+            }
             case NUMBER -> {
                 pos++;
                 return new Num(t.text(), line);
diff --git 
a/core/camel-java-io/src/test/java/org/apache/camel/java/in/LwJavaParserTest.java
 
b/core/camel-java-io/src/test/java/org/apache/camel/java/in/LwJavaParserTest.java
index 79169e1784ee..9b8fe57aa64a 100644
--- 
a/core/camel-java-io/src/test/java/org/apache/camel/java/in/LwJavaParserTest.java
+++ 
b/core/camel-java-io/src/test/java/org/apache/camel/java/in/LwJavaParserTest.java
@@ -19,13 +19,19 @@ package org.apache.camel.java.in;
 import java.util.List;
 
 import org.apache.camel.model.ChoiceDefinition;
+import org.apache.camel.model.CircuitBreakerDefinition;
+import org.apache.camel.model.DelayDefinition;
+import org.apache.camel.model.FilterDefinition;
+import org.apache.camel.model.MarshalDefinition;
 import org.apache.camel.model.OnExceptionDefinition;
 import org.apache.camel.model.ProcessDefinition;
 import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.model.SetHeaderDefinition;
+import org.apache.camel.model.SetHeadersDefinition;
 import org.apache.camel.model.SplitDefinition;
 import org.apache.camel.model.ToDefinition;
 import org.apache.camel.model.TryDefinition;
+import org.apache.camel.model.dataformat.ZipDeflaterDataFormat;
 import org.junit.jupiter.api.Test;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -143,6 +149,66 @@ class LwJavaParserTest {
         assertThat(result.isComplete()).as("%s", result.unresolved()).isTrue();
     }
 
+    @Test
+    void charLiteralsCollectionsAndJdkConstants() {
+        // CAMEL-25182: shapes of the Java examples of the documentation
+        JavaParseResult result = new LwJavaParser().parse("""
+                from("direct:a")
+                    .split(body().tokenize(","))
+                    .setHeaders(Map.of("foo", constant("ABC"), "bar", "XYZ"))
+                    .marshal().zipDeflater(Deflater.BEST_COMPRESSION)
+                    
.setHeader("unit").constant(TimeUnit.MILLISECONDS.toString())
+                    .delay(TimeUnit.SECONDS.toMillis(5))
+                    .to("mock:a");
+                """);
+        assertThat(result.isComplete()).as("%s", result.unresolved()).isTrue();
+        RouteDefinition route = result.routes().getRoutes().get(0);
+        SplitDefinition split = (SplitDefinition) route.getOutputs().get(0);
+        SetHeadersDefinition headers = (SetHeadersDefinition) 
split.getOutputs().get(0);
+        
assertThat(headers.getHeaders()).extracting(SetHeaderDefinition::getName).containsExactly("foo",
 "bar");
+        MarshalDefinition marshal = (MarshalDefinition) 
split.getOutputs().get(1);
+        assertThat(((ZipDeflaterDataFormat) 
marshal.getDataFormatType()).getCompressionLevel()).isEqualTo("9");
+        SetHeaderDefinition unit = (SetHeaderDefinition) 
split.getOutputs().get(2);
+        
assertThat(unit.getExpression().getExpression()).isEqualTo("MILLISECONDS");
+        DelayDefinition delay = (DelayDefinition) split.getOutputs().get(3);
+        assertThat(delay.getExpression().getExpression()).isEqualTo("5000");
+    }
+
+    @Test
+    void anObjectOfAClassBuiltInTheMethod() {
+        // Namespaces ns = new Namespaces(...): null stands in, and the rest 
of the route is read
+        JavaParseResult result = new LwJavaParser().parse("""
+                from("direct:a")
+                    .filter(xpath("/c:number = 55", ns))
+                        .to("mock:result");
+                """);
+        
assertThat(result.unresolved()).extracting(JavaParseResult.Unresolved::text).containsExactly("ns");
+        FilterDefinition filter = (FilterDefinition) 
result.routes().getRoutes().get(0).getOutputs().get(0);
+        
assertThat(filter.getExpression().getExpression()).isEqualTo("/c:number = 55");
+        assertThat(filter.getOutputs()).hasSize(1);
+
+        // xtokenize(path, 'i', ns) is the DSL method with a char, which uses 
ns right away
+        result = new LwJavaParser().parse("""
+                from("direct:a").split().xtokenize("//order", 'i', 
ns).to("mock:order");
+                """);
+        
assertThat(result.unresolved()).extracting(JavaParseResult.Unresolved::reason)
+                .contains("needs a value the parser cannot see");
+    }
+
+    @Test
+    void modelMethodsNamedLikeTheBuilderLifeCycle() {
+        // configuration(...) and configure(...) are only the builder's life 
cycle on the route builder
+        JavaParseResult result = new LwJavaParser().parse("""
+                from("direct:a")
+                    .circuitBreaker().configuration("myConfig")
+                        .to("mock:a")
+                    .end();
+                """);
+        assertThat(result.isComplete()).as("%s", result.unresolved()).isTrue();
+        CircuitBreakerDefinition cb = (CircuitBreakerDefinition) 
result.routes().getRoutes().get(0).getOutputs().get(0);
+        assertThat(cb.getConfiguration()).isEqualTo("myConfig");
+    }
+
     @Test
     void globalErrorHandlingAndRest() {
         JavaParseResult result = new LwJavaParser().parse("""
diff --git a/docs/user-manual/modules/ROOT/pages/exception-advanced.adoc 
b/docs/user-manual/modules/ROOT/pages/exception-advanced.adoc
index 2356967142d3..3de7dddb9746 100644
--- a/docs/user-manual/modules/ROOT/pages/exception-advanced.adoc
+++ b/docs/user-manual/modules/ROOT/pages/exception-advanced.adoc
@@ -425,36 +425,3 @@ public class MyRetryBean {
     }
 }
 ----
-
-=== Using Custom ExceptionPolicyStrategy
-
-The default `org.apache.camel.processor.errorhandler.ExceptionPolicyStrategy` 
in Camel should be sufficient in nearly all use-cases.
-However, if you need to use your own (use only for rare and advanced 
use-cases) this can be configured as the
-sample below illustrates:
-
-._Java-only: configuring a custom ExceptionPolicyStrategy_
-[source,java]
-----
-// configure the error handler to use my policy instead of the default from 
Camel
-errorHandler(deadLetterChannel("mock:error").exceptionPolicyStrategy(new 
MyPolicy()));
-----
-
-Using our own strategy *`MyPolicy`* we can change the default behavior of
-Camel with our own code to resolve which exception type
-from above should be handling the given thrown exception.
-
-._Java-only: custom ExceptionPolicyStrategy implementation_
-[source,java]
-----
-public static class MyPolicy implements ExceptionPolicyStrategy {
-
-    @Override
-    public ExceptionPolicyKey getExceptionPolicy(Set<ExceptionPolicyKey> 
exceptionPolicies, Exchange exchange, Throwable exception) {
-        // This is just an example that always forces the exception type 
configured
-        // with MyPolicyException to win.
-        return new ExceptionPolicyKey(null, MyPolicyException.class, null);
-    }
-}
-----
-
-
diff --git 
a/docs/user-manual/modules/ROOT/pages/exception-handling-patterns.adoc 
b/docs/user-manual/modules/ROOT/pages/exception-handling-patterns.adoc
index 8f4d84d210e0..e588166c4e80 100644
--- a/docs/user-manual/modules/ROOT/pages/exception-handling-patterns.adoc
+++ b/docs/user-manual/modules/ROOT/pages/exception-handling-patterns.adoc
@@ -96,7 +96,7 @@ Java::
 +
 [source,java]
 ----
-onException(ValidationException)
+onException(ValidationException.class)
     .handled(true);
 ----
 
diff --git a/docs/user-manual/modules/ROOT/pages/exception-redelivery.adoc 
b/docs/user-manual/modules/ROOT/pages/exception-redelivery.adoc
index cdd9ffff1a31..37c244c1a78d 100644
--- a/docs/user-manual/modules/ROOT/pages/exception-redelivery.adoc
+++ b/docs/user-manual/modules/ROOT/pages/exception-redelivery.adoc
@@ -115,10 +115,12 @@ All redelivery attempts start at the point of the 
failure. So the route:
 [source,java]
 ----
 onException(ConnectException.class)
-    .from("direct:start")
+    .maximumRedeliveries(3);
+
+from("direct:start")
     .process("processor1")
     .process("processor2") // <--- throws a ConnectException
-    .to("mock:theEnd")
+    .to("mock:theEnd");
 ----
 
 Will retry from *`processor2`* - not the complete route.
diff --git a/docs/user-manual/modules/ROOT/pages/rest-dsl-openapi.adoc 
b/docs/user-manual/modules/ROOT/pages/rest-dsl-openapi.adoc
index 97c4f1fc8a4d..39538fd49071 100644
--- a/docs/user-manual/modules/ROOT/pages/rest-dsl-openapi.adoc
+++ b/docs/user-manual/modules/ROOT/pages/rest-dsl-openapi.adoc
@@ -255,7 +255,7 @@ Java::
 +
 [source,java]
 ----
-    rest().openApi("petstore-v3.json").missingOperation("ignore");
+    
rest().openApi().specification("petstore-v3.json").missingOperation("ignore");
 ----
 
 XML::
@@ -291,7 +291,7 @@ Java::
 +
 [source,java]
 ----
-    rest().openApi("petstore-v3.json").missingOperation("mock");
+    
rest().openApi().specification("petstore-v3.json").missingOperation("mock");
 ----
 
 XML::
@@ -346,7 +346,7 @@ Java::
 ----
 restConfiguration().clientRequestValidation(true);
 
-rest().openApi("petstore-v3.json").missingOperation("mock");
+rest().openApi().specification("petstore-v3.json").missingOperation("mock");
 ----
 
 XML::
diff --git a/docs/user-manual/modules/ROOT/pages/route-template.adoc 
b/docs/user-manual/modules/ROOT/pages/route-template.adoc
index 30ac699d67ba..a89dcad18011 100644
--- a/docs/user-manual/modules/ROOT/pages/route-template.adoc
+++ b/docs/user-manual/modules/ROOT/pages/route-template.adoc
@@ -501,7 +501,7 @@ public class MyRouteTemplates extends RouteBuilder {
             .templateParameter("color")
             .from("direct:{{name}}")
                 .choice()
-                    .when(simple("'{{color}}' == 'red'") // <1>
+                    .when(simple("'{{color}}' == 'red'")) // <1>
                         .to("direct:red")
                     .otherwise()
                         .to("color:other")
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogEndpointDslResolver.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogEndpointDslResolver.java
index 1265d81d240b..502883bce5ab 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogEndpointDslResolver.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogEndpointDslResolver.java
@@ -45,11 +45,12 @@ final class CatalogEndpointDslResolver implements 
EndpointDslResolver {
             return null;
         }
         String scheme = named.uri().substring(0, named.uri().indexOf("://"));
-        // kafka("myKafka", "orders"): a component under another name, the 
catalog cannot say what it is
-        ComponentModel model = args.size() == 2 ? null : 
catalog.componentModel(scheme);
-        if (args.size() != 2 && model == null) {
+        if (catalog.componentModel(scheme) == null) {
+            // and(user, admin) is no endpoint
             return null;
         }
+        // kafka("myKafka", "orders"): a component under another name, the 
catalog cannot say what its options are
+        ComponentModel model = args.size() == 2 ? null : 
catalog.componentModel(scheme);
         List<Option> resolved = new ArrayList<>();
         List<String> problems = new ArrayList<>();
         for (Option o : options) {
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocJavaExamplesTest.java
 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocJavaExamplesTest.java
new file mode 100644
index 000000000000..becc40b7badd
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocJavaExamplesTest.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.commands.ai;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Stream;
+
+import org.apache.camel.catalog.CamelCatalog;
+import org.apache.camel.catalog.DefaultCamelCatalog;
+import org.apache.camel.java.in.JavaParseResult;
+import org.apache.camel.java.in.LwJavaParser;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * CAMEL-25182: every Java route example of the documentation calls the Java 
DSL as it is. The examples are read with
+ * the Java DSL parser of camel-java-io, which replays each chain of calls 
against Camel's DSL without compiling the
+ * snippet. What the parser cannot see (lambdas, variables, helper methods) is 
fine; a DSL method that does not exist,
+ * or does not take the arguments of the example, is a broken example.
+ */
+class CatalogDocJavaExamplesTest {
+
+    private static final Pattern BLOCK
+            = 
Pattern.compile("(?:^\\.(?<title>[^\\n]*)\\n)?\\[source,java\\]\\n-{4,}\\n(?<code>.*?)\\n-{4,}",
+                    Pattern.DOTALL | Pattern.MULTILINE);
+
+    /** A snippet with routes: blocks of plain Java (beans, configuration) are 
not read. */
+    private static final Pattern ROUTE_DSL = Pattern.compile(
+            
"(?<![\\w.])(from|fromF|rest|routeTemplate|onException|errorHandler|interceptFrom|intercept"
+                                                             + 
"|interceptSendToEndpoint|onCompletion)\\s*\\(");
+
+    /** Titles of examples that show code that is wrong on purpose, or is not 
Camel's Java DSL. */
+    private static final List<String> TITLES_SKIPPED
+            = List.of("pseudo", "incorrect", "will not compile", "does not 
compile", "before migration", "old ");
+
+    /** The reasons of the parser that mean the example calls the DSL wrongly. 
*/
+    private static final List<String> BROKEN = List.of(
+            "no such DSL method", "arguments the DSL method does not take", 
"the DSL refused it");
+
+    /** Where the user manual is in the source tree; its pages are not in the 
catalog. */
+    private static final Path USER_MANUAL = 
Path.of("../../../docs/user-manual/modules/ROOT/pages");
+
+    /** User manual pages that show old syntax on purpose. */
+    private static final List<String> USER_MANUAL_SKIPPED = 
List.of("upgrade-guide", "migration-guide");
+
+    private static CamelCatalog catalog;
+
+    @BeforeAll
+    static void setup() {
+        catalog = new DefaultCamelCatalog();
+    }
+
+    @Test
+    void everyJavaExampleOfTheDocumentationCallsTheJavaDsl() throws 
IOException {
+        List<String> failures = new ArrayList<>();
+        int examples = 0;
+        for (String name : catalog.findDocNames()) {
+            examples += check(name, catalog.asciiDoc(name), failures);
+        }
+        if (Files.isDirectory(USER_MANUAL)) {
+            try (Stream<Path> files = Files.list(USER_MANUAL)) {
+                for (Path f : files.filter(f -> 
f.toString().endsWith(".adoc")).sorted().toList()) {
+                    String name = f.getFileName().toString().replace(".adoc", 
"");
+                    if 
(USER_MANUAL_SKIPPED.stream().noneMatch(name::contains)) {
+                        examples += check(name, Files.readString(f), failures);
+                    }
+                }
+            }
+        }
+        assertThat(examples).as("Java route examples found in the 
documentation").isGreaterThan(2000);
+        assertThat(failures).as("Documentation examples that call the Java DSL 
wrongly").isEmpty();
+    }
+
+    private static int check(String page, String doc, List<String> failures) {
+        if (doc == null) {
+            return 0;
+        }
+        int examples = 0;
+        Matcher m = BLOCK.matcher(doc);
+        while (m.find()) {
+            String title = m.group("title") != null ? 
m.group("title").toLowerCase(Locale.ROOT) : "";
+            String code = m.group("code");
+            if (!ROUTE_DSL.matcher(code).find() || 
TITLES_SKIPPED.stream().anyMatch(title::contains)) {
+                continue;
+            }
+            examples++;
+            int line = 1 + (int) doc.substring(0, 
m.start("code")).chars().filter(c -> c == '\n').count();
+            JavaParseResult result = new LwJavaParser()
+                    .setEndpointDslResolver(new 
CatalogEndpointDslResolver(catalog))
+                    .setConstantResolver(new ProjectConstantResolver(Map.of(), 
catalog))
+                    .parse(code);
+            for (JavaParseResult.Unresolved u : result.unresolved()) {
+                if (BROKEN.stream().anyMatch(u.reason()::startsWith)) {
+                    failures.add(page + ":" + (line + u.line() - 1) + " " + 
u.text() + " - " + u.reason());
+                }
+            }
+        }
+        return examples;
+    }
+}

Reply via email to