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

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

commit 26321b98d7de15ce8ea20122a18774a1e9a5879e
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri Oct 16 12:06:22 2020 +0200

    CAMEL-15697: camel-joor - Camel expression langauge using jOOR runtime java 
compiled.
---
 .../apache/camel/catalog/docs/joor-language.adoc   | 111 +++++++++++++++++
 components/camel-joor/pom.xml                      |  66 ++++++++++
 .../services/org/apache/camel/language.properties  |   7 ++
 .../services/org/apache/camel/language/joor        |   2 +
 .../org/apache/camel/language/joor/joor.json       |  25 ++++
 .../camel-joor/src/main/docs/joor-language.adoc    | 111 +++++++++++++++++
 .../java/org/apache/camel/language/joor/Joor.java  |  36 ++++++
 .../apache/camel/language/joor/JoorExpression.java | 136 +++++++++++++++++++++
 .../apache/camel/language/joor/JoorLanguage.java   |  82 +++++++++++++
 .../camel/language/joor/JoorLanguageTest.java      |  89 ++++++++++++++
 .../src/test/resources/log4j2.properties           |  30 +++++
 components/pom.xml                                 |   1 +
 core/camel-allcomponents/pom.xml                   |   4 +
 .../services/org/apache/camel/model.properties     |   1 +
 .../org/apache/camel/model/aggregate.json          |   8 +-
 .../resources/org/apache/camel/model/delay.json    |   2 +-
 .../org/apache/camel/model/dynamicRouter.json      |   2 +-
 .../resources/org/apache/camel/model/enrich.json   |   2 +-
 .../resources/org/apache/camel/model/filter.json   |   2 +-
 .../org/apache/camel/model/idempotentConsumer.json |   2 +-
 .../org/apache/camel/model/language/jaxb.index     |   1 +
 .../org/apache/camel/model/language/joor.json      |  21 ++++
 .../apache/camel/model/loadbalancer/sticky.json    |   2 +-
 .../resources/org/apache/camel/model/loop.json     |   2 +-
 .../org/apache/camel/model/onException.json        |   6 +-
 .../org/apache/camel/model/pollEnrich.json         |   2 +-
 .../org/apache/camel/model/recipientList.json      |   2 +-
 .../org/apache/camel/model/resequence.json         |   2 +-
 .../org/apache/camel/model/routingSlip.json        |   2 +-
 .../resources/org/apache/camel/model/script.json   |   2 +-
 .../resources/org/apache/camel/model/setBody.json  |   2 +-
 .../org/apache/camel/model/setHeader.json          |   2 +-
 .../org/apache/camel/model/setProperty.json        |   2 +-
 .../resources/org/apache/camel/model/sort.json     |   2 +-
 .../resources/org/apache/camel/model/split.json    |   2 +-
 .../resources/org/apache/camel/model/throttle.json |   4 +-
 .../org/apache/camel/model/transform.json          |   2 +-
 .../resources/org/apache/camel/model/validate.json |   2 +-
 .../resources/org/apache/camel/model/when.json     |   2 +-
 .../apache/camel/model/whenSkipSendToEndpoint.json |   2 +-
 .../resources/org/apache/camel/model/wireTap.json  |   2 +-
 .../org/apache/camel/builder/BuilderSupport.java   |  16 ++-
 .../camel/builder/ExpressionClauseSupport.java     |  24 ++++
 .../camel/model/language/JoorExpression.java       |  89 ++++++++++++++
 .../camel/reifier/language/ExpressionReifier.java  |   2 +
 .../reifier/language/JoorExpressionReifier.java    |  62 ++++++++++
 .../java/org/apache/camel/xml/in/ModelParser.java  |  11 ++
 .../modules/languages/pages/joor-language.adoc     | 113 +++++++++++++++++
 parent/pom.xml                                     |   6 +
 49 files changed, 1074 insertions(+), 34 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/joor-language.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/joor-language.adoc
