You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by gn...@apache.org on 2020/03/25 15:23:02 UTC
[camel] 04/11: Add an init method to Expression / Predicate
This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 7afcecd94288e88df957f3a4f4d0facb1e747b8f
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Wed Mar 18 10:07:45 2020 +0100
Add an init method to Expression / Predicate
---
.../apache/camel/language/bean/BeanExpression.java | 4 +
.../camel/component/mock/MockExpressionClause.java | 34 +-
.../camel/component/mock/MockValueBuilder.java | 6 +
.../apache/camel/language/xpath/XPathBuilder.java | 4 +
.../src/main/java/org/apache/camel/Expression.java | 7 +
.../src/main/java/org/apache/camel/Predicate.java | 6 +
.../apache/camel/processor/FilterProcessor.java | 11 +-
.../org/apache/camel/builder/ExpressionClause.java | 34 +-
.../org/apache/camel/builder/SimpleBuilder.java | 88 ++++--
.../camel/model/language/ExpressionDefinition.java | 10 +
.../apache/camel/reifier/ExpressionReifier.java | 2 +-
.../org/apache/camel/reifier/FilterReifier.java | 2 +-
.../reifier/language/SimpleExpressionReifier.java | 37 ++-
.../apache/camel/processor/TryProcessorTest.java | 5 +
.../apache/camel/processor/ValidateSimpleTest.java | 4 +-
.../apache/camel/support/ExpressionSupport.java | 5 +
.../support/ExpressionToPredicateAdapter.java | 5 +
.../org/apache/camel/support/ScriptHelper.java | 10 +
.../support/builder/BinaryPredicateSupport.java | 7 +
.../camel/support/builder/ExpressionBuilder.java | 342 +++++++++++++++++----
.../apache/camel/support/builder/ValueBuilder.java | 6 +
21 files changed, 512 insertions(+), 117 deletions(-)
diff --git a/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanExpression.java b/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanExpression.java
index 516c131..3d48bf0 100644
--- a/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanExpression.java
+++ b/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanExpression.java
@@ -110,6 +110,10 @@ public class BeanExpression implements Expression, Predicate, AfterPropertiesCon
}
@Override
+ public void init(CamelContext context) {
+ }
+
+ @Override
public String toString() {
StringBuilder sb = new StringBuilder("BeanExpression[");
if (bean != null) {
diff --git a/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockExpressionClause.java b/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockExpressionClause.java
index aa3c77d..ba74616b 100644
--- a/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockExpressionClause.java
+++ b/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockExpressionClause.java
@@ -21,6 +21,7 @@ import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
+import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.Expression;
import org.apache.camel.ExpressionFactory;
@@ -425,23 +426,32 @@ public class MockExpressionClause<T> implements Expression, Predicate {
return delegate.getExpressionType();
}
+ private volatile Expression expr;
+
@Override
- public <T> T evaluate(Exchange exchange, Class<T> type) {
- if (getExpressionValue() != null) {
- return getExpressionValue().evaluate(exchange, type);
- } else {
- Expression exp = delegate.getExpressionType().createExpression(exchange.getContext());
- return exp.evaluate(exchange, type);
+ public void init(CamelContext context) {
+ if (expr == null) {
+ synchronized (this) {
+ if (expr == null) {
+ expr = getExpressionValue();
+ if (expr == null) {
+ expr = getExpressionType().createExpression(context);
+ }
+ expr.init(context);
+ }
+ }
}
}
@Override
+ public <T> T evaluate(Exchange exchange, Class<T> type) {
+ init(exchange.getContext());
+ return expr.evaluate(exchange, type);
+ }
+
+ @Override
public boolean matches(Exchange exchange) {
- if (getExpressionValue() != null) {
- return new ExpressionToPredicateAdapter(getExpressionValue()).matches(exchange);
- } else {
- Expression exp = delegate.getExpressionType().createExpression(exchange.getContext());
- return new ExpressionToPredicateAdapter(exp).matches(exchange);
- }
+ init(exchange.getContext());
+ return new ExpressionToPredicateAdapter(expr).matches(exchange);
}
}
diff --git a/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockValueBuilder.java b/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockValueBuilder.java
index 551c524..4082a0e 100644
--- a/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockValueBuilder.java
+++ b/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockValueBuilder.java
@@ -21,6 +21,7 @@ import java.util.Comparator;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
+import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.Expression;
import org.apache.camel.Predicate;
@@ -44,6 +45,11 @@ public class MockValueBuilder implements Expression, Predicate {
}
@Override
+ public void init(CamelContext context) {
+ expression.init(context);
+ }
+
+ @Override
public <T> T evaluate(Exchange exchange, Class<T> type) {
return expression.evaluate(exchange, type);
}
diff --git a/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/XPathBuilder.java b/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/XPathBuilder.java
index 6ff9fef..7adb463 100644
--- a/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/XPathBuilder.java
+++ b/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/XPathBuilder.java
@@ -171,6 +171,10 @@ public class XPathBuilder extends ServiceSupport implements CamelContextAware, E
}
@Override
+ public void init(CamelContext context) {
+ }
+
+ @Override
public boolean configure(CamelContext camelContext, Object target, String name, Object value, boolean ignoreCase) {
if (target != this) {
throw new IllegalStateException("Can only configure our own instance !");
diff --git a/core/camel-api/src/main/java/org/apache/camel/Expression.java b/core/camel-api/src/main/java/org/apache/camel/Expression.java
index 4995d0b..6fc0f64 100644
--- a/core/camel-api/src/main/java/org/apache/camel/Expression.java
+++ b/core/camel-api/src/main/java/org/apache/camel/Expression.java
@@ -30,4 +30,11 @@ public interface Expression {
* @return the value of the expression
*/
<T> T evaluate(Exchange exchange, Class<T> type);
+
+ /**
+ * Initialize the expression with the given camel context
+ */
+ default void init(CamelContext context) {
+ }
+
}
diff --git a/core/camel-api/src/main/java/org/apache/camel/Predicate.java b/core/camel-api/src/main/java/org/apache/camel/Predicate.java
index d6a81c0..2f7f3dc 100644
--- a/core/camel-api/src/main/java/org/apache/camel/Predicate.java
+++ b/core/camel-api/src/main/java/org/apache/camel/Predicate.java
@@ -31,4 +31,10 @@ public interface Predicate {
*/
boolean matches(Exchange exchange);
+ /**
+ * Initialize the predicate with the given camel context
+ */
+ default void init(CamelContext context) {
+ }
+
}
diff --git a/core/camel-base/src/main/java/org/apache/camel/processor/FilterProcessor.java b/core/camel-base/src/main/java/org/apache/camel/processor/FilterProcessor.java
index 637cc65..3c472df 100644
--- a/core/camel-base/src/main/java/org/apache/camel/processor/FilterProcessor.java
+++ b/core/camel-base/src/main/java/org/apache/camel/processor/FilterProcessor.java
@@ -17,6 +17,7 @@
package org.apache.camel.processor;
import org.apache.camel.AsyncCallback;
+import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.Predicate;
import org.apache.camel.Processor;
@@ -36,17 +37,25 @@ public class FilterProcessor extends DelegateAsyncProcessor implements Traceable
private static final Logger LOG = LoggerFactory.getLogger(FilterProcessor.class);
+ private final CamelContext context;
private String id;
private String routeId;
private final Predicate predicate;
private transient long filtered;
- public FilterProcessor(Predicate predicate, Processor processor) {
+ public FilterProcessor(CamelContext context, Predicate predicate, Processor processor) {
super(processor);
+ this.context = context;
this.predicate = predicate;
}
@Override
+ protected void doInit() throws Exception {
+ super.doInit();
+ predicate.init(context);
+ }
+
+ @Override
public boolean process(Exchange exchange, AsyncCallback callback) {
boolean matches = false;
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/builder/ExpressionClause.java b/core/camel-core-engine/src/main/java/org/apache/camel/builder/ExpressionClause.java
index ff2f968..9dd2f6f 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/builder/ExpressionClause.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/builder/ExpressionClause.java
@@ -20,6 +20,7 @@ import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Function;
+import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.Expression;
import org.apache.camel.ExpressionFactory;
@@ -939,23 +940,32 @@ public class ExpressionClause<T> implements Expression, Predicate {
return delegate.getExpressionType();
}
+ private volatile Expression expr;
+
@Override
- public <T> T evaluate(Exchange exchange, Class<T> type) {
- if (getExpressionValue() != null) {
- return getExpressionValue().evaluate(exchange, type);
- } else {
- Expression exp = delegate.getExpressionType().createExpression(exchange.getContext());
- return exp.evaluate(exchange, type);
+ public void init(CamelContext context) {
+ if (expr == null) {
+ synchronized (this) {
+ if (expr == null) {
+ expr = getExpressionValue();
+ if (expr == null) {
+ expr = delegate.getExpressionType().createExpression(context);
+ }
+ expr.init(context);
+ }
+ }
}
}
@Override
+ public <T> T evaluate(Exchange exchange, Class<T> type) {
+ init(exchange.getContext());
+ return expr.evaluate(exchange, type);
+ }
+
+ @Override
public boolean matches(Exchange exchange) {
- if (getExpressionValue() != null) {
- return new ExpressionToPredicateAdapter(getExpressionValue()).matches(exchange);
- } else {
- Expression exp = delegate.getExpressionType().createExpression(exchange.getContext());
- return new ExpressionToPredicateAdapter(exp).matches(exchange);
- }
+ init(exchange.getContext());
+ return new ExpressionToPredicateAdapter(expr).matches(exchange);
}
}
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/builder/SimpleBuilder.java b/core/camel-core-engine/src/main/java/org/apache/camel/builder/SimpleBuilder.java
index 894e5e6..d252920 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/builder/SimpleBuilder.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/builder/SimpleBuilder.java
@@ -103,60 +103,90 @@ public class SimpleBuilder implements Predicate, Expression, ExpressionResultTyp
}
@Override
- public boolean matches(Exchange exchange) {
+ public void init(CamelContext context) {
if (predicate == null) {
- predicate = createPredicate(exchange);
+ predicate = createPredicate(context);
}
+ predicate.init(context);
+ }
+
+ @Override
+ public boolean matches(Exchange exchange) {
+ init(exchange.getContext());
return predicate.matches(exchange);
}
@Override
public <T> T evaluate(Exchange exchange, Class<T> type) {
if (expression == null) {
- expression = createExpression(exchange);
+ expression = createExpression(exchange.getContext());
}
return expression.evaluate(exchange, type);
}
- private Predicate createPredicate(Exchange exchange) {
+ public Predicate createPredicate(CamelContext context) {
try {
+ Language simple = context.resolveLanguage("simple");
// resolve property placeholders
- String resolve = exchange.getContext().resolvePropertyPlaceholders(text);
- // and optional it be refer to an external script on the
- // file/classpath
- resolve = ScriptHelper.resolveOptionalExternalScript(exchange.getContext(), exchange, resolve);
- Language simple = exchange.getContext().resolveLanguage("simple");
- return simple.createPredicate(resolve);
- } catch (Exception e) {
- throw CamelExecutionException.wrapCamelExecutionException(exchange, e);
- }
- }
-
- private Expression createExpression(Exchange exchange) {
- try {
- // resolve property placeholders
- String resolve = exchange.getContext().resolvePropertyPlaceholders(text);
- // and optional it be refer to an external script on the
- // file/classpath
- resolve = ScriptHelper.resolveOptionalExternalScript(exchange.getContext(), exchange, resolve);
- Language simple = exchange.getContext().resolveLanguage("simple");
- return createSimpleExpression(simple, resolve, resultType);
+ String resolve = context.resolvePropertyPlaceholders(text);
+ // and optional it be refer to an external script on the file/classpath
+ if (ScriptHelper.hasExternalScript(resolve)) {
+ return new Predicate() {
+ @Override
+ public boolean matches(Exchange exchange) {
+ String r = ScriptHelper.resolveOptionalExternalScript(context, exchange, resolve);
+ return simple.createPredicate(r).matches(exchange);
+ }
+ @Override
+ public String toString() {
+ return text;
+ }
+ };
+ } else {
+ Predicate pred = simple.createPredicate(resolve);
+ pred.init(context);
+ return pred;
+ }
} catch (Exception e) {
- throw CamelExecutionException.wrapCamelExecutionException(exchange, e);
+ throw CamelExecutionException.wrapCamelExecutionException(null, e);
}
}
- private static Expression createSimpleExpression(Language simple, String expression, Class<?> resultType) {
+ public Expression createExpression(CamelContext context) {
if (resultType == Boolean.class || resultType == boolean.class) {
// if its a boolean as result then its a predicate
- Predicate predicate = simple.createPredicate(expression);
+ Predicate predicate = createPredicate(context);
return PredicateToExpressionAdapter.toExpression(predicate);
- } else {
- Expression exp = simple.createExpression(expression);
+ }
+ try {
+ // resolve property placeholders
+ Language simple = context.resolveLanguage("simple");
+ String resolve = context.resolvePropertyPlaceholders(text);
+ Expression exp;
+ // and optional it be refer to an external script on the file/classpath
+ if (ScriptHelper.hasExternalScript(resolve)) {
+ exp = new Expression() {
+ @Override
+ public <T> T evaluate(Exchange exchange, Class<T> type) {
+ String r = ScriptHelper.resolveOptionalExternalScript(context, exchange, resolve);
+ Expression exp = simple.createExpression(r);
+ return exp.evaluate(exchange, type);
+ }
+ @Override
+ public String toString() {
+ return text;
+ }
+ };
+ } else {
+ exp = simple.createExpression(resolve);
+ exp.init(context);
+ }
if (resultType != null) {
exp = ExpressionBuilder.convertToExpression(exp, resultType);
}
return exp;
+ } catch (Exception e) {
+ throw CamelExecutionException.wrapCamelExecutionException(null, e);
}
}
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java b/core/camel-core-engine/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java
index d2326b7..0ea00ef 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java
@@ -225,4 +225,14 @@ public class ExpressionDefinition implements Expression, Predicate, ExpressionFa
return predicate.matches(exchange);
}
+ @Override
+ public void init(CamelContext context) {
+ if (expressionValue == null) {
+ expressionValue = createExpression(context);
+ }
+ if (predicate == null) {
+ predicate = createPredicate(context);
+ }
+ }
+
}
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/ExpressionReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/ExpressionReifier.java
index 77667eb..672a1b6 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/ExpressionReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/ExpressionReifier.java
@@ -36,7 +36,7 @@ abstract class ExpressionReifier<T extends ExpressionNode> extends ProcessorReif
*/
protected FilterProcessor createFilterProcessor() throws Exception {
Processor childProcessor = createOutputsProcessor();
- return new FilterProcessor(createPredicate(), childProcessor);
+ return new FilterProcessor(camelContext, createPredicate(), childProcessor);
}
/**
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/FilterReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/FilterReifier.java
index 4d070ef..239a82b 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/FilterReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/FilterReifier.java
@@ -37,7 +37,7 @@ public class FilterReifier extends ExpressionReifier<FilterDefinition> {
protected FilterProcessor createFilterProcessor() throws Exception {
// filter EIP should have child outputs
Processor childProcessor = this.createChildProcessor(true);
- return new FilterProcessor(createPredicate(), childProcessor);
+ return new FilterProcessor(camelContext, createPredicate(), childProcessor);
}
}
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/SimpleExpressionReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/SimpleExpressionReifier.java
index c5f238d..0126cee 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/SimpleExpressionReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/SimpleExpressionReifier.java
@@ -20,6 +20,7 @@ import java.util.HashMap;
import java.util.Map;
import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
import org.apache.camel.Expression;
import org.apache.camel.Predicate;
import org.apache.camel.builder.SimpleBuilder;
@@ -34,13 +35,41 @@ public class SimpleExpressionReifier extends ExpressionReifier<SimpleExpression>
@Override
public Expression createExpression() {
+ Expression expr = createBuilder().createExpression(camelContext);
+ return new Expression() {
+ @Override
+ public <T> T evaluate(Exchange exchange, Class<T> type) {
+ return expr.evaluate(exchange, type);
+ }
+ @Override
+ public String toString() {
+ return definition.getExpression();
+ }
+ };
+ }
+
+ @Override
+ public Predicate createPredicate() {
+ Predicate pred = createBuilder().createPredicate(camelContext);
+ return new Predicate() {
+ @Override
+ public boolean matches(Exchange exchange) {
+ return pred.matches(exchange);
+ }
+ @Override
+ public String toString() {
+ return definition.getExpression();
+ }
+ };
+ }
+
+ protected SimpleBuilder createBuilder() {
String exp = parseString(definition.getExpression());
// should be true by default
boolean isTrim = parseBoolean(definition.getTrim(), true);
if (exp != null && isTrim) {
exp = exp.trim();
}
-
SimpleBuilder answer = new SimpleBuilder(exp);
Map<String, Object> props = new HashMap<>();
props.put("resultType", or(definition.getResultType(), definition.getResultTypeName()));
@@ -48,10 +77,4 @@ public class SimpleExpressionReifier extends ExpressionReifier<SimpleExpression>
return answer;
}
- @Override
- public Predicate createPredicate() {
- // SimpleBuilder is also a Predicate
- return (Predicate) createExpression();
- }
-
}
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/TryProcessorTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/TryProcessorTest.java
index 5d81d93..e978d7b 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/TryProcessorTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/TryProcessorTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.camel.processor;
+import org.apache.camel.CamelContext;
import org.apache.camel.CamelException;
import org.apache.camel.ContextTestSupport;
import org.apache.camel.Exchange;
@@ -95,6 +96,10 @@ public class TryProcessorTest extends ContextTestSupport {
public boolean matches(Exchange exchange) {
throw new RuntimeCamelException(new CamelException("Force to fail"));
}
+
+ @Override
+ public void init(CamelContext context) {
+ }
}
private class ProcessorHandle implements Processor {
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/ValidateSimpleTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/ValidateSimpleTest.java
index b463006..0498090 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/ValidateSimpleTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/ValidateSimpleTest.java
@@ -58,8 +58,8 @@ public class ValidateSimpleTest extends ContextTestSupport {
} catch (CamelExecutionException e) {
// expected
assertIsInstanceOf(PredicateValidationException.class, e.getCause());
- String s = "Validation failed for Predicate[Simple: ${body} contains 'Camel'].";
- assertTrue(e.getCause().getMessage().startsWith(s));
+ String s = "Validation failed for Predicate[${body} contains 'Camel'].";
+ assertStringContains(e.getCause().getMessage(), s);
}
assertMockEndpointsSatisfied();
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/ExpressionSupport.java b/core/camel-support/src/main/java/org/apache/camel/support/ExpressionSupport.java
index 322a742..c90810e 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/ExpressionSupport.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/ExpressionSupport.java
@@ -16,6 +16,7 @@
*/
package org.apache.camel.support;
+import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.Expression;
import org.apache.camel.Predicate;
@@ -27,6 +28,10 @@ import org.apache.camel.util.ObjectHelper;
public abstract class ExpressionSupport implements Expression, Predicate {
@Override
+ public void init(CamelContext context) {
+ }
+
+ @Override
public boolean matches(Exchange exchange) {
Object value = evaluate(exchange, Object.class);
return ObjectHelper.evaluateValuePredicate(value);
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/ExpressionToPredicateAdapter.java b/core/camel-support/src/main/java/org/apache/camel/support/ExpressionToPredicateAdapter.java
index 9c8fb6d3..51b4ab5 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/ExpressionToPredicateAdapter.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/ExpressionToPredicateAdapter.java
@@ -58,6 +58,11 @@ public final class ExpressionToPredicateAdapter implements Predicate, CamelConte
}
@Override
+ public void init(CamelContext context) {
+ expression.init(context);
+ }
+
+ @Override
public void setCamelContext(CamelContext camelContext) {
if (expression instanceof CamelContextAware) {
((CamelContextAware) expression).setCamelContext(camelContext);
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/ScriptHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/ScriptHelper.java
index 0550330..d66d02f 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/ScriptHelper.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/ScriptHelper.java
@@ -89,4 +89,14 @@ public final class ScriptHelper {
return expression;
}
+
+ public static boolean hasExternalScript(String external) {
+ if (external.startsWith("resource:")) {
+ external = external.substring(9);
+ if (ResourceHelper.hasScheme(external) && LanguageSupport.hasSimpleFunction(external)) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/builder/BinaryPredicateSupport.java b/core/camel-support/src/main/java/org/apache/camel/support/builder/BinaryPredicateSupport.java
index b7c49ec..65757c5 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/builder/BinaryPredicateSupport.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/builder/BinaryPredicateSupport.java
@@ -17,6 +17,7 @@
package org.apache.camel.support.builder;
import org.apache.camel.BinaryPredicate;
+import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.Expression;
import org.apache.camel.Predicate;
@@ -40,6 +41,12 @@ public abstract class BinaryPredicateSupport implements BinaryPredicate {
}
@Override
+ public void init(CamelContext context) {
+ left.init(context);
+ right.init(context);
+ }
+
+ @Override
public String toString() {
return left + " " + getOperationText() + " " + right;
}
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 71f1d68..d9c0a3a 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
@@ -35,6 +35,7 @@ import org.apache.camel.ExtendedCamelContext;
import org.apache.camel.InvalidPayloadException;
import org.apache.camel.Message;
import org.apache.camel.NoSuchLanguageException;
+import org.apache.camel.Predicate;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.RuntimeExchangeException;
import org.apache.camel.spi.Language;
@@ -65,9 +66,22 @@ public class ExpressionBuilder {
* @return an expression object which will return the header value
*/
public static Expression headerExpression(final String headerName) {
+ return headerExpression(simpleExpression(headerName));
+ }
+
+ /**
+ * Returns an expression for the header value with the given name
+ * <p/>
+ * Will fallback and look in properties if not found in headers.
+ *
+ * @param headerName the name of the header the expression will return
+ * @return an expression object which will return the header value
+ */
+ public static Expression headerExpression(final Expression headerName) {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
- String name = simpleExpression(headerName).evaluate(exchange, String.class);
+ String name = headerName.evaluate(exchange, String.class);
Object header = exchange.getIn().getHeader(name);
if (header == null) {
// fall back on a property
@@ -77,6 +91,11 @@ public class ExpressionBuilder {
}
@Override
+ public void init(CamelContext context) {
+ headerName.init(context);
+ }
+
+ @Override
public String toString() {
return "header(" + headerName + ")";
}
@@ -93,22 +112,7 @@ public class ExpressionBuilder {
* @return an expression object which will return the header value
*/
public static <T> Expression headerExpression(final String headerName, final Class<T> type) {
- return new ExpressionAdapter() {
- public Object evaluate(Exchange exchange) {
- String name = simpleExpression(headerName).evaluate(exchange, String.class);
- T header = exchange.getIn().getHeader(name, type);
- if (header == null) {
- // fall back on a property
- header = exchange.getProperty(name, type);
- }
- return header;
- }
-
- @Override
- public String toString() {
- return "headerAs(" + headerName + ", " + type + ")";
- }
- };
+ return headerExpression(simpleExpression(headerName), constantExpression(type));
}
/**
@@ -121,17 +125,30 @@ public class ExpressionBuilder {
* @return an expression object which will return the header value
*/
public static Expression headerExpression(final String headerName, final String typeName) {
+ return headerExpression(simpleExpression(headerName), simpleExpression(typeName));
+ }
+
+ /**
+ * Returns an expression for the header value with the given name converted to the given type
+ * <p/>
+ * Will fallback and look in properties if not found in headers.
+ *
+ * @param headerName the name of the header the expression will return
+ * @param typeName the type to convert to as a FQN class name
+ * @return an expression object which will return the header value
+ */
+ public static Expression headerExpression(final Expression headerName, final Expression typeName) {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
Class<?> type;
try {
- String text = simpleExpression(typeName).evaluate(exchange, String.class);
+ String text = typeName.evaluate(exchange, String.class);
type = exchange.getContext().getClassResolver().resolveMandatoryClass(text);
} catch (ClassNotFoundException e) {
throw CamelExecutionException.wrapCamelExecutionException(exchange, e);
}
-
- String text = simpleExpression(headerName).evaluate(exchange, String.class);
+ String text = headerName.evaluate(exchange, String.class);
Object header = exchange.getIn().getHeader(text, type);
if (header == null) {
// fall back on a property
@@ -141,6 +158,12 @@ public class ExpressionBuilder {
}
@Override
+ public void init(CamelContext context) {
+ headerName.init(context);
+ typeName.init(context);
+ }
+
+ @Override
public String toString() {
return "headerAs(" + headerName + ", " + typeName + ")";
}
@@ -276,13 +299,28 @@ public class ExpressionBuilder {
* @return an expression object which will return the bean
*/
public static Expression refExpression(final String ref) {
+ return refExpression(simpleExpression(ref));
+ }
+
+ /**
+ * Returns an expression for lookup a bean in the {@link org.apache.camel.spi.Registry}
+ *
+ * @return an expression object which will return the bean
+ */
+ public static Expression refExpression(final Expression ref) {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
- String text = simpleExpression(ref).evaluate(exchange, String.class);
+ String text = ref.evaluate(exchange, String.class);
return exchange.getContext().getRegistry().lookupByName(text);
}
@Override
+ public void init(CamelContext context) {
+ ref.init(context);
+ }
+
+ @Override
public String toString() {
return "ref(" + ref + ")";
}
@@ -384,13 +422,29 @@ public class ExpressionBuilder {
* @return an expression object which will return the property value
*/
public static Expression exchangePropertyExpression(final String propertyName) {
+ return exchangePropertyExpression(simpleExpression(propertyName));
+ }
+
+ /**
+ * Returns an expression for the property value of exchange with the given name
+ *
+ * @param propertyName the name of the property the expression will return
+ * @return an expression object which will return the property value
+ */
+ public static Expression exchangePropertyExpression(final Expression propertyName) {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
- String text = simpleExpression(propertyName).evaluate(exchange, String.class);
+ String text = propertyName.evaluate(exchange, String.class);
return exchange.getProperty(text);
}
@Override
+ public void init(CamelContext context) {
+ propertyName.init(context);
+ }
+
+ @Override
public String toString() {
return "exchangeProperty(" + propertyName + ")";
}
@@ -440,13 +494,29 @@ public class ExpressionBuilder {
* @return an expression object which will return the property value
*/
public static Expression camelContextPropertyExpression(final String propertyName) {
+ return camelContextPropertyExpression(simpleExpression(propertyName));
+ }
+
+ /**
+ * Returns an expression for the property value of the camel context with the given name
+ *
+ * @param propertyName the name of the property the expression will return
+ * @return an expression object which will return the property value
+ */
+ public static Expression camelContextPropertyExpression(final Expression propertyName) {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
- String text = simpleExpression(propertyName).evaluate(exchange, String.class);
+ String text = propertyName.evaluate(exchange, String.class);
return exchange.getContext().getGlobalOption(text);
}
@Override
+ public void init(CamelContext context) {
+ propertyName.init(context);
+ }
+
+ @Override
public String toString() {
return "camelContextProperty(" + propertyName + ")";
}
@@ -472,16 +542,37 @@ public class ExpressionBuilder {
*/
public static Expression systemPropertyExpression(final String propertyName,
final String defaultValue) {
+ Expression exprName = simpleExpression(propertyName);
+ Expression exprDeflt = simpleExpression(defaultValue);
+ return systemPropertyExpression(exprName, exprDeflt);
+ }
+
+ /**
+ * Returns an expression for a system property value with the given name
+ *
+ * @param exprName the name of the system property the expression will return
+ * @param defaultValue default value to return if no system property exists
+ * @return an expression object which will return the system property value
+ */
+ public static Expression systemPropertyExpression(final Expression exprName,
+ final Expression defaultValue) {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
- String text = simpleExpression(propertyName).evaluate(exchange, String.class);
- String text2 = simpleExpression(defaultValue).evaluate(exchange, String.class);
+ String text = exprName.evaluate(exchange, String.class);
+ String text2 = defaultValue.evaluate(exchange, String.class);
return System.getProperty(text, text2);
}
@Override
+ public void init(CamelContext context) {
+ exprName.init(context);
+ defaultValue.init(context);
+ }
+
+ @Override
public String toString() {
- return "systemProperty(" + propertyName + ")";
+ return "systemProperty(" + exprName + ")";
}
};
}
@@ -505,9 +596,24 @@ public class ExpressionBuilder {
*/
public static Expression systemEnvironmentExpression(final String propertyName,
final String defaultValue) {
+ Expression exprName = simpleExpression(propertyName);
+ Expression expDeflt = simpleExpression(defaultValue);
+ return systemEnvironmentExpression(exprName, expDeflt);
+ }
+
+ /**
+ * Returns an expression for a system environment value with the given name
+ *
+ * @param propertyName the name of the system environment the expression will return
+ * @param defaultValue default value to return if no system environment exists
+ * @return an expression object which will return the system environment value
+ */
+ public static Expression systemEnvironmentExpression(final Expression propertyName,
+ final Expression defaultValue) {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
- String text = simpleExpression(propertyName).evaluate(exchange, String.class);
+ String text = propertyName.evaluate(exchange, String.class);
String answer = null;
if (text != null) {
// lookup OS env with upper case key
@@ -521,12 +627,18 @@ public class ExpressionBuilder {
}
if (answer == null) {
- answer = simpleExpression(defaultValue).evaluate(exchange, String.class);
+ answer = defaultValue.evaluate(exchange, String.class);
}
return answer;
}
@Override
+ public void init(CamelContext context) {
+ propertyName.init(context);
+ defaultValue.init(context);
+ }
+
+ @Override
public String toString() {
return "systemEnvironment(" + propertyName + ")";
}
@@ -560,22 +672,36 @@ public class ExpressionBuilder {
*/
public static Expression languageExpression(final String language, final String expression) {
return new ExpressionAdapter() {
+ private volatile Expression expr;
+ private volatile Predicate pred;
+
public Object evaluate(Exchange exchange) {
- Language lan = exchange.getContext().resolveLanguage(language);
- if (lan != null) {
- return lan.createExpression(expression).evaluate(exchange, Object.class);
- } else {
- throw new NoSuchLanguageException(language);
- }
+ init(exchange.getContext());
+ return expr.evaluate(exchange, Object.class);
}
@Override
public boolean matches(Exchange exchange) {
- Language lan = exchange.getContext().resolveLanguage(language);
- if (lan != null) {
- return lan.createPredicate(expression).matches(exchange);
- } else {
- throw new NoSuchLanguageException(language);
+ init(exchange.getContext());
+ return pred.matches(exchange);
+ }
+
+ @Override
+ public void init(CamelContext context) {
+ if (expr == null) {
+ synchronized (this) {
+ if (expr == null) {
+ Language lan = context.resolveLanguage(language);
+ if (lan != null) {
+ pred = lan.createPredicate(expression);
+ pred.init(context);
+ expr = lan.createExpression(expression);
+ expr.init(context);
+ } else {
+ throw new NoSuchLanguageException(language);
+ }
+ }
+ }
}
}
@@ -698,11 +824,20 @@ public class ExpressionBuilder {
* to the given type
*/
public static Expression bodyExpression(final String name) {
+ return bodyExpression(simpleExpression(name));
+ }
+
+ /**
+ * Returns the expression for the exchanges inbound message body converted
+ * to the given type
+ */
+ public static Expression bodyExpression(final Expression name) {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
- String text = simpleExpression(name).evaluate(exchange, String.class);
Class<?> type;
try {
+ String text = name.evaluate(exchange, String.class);
type = exchange.getContext().getClassResolver().resolveMandatoryClass(text);
} catch (ClassNotFoundException e) {
throw CamelExecutionException.wrapCamelExecutionException(exchange, e);
@@ -711,6 +846,11 @@ public class ExpressionBuilder {
}
@Override
+ public void init(CamelContext context) {
+ name.init(context);
+ }
+
+ @Override
public String toString() {
return "bodyAs[" + name + "]";
}
@@ -722,6 +862,7 @@ public class ExpressionBuilder {
*/
public static Expression threadNameExpression() {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
return Thread.currentThread().getName();
}
@@ -738,6 +879,7 @@ public class ExpressionBuilder {
*/
public static Expression hostnameExpression() {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
return InetAddressUtil.getLocalHostNameSafe();
}
@@ -754,6 +896,7 @@ public class ExpressionBuilder {
*/
public static Expression stepIdExpression() {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
return exchange.getProperty(Exchange.STEP_ID);
}
@@ -785,6 +928,7 @@ public class ExpressionBuilder {
*/
public static <T> Expression mandatoryBodyExpression(final Class<T> type, final boolean nullBodyAllowed) {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
if (nullBodyAllowed) {
if (exchange.getIn().getBody() == null) {
@@ -811,6 +955,7 @@ public class ExpressionBuilder {
*/
public static Expression bodyTypeExpression() {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
return exchange.getIn().getBody().getClass();
}
@@ -827,6 +972,7 @@ public class ExpressionBuilder {
*/
public static Expression exchangeExpression() {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
return exchange;
}
@@ -843,6 +989,7 @@ public class ExpressionBuilder {
*/
public static Expression exchangeExpression(final Function<Exchange, Object> function) {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
return function.apply(exchange);
}
@@ -873,6 +1020,7 @@ public class ExpressionBuilder {
*/
public static Expression inMessageExpression() {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
return exchange.getIn();
}
@@ -889,6 +1037,7 @@ public class ExpressionBuilder {
*/
public static Expression inMessageExpression(final Function<Message, Object> function) {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
return function.apply(exchange.getIn());
}
@@ -905,6 +1054,7 @@ public class ExpressionBuilder {
*/
public static Expression convertToExpression(final Expression expression, final Class<?> type) {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
if (type != null) {
return expression.evaluate(exchange, type);
@@ -914,6 +1064,11 @@ public class ExpressionBuilder {
}
@Override
+ public void init(CamelContext context) {
+ expression.init(context);
+ }
+
+ @Override
public String toString() {
return "" + expression;
}
@@ -926,6 +1081,7 @@ public class ExpressionBuilder {
*/
public static Expression convertToExpression(final Expression expression, final Expression type) {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
Object result = type.evaluate(exchange, Object.class);
if (result != null) {
@@ -936,6 +1092,12 @@ public class ExpressionBuilder {
}
@Override
+ public void init(CamelContext context) {
+ expression.init(context);
+ type.init(context);
+ }
+
+ @Override
public String toString() {
return "" + expression;
}
@@ -948,15 +1110,31 @@ public class ExpressionBuilder {
*/
public static Expression tokenizeExpression(final Expression expression,
final String token) {
+ return tokenizeExpression(expression, simpleExpression(token));
+ }
+
+ /**
+ * Returns a tokenize expression which will tokenize the string with the
+ * given token
+ */
+ public static Expression tokenizeExpression(final Expression expression,
+ final Expression token) {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
- String text = simpleExpression(token).evaluate(exchange, String.class);
+ String text = token.evaluate(exchange, String.class);
Object value = expression.evaluate(exchange, Object.class);
Scanner scanner = ExchangeHelper.getScanner(exchange, value, text);
return scanner;
}
@Override
+ public void init(CamelContext context) {
+ expression.init(context);
+ token.init(context);
+ }
+
+ @Override
public String toString() {
return "tokenize(" + expression + ", " + token + ")";
}
@@ -968,6 +1146,7 @@ public class ExpressionBuilder {
*/
public static Expression skipFirstExpression(final Expression expression) {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
Object value = expression.evaluate(exchange, Object.class);
Iterator it = exchange.getContext().getTypeConverter().tryConvertTo(Iterator.class, exchange, value);
@@ -981,6 +1160,11 @@ public class ExpressionBuilder {
}
@Override
+ public void init(CamelContext context) {
+ expression.init(context);
+ }
+
+ @Override
public String toString() {
return "skipFirst(" + expression + ")";
}
@@ -994,6 +1178,7 @@ public class ExpressionBuilder {
public static Expression regexTokenizeExpression(final Expression expression,
final String regexTokenizer) {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
Object value = expression.evaluate(exchange, Object.class);
Scanner scanner = ExchangeHelper.getScanner(exchange, value, regexTokenizer);
@@ -1001,6 +1186,11 @@ public class ExpressionBuilder {
}
@Override
+ public void init(CamelContext context) {
+ expression.init(context);
+ }
+
+ @Override
public String toString() {
return "regexTokenize(" + expression + ", " + regexTokenizer + ")";
}
@@ -1009,6 +1199,7 @@ public class ExpressionBuilder {
public static Expression groupXmlIteratorExpression(final Expression expression, final String group) {
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
// evaluate expression as iterator
Iterator<?> it = expression.evaluate(exchange, Iterator.class);
@@ -1025,6 +1216,11 @@ public class ExpressionBuilder {
}
@Override
+ public void init(CamelContext context) {
+ expression.init(context);
+ }
+
+ @Override
public String toString() {
return "group " + expression + " " + group + " times";
}
@@ -1052,6 +1248,11 @@ public class ExpressionBuilder {
}
@Override
+ public void init(CamelContext context) {
+ expression.init(context);
+ }
+
+ @Override
public String toString() {
return "group " + expression + " " + group + " times";
}
@@ -1073,6 +1274,11 @@ public class ExpressionBuilder {
}
@Override
+ public void init(CamelContext context) {
+ expression.init(context);
+ }
+
+ @Override
public String toString() {
return "sort(" + expression + " by: " + comparator + ")";
}
@@ -1096,6 +1302,11 @@ public class ExpressionBuilder {
}
@Override
+ public void init(CamelContext context) {
+ expression.init(context);
+ }
+
+ @Override
public String toString() {
return "regexReplaceAll(" + expression + ", " + pattern.pattern() + ")";
}
@@ -1111,6 +1322,7 @@ public class ExpressionBuilder {
final Pattern pattern = Pattern.compile(regex);
return new ExpressionAdapter() {
+ @Override
public Object evaluate(Exchange exchange) {
String text = expression.evaluate(exchange, String.class);
String replacement = replacementExpression.evaluate(exchange, String.class);
@@ -1121,6 +1333,12 @@ public class ExpressionBuilder {
}
@Override
+ public void init(CamelContext context) {
+ expression.init(context);
+ replacementExpression.init(context);
+ }
+
+ @Override
public String toString() {
return "regexReplaceAll(" + expression + ", " + pattern.pattern() + ")";
}
@@ -1137,6 +1355,12 @@ public class ExpressionBuilder {
}
@Override
+ public void init(CamelContext context) {
+ left.init(context);
+ right.init(context);
+ }
+
+ @Override
public String toString() {
return "append(" + left + ", " + right + ")";
}
@@ -1153,6 +1377,12 @@ public class ExpressionBuilder {
}
@Override
+ public void init(CamelContext context) {
+ left.init(context);
+ right.init(context);
+ }
+
+ @Override
public String toString() {
return "prepend(" + left + ", " + right + ")";
}
@@ -1192,6 +1422,13 @@ public class ExpressionBuilder {
}
@Override
+ public void init(CamelContext context) {
+ for (Expression expression : expressions) {
+ expression.init(context);
+ }
+ }
+
+ @Override
public String toString() {
if (description != null) {
return description;
@@ -1252,24 +1489,24 @@ public class ExpressionBuilder {
}
public static Expression simpleExpression(final String expression) {
- return new ExpressionAdapter() {
- public Object evaluate(Exchange exchange) {
- if (LanguageSupport.hasSimpleFunction(expression)) {
+ if (LanguageSupport.hasSimpleFunction(expression)) {
+ return new ExpressionAdapter() {
+ public Object evaluate(Exchange exchange) {
// resolve language using context to have a clear separation of packages
// must call evaluate to return the nested language evaluate when evaluating
// stacked expressions
Language language = exchange.getContext().resolveLanguage("simple");
return language.createExpression(expression).evaluate(exchange, Object.class);
- } else {
- return expression;
}
- }
- @Override
- public String toString() {
- return "simple(" + expression + ")";
- }
- };
+ @Override
+ public String toString() {
+ return "simple(" + expression + ")";
+ }
+ };
+ } else {
+ return constantExpression(expression);
+ }
}
public static Expression beanExpression(final String expression) {
@@ -1423,4 +1660,5 @@ public class ExpressionBuilder {
throw new IllegalArgumentException("Failed to set property " + name + " on " + bean + ". Reason: " + e, e);
}
}
+
}
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/builder/ValueBuilder.java b/core/camel-support/src/main/java/org/apache/camel/support/builder/ValueBuilder.java
index 833de82..915a2fa 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/builder/ValueBuilder.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/builder/ValueBuilder.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
+import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.Expression;
import org.apache.camel.Predicate;
@@ -36,6 +37,11 @@ public class ValueBuilder implements Expression, Predicate {
}
@Override
+ public void init(CamelContext context) {
+ expression.init(context);
+ }
+
+ @Override
public <T> T evaluate(Exchange exchange, Class<T> type) {
return expression.evaluate(exchange, type);
}