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

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

commit 3062656f0469ca214dbce7f871922a397d0576e3
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri Feb 2 15:39:30 2024 +0100

    CAMEL-20378: Languages should be thread-safe and be configured only via 
properties array, all in the same way.
---
 .../org/apache/camel/language/jq/JqExpression.java | 81 ++++------------------
 .../org/apache/camel/language/jq/JqLanguage.java   |  7 +-
 .../language/jq/JqSimpleTransformVariableTest.java |  4 ++
 .../camel/support/SingleInputLanguageSupport.java  | 65 -----------------
 .../support/SingleInputTypedLanguageSupport.java   | 49 ++-----------
 .../camel/support/builder/ExpressionBuilder.java   | 29 +++++---
 6 files changed, 45 insertions(+), 190 deletions(-)

diff --git 
a/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqExpression.java
 
b/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqExpression.java
index a72cc5f90a3..1c9e3f6b068 100644
--- 
a/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqExpression.java
+++ 
b/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqExpression.java
@@ -29,16 +29,15 @@ import net.thisptr.jackson.jq.Versions;
 import net.thisptr.jackson.jq.exception.JsonQueryException;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
+import org.apache.camel.Expression;
 import org.apache.camel.ExpressionIllegalSyntaxException;
 import org.apache.camel.InvalidPayloadException;
-import org.apache.camel.NoSuchHeaderOrPropertyException;
-import org.apache.camel.NoSuchVariableException;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.TypeConverter;
 import org.apache.camel.spi.ExpressionResultTypeAware;
-import org.apache.camel.support.ExchangeHelper;
 import org.apache.camel.support.ExpressionAdapter;
 import org.apache.camel.support.MessageHelper;
+import org.apache.camel.support.builder.ExpressionBuilder;
 
 public class JqExpression extends ExpressionAdapter implements 
ExpressionResultTypeAware {
 
@@ -49,10 +48,7 @@ public class JqExpression extends ExpressionAdapter 
implements ExpressionResultT
     private Class<?> resultType;
     private JsonQuery query;
     private TypeConverter typeConverter;
-
-    private String variableName;
-    private String headerName;
-    private String propertyName;
+    private Expression source;
 
     public JqExpression(String expression) {
         this(null, expression);
@@ -88,6 +84,9 @@ public class JqExpression extends ExpressionAdapter 
implements ExpressionResultT
                 resultType = JsonNode.class;
             }
         }
+        if (this.source == null) {
+            source = ExpressionBuilder.bodyExpression();
+        }
     }
 
     public Scope getScope() {
@@ -120,41 +119,12 @@ public class JqExpression extends ExpressionAdapter 
implements ExpressionResultT
         this.resultTypeName = resultTypeName;
     }
 
