This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 35d1e9f6144 CAMEL-20127: Add messageAs function to simple language
(#12081)
35d1e9f6144 is described below
commit 35d1e9f61442d899a6e361ff47815fe427105f13
Author: Claus Ibsen <[email protected]>
AuthorDate: Sun Nov 19 14:02:41 2023 +0100
CAMEL-20127: Add messageAs function to simple language (#12081)
---
.../modules/languages/pages/csimple-language.adoc | 3 ++
.../modules/languages/pages/simple-language.adoc | 7 ++++
.../camel/language/csimple/CSimpleHelper.java | 4 ++
.../language/simple/SimpleExpressionBuilder.java | 46 ++++++++++++++++++++++
.../simple/ast/SimpleFunctionExpression.java | 32 ++++++++++++++-
.../camel/language/simple/MyAttachmentMessage.java | 40 +++++++++++++++++++
.../apache/camel/language/simple/SimpleTest.java | 16 ++++++++
.../camel/support/builder/ExpressionBuilder.java | 39 ++++++++++++++++++
8 files changed, 186 insertions(+), 1 deletion(-)
diff --git
a/core/camel-core-languages/src/main/docs/modules/languages/pages/csimple-language.adoc
b/core/camel-core-languages/src/main/docs/modules/languages/pages/csimple-language.adoc
index 35722af2c4e..aa704512956 100644
---
a/core/camel-core-languages/src/main/docs/modules/languages/pages/csimple-language.adoc
+++
b/core/camel-core-languages/src/main/docs/modules/languages/pages/csimple-language.adoc
@@ -60,6 +60,9 @@ and then converting the exchange property to the given type
determined by its cl
|mandatoryExchangePropertyAsIndex(_key_, _type_, _index_) |Type | To be used
for collecting an exchange property from an existing `Collection`, `Map` or
array (lookup by the index)
and then converting the exchange property to the given type determined by its
classname. Expects the exchange property to be not null.
+|messageAs(_type_) |Type |Converts the message to the given type determined by
its
+classname. The converted message can be null.
+
|=======================================================================
For example given the following simple expression:
diff --git
a/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
b/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
index c24d453eec4..b4825370a24 100644
---
a/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
+++
b/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
@@ -134,6 +134,13 @@ classname
|exchangeProperty.foo.*OGNL* |Object |refer to the foo property on the
exchange and invoke its
value using a Camel OGNL expression.
+|messageAs(_type_) |Type |Converts the message to the given type determined by
its
+classname. The converted message can be null.
+
+|messageAs(_type_).*OGNL* |Object |Converts the message to the given type
determined by its
+classname and then invoke methods using a Camel OGNL expression. The
+converted message can be null.
+
|sys.foo |String |refer to the JVM system property
|sysenv.foo |String |refer to the system environment variable
diff --git
a/core/camel-core-languages/src/main/java/org/apache/camel/language/csimple/CSimpleHelper.java
b/core/camel-core-languages/src/main/java/org/apache/camel/language/csimple/CSimpleHelper.java
index 4b5c4cd81cb..4bf6cdd5f09 100644
---
a/core/camel-core-languages/src/main/java/org/apache/camel/language/csimple/CSimpleHelper.java
+++
b/core/camel-core-languages/src/main/java/org/apache/camel/language/csimple/CSimpleHelper.java
@@ -66,6 +66,10 @@ public final class CSimpleHelper {
private CSimpleHelper() {
}
+ public static <T> T messageAs(Exchange exchange, Class<T> type) {
+ return exchange.getMessage(type);
+ }
+
public static <T> T bodyAs(Message message, Class<T> type) {
return message.getBody(type);
}
diff --git
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java
index 020d6209fec..b39e822adee 100644
---
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java
+++
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java
@@ -697,6 +697,52 @@ public final class SimpleExpressionBuilder {
};
}
+ /**
+ * Returns the expression for the message converted to the given type and
invoking methods on the converted message
+ * defined in a simple OGNL notation
+ */
+ public static Expression messageOgnlExpression(final String name, final
String ognl) {
+ return new ExpressionAdapter() {
+ private ClassResolver classResolver;
+ private Expression exp;
+ private Language bean;
+
+ @Override
+ public Object evaluate(Exchange exchange) {
+ String text = exp.evaluate(exchange, String.class);
+ Class<?> type;
+ try {
+ type = classResolver.resolveMandatoryClass(text);
+ } catch (ClassNotFoundException e) {
+ throw
CamelExecutionException.wrapCamelExecutionException(exchange, e);
+ }
+ Object msg = exchange.getMessage(type);
+ if (msg != null) {
+ // ognl is able to evaluate method name if it contains
nested functions
+ // so we should not eager evaluate ognl as a string
+ Expression ognlExp = bean.createExpression(null, new
Object[] { msg, ognl });
+ ognlExp.init(exchange.getContext());
+ return ognlExp.evaluate(exchange, Object.class);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void init(CamelContext context) {
+ classResolver = context.getClassResolver();
+ exp = ExpressionBuilder.simpleExpression(name);
+ exp.init(context);
+ bean = context.resolveLanguage("bean");
+ }
+
+ @Override
+ public String toString() {
+ return "messageOgnlAs[" + name + "](" + ognl + ")";
+ }
+ };
+ }
+
/**
* Returns the expression for the exchanges inbound message body converted
to the given type and invoking methods on
* the converted body defined in a simple OGNL notation
diff --git
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
index 20995e04116..f6b659fb725 100644
---
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
+++
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
@@ -77,6 +77,12 @@ public class SimpleFunctionExpression extends
LiteralExpression {
return answer;
}
+ // message first
+ answer = createSimpleExpressionMessage(camelContext, function, strict);
+ if (answer != null) {
+ return answer;
+ }
+
// body and headers first
answer = createSimpleExpressionBodyOrHeader(function, strict);
if (answer != null) {
@@ -303,6 +309,31 @@ public class SimpleFunctionExpression extends
LiteralExpression {
}
}
+ private Expression createSimpleExpressionMessage(CamelContext
camelContext, String function, boolean strict) {
+ // messageAs
+ String remainder = ifStartsWithReturnRemainder("messageAs(", function);
+ if (remainder != null) {
+ String type = StringHelper.before(remainder, ")");
+ if (type == null) {
+ throw new SimpleParserException("Valid syntax:
${messageAs(type)} was: " + function, token.getIndex());
+ }
+ type = StringHelper.removeQuotes(type);
+ remainder = StringHelper.after(remainder, ")");
+
+ if (ObjectHelper.isNotEmpty(remainder)) {
+ boolean invalid =
OgnlHelper.isInvalidValidOgnlExpression(remainder);
+ if (invalid) {
+ throw new SimpleParserException("Valid syntax:
${messageAs(type).OGNL} was: " + function, token.getIndex());
+ }
+ return SimpleExpressionBuilder.messageOgnlExpression(type,
remainder);
+ } else {
+ return ExpressionBuilder.messageExpression(type);
+ }
+ }
+
+ return null;
+ }
+
private Expression createSimpleExpressionBodyOrHeader(String function,
boolean strict) {
// bodyAs
String remainder = ifStartsWithReturnRemainder("bodyAs(", function);
@@ -322,7 +353,6 @@ public class SimpleFunctionExpression extends
LiteralExpression {
} else {
return ExpressionBuilder.bodyExpression(type);
}
-
}
// mandatoryBodyAs
remainder = ifStartsWithReturnRemainder("mandatoryBodyAs(", function);
diff --git
a/core/camel-core/src/test/java/org/apache/camel/language/simple/MyAttachmentMessage.java
b/core/camel-core/src/test/java/org/apache/camel/language/simple/MyAttachmentMessage.java
new file mode 100644
index 00000000000..3e5096daff3
--- /dev/null
+++
b/core/camel-core/src/test/java/org/apache/camel/language/simple/MyAttachmentMessage.java
@@ -0,0 +1,40 @@
+/*
+ * 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.Exchange;
+import org.apache.camel.support.DefaultMessage;
+
+public class MyAttachmentMessage extends DefaultMessage {
+
+ public MyAttachmentMessage(Exchange exchange) {
+ super(exchange);
+ }
+
+ public boolean hasAttachments() {
+ return true;
+ }
+
+ public String toString() {
+ return "MyAttachmentMessage";
+ }
+
+ public int size() {
+ return 42;
+ }
+
+}
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 b61f2c2e500..63503dc95e1 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
@@ -748,6 +748,21 @@ public class SimpleTest extends LanguageTestSupport {
assertEquals("Just testing", out.getMessage());
}
+ @Test
+ public void testMessageAs() throws Exception {
+ // should be false as message is default
+
assertPredicate("${messageAs(org.apache.camel.language.simple.MyAttachmentMessage).hasAttachments}",
false);
+
assertPredicate("${messageAs(org.apache.camel.language.simple.MyAttachmentMessage)?.hasAttachments}",
false);
+
+ MyAttachmentMessage msg = new MyAttachmentMessage(exchange);
+ msg.setBody("<hello id='m123'>world!</hello>");
+ exchange.setMessage(msg);
+
+
assertPredicate("${messageAs(org.apache.camel.language.simple.MyAttachmentMessage).hasAttachments}",
true);
+
assertPredicate("${messageAs(org.apache.camel.language.simple.MyAttachmentMessage)?.hasAttachments}",
true);
+
assertExpression("${messageAs(org.apache.camel.language.simple.MyAttachmentMessage).size}",
"42");
+ }
+
@Test
public void testBodyAs() throws Exception {
assertExpression("${bodyAs(String)}", "<hello
id='m123'>world!</hello>");
@@ -2254,4 +2269,5 @@ public class SimpleTest extends LanguageTestSupport {
return new Object[] { "Hallo", "World", "!" };
}
}
+
}
diff --git
a/core/camel-support/src/main/java/org/apache/camel/support/builder/ExpressionBuilder.java
b/core/camel-support/src/main/java/org/apache/camel/support/builder/ExpressionBuilder.java
index 115199271c5..f83b25ad901 100644
---
a/core/camel-support/src/main/java/org/apache/camel/support/builder/ExpressionBuilder.java
+++
b/core/camel-support/src/main/java/org/apache/camel/support/builder/ExpressionBuilder.java
@@ -1168,6 +1168,45 @@ public class ExpressionBuilder {
return inMessageExpression();
}
+ /**
+ * Returns the expression for the message converted to the given type
+ */
+ public static Expression messageExpression(final String name) {
+ return messageExpression(simpleExpression(name));
+ }
+
+ /**
+ * Returns the expression for the message converted to the given type
+ */
+ public static Expression messageExpression(final Expression name) {
+ return new ExpressionAdapter() {
+ private ClassResolver classResolver;
+
+ @Override
+ public Object evaluate(Exchange exchange) {
+ Class<?> type;
+ try {
+ String text = name.evaluate(exchange, String.class);
+ type = classResolver.resolveMandatoryClass(text);
+ } catch (ClassNotFoundException e) {
+ throw
CamelExecutionException.wrapCamelExecutionException(exchange, e);
+ }
+ return exchange.getMessage(type);
+ }
+
+ @Override
+ public void init(CamelContext context) {
+ name.init(context);
+ classResolver = context.getClassResolver();
+ }
+
+ @Override
+ public String toString() {
+ return "messageAs[" + name + "]";
+ }
+ };
+ }
+
/**
* Returns a functional expression for the IN message
*/