You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2020/10/21 18:45:46 UTC

[camel] branch master updated: CAMEL-15730: camel-core - Untangle simple refier from builder package and use language spi to be decoupled like the other language reifier does.

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 <cl...@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.
      *