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 3f0349f79be94141afacb4edfd44a25b7deb2296 Author: Claus Ibsen <[email protected]> AuthorDate: Thu Oct 1 17:06:04 2020 +0200 CAMEL-15605: Languages should be singleton for better performance. --- .../language/TokenizerExpressionReifier.java | 41 ++++++----- .../language/XMLTokenizerExpressionReifier.java | 37 +++++++--- .../camel/language/tokenizer/TokenizeLanguage.java | 82 +++++++--------------- .../apache/camel/language/LanguageServiceTest.java | 18 ----- .../org/apache/camel/language/TokenizerTest.java | 4 +- .../org/apache/camel/support/CustomizersTest.java | 8 ++- .../support/PredicateToExpressionAdapter.java | 3 + .../language/xtokenizer/XMLTokenizeLanguage.java | 21 ++++-- 8 files changed, 103 insertions(+), 111 deletions(-) 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 0f12413..02576d4 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,32 +29,29 @@ 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); } - @Override - protected void configureLanguage(Language language) { - Map<String, Object> props = new HashMap<>(); + protected Map<String, Object> createProperties() { + Map<String, Object> properties = new HashMap<>(10); // special for new line tokens, if defined from XML then its 2 // characters, so we replace that back to a single char String token = definition.getToken(); if (token.startsWith("\\n")) { token = '\n' + token.substring(2); } - props.put("token", token); - props.put("endToken", definition.getEndToken()); - props.put("inheritNamespaceTagName", definition.getInheritNamespaceTagName()); - props.put("headerName", definition.getHeaderName()); - props.put("groupDelimiter", definition.getGroupDelimiter()); - props.put("regex", definition.getRegex()); - props.put("xml", definition.getXml()); - props.put("includeTokens", definition.getIncludeTokens()); - props.put("group", definition.getGroup()); - props.put("skipFirst", definition.getSkipFirst()); - setProperties(language, props); + properties.put("token", token); + properties.put("endToken", definition.getEndToken()); + properties.put("inheritNamespaceTagName", definition.getInheritNamespaceTagName()); + properties.put("headerName", definition.getHeaderName()); + properties.put("groupDelimiter", definition.getGroupDelimiter()); + properties.put("regex", definition.getRegex()); + properties.put("xml", definition.getXml()); + properties.put("includeTokens", definition.getIncludeTokens()); + properties.put("group", definition.getGroup()); + properties.put("skipFirst", definition.getSkipFirst()); + return properties; } @Override @@ -63,4 +60,16 @@ public class TokenizerExpressionReifier extends ExpressionReifier<TokenizerExpre return ExpressionToPredicateAdapter.toPredicate(exp); } + @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/XMLTokenizerExpressionReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/XMLTokenizerExpressionReifier.java index aac9085..331a075 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 @@ -24,28 +24,42 @@ import org.apache.camel.Expression; import org.apache.camel.Predicate; import org.apache.camel.model.language.ExpressionDefinition; import org.apache.camel.model.language.XMLTokenizerExpression; +import org.apache.camel.spi.Language; import org.apache.camel.spi.NamespaceAware; +import org.apache.camel.support.ExpressionToPredicateAdapter; public class XMLTokenizerExpressionReifier extends ExpressionReifier<XMLTokenizerExpression> { - // TODO: Update me - public XMLTokenizerExpressionReifier(CamelContext camelContext, ExpressionDefinition definition) { super(camelContext, (XMLTokenizerExpression) definition); } @Override - protected void configureExpression(Expression expression) { - bindProperties(expression); - configureNamespaceAware(expression); - super.configureExpression(expression); + public Predicate createPredicate() { + Expression exp = createExpression(); + return ExpressionToPredicateAdapter.toPredicate(exp); + } + + @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()); } @Override protected void configurePredicate(Predicate predicate) { - bindProperties(predicate); configureNamespaceAware(predicate); - super.configurePredicate(predicate); + } + + @Override + protected void configureExpression(Expression expression) { + configureNamespaceAware(expression); } protected void configureNamespaceAware(Object builder) { @@ -55,12 +69,13 @@ public class XMLTokenizerExpressionReifier extends ExpressionReifier<XMLTokenize } } - protected void bindProperties(Object target) { - Map<String, Object> properties = new HashMap<>(); + protected Map<String, Object> createProperties() { + Map<String, Object> properties = new HashMap<>(3); properties.put("headerName", definition.getHeaderName()); properties.put("mode", definition.getMode()); properties.put("group", definition.getGroup()); - setProperties(target, properties); + properties.put("path", definition.getExpression()); + return properties; } } 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 20df970..aa087ae 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 @@ -16,15 +16,13 @@ */ package org.apache.camel.language.tokenizer; -import org.apache.camel.CamelContext; +import java.util.Map; + import org.apache.camel.Expression; -import org.apache.camel.IsSingleton; import org.apache.camel.Predicate; -import org.apache.camel.spi.Language; -import org.apache.camel.spi.PropertyConfigurer; import org.apache.camel.support.ExpressionToPredicateAdapter; +import org.apache.camel.support.LanguageSupport; import org.apache.camel.support.builder.ExpressionBuilder; -import org.apache.camel.support.component.PropertyConfigurerSupport; import org.apache.camel.util.ObjectHelper; /** @@ -40,7 +38,7 @@ import org.apache.camel.util.ObjectHelper; * <tt>token</tt> and <tt>endToken</tt>. And the <tt>xml</tt> mode supports the <tt>inheritNamespaceTagName</tt> option. */ @org.apache.camel.spi.annotations.Language("tokenize") -public class TokenizeLanguage implements Language, IsSingleton, PropertyConfigurer { +public class TokenizeLanguage extends LanguageSupport { private String token; private String endToken; @@ -93,53 +91,6 @@ public class TokenizeLanguage implements Language, IsSingleton, PropertyConfigur } @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 "token": - setToken(PropertyConfigurerSupport.property(camelContext, String.class, value)); - return true; - case "endtoken": - case "endToken": - setEndToken(PropertyConfigurerSupport.property(camelContext, String.class, value)); - return true; - case "inheritnamespacetagname": - case "inheritNamespaceTagName": - setInheritNamespaceTagName(PropertyConfigurerSupport.property(camelContext, String.class, value)); - return true; - case "headername": - case "headerName": - setHeaderName(PropertyConfigurerSupport.property(camelContext, String.class, value)); - return true; - case "regex": - setRegex(PropertyConfigurerSupport.property(camelContext, Boolean.class, value)); - return true; - case "xml": - setXml(PropertyConfigurerSupport.property(camelContext, Boolean.class, value)); - return true; - case "includetokens": - case "includeTokens": - setIncludeTokens(PropertyConfigurerSupport.property(camelContext, Boolean.class, value)); - return true; - case "group": - setGroup(PropertyConfigurerSupport.property(camelContext, String.class, value)); - return true; - case "groupdelimiter": - case "groupDelimiter": - setGroupDelimiter(PropertyConfigurerSupport.property(camelContext, String.class, value)); - return true; - case "skipfirst": - case "skipFirst": - setSkipFirst(PropertyConfigurerSupport.property(camelContext, Boolean.class, value)); - return true; - default: - return false; - } - } - - @Override public Predicate createPredicate(String expression) { return ExpressionToPredicateAdapter.toPredicate(createExpression(expression)); } @@ -201,6 +152,27 @@ public class TokenizeLanguage implements Language, IsSingleton, PropertyConfigur return createExpression(); } + @Override + public Predicate createPredicate(Map<String, Object> properties) { + return ExpressionToPredicateAdapter.toPredicate(createExpression(properties)); + } + + @Override + public Expression createExpression(Map<String, Object> properties) { + TokenizeLanguage answer = new TokenizeLanguage(); + answer.setInheritNamespaceTagName(property(String.class, properties, "inheritNamespaceTagName", null)); + answer.setToken(property(String.class, properties, "token", null)); + answer.setEndToken(property(String.class, properties, "endToken", null)); + answer.setHeaderName(property(String.class, properties, "headerName", null)); + answer.setRegex(property(boolean.class, properties, "regex", false)); + answer.setXml(property(boolean.class, properties, "xml", false)); + answer.setIncludeTokens(property(boolean.class, properties, "includeTokens", false)); + answer.setGroup(property(String.class, properties, "group", null)); + answer.setGroupDelimiter(property(String.class, properties, "groupDelimiter", null)); + answer.setSkipFirst(property(boolean.class, properties, "skipFirst", false)); + return answer.createExpression(); + } + public String getToken() { return token; } @@ -281,8 +253,4 @@ public class TokenizeLanguage implements Language, IsSingleton, PropertyConfigur this.skipFirst = skipFirst; } - @Override - public boolean isSingleton() { - return false; - } } diff --git a/core/camel-core/src/test/java/org/apache/camel/language/LanguageServiceTest.java b/core/camel-core/src/test/java/org/apache/camel/language/LanguageServiceTest.java index 6eb339a..fe5d3d0 100644 --- a/core/camel-core/src/test/java/org/apache/camel/language/LanguageServiceTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/language/LanguageServiceTest.java @@ -61,24 +61,6 @@ public class LanguageServiceTest extends ContextTestSupport { assertTrue(context.getLanguageNames().isEmpty()); } - @Test - public void testNonSingletonLanguage() throws Exception { - Language tol = context.resolveLanguage("tokenize"); - assertNotNull(tol); - // simple language is resolved by default hence why there is 2 - assertEquals(2, context.getLanguageNames().size()); - - // resolve again, should find another instance - Language tol2 = context.resolveLanguage("tokenize"); - assertNotNull(tol2); - assertNotSame(tol, tol2); - // simple language is resolved by default hence why there is 2 - assertEquals(2, context.getLanguageNames().size()); - - context.stop(); - assertTrue(context.getLanguageNames().isEmpty()); - } - public class MyLanguage extends ServiceSupport implements Language, IsSingleton { private String state; diff --git a/core/camel-core/src/test/java/org/apache/camel/language/TokenizerTest.java b/core/camel-core/src/test/java/org/apache/camel/language/TokenizerTest.java index 3931b72..40debe8 100644 --- a/core/camel-core/src/test/java/org/apache/camel/language/TokenizerTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/language/TokenizerTest.java @@ -37,7 +37,7 @@ public class TokenizerTest extends ExchangeTestSupport { } @Test - public void testTokenizeHeaderWithStringContructor() throws Exception { + public void testTokenizeHeaderWithStringConstructor() throws Exception { TokenizerExpression definition = new TokenizerExpression(","); definition.setHeaderName("names"); @@ -119,7 +119,7 @@ public class TokenizerTest extends ExchangeTestSupport { assertEquals("names", lan.getHeaderName()); assertEquals(",", lan.getToken()); assertEquals(false, lan.isRegex()); - assertEquals(false, lan.isSingleton()); + assertEquals(true, lan.isSingleton()); } @Test diff --git a/core/camel-core/src/test/java/org/apache/camel/support/CustomizersTest.java b/core/camel-core/src/test/java/org/apache/camel/support/CustomizersTest.java index 151f67d..d978540 100644 --- a/core/camel-core/src/test/java/org/apache/camel/support/CustomizersTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/support/CustomizersTest.java @@ -351,15 +351,16 @@ public class CustomizersTest { "tokenize-customizer", LanguageCustomizer.forType(TokenizeLanguage.class, target -> target.setGroup("" + counter.incrementAndGet()))); + // singleton language so its customized once Language l1 = context.resolveLanguage("tokenize"); assertTrue(l1 instanceof TokenizeLanguage); assertEquals("1", ((TokenizeLanguage) l1).getGroup()); Language l2 = context.resolveLanguage("tokenize"); assertTrue(l2 instanceof TokenizeLanguage); - assertEquals("2", ((TokenizeLanguage) l2).getGroup()); + assertEquals("1", ((TokenizeLanguage) l2).getGroup()); - assertNotSame(l1, l2); + assertSame(l1, l2); } @Test @@ -374,6 +375,7 @@ public class CustomizersTest { "tokenize-customizer", LanguageCustomizer.forType(TokenizeLanguage.class, target -> target.setGroup("" + counter.incrementAndGet()))); + // singleton language so its customized once Language l1 = context.resolveLanguage("tokenize"); assertTrue(l1 instanceof TokenizeLanguage); assertNull(((TokenizeLanguage) l1).getGroup()); @@ -382,7 +384,7 @@ public class CustomizersTest { assertTrue(l2 instanceof TokenizeLanguage); assertNull(((TokenizeLanguage) l2).getGroup()); - assertNotSame(l1, l2); + assertSame(l1, l2); } @ParameterizedTest diff --git a/core/camel-support/src/main/java/org/apache/camel/support/PredicateToExpressionAdapter.java b/core/camel-support/src/main/java/org/apache/camel/support/PredicateToExpressionAdapter.java index 6e6f138..13f8b16 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/PredicateToExpressionAdapter.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/PredicateToExpressionAdapter.java @@ -45,6 +45,9 @@ public final class PredicateToExpressionAdapter implements Expression { * Converts the given predicate into an {@link org.apache.camel.Expression} */ public static Expression toExpression(final Predicate predicate) { + if (predicate instanceof Expression) { + return (Expression) predicate; + } return new PredicateToExpressionAdapter(predicate); } diff --git a/core/camel-xml-jaxp/src/main/java/org/apache/camel/language/xtokenizer/XMLTokenizeLanguage.java b/core/camel-xml-jaxp/src/main/java/org/apache/camel/language/xtokenizer/XMLTokenizeLanguage.java index 50fbeef..876957a 100644 --- a/core/camel-xml-jaxp/src/main/java/org/apache/camel/language/xtokenizer/XMLTokenizeLanguage.java +++ b/core/camel-xml-jaxp/src/main/java/org/apache/camel/language/xtokenizer/XMLTokenizeLanguage.java @@ -16,6 +16,8 @@ */ package org.apache.camel.language.xtokenizer; +import java.util.Map; + import org.apache.camel.Expression; import org.apache.camel.Predicate; import org.apache.camel.spi.annotations.Language; @@ -87,6 +89,21 @@ public class XMLTokenizeLanguage extends LanguageSupport { return expr; } + @Override + public Predicate createPredicate(Map<String, Object> properties) { + return ExpressionToPredicateAdapter.toPredicate(createExpression(properties)); + } + + @Override + public Expression createExpression(Map<String, Object> properties) { + XMLTokenizeLanguage answer = new XMLTokenizeLanguage(); + answer.setHeaderName(property(String.class, properties, "headerName", null)); + answer.setMode(property(char.class, properties, "mode", 'i')); + answer.setGroup(property(int.class, properties, "group", 1)); + String path = property(String.class, properties, "path", null); + return answer.createExpression(path); + } + public String getHeaderName() { return headerName; } @@ -127,8 +144,4 @@ public class XMLTokenizeLanguage extends LanguageSupport { this.namespaces = namespaces; } - @Override - public boolean isSingleton() { - return false; - } }
