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); }
