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

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

commit a64249341c9d2443ed6b020f1872960951761c65
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Sun Nov 19 13:28:30 2023 +0100

    CAMEL-20127: Add messageAs function to simple language
---
 .../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
      */

Reply via email to