new file mode 100644
index 0000000..9f35f0f
--- /dev/null
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/joor-language.adoc
@@ -0,0 +1,111 @@
+[[joor-language]]
+= JOOR Language
+:docTitle: JOOR
+:artifactId: camel-joor
+:description: Evaluate a JOOR (Java compiled) expression Language against the 
Camel Exchange.
+:since: 3.7
+:supportLevel: Preview
+include::{cq-version}@camel-quarkus:ROOT:partial$reference/languages/joor.adoc[]
+
+*Since Camel {since}*
+
+The jOOR langauge allows to use Java code in your Camel expression, with some 
limitations.
+The jOOR library integrates with the Java compiler and performs runtime 
compilation of Java code (with some limitiations).
+
+NOTE: Java 8 is not supported. This requires Java 11 or 14.
+
+
+== JOOR Options
+
+
+
+// language options: START
+The JOOR language supports 3 options, which are listed below.
+
+
+
+[width="100%",cols="2,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| resultType |  | String | Sets the class name of the result type (type from 
output)
+| singleQuotes | true | Boolean | Whether single quotes can be used as 
replacement for double quotes. This is convenient when you need to work with 
strings inside strings.
+| trim | true | Boolean | Whether to trim the value to remove leading and 
trailing whitespaces and line breaks
+|===
+// language options: END
+
+=== Variables
+
+The JOOR language allows the following variables to be used in the script
+
+[width="100%",cols="2,1m,7",options="header"]
+|===
+| Variable | Java Type | Description
+| context | Context | The CamelContext
+| exchange | Exchange | The Camel Exchange
+| message | Message | The Camel message
+|===
+
+=== Sample
+
+For example to transform the message using joor language to upper case
+
+[source,java]
+----
+from("seda:orders")
+  .transform().joor("message.getBody(String.class).toUpperCase()")
+  .to("seda:upper");
+----
+
+And in XML DSL:
+[source,xml]
+----
+<route>
+   <from uri="seda:orders"/>
+   <transform>
+     <joor>message.getBody(String.class).toUpperCase()</joor>
+   </transform>
+   <to uri="seda:upper"/>
+</route>
+----
+
+=== Multi statements
+
+It is possible to include multiple statements, for example where we in the 
first statement gets the `user` header.
+And then in the 2nd statement we return a value whether the user is `null` or 
not.
+
+[source,java]
+----
+from("seda:orders")
+  .transform().joor("Object user = message.getHeader(\"user\"); return user != 
null ? \"User: \" + user : \"No user exists\";")
+  .to("seda:user");
+----
+
+Notice how we have to quote strings in strings, and that is annoying, so 
instead we can use single quotes:
+
+[source,java]
+----
+from("seda:orders")
+  .transform().joor("Object user = message.getHeader('user'); return user != 
null ? 'User: ' + user : 'No user exists';")
+  .to("seda:user");
+----
+
+=== Limitations
+
+
+== Dependencies
+
+To use scripting languages in your camel routes you need to add a
+dependency on *camel-joor*.
+
+If you use Maven you could just add the following to your `pom.xml`,
+substituting the version number for the latest and greatest release (see
+the download page for the latest versions).
+
+[source,xml]
+---------------------------------------
+<dependency>
+  <groupId>org.apache.camel</groupId>
+  <artifactId>camel-joor</artifactId>
+  <version>x.x.x</version>
+</dependency>
+---------------------------------------
diff --git a/components/camel-joor/pom.xml b/components/camel-joor/pom.xml
new file mode 100644
index 0000000..66d4e28
--- /dev/null
+++ b/components/camel-joor/pom.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>components</artifactId>
+        <version>3.6.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>camel-joor</artifactId>
+    <packaging>jar</packaging>
+    <name>Camel :: jOOR</name>
+    <description>Java expression language using jOOR compiler</description>
+
+    <properties>
+        <firstVersion>3.7.0</firstVersion>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-support</artifactId>
+        </dependency>
+
+        <!-- requires Java 11 or 14 -->
+        <dependency>
+            <groupId>org.jooq</groupId>
+            <artifactId>joor</artifactId>
+            <version>${joor-version}</version>
+        </dependency>
+
+        <!-- test dependencies -->
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-junit5</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-slf4j-impl</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git 
a/components/camel-joor/src/generated/resources/META-INF/services/org/apache/camel/language.properties
 
b/components/camel-joor/src/generated/resources/META-INF/services/org/apache/camel/language.properties
new file mode 100644
index 0000000..0a93b3d
--- /dev/null
+++ 
b/components/camel-joor/src/generated/resources/META-INF/services/org/apache/camel/language.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+languages=joor
+groupId=org.apache.camel
+artifactId=camel-joor
+version=3.6.0-SNAPSHOT
+projectName=Camel :: jOOR
+projectDescription=Java expression language using jOOR compiler
diff --git 
a/components/camel-joor/src/generated/resources/META-INF/services/org/apache/camel/language/joor
 
b/components/camel-joor/src/generated/resources/META-INF/services/org/apache/camel/language/joor
new file mode 100644
index 0000000..409dde3
--- /dev/null
+++ 
b/components/camel-joor/src/generated/resources/META-INF/services/org/apache/camel/language/joor
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.language.joor.JoorLanguage
diff --git 
a/components/camel-joor/src/generated/resources/org/apache/camel/language/joor/joor.json
 
b/components/camel-joor/src/generated/resources/org/apache/camel/language/joor/joor.json
new file mode 100644
index 0000000..b7439d3
--- /dev/null
+++ 
b/components/camel-joor/src/generated/resources/org/apache/camel/language/joor/joor.json
@@ -0,0 +1,25 @@
+{
+  "language": {
+    "kind": "language",
+    "name": "joor",
+    "title": "JOOR",
+    "description": "Evaluate a JOOR (Java compiled) expression Language 
against the Camel Exchange.",
+    "deprecated": false,
+    "firstVersion": "3.7.0",
+    "label": "language",
+    "javaType": "org.apache.camel.language.joor.JoorLanguage",
+    "supportLevel": "Preview",
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-joor",
+    "version": "3.6.0-SNAPSHOT",
+    "modelName": "joor",
+    "modelJavaType": "org.apache.camel.model.language.JoorExpression"
+  },
+  "properties": {
+    "expression": { "kind": "value", "displayName": "Expression", "required": 
true, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "description": "The expression value in your chosen language 
syntax" },
+    "resultType": { "kind": "attribute", "displayName": "Result Type", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "secret": false, "description": "Sets the class name of 
the result type (type from output)" },
+    "singleQuotes": { "kind": "attribute", "displayName": "Single Quotes", 
"required": false, "type": "boolean", "javaType": "java.lang.Boolean", 
"deprecated": false, "secret": false, "defaultValue": true, "description": 
"Whether single quotes can be used as replacement for double quotes. This is 
convenient when you need to work with strings inside strings." },
+    "trim": { "kind": "attribute", "displayName": "Trim", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
value to remove leading and trailing whitespaces and line breaks" },
+    "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "description": "Sets the id of this node" }
+  }
+}
diff --git a/components/camel-joor/src/main/docs/joor-language.adoc 
b/components/camel-joor/src/main/docs/joor-language.adoc
new file mode 100644
index 0000000..9f35f0f
--- /dev/null
+++ b/components/camel-joor/src/main/docs/joor-language.adoc
@@ -0,0 +1,111 @@
+[[joor-language]]
+= JOOR Language
+:docTitle: JOOR
+:artifactId: camel-joor
+:description: Evaluate a JOOR (Java compiled) expression Language against the 
Camel Exchange.
+:since: 3.7
+:supportLevel: Preview
+include::{cq-version}@camel-quarkus:ROOT:partial$reference/languages/joor.adoc[]
+
+*Since Camel {since}*
+
+The jOOR langauge allows to use Java code in your Camel expression, with some 
limitations.
+The jOOR library integrates with the Java compiler and performs runtime 
compilation of Java code (with some limitiations).
+
+NOTE: Java 8 is not supported. This requires Java 11 or 14.
+
+
+== JOOR Options
+
+
+
+// language options: START
+The JOOR language supports 3 options, which are listed below.
+
+
+
+[width="100%",cols="2,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| resultType |  | String | Sets the class name of the result type (type from 
output)
+| singleQuotes | true | Boolean | Whether single quotes can be used as 
replacement for double quotes. This is convenient when you need to work with 
strings inside strings.
+| trim | true | Boolean | Whether to trim the value to remove leading and 
trailing whitespaces and line breaks
+|===
+// language options: END
+
+=== Variables
+
+The JOOR language allows the following variables to be used in the script
+
+[width="100%",cols="2,1m,7",options="header"]
+|===
+| Variable | Java Type | Description
+| context | Context | The CamelContext
+| exchange | Exchange | The Camel Exchange
+| message | Message | The Camel message
+|===
+
+=== Sample
+
+For example to transform the message using joor language to upper case
+
+[source,java]
+----
+from("seda:orders")
+  .transform().joor("message.getBody(String.class).toUpperCase()")
+  .to("seda:upper");
+----
+
+And in XML DSL:
+[source,xml]
+----
+<route>
+   <from uri="seda:orders"/>
+   <transform>
+     <joor>message.getBody(String.class).toUpperCase()</joor>
+   </transform>
+   <to uri="seda:upper"/>
+</route>
+----
+
+=== Multi statements
+
+It is possible to include multiple statements, for example where we in the 
first statement gets the `user` header.
+And then in the 2nd statement we return a value whether the user is `null` or 
not.
+
+[source,java]
+----
+from("seda:orders")
+  .transform().joor("Object user = message.getHeader(\"user\"); return user != 
null ? \"User: \" + user : \"No user exists\";")
+  .to("seda:user");
+----
+
+Notice how we have to quote strings in strings, and that is annoying, so 
instead we can use single quotes:
+
+[source,java]
+----
+from("seda:orders")
+  .transform().joor("Object user = message.getHeader('user'); return user != 
null ? 'User: ' + user : 'No user exists';")
+  .to("seda:user");
+----
+
+=== Limitations
+
+
+== Dependencies
+
+To use scripting languages in your camel routes you need to add a
+dependency on *camel-joor*.
+
+If you use Maven you could just add the following to your `pom.xml`,
+substituting the version number for the latest and greatest release (see
+the download page for the latest versions).
+
+[source,xml]
+---------------------------------------
+<dependency>
+  <groupId>org.apache.camel</groupId>
+  <artifactId>camel-joor</artifactId>
+  <version>x.x.x</version>
+</dependency>
+---------------------------------------
diff --git 
a/components/camel-joor/src/main/java/org/apache/camel/language/joor/Joor.java 
b/components/camel-joor/src/main/java/org/apache/camel/language/joor/Joor.java
new file mode 100644
index 0000000..4dbd65d
--- /dev/null
+++ 
b/components/camel-joor/src/main/java/org/apache/camel/language/joor/Joor.java
@@ -0,0 +1,36 @@
+/*
+ * 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.language.joor;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.apache.camel.support.language.LanguageAnnotation;
+
+/**
+ * Used to inject a joor expression into a field, property, method or 
parameter when using Bean Integration.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
+@LanguageAnnotation(language = "joor")
+public @interface Joor {
+    String value();
+}
diff --git 
a/components/camel-joor/src/main/java/org/apache/camel/language/joor/JoorExpression.java
 
b/components/camel-joor/src/main/java/org/apache/camel/language/joor/JoorExpression.java
new file mode 100644
index 0000000..b33b8ed
--- /dev/null
+++ 
b/components/camel-joor/src/main/java/org/apache/camel/language/joor/JoorExpression.java
@@ -0,0 +1,136 @@
+/*
+ * 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.language.joor;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.ExpressionEvaluationException;
+import org.apache.camel.support.ExpressionAdapter;
+import org.joor.Reflect;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class JoorExpression extends ExpressionAdapter {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(JoorExpression.class);
+    private static Boolean JAVA8;
+
+    private final String fqn;
+    private final String text;
+    private Reflect compiled;
+
+    private Class<?> resultType;
+    private boolean singleQuotes = true;
+
+    public JoorExpression(String fqn, String text) {
+        this.fqn = fqn;
+        this.text = text;
+    }
+
+    @Override
+    public String toString() {
+        return "joor:" + text;
+    }
+
+    public Class<?> getResultType() {
+        return resultType;
+    }
+
+    public void setResultType(Class<?> resultType) {
+        this.resultType = resultType;
+    }
+
+    public boolean isSingleQuotes() {
+        return singleQuotes;
+    }
+
+    public void setSingleQuotes(boolean singleQuotes) {
+        this.singleQuotes = singleQuotes;
+    }
+
+    @Override
+    public void init(CamelContext context) {
+        super.init(context);
+
+        if (JAVA8 == null) {
+            JAVA8 = getJavaMajorVersion() == 8;
+            if (JAVA8) {
+                throw new UnsupportedOperationException("Java 8 is not 
supported. Use Java 11 or higher");
+            }
+        }
+
+        String qn = fqn.substring(0, fqn.lastIndexOf('.'));
+        String name = fqn.substring(fqn.lastIndexOf('.') + 1);
+
+        //  wrap text into a class method we can call
+        StringBuilder sb = new StringBuilder();
+        sb.append("\n");
+        sb.append("package ").append(qn).append(";\n");
+        sb.append("\n");
+        sb.append("import org.apache.camel.*;\n");
+        sb.append("\n");
+        sb.append("public class ").append(name).append(" {\n");
+        sb.append("\n");
+        sb.append("\n");
+        sb.append(
+                "    public static Object evaluate(CamelContext context, 
Exchange exchange, Message message) throws Exception {\n");
+        sb.append("        ");
+        if (!text.contains("return ")) {
+            sb.append("return ");
+        }
+        if (singleQuotes) {
+            // single quotes instead of double quotes, as its very annoying 
for string in strings
+            String quoted = text.replace('\'', '"');
+            sb.append(quoted);
+        } else {
+            sb.append(text);
+        }
+        if (!text.endsWith(";")) {
+            sb.append(";");
+        }
+        sb.append("\n");
+        sb.append("    }\n");
+        sb.append("}\n");
+        sb.append("\n");
+
+        String code = sb.toString();
+        LOG.debug(code);
+
+        compiled = Reflect.compile(fqn, code);
+    }
+
+    @Override
+    public Object evaluate(Exchange exchange) {
+        try {
+            Object out = compiled.call("evaluate", exchange.getContext(), 
exchange, exchange.getIn()).get();
+            if (out != null && resultType != null) {
+                return 
exchange.getContext().getTypeConverter().convertTo(resultType, exchange, out);
+            } else {
+                return out;
+            }
+        } catch (Exception e) {
+            throw new ExpressionEvaluationException(this, exchange, e);
+        }
+    }
+
+    private static int getJavaMajorVersion() {
+        String javaSpecVersion = 
System.getProperty("java.specification.version");
+        return javaSpecVersion.contains(".")
+                ? Integer.parseInt(javaSpecVersion.split("\\.")[1]) : 
Integer.parseInt(javaSpecVersion);
+    }
+
+}
diff --git 
a/components/camel-joor/src/main/java/org/apache/camel/language/joor/JoorLanguage.java
 
b/components/camel-joor/src/main/java/org/apache/camel/language/joor/JoorLanguage.java
new file mode 100644
index 0000000..19933f5
--- /dev/null
+++ 
b/components/camel-joor/src/main/java/org/apache/camel/language/joor/JoorLanguage.java
@@ -0,0 +1,82 @@
+/*
+ * 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.language.joor;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.camel.Expression;
+import org.apache.camel.Predicate;
+import org.apache.camel.spi.annotations.Language;
+import org.apache.camel.support.ExpressionToPredicateAdapter;
+import org.apache.camel.support.LanguageSupport;
+
+@Language("joor")
+public class JoorLanguage extends LanguageSupport {
+
+    private static final AtomicInteger COUNTER = new AtomicInteger();
+
+    private Class<?> resultType;
+    private boolean singleQuotes = true;
+
+    public Class<?> getResultType() {
+        return resultType;
+    }
+
+    public void setResultType(Class<?> resultType) {
+        this.resultType = resultType;
+    }
+
+    public boolean isSingleQuotes() {
+        return singleQuotes;
+    }
+
+    public void setSingleQuotes(boolean singleQuotes) {
+        this.singleQuotes = singleQuotes;
+    }
+
+    @Override
+    public Predicate createPredicate(String expression) {
+        return 
ExpressionToPredicateAdapter.toPredicate(createExpression(expression));
+    }
+
+    @Override
+    public Expression createExpression(String expression) {
+        JoorExpression exp = new JoorExpression(nextFQN(), expression);
+        exp.setResultType(resultType);
+        exp.setSingleQuotes(singleQuotes);
+        exp.init(getCamelContext());
+        return exp;
+    }
+
+    @Override
+    public Predicate createPredicate(String expression, Object[] properties) {
+        return (JoorExpression) createExpression(expression, properties);
+    }
+
+    @Override
+    public Expression createExpression(String expression, Object[] properties) 
{
+        JoorExpression exp = new JoorExpression(nextFQN(), expression);
+        exp.setResultType(property(Class.class, properties, 0, resultType));
+        exp.setSingleQuotes(property(boolean.class, properties, 1, 
singleQuotes));
+        exp.init(getCamelContext());
+        return exp;
+    }
+
+    private static String nextFQN() {
+        return "org.apache.camel.language.joor.compiled.JoorLanguage" + 
COUNTER.incrementAndGet();
+    }
+}
diff --git 
a/components/camel-joor/src/test/java/org/apache/camel/language/joor/JoorLanguageTest.java
 
b/components/camel-joor/src/test/java/org/apache/camel/language/joor/JoorLanguageTest.java
new file mode 100644
index 0000000..56e43d5
--- /dev/null
+++ 
b/components/camel-joor/src/test/java/org/apache/camel/language/joor/JoorLanguageTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.language.joor;
+
+import org.apache.camel.test.junit5.LanguageTestSupport;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class JoorLanguageTest extends LanguageTestSupport {
+
+    @Override
+    protected String getLanguageName() {
+        return "joor";
+    }
+
+    @Test
+    public void testJoorExpressions() throws Exception {
+        assertExpression("return \"Hello World 1\";", "Hello World 1");
+        assertExpression("return \"Hello World 2\"", "Hello World 2");
+        assertExpression("\"Hello World 3\"", "Hello World 3");
+
+        assertExpression("return 'Hello World 1';", "Hello World 1");
+        assertExpression("return 'Hello World 2'", "Hello World 2");
+        assertExpression("'Hello World 3'", "Hello World 3");
+    }
+
+    @Test
+    public void testExchange() throws Exception {
+        exchange.getIn().setBody("World");
+
+        assertExpression("return \"Hello \" + exchange.getIn().getBody();", 
"Hello World");
+        assertExpression("return \"Hello \" + exchange.getIn().getBody()", 
"Hello World");
+        assertExpression("\"Hello \" + exchange.getIn().getBody()", "Hello 
World");
+
+        assertExpression("return 'Hello ' + exchange.getIn().getBody();", 
"Hello World");
+        assertExpression("return 'Hello ' + exchange.getIn().getBody()", 
"Hello World");
+        assertExpression("'Hello ' + exchange.getIn().getBody()", "Hello 
World");
+    }
+
+    @Test
+    public void testExchangeHeader() throws Exception {
+        exchange.getIn().setHeader("foo", 22);
+
+        assertExpression("return 2 * exchange.getIn().getHeader(\"foo\", 
int.class);", "44");
+        assertExpression("return 3 * exchange.getIn().getHeader(\"foo\", 
int.class);", "66");
+        assertExpression("4 * exchange.getIn().getHeader(\"foo\", int.class)", 
"88");
+
+        assertExpression("return 2 * exchange.getIn().getHeader('foo', 
int.class);", "44");
+        assertExpression("return 3 * exchange.getIn().getHeader('foo', 
int.class);", "66");
+        assertExpression("4 * exchange.getIn().getHeader('foo', int.class)", 
"88");
+    }
+
+    @Test
+    public void testExchangeBody() throws Exception {
+        exchange.getIn().setBody("Hello big world how are you");
+
+        assertExpression("message.getBody(String.class).toUpperCase()", "HELLO 
BIG WORLD HOW ARE YOU");
+    }
+
+    @Test
+    public void testMultiStatements() throws Exception {
+        assertExpression("exchange.getIn().setHeader(\"tiger\", \"Tony\"); 
return null;", null);
+        assertExpression("exchange.getIn().setHeader('tiger', 'Tony'); return 
null;", null);
+        assertEquals("Tony", exchange.getIn().getHeader("tiger"));
+
+        exchange.getIn().setHeader("user", "Donald");
+        assertExpression("Object user = message.getHeader('user'); return user 
!= null ? 'User: ' + user : 'No user exists';",
+                "User: Donald");
+        exchange.getIn().removeHeader("user");
+        assertExpression("Object user = message.getHeader('user'); return user 
!= null ? 'User: ' + user : 'No user exists';",
+                "No user exists");
+    }
+
+}
diff --git a/components/camel-joor/src/test/resources/log4j2.properties 
b/components/camel-joor/src/test/resources/log4j2.properties
new file mode 100644
index 0000000..e4e6691
--- /dev/null
+++ b/components/camel-joor/src/test/resources/log4j2.properties
@@ -0,0 +1,30 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+appender.file.type = File
+appender.file.name = file
+appender.file.fileName = target/camel-joor-test.log
+appender.file.layout.type = PatternLayout
+appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+appender.out.type = Console
+appender.out.name = out
+appender.out.layout.type = PatternLayout
+appender.out.layout.pattern = [%30.30t] %-30.30c{1} %-5p %m%n
+logger.springframework.name = org.springframework
+logger.springframework.level = WARN
+rootLogger.level = INFO
+rootLogger.appenderRef.file.ref = file
diff --git a/components/pom.xml b/components/pom.xml
index 64f4752..5c457fa 100644
--- a/components/pom.xml
+++ b/components/pom.xml
@@ -251,6 +251,7 @@
         <module>camel-johnzon</module>
         <module>camel-jolt</module>
         <module>camel-jooq</module>
+        <module>camel-joor</module>
         <module>camel-jpa</module>
         <module>camel-jsch</module>
         <module>camel-jslt</module>
diff --git a/core/camel-allcomponents/pom.xml b/core/camel-allcomponents/pom.xml
index 12a3ae4..a7938c7 100644
--- a/core/camel-allcomponents/pom.xml
+++ b/core/camel-allcomponents/pom.xml
@@ -724,6 +724,10 @@
                </dependency>
                <dependency>
                        <groupId>org.apache.camel</groupId>
+                       <artifactId>camel-joor</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.apache.camel</groupId>
                        <artifactId>camel-jpa</artifactId>
                </dependency>
                <dependency>
diff --git 
a/core/camel-core-engine/src/generated/resources/META-INF/services/org/apache/camel/model.properties
 
b/core/camel-core-engine/src/generated/resources/META-INF/services/org/apache/camel/model.properties
index 8ed8c49..2777089 100644
--- 
a/core/camel-core-engine/src/generated/resources/META-INF/services/org/apache/camel/model.properties
+++ 
b/core/camel-core-engine/src/generated/resources/META-INF/services/org/apache/camel/model.properties
@@ -71,6 +71,7 @@ interceptFrom
 interceptSendToEndpoint
 jacksonxml
 jaxb
+joor
 json
 jsonApi
 jsonpath
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/aggregate.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/aggregate.json
index 22ffe1b..d257c8d 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/aggregate.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/aggregate.json
@@ -11,10 +11,10 @@
     "output": false
   },
   "properties": {
-    "correlationExpression": { "kind": "expression", "displayName": 
"Correlation Expression", "required": true, "type": "object", "javaType": 
"org.apache.camel.model.ExpressionSubElementDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"The expression used to calculate the corre [...]
-    "completionPredicate": { "kind": "expression", "displayName": "Completion 
Predicate", "required": false, "type": "object", "javaType": 
"org.apache.camel.model.ExpressionSubElementDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "asPredicate": 
true, "description": "A Predicate to indicate  [...]
-    "completionTimeoutExpression": { "kind": "expression", "displayName": 
"Completion Timeout Expression", "required": false, "type": "object", 
"javaType": "org.apache.camel.model.ExpressionSubElementDefinition", "oneOf": [ 
"constant", "exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "Time in millis that an aggre [...]
-    "completionSizeExpression": { "kind": "expression", "displayName": 
"Completion Size Expression", "required": false, "type": "object", "javaType": 
"org.apache.camel.model.ExpressionSubElementDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"Number of messages aggregated befo [...]
+    "correlationExpression": { "kind": "expression", "displayName": 
"Correlation Expression", "required": true, "type": "object", "javaType": 
"org.apache.camel.model.ExpressionSubElementDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "The expression used to calculate t [...]
+    "completionPredicate": { "kind": "expression", "displayName": "Completion 
Predicate", "required": false, "type": "object", "javaType": 
"org.apache.camel.model.ExpressionSubElementDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"asPredicate": true, "description": "A Predicate to i [...]
+    "completionTimeoutExpression": { "kind": "expression", "displayName": 
"Completion Timeout Expression", "required": false, "type": "object", 
"javaType": "org.apache.camel.model.ExpressionSubElementDefinition", "oneOf": [ 
"constant", "exchangeProperty", "groovy", "header", "hl7terser", "joor", 
"jsonpath", "language", "method", "mvel", "ognl", "ref", "simple", "spel", 
"tokenize", "xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": 
false, "description": "Time in millis that  [...]
+    "completionSizeExpression": { "kind": "expression", "displayName": 
"Completion Size Expression", "required": false, "type": "object", "javaType": 
"org.apache.camel.model.ExpressionSubElementDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "Number of messages aggrega [...]
     "optimisticLockRetryPolicy": { "kind": "element", "displayName": 
"Optimistic Lock Retry Policy", "required": false, "type": "object", 
"javaType": "org.apache.camel.model.OptimisticLockRetryPolicyDefinition", 
"deprecated": false, "secret": false, "description": "Allows to configure retry 
settings when using optimistic locking." },
     "parallelProcessing": { "kind": "attribute", "displayName": "Parallel 
Processing", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "secret": false, "defaultValue": 
false, "description": "When aggregated are completed they are being send out of 
the aggregator. This option indicates whether or not Camel should use a thread 
pool with multiple threads for concurrency. If no custom thread pool has been 
specified then Camel creates a default pool [...]
     "optimisticLocking": { "kind": "attribute", "displayName": "Optimistic 
Locking", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "secret": false, "defaultValue": 
false, "description": "Turns on using optimistic locking, which requires the 
aggregationRepository being used, is supporting this by implementing 
org.apache.camel.spi.OptimisticLockingAggregationRepository ." },
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/delay.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/delay.json
index ce12b2a..6e93aad 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/delay.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/delay.json
@@ -11,7 +11,7 @@
     "output": false
   },
   "properties": {
-    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"Expression to define how long time to wait (in millis)" },
+    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "Expression to define how long time to wait (in millis)" },
     "executorServiceRef": { "kind": "attribute", "displayName": "Executor 
Service Ref", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "secret": false, "description": 
"Refers to a custom Thread Pool if asyncDelay has been enabled." },
     "asyncDelayed": { "kind": "attribute", "displayName": "Async Delayed", 
"required": false, "type": "boolean", "javaType": "java.lang.Boolean", 
"deprecated": false, "secret": false, "defaultValue": true, "description": 
"Enables asynchronous delay which means the thread will not block while 
delaying." },
     "callerRunsWhenRejected": { "kind": "attribute", "displayName": "Caller 
Runs When Rejected", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "secret": false, "defaultValue": 
true, "description": "Whether or not the caller should run the task when it was 
rejected by the thread pool. Is by default true" },
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/dynamicRouter.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/dynamicRouter.json
index c0cbdac..cc2b4ec 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/dynamicRouter.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/dynamicRouter.json
@@ -11,7 +11,7 @@
     "output": false
   },
   "properties": {
-    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"Expression to call that returns the endpoint(s) to route to in the [...]
+    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "Expression to call that returns the endpoint(s) to route t [...]
     "uriDelimiter": { "kind": "attribute", "displayName": "Uri Delimiter", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "secret": false, "defaultValue": ",", "description": "Sets 
the uri delimiter to use" },
     "ignoreInvalidEndpoints": { "kind": "attribute", "displayName": "Ignore 
Invalid Endpoints", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "secret": false, "description": 
"Ignore the invalidate endpoint exception when try to create a producer with 
that endpoint" },
     "cacheSize": { "kind": "attribute", "displayName": "Cache Size", 
"required": false, "type": "integer", "javaType": "java.lang.Integer", 
"deprecated": false, "secret": false, "description": "Sets the maximum size 
used by the org.apache.camel.spi.ProducerCache which is used to cache and reuse 
producers when using this dynamic router, when uris are reused. Beware that 
when using dynamic endpoints then it affects how well the cache can be 
utilized. If each dynamic endpoint is unique then [...]
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/enrich.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/enrich.json
index 554b840..733f48c 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/enrich.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/enrich.json
@@ -11,7 +11,7 @@
     "output": false
   },
   "properties": {
-    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"Expression that computes the endpoint uri to use as the resource e [...]
+    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "Expression that computes the endpoint uri to use as the re [...]
     "strategyRef": { "kind": "attribute", "displayName": "Strategy Ref", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "secret": false, "description": "Refers to an 
AggregationStrategy to be used to merge the reply from the external service, 
into a single outgoing message. By default Camel will use the reply from the 
external service as outgoing message." },
     "strategyMethodName": { "kind": "attribute", "displayName": "Strategy 
Method Name", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "secret": false, "description": "This 
option can be used to explicit declare the method name to use, when using POJOs 
as the AggregationStrategy." },
     "strategyMethodAllowNull": { "kind": "attribute", "displayName": "Strategy 
Method Allow Null", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "secret": false, "description": "If 
this option is false then the aggregate method is not used if there was no data 
to enrich. If this option is true then null values is used as the oldExchange 
(when no data to enrich), when using POJOs as the AggregationStrategy." },
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/filter.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/filter.json
index 95f2c5e..d861e32 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/filter.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/filter.json
@@ -11,7 +11,7 @@
     "output": true
   },
   "properties": {
-    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "asPredicate": 
true, "description": "Expression to determine if the message should [...]
+    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"asPredicate": true, "description": "Expression to determine if the messag [...]
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "description": "Sets the id of this node" },
     "description": { "kind": "element", "displayName": "Description", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.model.DescriptionDefinition", "deprecated": false, "secret": 
false, "description": "Sets the description of this node" }
   }
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/idempotentConsumer.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/idempotentConsumer.json
index c3c979f..71decdb 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/idempotentConsumer.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/idempotentConsumer.json
@@ -11,7 +11,7 @@
     "output": true
   },
   "properties": {
-    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"Expression used to calculate the correlation key to use for duplic [...]
+    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "Expression used to calculate the correlation key to use fo [...]
     "messageIdRepositoryRef": { "kind": "attribute", "displayName": "Message 
Id Repository Ref", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "secret": false, "description": "Sets 
the reference name of the message id repository" },
     "eager": { "kind": "attribute", "displayName": "Eager", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"secret": false, "defaultValue": true, "description": "Sets whether to eagerly 
add the key to the idempotent repository or wait until the exchange is 
complete. Eager is default enabled." },
     "completionEager": { "kind": "attribute", "displayName": "Completion 
Eager", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "secret": false, "description": "Sets whether to complete 
the idempotent consumer eager or when the exchange is done. If this option is 
true to complete eager, then the idempotent consumer will trigger its 
completion when the exchange reached the end of the block of the idempotent 
consumer pattern. So if the exchange is [...]
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/language/jaxb.index
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/language/jaxb.index
index d1d418b..8d4a935 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/language/jaxb.index
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/language/jaxb.index
@@ -5,6 +5,7 @@ ExpressionDefinition
 GroovyExpression
 HeaderExpression
 Hl7TerserExpression
+JoorExpression
 JsonPathExpression
 LanguageExpression
 MethodCallExpression
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/language/joor.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/language/joor.json
new file mode 100644
index 0000000..044bd16
--- /dev/null
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/language/joor.json
@@ -0,0 +1,21 @@
+{
+  "model": {
+    "kind": "model",
+    "name": "joor",
+    "title": "JOOR",
+    "description": "Evaluate a JOOR (Java compiled) expression Language 
against the Camel Exchange.",
+    "deprecated": false,
+    "firstVersion": "3.7.0",
+    "label": "language",
+    "javaType": "org.apache.camel.model.language.JoorExpression",
+    "input": false,
+    "output": false
+  },
+  "properties": {
+    "expression": { "kind": "value", "displayName": "Expression", "required": 
true, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "description": "The expression value in your chosen language 
syntax" },
+    "resultType": { "kind": "attribute", "displayName": "Result Type", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "secret": false, "description": "Sets the class name of 
the result type (type from output)" },
+    "singleQuotes": { "kind": "attribute", "displayName": "Single Quotes", 
"required": false, "type": "boolean", "javaType": "java.lang.Boolean", 
"deprecated": false, "secret": false, "defaultValue": true, "description": 
"Whether single quotes can be used as replacement for double quotes. This is 
convenient when you need to work with strings inside strings." },
+    "trim": { "kind": "attribute", "displayName": "Trim", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
value to remove leading and trailing whitespaces and line breaks" },
+    "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "description": "Sets the id of this node" }
+  }
+}
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/loadbalancer/sticky.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/loadbalancer/sticky.json
index 151d15c..5696436 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/loadbalancer/sticky.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/loadbalancer/sticky.json
@@ -11,7 +11,7 @@
     "output": false
   },
   "properties": {
-    "correlationExpression": { "kind": "expression", "displayName": 
"Correlation Expression", "required": true, "type": "object", "javaType": 
"org.apache.camel.model.ExpressionSubElementDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"The correlation expression to use to calcu [...]
+    "correlationExpression": { "kind": "expression", "displayName": 
"Correlation Expression", "required": true, "type": "object", "javaType": 
"org.apache.camel.model.ExpressionSubElementDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "The correlation expression to use  [...]
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "description": "The id of this node" }
   }
 }
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/loop.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/loop.json
index ad2efad..e882ecc 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/loop.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/loop.json
@@ -11,7 +11,7 @@
     "output": true
   },
   "properties": {
-    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"Expression to define how many times we should loop. Notice the exp [...]
+    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "Expression to define how many times we should loop. Notice [...]
     "copy": { "kind": "attribute", "displayName": "Copy", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"secret": false, "defaultValue": false, "description": "If the copy attribute 
is true, a copy of the input Exchange is used for each iteration. That means 
each iteration will start from a copy of the same message. By default loop will 
loop the same exchange all over, so each iteration may have different message 
content." },
     "doWhile": { "kind": "attribute", "displayName": "Do While", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"secret": false, "defaultValue": false, "description": "Enables the while loop 
that loops until the predicate evaluates to false or null." },
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "description": "Sets the id of this node" },
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/onException.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/onException.json
index 2861c77..a6f3ddb 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/onException.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/onException.json
@@ -13,11 +13,11 @@
   "properties": {
     "exception": { "kind": "element", "displayName": "Exception", "required": 
true, "type": "array", "javaType": "java.util.List<java.lang.String>", 
"deprecated": false, "secret": false, "description": "A set of exceptions to 
react upon." },
     "onWhen": { "kind": "element", "displayName": "On When", "required": 
false, "type": "object", "javaType": "org.apache.camel.model.WhenDefinition", 
"deprecated": false, "secret": false, "asPredicate": true, "description": "Sets 
an additional predicate that should be true before the onException is 
triggered. To be used for fine grained controlling whether a thrown exception 
should be intercepted by this exception type or not." },
-    "retryWhile": { "kind": "expression", "displayName": "Retry While", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.model.ExpressionSubElementDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "asPredicate": 
true, "description": "Sets the retry while predicate. Will conti [...]
+    "retryWhile": { "kind": "expression", "displayName": "Retry While", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.model.ExpressionSubElementDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"asPredicate": true, "description": "Sets the retry while predicate. Wi [...]
     "redeliveryPolicy": { "kind": "element", "displayName": "Redelivery 
Policy", "required": false, "type": "object", "javaType": 
"org.apache.camel.model.RedeliveryPolicyDefinition", "deprecated": false, 
"secret": false, "description": "Used for configuring redelivery options" },
     "redeliveryPolicyRef": { "kind": "attribute", "displayName": "Redelivery 
Policy Ref", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "secret": false, "description": "Sets 
a reference to a RedeliveryPolicy to lookup in the 
org.apache.camel.spi.Registry to be used." },
-    "handled": { "kind": "expression", "displayName": "Handled", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.model.ExpressionSubElementDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "asPredicate": 
true, "description": "Sets whether the exchange should be marked as han [...]
-    "continued": { "kind": "expression", "displayName": "Continued", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.model.ExpressionSubElementDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "asPredicate": 
true, "description": "Sets whether the exchange should handle and c [...]
+    "handled": { "kind": "expression", "displayName": "Handled", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.model.ExpressionSubElementDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"asPredicate": true, "description": "Sets whether the exchange should be marke 
[...]
+    "continued": { "kind": "expression", "displayName": "Continued", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.model.ExpressionSubElementDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"asPredicate": true, "description": "Sets whether the exchange should hand [...]
     "onRedeliveryRef": { "kind": "attribute", "displayName": "On Redelivery 
Ref", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "secret": false, "description": "Sets a reference to a 
processor that should be processed before a redelivery attempt. Can be used to 
change the org.apache.camel.Exchange before its being redelivered." },
     "onExceptionOccurredRef": { "kind": "attribute", "displayName": "On 
Exception Occurred Ref", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "secret": false, "description": "Sets 
a reference to a processor that should be processed just after an exception 
occurred. Can be used to perform custom logging about the occurred exception at 
the exact time it happened. Important: Any exception thrown from this processor 
will be ignored." },
     "useOriginalMessage": { "kind": "attribute", "displayName": "Use Original 
Message", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "secret": false, "defaultValue": 
false, "description": "Will use the original input org.apache.camel.Message 
(original body and headers) when an org.apache.camel.Exchange is moved to the 
dead letter queue. Notice: this only applies when all redeliveries attempt have 
failed and the org.apache.camel.Exchange is d [...]
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/pollEnrich.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/pollEnrich.json
index 867b3e0..82d3e5f 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/pollEnrich.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/pollEnrich.json
@@ -11,7 +11,7 @@
     "output": false
   },
   "properties": {
-    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"Expression that computes the endpoint uri to use as the resource e [...]
+    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "Expression that computes the endpoint uri to use as the re [...]
     "timeout": { "kind": "attribute", "displayName": "Timeout", "required": 
false, "type": "duration", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "defaultValue": "-1", "description": "Timeout in millis when 
polling from the external service. The timeout has influence about the poll 
enrich behavior. It basically operations in three different modes: negative 
value - Waits until a message is available and then returns it. Warning that 
this method could block indef [...]
     "strategyRef": { "kind": "attribute", "displayName": "Strategy Ref", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "secret": false, "description": "Refers to an 
AggregationStrategy to be used to merge the reply from the external service, 
into a single outgoing message. By default Camel will use the reply from the 
external service as outgoing message." },
     "strategyMethodName": { "kind": "attribute", "displayName": "Strategy 
Method Name", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "secret": false, "description": "This 
option can be used to explicit declare the method name to use, when using POJOs 
as the AggregationStrategy." },
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/recipientList.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/recipientList.json
index ba4da08..9d284b3 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/recipientList.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/recipientList.json
@@ -11,7 +11,7 @@
     "output": false
   },
   "properties": {
-    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"Expression that returns which endpoints (url) to send the message  [...]
+    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "Expression that returns which endpoints (url) to send the  [...]
     "delimiter": { "kind": "attribute", "displayName": "Delimiter", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "secret": false, "defaultValue": ",", "description": 
"Delimiter used if the Expression returned multiple endpoints. Can be turned 
off using the value false. The default value is ," },
     "parallelProcessing": { "kind": "attribute", "displayName": "Parallel 
Processing", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "secret": false, "defaultValue": 
false, "description": "If enabled then sending messages to the recipients 
occurs concurrently. Note the caller thread will still wait until all messages 
has been fully processed, before it continues. Its only the sending and 
processing the replies from the recipients which happen [...]
     "strategyRef": { "kind": "attribute", "displayName": "Strategy Ref", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "secret": false, "description": "Sets a reference to the 
AggregationStrategy to be used to assemble the replies from the recipients, 
into a single outgoing message from the RecipientList. By default Camel will 
use the last reply as the outgoing message. You can also use a POJO as the 
AggregationStrategy" },
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/resequence.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/resequence.json
index 30bf7ef..300eae1 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/resequence.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/resequence.json
@@ -11,7 +11,7 @@
     "output": false
   },
   "properties": {
-    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"Expression to use for re-ordering the messages, such as a header w [...]
+    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "Expression to use for re-ordering the messages, such as a  [...]
     "resequencerConfig": { "kind": "element", "displayName": "Resequencer 
Config", "required": false, "type": "object", "javaType": 
"org.apache.camel.model.config.ResequencerConfig", "oneOf": [ "batch-config", 
"stream-config" ], "deprecated": false, "secret": false, "description": "To 
configure the resequencer in using either batch or stream configuration. Will 
by default use batch configuration." },
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "description": "Sets the id of this node" },
     "description": { "kind": "element", "displayName": "Description", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.model.DescriptionDefinition", "deprecated": false, "secret": 
false, "description": "Sets the description of this node" }
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/routingSlip.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/routingSlip.json
index f316ddc..4a550f5 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/routingSlip.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/routingSlip.json
@@ -11,7 +11,7 @@
     "output": false
   },
   "properties": {
-    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"Expression to define the routing slip, which defines which endpoin [...]
+    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "Expression to define the routing slip, which defines which [...]
     "uriDelimiter": { "kind": "attribute", "displayName": "Uri Delimiter", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "secret": false, "defaultValue": ",", "description": "Sets 
the uri delimiter to use" },
     "ignoreInvalidEndpoints": { "kind": "attribute", "displayName": "Ignore 
Invalid Endpoints", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "secret": false, "defaultValue": 
false, "description": "Ignore the invalidate endpoint exception when try to 
create a producer with that endpoint" },
     "cacheSize": { "kind": "attribute", "displayName": "Cache Size", 
"required": false, "type": "integer", "javaType": "java.lang.Integer", 
"deprecated": false, "secret": false, "description": "Sets the maximum size 
used by the org.apache.camel.spi.ProducerCache which is used to cache and reuse 
producers when using this routing slip, when uris are reused. Beware that when 
using dynamic endpoints then it affects how well the cache can be utilized. If 
each dynamic endpoint is unique then i [...]
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/script.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/script.json
index c8a051c..4f820c4 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/script.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/script.json
@@ -11,7 +11,7 @@
     "output": false
   },
   "properties": {
-    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"Expression to return the transformed message body (the new message [...]
+    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "Expression to return the transformed message body (the new [...]
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "description": "Sets the id of this node" },
     "description": { "kind": "element", "displayName": "Description", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.model.DescriptionDefinition", "deprecated": false, "secret": 
false, "description": "Sets the description of this node" }
   }
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/setBody.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/setBody.json
index ebf7a8e..5366aeb 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/setBody.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/setBody.json
@@ -11,7 +11,7 @@
     "output": false
   },
   "properties": {
-    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"Expression that returns the new body to use" },
+    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "Expression that returns the new body to use" },
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "description": "Sets the id of this node" },
     "description": { "kind": "element", "displayName": "Description", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.model.DescriptionDefinition", "deprecated": false, "secret": 
false, "description": "Sets the description of this node" }
   }
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/setHeader.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/setHeader.json
index b570632..d96cd5f 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/setHeader.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/setHeader.json
@@ -11,7 +11,7 @@
     "output": false
   },
   "properties": {
-    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"Expression to return the value of the header" },
+    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "Expression to return the value of the header" },
     "name": { "kind": "attribute", "displayName": "Name", "required": true, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "description": "Name of message header to set a new value The 
simple language can be used to define a dynamic evaluated header name to be 
used. Otherwise a constant name will be used." },
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "description": "Sets the id of this node" },
     "description": { "kind": "element", "displayName": "Description", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.model.DescriptionDefinition", "deprecated": false, "secret": 
false, "description": "Sets the description of this node" }
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/setProperty.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/setProperty.json
index 6b97595..bdd6c7f 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/setProperty.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/setProperty.json
@@ -11,7 +11,7 @@
     "output": false
   },
   "properties": {
-    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"Expression to return the value of the message exchange property" },
+    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "Expression to return the value of the message exchange pro [...]
     "name": { "kind": "attribute", "displayName": "Name", "required": true, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "description": "Name of exchange property to set a new value. 
The simple language can be used to define a dynamic evaluated exchange property 
name to be used. Otherwise a constant name will be used." },
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "description": "Sets the id of this node" },
     "description": { "kind": "element", "displayName": "Description", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.model.DescriptionDefinition", "deprecated": false, "secret": 
false, "description": "Sets the description of this node" }
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/sort.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/sort.json
index bcc7c87..8f95288 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/sort.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/sort.json
@@ -11,7 +11,7 @@
     "output": false
   },
   "properties": {
-    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"Optional expression to sort by something else than the message body" },
+    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "Optional expression to sort by something else than the mes [...]
     "comparatorRef": { "kind": "attribute", "displayName": "Comparator Ref", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "secret": false, "description": "Sets a reference to 
lookup for the comparator to use for sorting" },
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "description": "Sets the id of this node" },
     "description": { "kind": "element", "displayName": "Description", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.model.DescriptionDefinition", "deprecated": false, "secret": 
false, "description": "Sets the description of this node" }
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/split.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/split.json
index 01e5a39..e48b56e 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/split.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/split.json
@@ -11,7 +11,7 @@
     "output": true
   },
   "properties": {
-    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"Expression of how to split the message body, such as as-is, using  [...]
+    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "Expression of how to split the message body, such as as-is [...]
     "parallelProcessing": { "kind": "attribute", "displayName": "Parallel 
Processing", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "secret": false, "defaultValue": 
false, "description": "If enabled then processing each splitted messages occurs 
concurrently. Note the caller thread will still wait until all messages has 
been fully processed, before it continues. Its only processing the sub messages 
from the splitter which happens concurrently." },
     "strategyRef": { "kind": "attribute", "displayName": "Strategy Ref", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "secret": false, "description": "Sets a reference to the 
AggregationStrategy to be used to assemble the replies from the splitted 
messages, into a single outgoing message from the Splitter. By default Camel 
will use the original incoming message to the splitter (leave it unchanged). 
You can also use a POJO as the AggregationStr [...]
     "strategyMethodName": { "kind": "attribute", "displayName": "Strategy 
Method Name", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "secret": false, "description": "This 
option can be used to explicit declare the method name to use, when using POJOs 
as the AggregationStrategy." },
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/throttle.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/throttle.json
index 629ae7b..52d19e3 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/throttle.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/throttle.json
@@ -11,8 +11,8 @@
     "output": false
   },
   "properties": {
-    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"Expression to configure the maximum number of messages to throttle [...]
-    "correlationExpression": { "kind": "expression", "displayName": 
"Correlation Expression", "required": false, "type": "object", "javaType": 
"org.apache.camel.model.ExpressionSubElementDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"The expression used to calculate the corr [...]
+    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "Expression to configure the maximum number of messages to  [...]
+    "correlationExpression": { "kind": "expression", "displayName": 
"Correlation Expression", "required": false, "type": "object", "javaType": 
"org.apache.camel.model.ExpressionSubElementDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "The expression used to calculate  [...]
     "executorServiceRef": { "kind": "attribute", "displayName": "Executor 
Service Ref", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "secret": false, "description": "To 
use a custom thread pool (ScheduledExecutorService) by the throttler." },
     "timePeriodMillis": { "kind": "attribute", "displayName": "Time Period 
Millis", "required": false, "type": "duration", "javaType": "java.lang.String", 
"deprecated": false, "secret": false, "defaultValue": "1000", "description": 
"Sets the time period during which the maximum request count is valid for" },
     "asyncDelayed": { "kind": "attribute", "displayName": "Async Delayed", 
"required": false, "type": "boolean", "javaType": "java.lang.Boolean", 
"deprecated": false, "secret": false, "defaultValue": false, "description": 
"Enables asynchronous delay which means the thread will not block while 
delaying." },
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/transform.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/transform.json
index 6344aef..8e21828 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/transform.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/transform.json
@@ -11,7 +11,7 @@
     "output": false
   },
   "properties": {
-    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"Expression to return the transformed message body (the new message [...]
+    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "Expression to return the transformed message body (the new [...]
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "description": "Sets the id of this node" },
     "description": { "kind": "element", "displayName": "Description", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.model.DescriptionDefinition", "deprecated": false, "secret": 
false, "description": "Sets the description of this node" }
   }
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/validate.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/validate.json
index 0bd1d25..a10c87a 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/validate.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/validate.json
@@ -11,7 +11,7 @@
     "output": false
   },
   "properties": {
-    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "asPredicate": 
true, "description": "Expression to use for validation as a predica [...]
+    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"asPredicate": true, "description": "Expression to use for validation as a [...]
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "description": "Sets the id of this node" },
     "description": { "kind": "element", "displayName": "Description", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.model.DescriptionDefinition", "deprecated": false, "secret": 
false, "description": "Sets the description of this node" }
   }
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/when.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/when.json
index 78877f2..6694725 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/when.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/when.json
@@ -11,7 +11,7 @@
     "output": true
   },
   "properties": {
-    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "asPredicate": 
true, "description": "Expression used as the predicate to evaluate  [...]
+    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"asPredicate": true, "description": "Expression used as the predicate to e [...]
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "description": "Sets the id of this node" },
     "description": { "kind": "element", "displayName": "Description", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.model.DescriptionDefinition", "deprecated": false, "secret": 
false, "description": "Sets the description of this node" }
   }
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/whenSkipSendToEndpoint.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/whenSkipSendToEndpoint.json
index 760bd5e..19f8a08 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/whenSkipSendToEndpoint.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/whenSkipSendToEndpoint.json
@@ -11,7 +11,7 @@
     "output": true
   },
   "properties": {
-    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "asPredicate": 
true, "description": "Expression used as the predicate to evaluate  [...]
+    "expression": { "kind": "expression", "displayName": "Expression", 
"required": true, "type": "object", "javaType": 
"org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"asPredicate": true, "description": "Expression used as the predicate to e [...]
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "description": "Sets the id of this node" },
     "description": { "kind": "element", "displayName": "Description", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.model.DescriptionDefinition", "deprecated": false, "secret": 
false, "description": "Sets the description of this node" }
   }
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/wireTap.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/wireTap.json
index 5877373..2873277 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/wireTap.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/wireTap.json
@@ -12,7 +12,7 @@
   },
   "properties": {
     "processorRef": { "kind": "attribute", "displayName": "Processor Ref", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "secret": false, "description": "Reference to a Processor 
to use for creating a new body as the message to use for wire tapping" },
-    "body": { "kind": "expression", "displayName": "Body", "required": false, 
"type": "object", "javaType": 
"org.apache.camel.model.ExpressionSubElementDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "jsonpath", "language", 
"method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", 
"xquery", "xtokenize" ], "deprecated": false, "secret": false, "description": 
"Uses the expression for creating a new body as the message to use for wire t 
[...]
+    "body": { "kind": "expression", "displayName": "Body", "required": false, 
"type": "object", "javaType": 
"org.apache.camel.model.ExpressionSubElementDefinition", "oneOf": [ "constant", 
"exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", 
"language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", 
"xpath", "xquery", "xtokenize" ], "deprecated": false, "secret": false, 
"description": "Uses the expression for creating a new body as the message to 
use fo [...]
     "executorServiceRef": { "kind": "attribute", "displayName": "Executor 
Service Ref", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "secret": false, "description": "Uses 
a custom thread pool" },
     "copy": { "kind": "attribute", "displayName": "Copy", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"secret": false, "defaultValue": true, "description": "Uses a copy of the 
original exchange" },
     "dynamicUri": { "kind": "attribute", "displayName": "Dynamic Uri", 
"required": false, "type": "boolean", "javaType": "java.lang.Boolean", 
"deprecated": false, "secret": false, "defaultValue": true, "description": 
"Whether the uri is dynamic or static. If the uri is dynamic then the simple 
language is used to evaluate a dynamic uri to use as the wire-tap destination, 
for each incoming message. This works similar to how the toD EIP pattern works. 
If static then the uri is used as-is as [...]
diff --git 
a/core/camel-core-engine/src/main/java/org/apache/camel/builder/BuilderSupport.java
 
b/core/camel-core-engine/src/main/java/org/apache/camel/builder/BuilderSupport.java
index 1a6b80c..624b32e 100644
--- 
a/core/camel-core-engine/src/main/java/org/apache/camel/builder/BuilderSupport.java
+++ 
b/core/camel-core-engine/src/main/java/org/apache/camel/builder/BuilderSupport.java
@@ -27,6 +27,7 @@ import org.apache.camel.NoSuchEndpointException;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.model.language.ExchangePropertyExpression;
 import org.apache.camel.model.language.HeaderExpression;
+import org.apache.camel.model.language.JoorExpression;
 import org.apache.camel.model.language.JsonPathExpression;
 import org.apache.camel.model.language.XPathExpression;
 import org.apache.camel.support.builder.Namespaces;
@@ -102,10 +103,19 @@ public abstract class BuilderSupport {
     }
 
     /**
-     * Returns a JSonPath expression value builder
+     * Returns a JOOR expression value builder
      */
-    public ValueBuilder jsonpath(String value) {
-        JsonPathExpression exp = new JsonPathExpression(value);
+    public ValueBuilder joor(String value) {
+        JoorExpression exp = new JoorExpression(value);
+        return new ValueBuilder(exp);
+    }
+
+    /**
+     * Returns a JOOR expression value builder
+     */
+    public ValueBuilder joor(String value, Class<?> resultType) {
+        JoorExpression exp = new JoorExpression(value);
+        exp.setResultType(resultType);
         return new ValueBuilder(exp);
     }
 
diff --git 
a/core/camel-core-engine/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java
 
b/core/camel-core-engine/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java
index 3f52873..c878e63 100644
--- 
a/core/camel-core-engine/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java
+++ 
b/core/camel-core-engine/src/main/java/org/apache/camel/builder/ExpressionClauseSupport.java
@@ -27,6 +27,7 @@ import 
org.apache.camel.model.language.ExchangePropertyExpression;
 import org.apache.camel.model.language.GroovyExpression;
 import org.apache.camel.model.language.HeaderExpression;
 import org.apache.camel.model.language.Hl7TerserExpression;
+import org.apache.camel.model.language.JoorExpression;
 import org.apache.camel.model.language.JsonPathExpression;
 import org.apache.camel.model.language.LanguageExpression;
 import org.apache.camel.model.language.MethodCallExpression;
@@ -300,6 +301,29 @@ public class ExpressionClauseSupport<T> {
     }
 
     /**
+     * Evaluates an JOOR expression
+     *
+     * @param  text the expression to be evaluated
+     * @return      the builder to continue processing the DSL
+     */
+    public T joor(String text) {
+        return expression(new JoorExpression(text));
+    }
+
+    /**
+     * Evaluates an JOOR expression
+     *
+     * @param  text       the expression to be evaluated
+     * @param  resultType the return type expected by the expression
+     * @return            the builder to continue processing the DSL
+     */
+    public T joor(String text, Class<?> resultType) {
+        JoorExpression exp = new JoorExpression(text);
+        exp.setResultType(resultType);
+        return expression(exp);
+    }
+
+    /**
      * Evaluates a <a href="http://camel.apache.org/jsonpath.html";>Json Path 
expression</a>
      *
      * @param  text the expression to be evaluated
diff --git 
a/core/camel-core-engine/src/main/java/org/apache/camel/model/language/JoorExpression.java
 
b/core/camel-core-engine/src/main/java/org/apache/camel/model/language/JoorExpression.java
new file mode 100644
index 0000000..49e17bf
--- /dev/null
+++ 
b/core/camel-core-engine/src/main/java/org/apache/camel/model/language/JoorExpression.java
@@ -0,0 +1,89 @@
+/*
+ * 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.model.language;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.camel.spi.Metadata;
+
+/**
+ * Evaluate a jOOR (Java compiled once at runtime) expression language.
+ */
+@Metadata(firstVersion = "3.7.0", label = "language", title = "jOOR")
+@XmlRootElement(name = "joor")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class JoorExpression extends ExpressionDefinition {
+
+    @XmlAttribute(name = "resultType")
+    private String resultTypeName;
+    @XmlTransient
+    private Class<?> resultType;
+    @XmlAttribute
+    @Metadata(defaultValue = "true", javaType = "java.lang.Boolean")
+    private String singleQuotes;
+
+    public JoorExpression() {
+    }
+
+    public JoorExpression(String expression) {
+        super(expression);
+    }
+
+    @Override
+    public String getLanguage() {
+        return "joor";
+    }
+
+    public String getSingleQuotes() {
+        return singleQuotes;
+    }
+
+    /**
+     * Whether single quotes can be used as replacement for double quotes. 
This is convenient when you need to work with
+     * strings inside strings.
+     */
+    public void setSingleQuotes(String singleQuotes) {
+        this.singleQuotes = singleQuotes;
+    }
+
+    public Class<?> getResultType() {
+        return resultType;
+    }
+
+    /**
+     * Sets the class of the result type (type from output)
+     */
+    public void setResultType(Class<?> resultType) {
+        this.resultType = resultType;
+    }
+
+    public String getResultTypeName() {
+        return resultTypeName;
+    }
+
+    /**
+     * Sets the class name of the result type (type from output)
+     */
+    public void setResultTypeName(String resultTypeName) {
+        this.resultTypeName = resultTypeName;
+    }
+
+}
diff --git 
a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/ExpressionReifier.java
 
b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/ExpressionReifier.java
index 526615d..e23f3c5 100644
--- 
a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/ExpressionReifier.java
+++ 
b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/ExpressionReifier.java
@@ -33,6 +33,7 @@ import org.apache.camel.model.language.ExpressionDefinition;
 import org.apache.camel.model.language.GroovyExpression;
 import org.apache.camel.model.language.HeaderExpression;
 import org.apache.camel.model.language.Hl7TerserExpression;
+import org.apache.camel.model.language.JoorExpression;
 import org.apache.camel.model.language.JsonPathExpression;
 import org.apache.camel.model.language.LanguageExpression;
 import org.apache.camel.model.language.MethodCallExpression;
@@ -68,6 +69,7 @@ public class ExpressionReifier<T extends 
ExpressionDefinition> extends AbstractR
         map.put(GroovyExpression.class, ExpressionReifier::new);
         map.put(HeaderExpression.class, ExpressionReifier::new);
         map.put(Hl7TerserExpression.class, ExpressionReifier::new);
+        map.put(JoorExpression.class, JoorExpressionReifier::new);
         map.put(JsonPathExpression.class, JsonPathExpressionReifier::new);
         map.put(LanguageExpression.class, ExpressionReifier::new);
         map.put(MethodCallExpression.class, MethodCallExpressionReifier::new);
diff --git 
a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/JoorExpressionReifier.java
 
b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/JoorExpressionReifier.java
new file mode 100644
index 0000000..87075a5
--- /dev/null
+++ 
b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/JoorExpressionReifier.java
@@ -0,0 +1,62 @@
+/*
+ * 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.reifier.language;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Expression;
+import org.apache.camel.Predicate;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.model.language.ExpressionDefinition;
+import org.apache.camel.model.language.JoorExpression;
+import org.apache.camel.spi.Language;
+
+public class JoorExpressionReifier extends ExpressionReifier<JoorExpression> {
+
+    public JoorExpressionReifier(CamelContext camelContext, 
ExpressionDefinition definition) {
+        super(camelContext, (JoorExpression) definition);
+    }
+
+    @Override
+    protected void configureLanguage(Language language) {
+        if (definition.getResultType() == null && 
definition.getResultTypeName() != null) {
+            try {
+                Class<?> clazz = 
camelContext.getClassResolver().resolveMandatoryClass(definition.getResultTypeName());
+                definition.setResultType(clazz);
+            } catch (ClassNotFoundException e) {
+                throw RuntimeCamelException.wrapRuntimeException(e);
+            }
+        }
+    }
+
+    private Object[] createProperties() {
+        Object[] properties = new Object[2];
+        properties[0] = definition.getResultType();
+        properties[1] = parseBoolean(definition.getSingleQuotes());
+        return properties;
+    }
+
+    @Override
+    protected Expression createExpression(Language language, String exp) {
+        return language.createExpression(exp, createProperties());
+    }
+
+    @Override
+    protected Predicate createPredicate(Language language, String exp) {
+        return language.createPredicate(exp, createProperties());
+    }
+
+}
diff --git 
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java 
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
index 29ad26b..0bec5be 100644
--- 
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
+++ 
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
@@ -2346,6 +2346,16 @@ public class ModelParser extends BaseParser {
         return doParse(new Hl7TerserExpression(),
             expressionDefinitionAttributeHandler(), noElementHandler(), 
expressionDefinitionValueHandler());
     }
+    protected JoorExpression doParseJoorExpression() throws IOException, 
XmlPullParserException {
+        return doParse(new JoorExpression(), (def, key, val) -> {
+            switch (key) {
+                case "resultType": def.setResultTypeName(val); break;
+                case "singleQuotes": def.setSingleQuotes(val); break;
+                default: return 
expressionDefinitionAttributeHandler().accept(def, key, val);
+            }
+            return true;
+        }, noElementHandler(), expressionDefinitionValueHandler());
+    }
     protected JsonPathExpression doParseJsonPathExpression() throws 
IOException, XmlPullParserException {
         return doParse(new JsonPathExpression(), (def, key, val) -> {
             switch (key) {
@@ -2965,6 +2975,7 @@ public class ModelParser extends BaseParser {
             case "groovy": return doParseGroovyExpression();
             case "header": return doParseHeaderExpression();
             case "hl7terser": return doParseHl7TerserExpression();
+            case "joor": return doParseJoorExpression();
             case "jsonpath": return doParseJsonPathExpression();
             case "language": return doParseLanguageExpression();
             case "method": return doParseMethodCallExpression();
diff --git a/docs/components/modules/languages/pages/joor-language.adoc 
b/docs/components/modules/languages/pages/joor-language.adoc
new file mode 100644
index 0000000..b36e9e8
--- /dev/null
+++ b/docs/components/modules/languages/pages/joor-language.adoc
@@ -0,0 +1,113 @@
+[[joor-language]]
+= JOOR Language
+//THIS FILE IS COPIED: EDIT THE SOURCE FILE:
+:page-source: components/camel-joor/src/main/docs/joor-language.adoc
+:docTitle: JOOR
+:artifactId: camel-joor
+:description: Evaluate a JOOR (Java compiled) expression Language against the 
Camel Exchange.
+:since: 3.7
+:supportLevel: Preview
+include::{cq-version}@camel-quarkus:ROOT:partial$reference/languages/joor.adoc[]
+
+*Since Camel {since}*
+
+The jOOR langauge allows to use Java code in your Camel expression, with some 
limitations.
+The jOOR library integrates with the Java compiler and performs runtime 
compilation of Java code (with some limitiations).
+
+NOTE: Java 8 is not supported. This requires Java 11 or 14.
+
+
+== JOOR Options
+
+
+
+// language options: START
+The JOOR language supports 3 options, which are listed below.
+
+
+
+[width="100%",cols="2,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| resultType |  | String | Sets the class name of the result type (type from 
output)
+| singleQuotes | true | Boolean | Whether single quotes can be used as 
replacement for double quotes. This is convenient when you need to work with 
strings inside strings.
+| trim | true | Boolean | Whether to trim the value to remove leading and 
trailing whitespaces and line breaks
+|===
+// language options: END
+
+=== Variables
+
+The JOOR language allows the following variables to be used in the script
+
+[width="100%",cols="2,1m,7",options="header"]
+|===
+| Variable | Java Type | Description
+| context | Context | The CamelContext
+| exchange | Exchange | The Camel Exchange
+| message | Message | The Camel message
+|===
+
+=== Sample
+
+For example to transform the message using joor language to upper case
+
+[source,java]
+----
+from("seda:orders")
+  .transform().joor("message.getBody(String.class).toUpperCase()")
+  .to("seda:upper");
+----
+
+And in XML DSL:
+[source,xml]
+----
+<route>
+   <from uri="seda:orders"/>
+   <transform>
+     <joor>message.getBody(String.class).toUpperCase()</joor>
+   </transform>
+   <to uri="seda:upper"/>
+</route>
+----
+
+=== Multi statements
+
+It is possible to include multiple statements, for example where we in the 
first statement gets the `user` header.
+And then in the 2nd statement we return a value whether the user is `null` or 
not.
+
+[source,java]
+----
+from("seda:orders")
+  .transform().joor("Object user = message.getHeader(\"user\"); return user != 
null ? \"User: \" + user : \"No user exists\";")
+  .to("seda:user");
+----
+
+Notice how we have to quote strings in strings, and that is annoying, so 
instead we can use single quotes:
+
+[source,java]
+----
+from("seda:orders")
+  .transform().joor("Object user = message.getHeader('user'); return user != 
null ? 'User: ' + user : 'No user exists';")
+  .to("seda:user");
+----
+
+=== Limitations
+
+
+== Dependencies
+
+To use scripting languages in your camel routes you need to add a
+dependency on *camel-joor*.
+
+If you use Maven you could just add the following to your `pom.xml`,
+substituting the version number for the latest and greatest release (see
+the download page for the latest versions).
+
+[source,xml]
+---------------------------------------
+<dependency>
+  <groupId>org.apache.camel</groupId>
+  <artifactId>camel-joor</artifactId>
+  <version>x.x.x</version>
+</dependency>
+---------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index 226c96c..8be69f9 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -339,6 +339,7 @@
         <jolt-version>0.1.1</jolt-version>
         <jool-version>0.9.12</jool-version>
         <jooq-version>3.13.4</jooq-version>
+        <joor-version>0.9.13</joor-version>
         <johnzon-version>1.2.8</johnzon-version>
         <jose4j-version>0.6.4</jose4j-version>
         <jsendnsca-version>2.1.1</jsendnsca-version>
@@ -1693,6 +1694,11 @@
                        </dependency>
                        <dependency>
                                <groupId>org.apache.camel</groupId>
+                               <artifactId>camel-joor</artifactId>
+                               <version>${project.version}</version>
+                       </dependency>
+                       <dependency>
+                               <groupId>org.apache.camel</groupId>
                                <artifactId>camel-jpa</artifactId>
                                <version>${project.version}</version>
                        </dependency>

Reply via email to