You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2023/11/19 12:34:08 UTC

(camel) branch messageAs created (now a64249341c9)

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

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


      at a64249341c9 CAMEL-20127: Add messageAs function to simple language

This branch includes the following new commits:

     new a64249341c9 CAMEL-20127: Add messageAs function to simple language

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(camel) 01/01: CAMEL-20127: Add messageAs function to simple language

Posted by da...@apache.org.
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 <cl...@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
      */