This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/master by this push: new b3e2fff CAMEL-15730: camel-core - Untangle simple refier from builder package and use language spi to be decoupled like the other language reifier does. b3e2fff is described below commit b3e2fff377bc6205453af289da0dbe876e3f1a19 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Wed Oct 21 20:44:43 2020 +0200 CAMEL-15730: camel-core - Untangle simple refier from builder package and use language spi to be decoupled like the other language reifier does. --- .../org/apache/camel/builder/SimpleBuilder.java | 116 ++++----------------- .../apache/camel/model/ExpressionNodeHelper.java | 13 ++- .../reifier/language/SimpleExpressionReifier.java | 36 +++---- .../camel/language/simple/SimpleLanguage.java | 71 ++++++++++++- .../org/apache/camel/support/LanguageSupport.java | 13 ++- 5 files changed, 122 insertions(+), 127 deletions(-) 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 e681dd2..1a35247 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 @@ -17,15 +17,11 @@ package org.apache.camel.builder; import org.apache.camel.CamelContext; -import org.apache.camel.CamelExecutionException; import org.apache.camel.Exchange; import org.apache.camel.Expression; import org.apache.camel.Predicate; import org.apache.camel.spi.ExpressionResultTypeAware; import org.apache.camel.spi.Language; -import org.apache.camel.support.LanguageSupport; -import org.apache.camel.support.PredicateToExpressionAdapter; -import org.apache.camel.support.ScriptHelper; /** * Creates an Simple language builder. @@ -38,6 +34,7 @@ public class SimpleBuilder implements Predicate, Expression, ExpressionResultTyp private final String text; private Class<?> resultType; // cache the expression/predicate + private Language simple; private volatile Expression expression; private volatile Predicate predicate; @@ -87,109 +84,42 @@ public class SimpleBuilder implements Predicate, Expression, ExpressionResultTyp } @Override - public void init(CamelContext context) { - } - - @Override - public boolean matches(Exchange exchange) { - if (predicate == null) { - predicate = createPredicate(exchange.getContext()); - } - return predicate.matches(exchange); + public String toString() { + return text; } @Override public <T> T evaluate(Exchange exchange, Class<T> type) { if (expression == null) { - expression = createExpression(exchange.getContext()); - } - return expression.evaluate(exchange, type); - } - - public Predicate createPredicate(CamelContext context) { - try { - Language simple = context.resolveLanguage("simple"); - // resolve property placeholders - String resolve = context.resolvePropertyPlaceholders(text); - boolean external = ScriptHelper.hasExternalScript(resolve); - Predicate pred; - // and optional it be refer to an external script on the file/classpath - if (external && LanguageSupport.hasSimpleFunction(resolve)) { - // need to lazy eval as its a dynamic resource - pred = 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 if (external) { - // its a static resource so evaluate it eager - String r = ScriptHelper.resolveOptionalExternalScript(context, null, resolve); - pred = simple.createPredicate(r); + if (simple == null) { + init(exchange.getContext()); + } + if (resultType != null) { + Object[] properties = new Object[2]; + properties[0] = resultType; + expression = simple.createExpression(text, properties); } else { - pred = simple.createPredicate(resolve); + expression = simple.createExpression(text); } - pred.init(context); - return pred; - } catch (Exception e) { - throw CamelExecutionException.wrapCamelExecutionException(null, e); + expression.init(exchange.getContext()); } + return expression.evaluate(exchange, type); } - public Expression createExpression(CamelContext context) { - if (resultType == Boolean.class || resultType == boolean.class) { - // if its a boolean as result then its a predicate - Predicate predicate = createPredicate(context); - return PredicateToExpressionAdapter.toExpression(predicate); - } - try { - // resolve property placeholders - Language simple = context.resolveLanguage("simple"); - String resolve = context.resolvePropertyPlaceholders(text); - boolean external = ScriptHelper.hasExternalScript(resolve); - Expression exp; - // and optional it be refer to an external script on the file/classpath - if (external && ScriptHelper.hasExternalScript(resolve)) { - // need to lazy eval as its a dynamic resource - 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 if (external) { - // its a static resource so evaluate it eager - String r = ScriptHelper.resolveOptionalExternalScript(context, null, resolve); - exp = simple.createExpression(r); - } else { - exp = simple.createExpression(resolve); - } - if (resultType != null) { - exp = ExpressionBuilder.convertToExpression(exp, resultType); + @Override + public boolean matches(Exchange exchange) { + if (predicate == null) { + if (simple == null) { + init(exchange.getContext()); } - exp.init(context); - return exp; - } catch (Exception e) { - throw CamelExecutionException.wrapCamelExecutionException(null, e); + predicate = simple.createPredicate(text); + predicate.init(exchange.getContext()); } + return predicate.matches(exchange); } @Override - public String toString() { - return text; + public void init(CamelContext context) { + simple = context.resolveLanguage("simple"); } - } diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/ExpressionNodeHelper.java b/core/camel-core-engine/src/main/java/org/apache/camel/model/ExpressionNodeHelper.java index 09387e2..c94fbac 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/model/ExpressionNodeHelper.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/model/ExpressionNodeHelper.java @@ -45,10 +45,9 @@ public final class ExpressionNodeHelper { public static ExpressionDefinition toExpressionDefinition(Expression expression) { if (expression instanceof SimpleBuilder) { SimpleBuilder builder = (SimpleBuilder) expression; - // we keep the original expression by using the constructor that - // accepts an expression - SimpleExpression answer = new SimpleExpression(builder); - answer.setExpression(builder.getText()); + // only transfer over the expression text and result type from SimpleBuilder + // as we want to use the definition objects in the route graph + SimpleExpression answer = new SimpleExpression(builder.getText()); answer.setResultType(builder.getResultType()); return answer; } else if (expression instanceof ExpressionResultTypeAware @@ -84,9 +83,9 @@ public final class ExpressionNodeHelper { public static ExpressionDefinition toExpressionDefinition(Predicate predicate) { if (predicate instanceof SimpleBuilder) { SimpleBuilder builder = (SimpleBuilder) predicate; - // we keep the original expression by using the constructor that - // accepts an expression - SimpleExpression answer = new SimpleExpression(builder); + // only transfer over the expression text and result type from SimpleBuilder + // as we want to use the definition objects in the route graph + SimpleExpression answer = new SimpleExpression(builder.getText()); answer.setExpression(builder.getText()); return answer; } else if (predicate instanceof ExpressionResultTypeAware 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 3731ba3..3ab8647 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,7 +20,6 @@ import org.apache.camel.CamelContext; import org.apache.camel.Expression; import org.apache.camel.Predicate; import org.apache.camel.RuntimeCamelException; -import org.apache.camel.builder.SimpleBuilder; import org.apache.camel.model.language.ExpressionDefinition; import org.apache.camel.model.language.SimpleExpression; import org.apache.camel.spi.Language; @@ -32,37 +31,26 @@ public class SimpleExpressionReifier extends ExpressionReifier<SimpleExpression> } @Override - public Expression createExpression() { - return createBuilder(definition.getExpression()).createExpression(camelContext); - } - - @Override - public Predicate createPredicate() { - return createBuilder(definition.getExpression()).createPredicate(camelContext); - } - - protected SimpleBuilder createBuilder(String expression) { - String exp = parseString(expression); - // should be true by default - boolean isTrim = parseBoolean(definition.getTrim(), true); - if (exp != null && isTrim) { - exp = exp.trim(); - } - SimpleBuilder answer = new SimpleBuilder(exp); - // need to configure result type which can be set via xml dsl vs java dsl - configureLanguage(null); - answer.setResultType(definition.getResultType()); - return answer; + public boolean isResolveOptionalExternalScriptEnabled() { + // simple language will handle to resolve external scripts as they can be dynamic using simple language itself + return false; } @Override protected Expression createExpression(Language language, String exp) { - return createBuilder(exp); + return language.createExpression(exp, createProperties()); } @Override protected Predicate createPredicate(Language language, String exp) { - return createBuilder(exp); + return language.createPredicate(exp, createProperties()); + } + + private Object[] createProperties() { + Object[] properties = new Object[2]; + properties[0] = definition.getResultType(); + properties[1] = parseBoolean(definition.getTrim()); + return properties; } @Override diff --git a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java index 6c0415f..4e67a11 100644 --- a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java +++ b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleLanguage.java @@ -18,6 +18,7 @@ package org.apache.camel.language.simple; import java.util.Map; +import org.apache.camel.Exchange; import org.apache.camel.Expression; import org.apache.camel.Predicate; import org.apache.camel.StaticService; @@ -27,6 +28,7 @@ import org.apache.camel.support.LRUCache; import org.apache.camel.support.LRUCacheFactory; import org.apache.camel.support.LanguageSupport; import org.apache.camel.support.PredicateToExpressionAdapter; +import org.apache.camel.support.ScriptHelper; import org.apache.camel.support.builder.ExpressionBuilder; import org.apache.camel.util.ObjectHelper; import org.slf4j.Logger; @@ -104,7 +106,30 @@ public class SimpleLanguage extends LanguageSupport implements StaticService { Predicate answer = cachePredicate != null ? cachePredicate.get(expression) : null; if (answer == null) { - expression = loadResource(expression); + if (isDynamicResource(expression)) { + // we need to load the resource dynamic based on evaluating the expression via the exchange + // so create an embedded expression as result + // need to lazy eval as its a dynamic resource + final String text = expression; + return new Predicate() { + @Override + public boolean matches(Exchange exchange) { + String r = ScriptHelper.resolveOptionalExternalScript(getCamelContext(), exchange, text); + Predicate pred = SimpleLanguage.this.createPredicate(r); + pred.init(getCamelContext()); + return pred.matches(exchange); + } + + @Override + public String toString() { + return text; + } + }; + } + + if (isStaticResource(expression)) { + expression = loadResource(expression); + } SimplePredicateParser parser = new SimplePredicateParser(getCamelContext(), expression, allowEscape, cacheExpression); @@ -119,13 +144,55 @@ public class SimpleLanguage extends LanguageSupport implements StaticService { } @Override + public Predicate createPredicate(String expression, Object[] properties) { + boolean trim = property(boolean.class, properties, 1, true); + if (trim) { + expression = expression.trim(); + } + return createPredicate(expression); + } + + @Override + public Expression createExpression(String expression, Object[] properties) { + Class<?> resultType = property(Class.class, properties, 0, null); + boolean trim = property(boolean.class, properties, 1, true); + if (trim) { + expression = expression.trim(); + } + return createExpression(expression, resultType); + } + + @Override public Expression createExpression(String expression) { ObjectHelper.notNull(expression, "expression"); Expression answer = cacheExpression != null ? cacheExpression.get(expression) : null; if (answer == null) { - expression = loadResource(expression); + if (isDynamicResource(expression)) { + // we need to load the resource dynamic based on evaluating the expression via the exchange + // so create an embedded expression as result + // need to lazy eval as its a dynamic resource + final String text = expression; + return new Expression() { + @Override + public <T> T evaluate(Exchange exchange, Class<T> type) { + String r = ScriptHelper.resolveOptionalExternalScript(getCamelContext(), exchange, text); + Expression exp = SimpleLanguage.this.createExpression(r); + exp.init(getCamelContext()); + return exp.evaluate(exchange, type); + } + + @Override + public String toString() { + return text; + } + }; + } + + if (isStaticResource(expression)) { + expression = loadResource(expression); + } SimpleExpressionParser parser = new SimpleExpressionParser(getCamelContext(), expression, allowEscape, cacheExpression); diff --git a/core/camel-support/src/main/java/org/apache/camel/support/LanguageSupport.java b/core/camel-support/src/main/java/org/apache/camel/support/LanguageSupport.java index bb5a0e7..6937474 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/LanguageSupport.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/LanguageSupport.java @@ -66,7 +66,8 @@ public abstract class LanguageSupport implements Language, IsSingleton, CamelCon * @throws ExpressionIllegalSyntaxException is thrown if error loading the resource */ protected String loadResource(String expression) throws ExpressionIllegalSyntaxException { - if (camelContext != null && expression.startsWith(RESOURCE)) { + // we can only load static resources (if they are dynamic then simple will load them on-demand) + if (camelContext != null && isStaticResource(expression)) { String uri = expression.substring(RESOURCE.length()); InputStream is = null; try { @@ -81,6 +82,16 @@ public abstract class LanguageSupport implements Language, IsSingleton, CamelCon return expression; } + // TODO: javadoc + + protected boolean isStaticResource(String expression) { + return expression.startsWith(RESOURCE) && !hasSimpleFunction(expression); + } + + protected boolean isDynamicResource(String expression) { + return expression.startsWith(RESOURCE) && hasSimpleFunction(expression); + } + /** * Does the expression include a simple function. *