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
commit eb06b1f4ba8e65356fb0162cdeb514f0f3f53868 Author: Claus Ibsen <[email protected]> AuthorDate: Thu Oct 1 13:10:52 2020 +0200 CAMEL-15605: Languages should be singleton for better performance. --- .../apache/camel/language/bean/BeanLanguage.java | 89 +++++----------------- .../main/java/org/apache/camel/spi/Language.java | 28 +++++++ .../camel/impl/engine/AbstractCamelContext.java | 2 + .../camel/model/language/MethodCallExpression.java | 6 +- .../camel/reifier/language/ExpressionReifier.java | 13 +++- .../language/JsonPathExpressionReifier.java | 2 + .../language/MethodCallExpressionReifier.java | 30 ++++++-- .../reifier/language/SimpleExpressionReifier.java | 27 +++++-- .../language/TokenizerExpressionReifier.java | 2 + .../language/XMLTokenizerExpressionReifier.java | 2 + .../reifier/language/XPathExpressionReifier.java | 2 + .../reifier/language/XQueryExpressionReifier.java | 2 + .../camel/language/tokenizer/TokenizeLanguage.java | 8 +- .../support/ExpressionToPredicateAdapter.java | 3 + .../camel/support/builder/ExpressionBuilder.java | 14 ++-- 15 files changed, 133 insertions(+), 97 deletions(-) diff --git a/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanLanguage.java b/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanLanguage.java index c85395d..70d6692 100644 --- a/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanLanguage.java +++ b/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanLanguage.java @@ -16,13 +16,12 @@ */ package org.apache.camel.language.bean; -import org.apache.camel.CamelContext; +import java.util.Map; + import org.apache.camel.Expression; import org.apache.camel.Predicate; -import org.apache.camel.spi.GeneratedPropertyConfigurer; import org.apache.camel.support.ExpressionToPredicateAdapter; import org.apache.camel.support.LanguageSupport; -import org.apache.camel.support.component.PropertyConfigurerSupport; import org.apache.camel.util.StringHelper; /** @@ -37,88 +36,42 @@ import org.apache.camel.util.StringHelper; * As of Camel 1.5 the bean language also supports invoking a provided bean by its classname or the bean itself. */ @org.apache.camel.spi.annotations.Language("bean") -public class BeanLanguage extends LanguageSupport implements GeneratedPropertyConfigurer { - - private Object bean; - private Class<?> beanType; - private String ref; - private String method; +public class BeanLanguage extends LanguageSupport { public BeanLanguage() { } @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 !"); - } - switch (ignoreCase ? name.toLowerCase() : name) { - case "bean": - setBean(PropertyConfigurerSupport.property(camelContext, Object.class, value)); - return true; - case "beantype": - case "beanType": - setBeanType(PropertyConfigurerSupport.property(camelContext, Class.class, value)); - return true; - case "ref": - setRef(PropertyConfigurerSupport.property(camelContext, String.class, value)); - return true; - case "method": - setMethod(PropertyConfigurerSupport.property(camelContext, String.class, value)); - return true; - default: - return false; - } - } - - public Object getBean() { - return bean; - } - - public void setBean(Object bean) { - this.bean = bean; - } - - public Class<?> getBeanType() { - return beanType; - } - - public void setBeanType(Class<?> beanType) { - this.beanType = beanType; - } - - public String getRef() { - return ref; - } - - public void setRef(String ref) { - this.ref = ref; - } - - public String getMethod() { - return method; - } - - public void setMethod(String method) { - this.method = method; + public Predicate createPredicate(String expression) { + return ExpressionToPredicateAdapter.toPredicate(createExpression(expression)); } @Override - public Predicate createPredicate(String expression) { - return ExpressionToPredicateAdapter.toPredicate(createExpression(expression)); + public Predicate createPredicate(Map<String, Object> properties) { + return ExpressionToPredicateAdapter.toPredicate(createExpression(properties)); } @Override - public Expression createExpression(String expression) { - // favour using the configured options + public Expression createExpression(Map<String, Object> properties) { + Object bean = properties.get("bean"); + Class<?> beanType = (Class<?>) properties.get("beanType"); + String ref = (String) properties.get("ref"); + String method = (String) properties.get("method"); + if (bean != null) { return new BeanExpression(bean, method); } else if (beanType != null) { return new BeanExpression(beanType, method); } else if (ref != null) { return new BeanExpression(ref, method); + } else { + throw new IllegalArgumentException("Bean language requires bean, beanType, or ref argument"); } + } + @Override + public Expression createExpression(String expression) { + // favour using the configured options String beanName = expression; String method = null; @@ -147,8 +100,4 @@ public class BeanLanguage extends LanguageSupport implements GeneratedPropertyCo return new BeanExpression(beanName, method); } - @Override - public boolean isSingleton() { - return false; - } } diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/Language.java b/core/camel-api/src/main/java/org/apache/camel/spi/Language.java index a666d4d5..1376c76 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/Language.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/Language.java @@ -16,6 +16,8 @@ */ package org.apache.camel.spi; +import java.util.Map; + import org.apache.camel.Expression; import org.apache.camel.Predicate; @@ -39,4 +41,30 @@ public interface Language { * @return the created expression */ Expression createExpression(String expression); + + /** + * Creates an expression based on the given inputs properties + * + * This is used for languages that have been configured with custom properties + * most noticeable for xpath/xquery/tokenizer languages that have several options. + * + * @param properties arguments + * @return the created predicate + */ + default Predicate createPredicate(Map<String, Object> properties) { + return null; + } + + /** + * Creates an expression based on the given inputs properties + * + * This is used for languages that have been configured with custom properties + * most noticeable for xpath/xquery/tokenizer languages that have several options. + * + * @param properties arguments + * @return the created expression + */ + default Expression createExpression(Map<String, Object> properties) { + return null; + } } diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java index e80f52f..93c92b5 100644 --- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java +++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java @@ -1637,6 +1637,8 @@ public abstract class AbstractCamelContext extends BaseService @Override public Language resolveLanguage(String language) { + LOG.debug("Resolving language: {}", language); + Language answer; synchronized (languages) { // as first iteration, check if there is a language instance for the given name diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/language/MethodCallExpression.java b/core/camel-core-engine/src/main/java/org/apache/camel/model/language/MethodCallExpression.java index 82870b0..4be866e 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/model/language/MethodCallExpression.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/model/language/MethodCallExpression.java @@ -51,7 +51,7 @@ public class MethodCallExpression extends ExpressionDefinition { } public MethodCallExpression(String beanName, String method) { - super((String) null); // we dont use @XmlValue but the attributes instead + super(""); // we dont use @XmlValue but the attributes instead if (beanName != null && beanName.startsWith("ref:")) { beanName = beanName.substring(4); } else if (beanName != null && beanName.startsWith("bean:")) { @@ -66,7 +66,7 @@ public class MethodCallExpression extends ExpressionDefinition { } public MethodCallExpression(Object instance, String method) { - super((String) null); // we dont use @XmlValue but the attributes instead + super(""); // we dont use @XmlValue but the attributes instead // must use setter as they have special logic setInstance(instance); setMethod(method); @@ -77,7 +77,7 @@ public class MethodCallExpression extends ExpressionDefinition { } public MethodCallExpression(Class<?> type, String method) { - super((String) null); // we dont use @XmlValue but the attributes instead + super(""); // we dont use @XmlValue but the attributes instead setBeanType(type); setBeanTypeName(type.getName()); setMethod(method); diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/ExpressionReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/ExpressionReifier.java index 01e7714..526615d 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/ExpressionReifier.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/ExpressionReifier.java @@ -132,7 +132,7 @@ public class ExpressionReifier<T extends ExpressionDefinition> extends AbstractR // the classpath/file etc exp = ScriptHelper.resolveOptionalExternalScript(camelContext, exp); configureLanguage(language); - expression = language.createExpression(exp); + expression = createExpression(language, exp); configureExpression(expression); } } @@ -168,7 +168,7 @@ public class ExpressionReifier<T extends ExpressionDefinition> extends AbstractR // the classpath/file etc exp = ScriptHelper.resolveOptionalExternalScript(camelContext, exp); configureLanguage(language); - predicate = language.createPredicate(exp); + predicate = createPredicate(language, exp); configurePredicate(predicate); } } @@ -180,6 +180,14 @@ public class ExpressionReifier<T extends ExpressionDefinition> extends AbstractR return predicate; } + protected Expression createExpression(Language language, String exp) { + return language.createExpression(exp); + } + + protected Predicate createPredicate(Language language, String exp) { + return language.createPredicate(exp); + } + protected void configureLanguage(Language language) { } @@ -201,6 +209,7 @@ public class ExpressionReifier<T extends ExpressionDefinition> extends AbstractR } } + @Deprecated protected void setProperties(Object target, Map<String, Object> properties) { properties.entrySet().removeIf(e -> e.getValue() == null); diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/JsonPathExpressionReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/JsonPathExpressionReifier.java index 471c0c3..669386d 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/JsonPathExpressionReifier.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/JsonPathExpressionReifier.java @@ -27,6 +27,8 @@ import org.apache.camel.model.language.JsonPathExpression; public class JsonPathExpressionReifier extends ExpressionReifier<JsonPathExpression> { + // TODO: Update me + public JsonPathExpressionReifier(CamelContext camelContext, ExpressionDefinition definition) { super(camelContext, (JsonPathExpression) definition); } diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/MethodCallExpressionReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/MethodCallExpressionReifier.java index b736416..e6c3b52 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/MethodCallExpressionReifier.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/MethodCallExpressionReifier.java @@ -20,7 +20,9 @@ import java.util.HashMap; import java.util.Map; import org.apache.camel.CamelContext; +import org.apache.camel.Expression; import org.apache.camel.Predicate; +import org.apache.camel.RuntimeCamelException; import org.apache.camel.model.language.ExpressionDefinition; import org.apache.camel.model.language.MethodCallExpression; import org.apache.camel.spi.Language; @@ -31,18 +33,36 @@ public class MethodCallExpressionReifier extends ExpressionReifier<MethodCallExp super(camelContext, (MethodCallExpression) definition); } - protected void configureLanguage(Language language) { - Map<String, Object> properties = new HashMap<>(); + protected Map<String, Object> createProperties() { + Map<String, Object> properties = new HashMap<>(4); properties.put("bean", definition.getInstance()); properties.put("beanType", or(definition.getBeanType(), definition.getBeanTypeName())); properties.put("ref", definition.getRef()); properties.put("method", definition.getMethod()); - setProperties(language, properties); + return properties; } @Override - public Predicate createPredicate() { - return (Predicate) createExpression(); + protected void configureLanguage(Language language) { + if (definition.getBeanType() == null && definition.getBeanTypeName() != null) { + try { + Class<?> clazz = camelContext.getClassResolver().resolveMandatoryClass(definition.getBeanTypeName()); + definition.setBeanType(clazz); + } catch (ClassNotFoundException e) { + throw RuntimeCamelException.wrapRuntimeException(e); + } + } } + @Override + protected Expression createExpression(Language language, String exp) { + // method call does not use the string exp so its not in use + return language.createExpression(createProperties()); + } + + @Override + protected Predicate createPredicate(Language language, String exp) { + // method call does not use the string exp so its not in use + return language.createPredicate(createProperties()); + } } 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 f740b3b..2bc0a3b 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 @@ -16,16 +16,15 @@ */ package org.apache.camel.reifier.language; -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.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; public class SimpleExpressionReifier extends ExpressionReifier<SimpleExpression> { @@ -68,15 +67,29 @@ public class SimpleExpressionReifier extends ExpressionReifier<SimpleExpression> protected SimpleBuilder createBuilder() { String exp = parseString(definition.getExpression()); // should be true by default - boolean isTrim = parseBoolean(definition.getTrim(), true); + boolean isTrim = true; + if (definition.getTrim() != null) { + isTrim = parseBoolean(definition.getTrim()); + } 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())); - setProperties(answer, props); + answer.setResultType(definition.getResultType()); return answer; } + @Override + protected void configureLanguage(Language language) { + if (definition.getResultType() == null && definition.getResultTypeName() != null) { + Class<?> clazz; + try { + clazz = camelContext.getClassResolver().resolveMandatoryClass(definition.getResultTypeName()); + } catch (ClassNotFoundException e) { + throw RuntimeCamelException.wrapRuntimeException(e); + } + definition.setResultType(clazz); + } + } + } diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/TokenizerExpressionReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/TokenizerExpressionReifier.java index ef08490..0f12413 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/TokenizerExpressionReifier.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/TokenizerExpressionReifier.java @@ -29,6 +29,8 @@ import org.apache.camel.support.ExpressionToPredicateAdapter; public class TokenizerExpressionReifier extends ExpressionReifier<TokenizerExpression> { + // TODO: Update me + public TokenizerExpressionReifier(CamelContext camelContext, ExpressionDefinition definition) { super(camelContext, (TokenizerExpression) definition); } diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XMLTokenizerExpressionReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XMLTokenizerExpressionReifier.java index 2676560..aac9085 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XMLTokenizerExpressionReifier.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XMLTokenizerExpressionReifier.java @@ -28,6 +28,8 @@ import org.apache.camel.spi.NamespaceAware; public class XMLTokenizerExpressionReifier extends ExpressionReifier<XMLTokenizerExpression> { + // TODO: Update me + public XMLTokenizerExpressionReifier(CamelContext camelContext, ExpressionDefinition definition) { super(camelContext, (XMLTokenizerExpression) definition); } diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XPathExpressionReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XPathExpressionReifier.java index 6cae1e0..a34af0f 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XPathExpressionReifier.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XPathExpressionReifier.java @@ -28,6 +28,8 @@ import org.apache.camel.spi.NamespaceAware; public class XPathExpressionReifier extends ExpressionReifier<XPathExpression> { + // TODO: Update me + public XPathExpressionReifier(CamelContext camelContext, ExpressionDefinition definition) { super(camelContext, (XPathExpression) definition); } diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XQueryExpressionReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XQueryExpressionReifier.java index 2e0985a..4fb2ee2 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XQueryExpressionReifier.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XQueryExpressionReifier.java @@ -28,6 +28,8 @@ import org.apache.camel.spi.NamespaceAware; public class XQueryExpressionReifier extends ExpressionReifier<XQueryExpression> { + // TODO: Update me + public XQueryExpressionReifier(CamelContext camelContext, ExpressionDefinition definition) { super(camelContext, (XQueryExpression) definition); } diff --git a/core/camel-core-languages/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java b/core/camel-core-languages/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java index 3007be6..20df970 100644 --- a/core/camel-core-languages/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java +++ b/core/camel-core-languages/src/main/java/org/apache/camel/language/tokenizer/TokenizeLanguage.java @@ -61,7 +61,7 @@ public class TokenizeLanguage implements Language, IsSingleton, PropertyConfigur TokenizeLanguage language = new TokenizeLanguage(); language.setToken(token); language.setRegex(regex); - return language.createExpression(null); + return language.createExpression((String) null); } public static Expression tokenize(String headerName, String token) { @@ -73,7 +73,7 @@ public class TokenizeLanguage implements Language, IsSingleton, PropertyConfigur language.setHeaderName(headerName); language.setToken(token); language.setRegex(regex); - return language.createExpression(null); + return language.createExpression((String) null); } public static Expression tokenizePair(String startToken, String endToken, boolean includeTokens) { @@ -81,7 +81,7 @@ public class TokenizeLanguage implements Language, IsSingleton, PropertyConfigur language.setToken(startToken); language.setEndToken(endToken); language.setIncludeTokens(includeTokens); - return language.createExpression(null); + return language.createExpression((String) null); } public static Expression tokenizeXML(String tagName, String inheritNamespaceTagName) { @@ -89,7 +89,7 @@ public class TokenizeLanguage implements Language, IsSingleton, PropertyConfigur language.setToken(tagName); language.setInheritNamespaceTagName(inheritNamespaceTagName); language.setXml(true); - return language.createExpression(null); + return language.createExpression((String) null); } @Override 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 f8e3808..e2ecf1f 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 @@ -54,6 +54,9 @@ public final class ExpressionToPredicateAdapter implements Predicate, CamelConte * Converts the given expression into an {@link Predicate} */ public static Predicate toPredicate(final Expression expression) { + if (expression instanceof Predicate) { + return (Predicate) expression; + } return new ExpressionToPredicateAdapter(expression); } 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 19b8fa4..c180124 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 @@ -20,6 +20,7 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.util.Collection; import java.util.Comparator; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -1529,17 +1530,18 @@ public class ExpressionBuilder { }; } - public static Expression beanExpression(final Object bean, final String expression) { + public static Expression beanExpression(final Object bean, final String method) { return new ExpressionAdapter() { public Object evaluate(Exchange exchange) { Language language = exchange.getContext().resolveLanguage("bean"); - setProperty(exchange.getContext(), language, "bean", bean); - setProperty(exchange.getContext(), language, "method", expression); - return language.createExpression(null).evaluate(exchange, Object.class); + Map<String, Object> properties = new HashMap<>(2); + properties.put("bean", bean); + properties.put("method", method); + return language.createExpression(properties).evaluate(exchange, Object.class); } public String toString() { - return "bean(" + bean + ", " + expression + ")"; + return "bean(" + bean + ", " + method + ")"; } }; } @@ -1623,7 +1625,7 @@ public class ExpressionBuilder { setProperty(exchange.getContext(), language, "namespaces", namespaces); } setProperty(exchange.getContext(), language, "path", path); - return language.createExpression(null).evaluate(exchange, Object.class); + return language.createExpression((String)null).evaluate(exchange, Object.class); } @Override
