This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch ns in repository https://gitbox.apache.org/repos/asf/camel.git
commit ac2828e78b156f8e5502aea43f04131e2b5de3c2 Author: Claus Ibsen <[email protected]> AuthorDate: Wed Feb 4 10:07:00 2026 +0100 CAMEL-22954: camel-core - Add nested option to simple --- .../org/apache/camel/catalog/languages/file.json | 5 +- .../org/apache/camel/catalog/languages/simple.json | 5 +- .../org/apache/camel/catalog/models/simple.json | 5 +- .../apache/camel/catalog/schemas/camel-spring.xsd | 9 ++++ .../apache/camel/catalog/schemas/camel-xml-io.xsd | 9 ++++ .../org/apache/camel/language/simple/file.json | 5 +- .../org/apache/camel/language/simple/simple.json | 5 +- .../camel/language/simple/SimpleLanguage.java | 41 ++++++++++++++++- .../org/apache/camel/model/language/simple.json | 5 +- .../camel/model/language/SimpleExpression.java | 33 ++++++++++++++ .../reifier/language/SimpleExpressionReifier.java | 3 +- .../camel/language/simple/SimpleNestedTest.java | 53 ++++++++++++++++++++++ .../apache/camel/language/simple/SimpleTest.java | 4 +- .../java/org/apache/camel/xml/in/ModelParser.java | 1 + .../java/org/apache/camel/xml/out/ModelWriter.java | 1 + .../org/apache/camel/yaml/out/ModelWriter.java | 1 + .../dsl/yaml/deserializers/ModelDeserializers.java | 6 +++ .../generated/resources/schema/camelYamlDsl.json | 6 +++ 18 files changed, 180 insertions(+), 17 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/file.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/file.json index b9d101b4b6ae..d2d972ed2d66 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/file.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/file.json @@ -20,8 +20,9 @@ "expression": { "index": 1, "kind": "value", "displayName": "Expression", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The expression value in your chosen language syntax" }, "trimResult": { "index": 2, "kind": "attribute", "displayName": "Trim Result", "group": "common", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to trim the returned values when this language are in use. For example the output result may contain unwanted line breaks at the beginning and end such as when using Java DSL with multi-line blocks. Is default fals [...] "pretty": { "index": 3, "kind": "attribute", "displayName": "Pretty", "group": "common", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "To pretty format the output (only JSon or XML supported)" }, - "resultType": { "index": 4, "kind": "attribute", "displayName": "Result Type", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the class of the result type (type from output)" }, - "trim": { "index": 5, "kind": "attribute", "displayName": "Trim", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to trim the source code to remove leading and trailing whitespaces and line breaks. For example when using DSLs where the source will span across multiple lines and there may be additional line breaks at b [...] + "nested": { "index": 4, "kind": "attribute", "displayName": "Nested", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If the result is a nested simple expression should this expression be evaluated as well" }, + "resultType": { "index": 5, "kind": "attribute", "displayName": "Result Type", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the class of the result type (type from output)" }, + "trim": { "index": 6, "kind": "attribute", "displayName": "Trim", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to trim the source code to remove leading and trailing whitespaces and line breaks. For example when using DSLs where the source will span across multiple lines and there may be additional line breaks at b [...] }, "functions": { "file:name": { "index": 0, "kind": "function", "displayName": "File", "group": "function", "label": "function", "required": false, "javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The file name (relative from starting directory)", "ognl": false, "suffix": "}" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json index 4c7afb123c23..87ca1193ffaf 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json @@ -20,8 +20,9 @@ "expression": { "index": 1, "kind": "value", "displayName": "Expression", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The expression value in your chosen language syntax" }, "trimResult": { "index": 2, "kind": "attribute", "displayName": "Trim Result", "group": "common", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to trim the returned values when this language are in use. For example the output result may contain unwanted line breaks at the beginning and end such as when using Java DSL with multi-line blocks. Is default fals [...] "pretty": { "index": 3, "kind": "attribute", "displayName": "Pretty", "group": "common", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "To pretty format the output (only JSon or XML supported)" }, - "resultType": { "index": 4, "kind": "attribute", "displayName": "Result Type", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the class of the result type (type from output)" }, - "trim": { "index": 5, "kind": "attribute", "displayName": "Trim", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to trim the source code to remove leading and trailing whitespaces and line breaks. For example when using DSLs where the source will span across multiple lines and there may be additional line breaks at b [...] + "nested": { "index": 4, "kind": "attribute", "displayName": "Nested", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If the result is a nested simple expression should this expression be evaluated as well" }, + "resultType": { "index": 5, "kind": "attribute", "displayName": "Result Type", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the class of the result type (type from output)" }, + "trim": { "index": 6, "kind": "attribute", "displayName": "Trim", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to trim the source code to remove leading and trailing whitespaces and line breaks. For example when using DSLs where the source will span across multiple lines and there may be additional line breaks at b [...] }, "functions": { "abs(exp)": { "index": 0, "kind": "function", "displayName": "Absolute Number", "group": "function", "label": "function", "required": false, "javaType": "Long", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Converts the message body (or expression) to a long number and return the absolute value.", "ognl": false, "suffix": "}" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/simple.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/simple.json index 0e1c485d9da5..ceac26d132c6 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/simple.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/simple.json @@ -17,7 +17,8 @@ "expression": { "index": 1, "kind": "value", "displayName": "Expression", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The expression value in your chosen language syntax" }, "trimResult": { "index": 2, "kind": "attribute", "displayName": "Trim Result", "group": "common", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to trim the returned values when this language are in use. For example the output result may contain unwanted line breaks at the beginning and end such as when using Java DSL with multi-line blocks. Is default fals [...] "pretty": { "index": 3, "kind": "attribute", "displayName": "Pretty", "group": "common", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "To pretty format the output (only JSon or XML supported)" }, - "resultType": { "index": 4, "kind": "attribute", "displayName": "Result Type", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the class of the result type (type from output)" }, - "trim": { "index": 5, "kind": "attribute", "displayName": "Trim", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to trim the source code to remove leading and trailing whitespaces and line breaks. For example when using DSLs where the source will span across multiple lines and there may be additional line breaks at b [...] + "nested": { "index": 4, "kind": "attribute", "displayName": "Nested", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If the result is a nested simple expression should this expression be evaluated as well" }, + "resultType": { "index": 5, "kind": "attribute", "displayName": "Result Type", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the class of the result type (type from output)" }, + "trim": { "index": 6, "kind": "attribute", "displayName": "Trim", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to trim the source code to remove leading and trailing whitespaces and line breaks. For example when using DSLs where the source will span across multiple lines and there may be additional line breaks at b [...] } } diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd index 188477b24caf..673fe0f77b45 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd @@ -17768,6 +17768,15 @@ backwards compatible with existing behavior. Default value: false <xs:documentation xml:lang="en"> <![CDATA[ To pretty format the output (only JSon or XML supported). Default value: false +]]> + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="nested" type="xs:string"> + <xs:annotation> + <xs:documentation xml:lang="en"> +<![CDATA[ +If the result is a nested simple expression should this expression be evaluated as well. Default value: false ]]> </xs:documentation> </xs:annotation> diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd index 639caa699229..f64cccd199bb 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd @@ -16462,6 +16462,15 @@ backwards compatible with existing behavior. Default value: false <xs:documentation xml:lang="en"> <![CDATA[ To pretty format the output (only JSon or XML supported). Default value: false +]]> + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="nested" type="xs:string"> + <xs:annotation> + <xs:documentation xml:lang="en"> +<![CDATA[ +If the result is a nested simple expression should this expression be evaluated as well. Default value: false ]]> </xs:documentation> </xs:annotation> diff --git a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/file.json b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/file.json index b9d101b4b6ae..d2d972ed2d66 100644 --- a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/file.json +++ b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/file.json @@ -20,8 +20,9 @@ "expression": { "index": 1, "kind": "value", "displayName": "Expression", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The expression value in your chosen language syntax" }, "trimResult": { "index": 2, "kind": "attribute", "displayName": "Trim Result", "group": "common", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to trim the returned values when this language are in use. For example the output result may contain unwanted line breaks at the beginning and end such as when using Java DSL with multi-line blocks. Is default fals [...] "pretty": { "index": 3, "kind": "attribute", "displayName": "Pretty", "group": "common", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "To pretty format the output (only JSon or XML supported)" }, - "resultType": { "index": 4, "kind": "attribute", "displayName": "Result Type", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the class of the result type (type from output)" }, - "trim": { "index": 5, "kind": "attribute", "displayName": "Trim", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to trim the source code to remove leading and trailing whitespaces and line breaks. For example when using DSLs where the source will span across multiple lines and there may be additional line breaks at b [...] + "nested": { "index": 4, "kind": "attribute", "displayName": "Nested", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If the result is a nested simple expression should this expression be evaluated as well" }, + "resultType": { "index": 5, "kind": "attribute", "displayName": "Result Type", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the class of the result type (type from output)" }, + "trim": { "index": 6, "kind": "attribute", "displayName": "Trim", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to trim the source code to remove leading and trailing whitespaces and line breaks. For example when using DSLs where the source will span across multiple lines and there may be additional line breaks at b [...] }, "functions": { "file:name": { "index": 0, "kind": "function", "displayName": "File", "group": "function", "label": "function", "required": false, "javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The file name (relative from starting directory)", "ognl": false, "suffix": "}" }, diff --git a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json index 4c7afb123c23..87ca1193ffaf 100644 --- a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json +++ b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json @@ -20,8 +20,9 @@ "expression": { "index": 1, "kind": "value", "displayName": "Expression", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The expression value in your chosen language syntax" }, "trimResult": { "index": 2, "kind": "attribute", "displayName": "Trim Result", "group": "common", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to trim the returned values when this language are in use. For example the output result may contain unwanted line breaks at the beginning and end such as when using Java DSL with multi-line blocks. Is default fals [...] "pretty": { "index": 3, "kind": "attribute", "displayName": "Pretty", "group": "common", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "To pretty format the output (only JSon or XML supported)" }, - "resultType": { "index": 4, "kind": "attribute", "displayName": "Result Type", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the class of the result type (type from output)" }, - "trim": { "index": 5, "kind": "attribute", "displayName": "Trim", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to trim the source code to remove leading and trailing whitespaces and line breaks. For example when using DSLs where the source will span across multiple lines and there may be additional line breaks at b [...] + "nested": { "index": 4, "kind": "attribute", "displayName": "Nested", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If the result is a nested simple expression should this expression be evaluated as well" }, + "resultType": { "index": 5, "kind": "attribute", "displayName": "Result Type", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the class of the result type (type from output)" }, + "trim": { "index": 6, "kind": "attribute", "displayName": "Trim", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to trim the source code to remove leading and trailing whitespaces and line breaks. For example when using DSLs where the source will span across multiple lines and there may be additional line breaks at b [...] }, "functions": { "abs(exp)": { "index": 0, "kind": "function", "displayName": "Absolute Number", "group": "function", "label": "function", "required": false, "javaType": "Long", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Converts the message body (or expression) to a long number and return the absolute value.", "ognl": false, "suffix": "}" }, diff --git a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java index b5bfc7e23cf8..4be673a39504 100644 --- a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java +++ b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java @@ -18,12 +18,14 @@ package org.apache.camel.language.simple; import java.util.Map; +import org.apache.camel.CamelContext; import org.apache.camel.Exchange; import org.apache.camel.Expression; import org.apache.camel.Predicate; import org.apache.camel.StaticService; import org.apache.camel.spi.annotations.Language; import org.apache.camel.support.CamelContextHelper; +import org.apache.camel.support.ExpressionAdapter; import org.apache.camel.support.LRUCache; import org.apache.camel.support.LRUCacheFactory; import org.apache.camel.support.LanguageSupport; @@ -160,13 +162,14 @@ public class SimpleLanguage extends LanguageSupport implements StaticService { boolean trim = property(boolean.class, properties, 1, true); boolean pretty = property(boolean.class, properties, 2, false); boolean trimResult = property(boolean.class, properties, 3, false); + boolean nested = property(boolean.class, properties, 4, false); if (trim && expression != null) { expression = expression.trim(); } if (expression == null) { expression = "${null}"; } - return createExpression(expression, resultType, pretty, trimResult); + return createExpression(expression, resultType, pretty, trimResult, nested); } @Override @@ -204,13 +207,17 @@ public class SimpleLanguage extends LanguageSupport implements StaticService { return answer; } - public Expression createExpression(String expression, Class<?> resultType, boolean pretty, boolean trimResult) { + public Expression createExpression( + String expression, Class<?> resultType, boolean pretty, boolean trimResult, boolean nested) { if (resultType == Boolean.class || resultType == boolean.class) { // if its a boolean as result then its a predicate Predicate predicate = createPredicate(expression); return PredicateToExpressionAdapter.toExpression(predicate); } else { Expression exp = createExpression(expression); + if (nested) { + exp = nestedExpression(exp); + } if (resultType != null) { exp = ExpressionBuilder.convertToExpression(exp, resultType); } @@ -265,4 +272,34 @@ public class SimpleLanguage extends LanguageSupport implements StaticService { return text; } } + + private static Expression nestedExpression(final Expression expression) { + return new ExpressionAdapter() { + private org.apache.camel.spi.Language language; + + @Override + public void init(CamelContext context) { + super.init(context); + expression.init(context); + language = context.resolveLanguage("simple"); + } + + @Override + public Object evaluate(Exchange exchange) { + Object answer = expression.evaluate(exchange, Object.class); + if (answer instanceof String str && hasSimpleFunction(str)) { + Expression nested = language.createExpression(str); + nested.init(exchange.getContext()); + answer = nested.evaluate(exchange, Object.class); + } + return answer; + } + + @Override + public String toString() { + return expression.toString(); + } + }; + } + } diff --git a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/language/simple.json b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/language/simple.json index 0e1c485d9da5..ceac26d132c6 100644 --- a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/language/simple.json +++ b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/language/simple.json @@ -17,7 +17,8 @@ "expression": { "index": 1, "kind": "value", "displayName": "Expression", "group": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The expression value in your chosen language syntax" }, "trimResult": { "index": 2, "kind": "attribute", "displayName": "Trim Result", "group": "common", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to trim the returned values when this language are in use. For example the output result may contain unwanted line breaks at the beginning and end such as when using Java DSL with multi-line blocks. Is default fals [...] "pretty": { "index": 3, "kind": "attribute", "displayName": "Pretty", "group": "common", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "To pretty format the output (only JSon or XML supported)" }, - "resultType": { "index": 4, "kind": "attribute", "displayName": "Result Type", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the class of the result type (type from output)" }, - "trim": { "index": 5, "kind": "attribute", "displayName": "Trim", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to trim the source code to remove leading and trailing whitespaces and line breaks. For example when using DSLs where the source will span across multiple lines and there may be additional line breaks at b [...] + "nested": { "index": 4, "kind": "attribute", "displayName": "Nested", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "If the result is a nested simple expression should this expression be evaluated as well" }, + "resultType": { "index": 5, "kind": "attribute", "displayName": "Result Type", "group": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the class of the result type (type from output)" }, + "trim": { "index": 6, "kind": "attribute", "displayName": "Trim", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to trim the source code to remove leading and trailing whitespaces and line breaks. For example when using DSLs where the source will span across multiple lines and there may be additional line breaks at b [...] } } diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/language/SimpleExpression.java b/core/camel-core-model/src/main/java/org/apache/camel/model/language/SimpleExpression.java index 59e5280bc846..3abcb5793198 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/language/SimpleExpression.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/language/SimpleExpression.java @@ -39,6 +39,9 @@ public class SimpleExpression extends TypedExpressionDefinition { @XmlAttribute @Metadata(defaultValue = "false", javaType = "java.lang.Boolean") private String pretty; + @XmlAttribute + @Metadata(defaultValue = "false", javaType = "java.lang.Boolean", label = "advanced") + private String nested; public SimpleExpression() { } @@ -47,6 +50,7 @@ public class SimpleExpression extends TypedExpressionDefinition { super(source); this.trimResult = source.trimResult; this.pretty = source.pretty; + this.nested = source.nested; } public SimpleExpression(String expression) { @@ -61,6 +65,7 @@ public class SimpleExpression extends TypedExpressionDefinition { super(builder); this.trimResult = builder.trimResult; this.pretty = builder.pretty; + this.nested = builder.nested; } @Override @@ -100,6 +105,17 @@ public class SimpleExpression extends TypedExpressionDefinition { this.pretty = pretty; } + public String getNested() { + return nested; + } + + /** + * If the result is a nested simple expression should this expression be evaluated as well + */ + public void setNested(String nested) { + this.nested = nested; + } + /** * {@code Builder} is a specific builder for {@link SimpleExpression}. */ @@ -108,6 +124,7 @@ public class SimpleExpression extends TypedExpressionDefinition { private String trimResult; private String pretty; + private String nested; /** * Whether to trim the returned values when this language are in use. @@ -151,6 +168,22 @@ public class SimpleExpression extends TypedExpressionDefinition { return this; } + /** + * If the result is a nested simple expression should this expression be evaluated as well + */ + public Builder nested(String nested) { + this.nested = nested; + return this; + } + + /** + * If the result is a nested simple expression should this expression be evaluated as well + */ + public Builder nested(boolean nested) { + this.nested = Boolean.toString(nested); + return this; + } + @Override public SimpleExpression end() { return new SimpleExpression(this); diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/SimpleExpressionReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/SimpleExpressionReifier.java index c2c0454dbc5d..fd4c736a4d9a 100644 --- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/SimpleExpressionReifier.java +++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/SimpleExpressionReifier.java @@ -34,11 +34,12 @@ public class SimpleExpressionReifier extends TypedExpressionReifier<SimpleExpres @Override protected Object[] createProperties() { - Object[] properties = new Object[4]; + Object[] properties = new Object[5]; properties[0] = asResultType(); properties[1] = parseBoolean(definition.getTrim()); properties[2] = parseBoolean(definition.getPretty()); properties[3] = parseBoolean(definition.getTrimResult()); + properties[4] = parseBoolean(definition.getNested()); return properties; } diff --git a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleNestedTest.java b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleNestedTest.java new file mode 100644 index 000000000000..6805f9a97f23 --- /dev/null +++ b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleNestedTest.java @@ -0,0 +1,53 @@ +/* + * 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.simple; + +import org.apache.camel.ContextTestSupport; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.junit.jupiter.api.Test; + +public class SimpleNestedTest extends ContextTestSupport { + + @Test + public void testNested() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:result"); + mock.expectedBodiesReceived(23); + + template.sendBodyAndHeader("direct:start", "13", "myValue", "${sum(${body},10)}"); + + assertMockEndpointsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + context.getPropertiesComponent().addInitialProperty("myProp", "${header.myValue}"); + + // turn on nested support in simple (to re-evaluate again) + // {{myProp}} -> header.myValue -> sum + var nested = expression().simple("{{myProp}}").nested(true).end(); + + from("direct:start") + .setBody(nested) + .to("mock:result"); + } + }; + } +} diff --git a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java index ea9446f48d5e..8d48717fea38 100644 --- a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java @@ -3253,11 +3253,11 @@ public class SimpleTest extends LanguageTestSupport { SimpleLanguage sl = (SimpleLanguage) context.resolveLanguage("simple"); - Expression expression = sl.createExpression(" Hi ${body}", Object.class, false, false); + Expression expression = sl.createExpression(" Hi ${body}", Object.class, false, false, false); String out = expression.evaluate(exchange, String.class); assertEquals(" Hi Camel ", out); - expression = sl.createExpression(" Hi ${body}", Object.class, false, true); + expression = sl.createExpression(" Hi ${body}", Object.class, false, true, false); out = expression.evaluate(exchange, String.class); assertEquals("Hi Camel", out); } 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 e9f7b1cbf8f7..13920b6e1df8 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 @@ -2478,6 +2478,7 @@ public class ModelParser extends BaseParser { } protected SimpleExpression doParseSimpleExpression() throws IOException, XmlPullParserException { return doParse(new SimpleExpression(), (def, key, val) -> switch (key) { + case "nested": def.setNested(val); yield true; case "pretty": def.setPretty(val); yield true; case "trimResult": def.setTrimResult(val); yield true; default: yield typedExpressionDefinitionAttributeHandler().accept(def, key, val); diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java index 69fc9d2e5750..d819281e9904 100644 --- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java +++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java @@ -3265,6 +3265,7 @@ public class ModelWriter extends BaseWriter { doWriteTypedExpressionDefinitionAttributes(def); doWriteAttribute("pretty", def.getPretty(), "false"); doWriteAttribute("trimResult", def.getTrimResult(), "false"); + doWriteAttribute("nested", def.getNested(), "false"); doWriteValue(def.getExpression()); endElement(name); } diff --git a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java index fa9a4c21d316..47c6ecf107a0 100644 --- a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java +++ b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java @@ -3265,6 +3265,7 @@ public class ModelWriter extends BaseWriter { doWriteTypedExpressionDefinitionAttributes(def); doWriteAttribute("pretty", def.getPretty(), "false"); doWriteAttribute("trimResult", def.getTrimResult(), "false"); + doWriteAttribute("nested", def.getNested(), "false"); doWriteValue(def.getExpression()); endElement(name); } diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java index 7da575e914eb..1364e05b6851 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java @@ -17760,6 +17760,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { properties = { @YamlProperty(name = "expression", type = "string", required = true, description = "The expression value in your chosen language syntax", displayName = "Expression"), @YamlProperty(name = "id", type = "string", description = "Sets the id of this node", displayName = "Id"), + @YamlProperty(name = "nested", type = "boolean", defaultValue = "false", description = "If the result is a nested simple expression should this expression be evaluated as well", displayName = "Nested"), @YamlProperty(name = "pretty", type = "boolean", defaultValue = "false", description = "To pretty format the output (only JSon or XML supported)", displayName = "Pretty"), @YamlProperty(name = "resultType", type = "string", description = "Sets the class of the result type (type from output)", displayName = "Result Type"), @YamlProperty(name = "trim", type = "boolean", defaultValue = "true", description = "Whether to trim the source code to remove leading and trailing whitespaces and line breaks. For example when using DSLs where the source will span across multiple lines and there may be additional line breaks at both the beginning and end.", displayName = "Trim"), @@ -17796,6 +17797,11 @@ public final class ModelDeserializers extends YamlDeserializerSupport { target.setId(val); break; } + case "nested": { + String val = asText(node); + target.setNested(val); + break; + } case "pretty": { String val = asText(node); target.setPretty(val); diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json index e71bf146b348..49c0844d0cac 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json @@ -14929,6 +14929,12 @@ "title" : "Id", "description" : "Sets the id of this node" }, + "nested" : { + "type" : "boolean", + "title" : "Nested", + "description" : "If the result is a nested simple expression should this expression be evaluated as well", + "default" : false + }, "pretty" : { "type" : "boolean", "title" : "Pretty",