-    public String getVariableName() {
-        return variableName;
-    }
-
-    /**
-     * Name of the variable to use as input instead of the message body.
-     */
-    public void setVariableName(String variableName) {
-        this.variableName = variableName;
-    }
-
-    public String getHeaderName() {
-        return headerName;
-    }
-
-    /**
-     * Name of the header to use as input instead of the message body.
-     * </p>
-     * It has higher precedence than the propertyName if both are set.
-     */
-    public void setHeaderName(String headerName) {
-        this.headerName = headerName;
-    }
-
-    public String getPropertyName() {
-        return propertyName;
+    public Expression getSource() {
+        return source;
     }
 
-    /**
-     * Name of the property to use as input instead of the message body.
-     * </p>
-     * It has lower precedence than the headerName if both are set.
-     */
-    public void setPropertyName(String propertyName) {
-        this.propertyName = propertyName;
+    public void setSource(Expression source) {
+        this.source = source;
     }
 
     @Override
@@ -218,33 +188,12 @@ public class JqExpression extends ExpressionAdapter 
implements ExpressionResultT
      * @return          the {@link JsonNode} to be processed by the expression
      */
     private JsonNode getPayload(Exchange exchange) throws Exception {
-        JsonNode payload = null;
-
-        if (variableName == null && headerName == null && propertyName == 
null) {
-            payload = exchange.getMessage().getBody(JsonNode.class);
-            if (payload == null) {
-                throw new InvalidPayloadException(exchange, JsonNode.class);
-            }
-            // if body is stream cached then reset, so we can re-read it again
-            MessageHelper.resetStreamCache(exchange.getMessage());
-        } else {
-            if (variableName != null) {
-                payload = ExchangeHelper.getVariable(exchange, variableName, 
JsonNode.class);
-                if (payload == null) {
-                    throw new NoSuchVariableException(exchange, variableName, 
JsonNode.class);
-                }
-            }
-            if (payload == null && headerName != null) {
-                payload = exchange.getMessage().getHeader(headerName, 
JsonNode.class);
-            }
-            if (payload == null && propertyName != null) {
-                payload = exchange.getProperty(propertyName, JsonNode.class);
-            }
-            if (payload == null) {
-                throw new NoSuchHeaderOrPropertyException(exchange, 
headerName, propertyName, JsonNode.class);
-            }
+        JsonNode payload = source.evaluate(exchange, JsonNode.class);
+        // if body is stream cached then reset, so we can re-read it again
+        MessageHelper.resetStreamCache(exchange.getMessage());
+        if (payload == null) {
+            throw new InvalidPayloadException(exchange, JsonNode.class);
         }
-
         return payload;
     }
 }
diff --git 
a/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqLanguage.java
 
b/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqLanguage.java
index 138fcbeb722..027b3684195 100644
--- 
a/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqLanguage.java
+++ 
b/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqLanguage.java
@@ -73,15 +73,14 @@ public class JqLanguage extends 
SingleInputTypedLanguageSupport implements Stati
     }
 
     @Override
-    public Expression createExpression(String expression, Object[] properties) 
{
+    public Expression createExpression(Expression source, String expression, 
Object[] properties) {
         JqExpression answer = new JqExpression(Scope.newChildScope(rootScope), 
expression);
         answer.setResultType(property(Class.class, properties, 0, 
getResultType()));
-        answer.setVariableName(property(String.class, properties, 1, 
getVariableName()));
-        answer.setHeaderName(property(String.class, properties, 2, 
getHeaderName()));
-        answer.setPropertyName(property(String.class, properties, 3, 
getPropertyName()));
+        answer.setSource(source);
         if (getCamelContext() != null) {
             answer.init(getCamelContext());
         }
         return answer;
     }
+
 }
diff --git 
a/components/camel-jq/src/test/java/org/apache/camel/language/jq/JqSimpleTransformVariableTest.java
 
b/components/camel-jq/src/test/java/org/apache/camel/language/jq/JqSimpleTransformVariableTest.java
index 5e62dbad94f..73a11d49e75 100644
--- 
a/components/camel-jq/src/test/java/org/apache/camel/language/jq/JqSimpleTransformVariableTest.java
+++ 
b/components/camel-jq/src/test/java/org/apache/camel/language/jq/JqSimpleTransformVariableTest.java
@@ -24,7 +24,9 @@ public class JqSimpleTransformVariableTest extends 
JqTestSupport {
 
     private static String EXPECTED = """
             {
+              "roll": 123,
               "country": "se",
+              "fullname": "scott"
             }""";
 
     @Override
@@ -36,7 +38,9 @@ public class JqSimpleTransformVariableTest extends 
JqTestSupport {
                         .setVariable("place", constant("{ \"name\": 
\"sweden\", \"iso\": \"se\" }"))
                         .transform().simple("""
                                 {
+                                  "roll": ${jq(.id)},
                                   "country": "${jq(variable:place,.iso)}",
+                                  "fullname": "${jq(.name)}"
                                 }""")
                         .to("mock:result");
             }
diff --git 
a/core/camel-support/src/main/java/org/apache/camel/support/SingleInputLanguageSupport.java
 
b/core/camel-support/src/main/java/org/apache/camel/support/SingleInputLanguageSupport.java
deleted file mode 100644
index 4b84833105d..00000000000
--- 
a/core/camel-support/src/main/java/org/apache/camel/support/SingleInputLanguageSupport.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.support;
-
-import org.apache.camel.spi.Language;
-
-/**
- * Base class for {@link Language} implementations that support different 
sources of input data.
- */
-@Deprecated
-public abstract class SingleInputLanguageSupport extends LanguageSupport {
-
-    private String variableName;
-    private String headerName;
-    private String propertyName;
-
-    public String getVariableName() {
-        return variableName;
-    }
-
-    /**
-     * Name of variable to use as input, instead of the message body
-     */
-    public void setVariableName(String variableName) {
-        this.variableName = variableName;
-    }
-
-    public String getHeaderName() {
-        return headerName;
-    }
-
-    /**
-     * Name of header to use as input, instead of the message body
-     */
-    public void setHeaderName(String headerName) {
-        this.headerName = headerName;
-    }
-
-    public String getPropertyName() {
-        return propertyName;
-    }
-
-    /**
-     * Name of property to use as input, instead of the message body.
-     * <p>
-     * It has a lower precedent than the name of header if both are set.
-     */
-    public void setPropertyName(String propertyName) {
-        this.propertyName = propertyName;
-    }
-}
diff --git 
a/core/camel-support/src/main/java/org/apache/camel/support/SingleInputTypedLanguageSupport.java
 
b/core/camel-support/src/main/java/org/apache/camel/support/SingleInputTypedLanguageSupport.java
index 9e1f98a8805..19e00a97997 100644
--- 
a/core/camel-support/src/main/java/org/apache/camel/support/SingleInputTypedLanguageSupport.java
+++ 
b/core/camel-support/src/main/java/org/apache/camel/support/SingleInputTypedLanguageSupport.java
@@ -25,53 +25,12 @@ import org.apache.camel.support.builder.ExpressionBuilder;
  */
 public abstract class SingleInputTypedLanguageSupport extends 
TypedLanguageSupport {
 
-    private String variableName;
-    private String headerName;
-    private String propertyName;
-
-    public String getVariableName() {
-        return variableName;
-    }
-
-    /**
-     * Name of variable to use as input, instead of the message body
-     * </p>
-     * It has as higher precedent if other are set.
-     */
-    public void setVariableName(String variableName) {
-        this.variableName = variableName;
-    }
-
-    public String getHeaderName() {
-        return headerName;
-    }
-
-    /**
-     * Name of header to use as input, instead of the message body
-     */
-    public void setHeaderName(String headerName) {
-        this.headerName = headerName;
-    }
-
-    public String getPropertyName() {
-        return propertyName;
-    }
-
-    /**
-     * Name of property to use as input, instead of the message body.
-     * <p>
-     * It has a lower precedent than the name of header if both are set.
-     */
-    public void setPropertyName(String propertyName) {
-        this.propertyName = propertyName;
-    }
-
     @Override
     public Expression createExpression(String expression, Object[] properties) 
{
         Class<?> type = property(Class.class, properties, 0, getResultType());
-        String variable = property(String.class, properties, 1, 
getVariableName());
-        String header = property(String.class, properties, 2, getHeaderName());
-        String property = property(String.class, properties, 3, 
getPropertyName());
+        String variable = property(String.class, properties, 1, null);
+        String header = property(String.class, properties, 2, null);
+        String property = property(String.class, properties, 3, null);
         Expression source = ExpressionBuilder.singleInputExpression(variable, 
header, property);
         if (type == null || type == Object.class) {
             return createExpression(source, expression, properties);
@@ -87,7 +46,7 @@ public abstract class SingleInputTypedLanguageSupport extends 
TypedLanguageSuppo
      * @param  properties configuration properties (optimized as object array 
with hardcoded positions for properties)
      * @return            the created expression
      */
-    protected Expression createExpression(Expression source, String 
expression, Object[] properties) {
+    public Expression createExpression(Expression source, String expression, 
Object[] properties) {
         throw new UnsupportedOperationException();
     }
 }
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 0f3bb477721..058ad8ce1dc 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
@@ -987,29 +987,38 @@ public class ExpressionBuilder {
                 if (lan != null) {
                     if (input != null && lan instanceof 
SingleInputTypedLanguageSupport sil) {
                         String prefix = StringHelper.before(input, ":");
-                        String source = StringHelper.after(input, ":");
+                        String name = StringHelper.after(input, ":");
                         if (prefix != null) {
                             prefix = prefix.trim();
                         }
-                        if (source != null) {
-                            source = source.trim();
+                        if (name != null) {
+                            name = name.trim();
                         }
+                        String header = null;
+                        String property = null;
+                        String variable = null;
                         if ("header".equals(prefix)) {
-                            sil.setHeaderName(source);
+                            header = name;
                         } else if ("property".equals(prefix) || 
"exchangeProperty".equals(prefix)) {
-                            sil.setPropertyName(source);
+                            property = name;
                         } else if ("variable".equals(prefix)) {
-                            sil.setVariableName(source);
+                            variable = name;
                         } else {
                             throw new IllegalArgumentException(
                                     "Invalid input source for language. Should 
either be header:key, exchangeProperty:key, or variable:key, was: "
                                                                + input);
                         }
+                        Expression source = 
ExpressionBuilder.singleInputExpression(variable, header, property);
+                        expr = sil.createExpression(source, expression, null);
+                        expr.init(context);
+                        pred = PredicateBuilder.toPredicate(expr);
+                        pred.init(context);
+                    } else {
+                        pred = lan.createPredicate(expression);
+                        pred.init(context);
+                        expr = lan.createExpression(expression);
+                        expr.init(context);
                     }
-                    pred = lan.createPredicate(expression);
-                    pred.init(context);
-                    expr = lan.createExpression(expression);
-                    expr.init(context);
                 } else {
                     throw new NoSuchLanguageException(language);
                 }

Reply via email to