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 1aa13fa CAMEL-15704: camel-csimple - Compiled simple language. 1aa13fa is described below commit 1aa13fa5a5a7752d80bc0659d26da07553117e66 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Fri Dec 4 09:48:54 2020 +0100 CAMEL-15704: camel-csimple - Compiled simple language. --- .../apache/camel/language/bean/BeanLanguage.java | 5 +- .../csimple/joor/OriginalSimpleOperatorTest.java | 806 +++++++++++++++++++++ .../camel/language/csimple/CSimpleHelper.java | 5 +- .../language/simple/SimpleExpressionParser.java | 4 + .../language/simple/SimplePredicateParser.java | 4 + .../language/simple/ast/BinaryExpression.java | 16 +- .../org/apache/camel/support/LanguageSupport.java | 2 +- .../org/apache/camel/support/ObjectHelper.java | 22 + 8 files changed, 859 insertions(+), 5 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 65b8146..3780d1b 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 @@ -165,7 +165,10 @@ public class BeanLanguage extends LanguageSupport implements PropertyConfigurer, throw new IllegalArgumentException("Bean language requires bean, beanType, or ref argument"); } if (properties.length == 5) { - answer.setScope(property(BeanScope.class, properties, 4, scope)); + BeanScope scope = (BeanScope) properties[4]; + if (scope != null) { + answer.setScope(scope); + } } answer.setBeanComponent(beanComponent); answer.setParameterMappingStrategy(parameterMappingStrategy); diff --git a/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleOperatorTest.java b/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleOperatorTest.java new file mode 100644 index 0000000..dd3b62e --- /dev/null +++ b/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleOperatorTest.java @@ -0,0 +1,806 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.language.csimple.joor; + +import org.apache.camel.BindToRegistry; +import org.apache.camel.Exchange; +import org.apache.camel.language.simple.types.SimpleIllegalSyntaxException; +import org.apache.camel.test.junit5.LanguageTestSupport; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +public class OriginalSimpleOperatorTest extends LanguageTestSupport { + + @BindToRegistry + private MyFileNameGenerator generator = new MyFileNameGenerator(); + + @Test + public void testValueWithSpace() throws Exception { + exchange.getIn().setBody("Hello Big World"); + assertPredicate("${in.body} == 'Hello Big World'", true); + } + + @Test + public void testNullValue() throws Exception { + exchange.getIn().setBody("Value"); + assertPredicate("${in.body} != null", true); + assertPredicate("${body} == null", false); + + exchange.getIn().setBody(null); + assertPredicate("${in.body} == null", true); + assertPredicate("${body} != null", false); + } + + @Test + public void testEmptyValue() throws Exception { + exchange.getIn().setBody(""); + assertPredicate("${in.body} == null", false); + assertPredicate("${body} == null", false); + + exchange.getIn().setBody(""); + assertPredicate("${in.body} == ''", true); + assertPredicate("${body} == \"\"", true); + + exchange.getIn().setBody(" "); + assertPredicate("${in.body} == ''", false); + assertPredicate("${body} == \"\"", false); + + exchange.getIn().setBody("Value"); + assertPredicate("${in.body} == ''", false); + assertPredicate("${body} == \"\"", false); + } + + @Test + public void testAnd() throws Exception { + assertPredicate("${in.header.foo} == 'abc' && ${in.header.bar} == 123", true); + assertPredicate("${in.header.foo} == 'abc' && ${in.header.bar} == 444", false); + assertPredicate("${in.header.foo} == 'def' && ${in.header.bar} == 123", false); + assertPredicate("${in.header.foo} == 'def' && ${in.header.bar} == 444", false); + + assertPredicate("${in.header.foo} == 'abc' && ${in.header.bar} > 100", true); + assertPredicate("${in.header.foo} == 'abc' && ${in.header.bar} < 200", true); + } + + @Test + public void testTwoAnd() throws Exception { + exchange.getIn().setBody("Hello World"); + assertPredicate("${in.header.foo} == 'abc' && ${in.header.bar} == 123 && ${body} == 'Hello World'", true); + assertPredicate("${in.header.foo} == 'abc' && ${in.header.bar} == 123 && ${body} == 'Bye World'", false); + } + + @Test + public void testThreeAnd() throws Exception { + exchange.getIn().setBody("Hello World"); + assertPredicate( + "${in.header.foo} == 'abc' && ${in.header.bar} == 123 && ${body} == 'Hello World' && ${in.header.xx} == null", + true); + } + + @Test + public void testTwoOr() throws Exception { + exchange.getIn().setBody("Hello World"); + assertPredicate("${in.header.foo} == 'abc' || ${in.header.bar} == 44 || ${body} == 'Bye World'", true); + assertPredicate("${in.header.foo} == 'xxx' || ${in.header.bar} == 44 || ${body} == 'Bye World'", false); + assertPredicate("${in.header.foo} == 'xxx' || ${in.header.bar} == 44 || ${body} == 'Hello World'", true); + assertPredicate("${in.header.foo} == 'xxx' || ${in.header.bar} == 123 || ${body} == 'Bye World'", true); + } + + @Test + public void testThreeOr() throws Exception { + exchange.getIn().setBody("Hello World"); + assertPredicate( + "${in.header.foo} == 'xxx' || ${in.header.bar} == 44 || ${body} == 'Bye Moon' || ${body} contains 'World'", + true); + assertPredicate( + "${in.header.foo} == 'xxx' || ${in.header.bar} == 44 || ${body} == 'Bye Moon' || ${body} contains 'Moon'", + false); + assertPredicate( + "${in.header.foo} == 'abc' || ${in.header.bar} == 44 || ${body} == 'Bye Moon' || ${body} contains 'Moon'", + true); + assertPredicate( + "${in.header.foo} == 'xxx' || ${in.header.bar} == 123 || ${body} == 'Bye Moon' || ${body} contains 'Moon'", + true); + assertPredicate( + "${in.header.foo} == 'xxx' || ${in.header.bar} == 44 || ${body} == 'Hello World' || ${body} contains 'Moon'", + true); + } + + @Test + public void testAndWithQuotation() throws Exception { + assertPredicate("${in.header.foo} == 'abc' && ${in.header.bar} == '123'", true); + assertPredicate("${in.header.foo} == 'abc' && ${in.header.bar} == '444'", false); + assertPredicate("${in.header.foo} == 'def' && ${in.header.bar} == '123'", false); + assertPredicate("${in.header.foo} == 'def' && ${in.header.bar} == '444'", false); + + assertPredicate("${in.header.foo} == 'abc' && ${in.header.bar} > '100'", true); + assertPredicate("${in.header.foo} == 'abc' && ${in.header.bar} < '200'", true); + } + + @Test + public void testOr() throws Exception { + assertPredicate("${in.header.foo} == 'abc' || ${in.header.bar} == 123", true); + assertPredicate("${in.header.foo} == 'abc' || ${in.header.bar} == 444", true); + assertPredicate("${in.header.foo} == 'def' || ${in.header.bar} == 123", true); + assertPredicate("${in.header.foo} == 'def' || ${in.header.bar} == 444", false); + + assertPredicate("${in.header.foo} == 'abc' || ${in.header.bar} < 100", true); + assertPredicate("${in.header.foo} == 'abc' || ${in.header.bar} < 200", true); + assertPredicate("${in.header.foo} == 'def' || ${in.header.bar} < 200", true); + assertPredicate("${in.header.foo} == 'def' || ${in.header.bar} < 100", false); + } + + @Test + public void testOrWithQuotation() throws Exception { + assertPredicate("${in.header.foo} == 'abc' || ${in.header.bar} == '123'", true); + assertPredicate("${in.header.foo} == 'abc' || ${in.header.bar} == '444'", true); + assertPredicate("${in.header.foo} == 'def' || ${in.header.bar} == '123'", true); + assertPredicate("${in.header.foo} == 'def' || ${in.header.bar} == '444'", false); + + assertPredicate("${in.header.foo} == 'abc' || ${in.header.bar} < '100'", true); + assertPredicate("${in.header.foo} == 'abc' || ${in.header.bar} < '200'", true); + assertPredicate("${in.header.foo} == 'def' || ${in.header.bar} < '200'", true); + assertPredicate("${in.header.foo} == 'def' || ${in.header.bar} < '100'", false); + } + + @Test + public void testEqualOperator() throws Exception { + // string to string comparison + assertPredicate("${in.header.foo} == 'abc'", true); + assertPredicate("${in.header.foo} == 'def'", false); + assertPredicate("${in.header.foo} == '1'", false); + + // no type converter needed from this point forward + context.getTypeConverterRegistry().getStatistics().setStatisticsEnabled(true); + context.getTypeConverterRegistry().getStatistics().reset(); + + // boolean to boolean comparison + exchange.getIn().setHeader("bool", true); + exchange.getIn().setHeader("booley", false); + assertPredicate("${in.header.bool} == true", true); + assertPredicate("${in.header.bool} == 'true'", true); + assertPredicate("${in.header.booley} == false", true); + assertPredicate("${in.header.booley} == 'false'", true); + + // integer to string comparison + assertPredicate("${in.header.bar} == '123'", true); + assertPredicate("${in.header.bar} == 123", true); + assertPredicate("${in.header.bar} == '444'", false); + assertPredicate("${in.header.bar} == 444", false); + assertPredicate("${in.header.bar} == '1'", false); + + // should not need type conversion + assertEquals(0, context.getTypeConverterRegistry().getStatistics().getAttemptCounter()); + } + + @Test + public void testEqualIgnoreOperator() throws Exception { + // string to string comparison + assertPredicate("${in.header.foo} =~ 'abc'", true); + assertPredicate("${in.header.foo} =~ 'ABC'", true); + assertPredicate("${in.header.foo} =~ 'Abc'", true); + assertPredicate("${in.header.foo} =~ 'Def'", false); + assertPredicate("${in.header.foo} =~ '1'", false); + + // integer to string comparison + assertPredicate("${in.header.bar} =~ '123'", true); + assertPredicate("${in.header.bar} =~ 123", true); + assertPredicate("${in.header.bar} =~ '444'", false); + assertPredicate("${in.header.bar} =~ 444", false); + assertPredicate("${in.header.bar} =~ '1'", false); + } + + @Test + public void testNotEqualOperator() throws Exception { + // string to string comparison + assertPredicate("${in.header.foo} != 'abc'", false); + assertPredicate("${in.header.foo} != 'def'", true); + assertPredicate("${in.header.foo} != '1'", true); + + // integer to string comparison + assertPredicate("${in.header.bar} != '123'", false); + assertPredicate("${in.header.bar} != 123", false); + assertPredicate("${in.header.bar} != '444'", true); + assertPredicate("${in.header.bar} != 444", true); + assertPredicate("${in.header.bar} != '1'", true); + } + + @Test + public void testNotEqualIgnoreOperator() throws Exception { + // string to string comparison + assertPredicate("${in.header.foo} !=~ 'abc'", false); + assertPredicate("${in.header.foo} !=~ 'ABC'", false); + assertPredicate("${in.header.foo} !=~ 'Abc'", false); + assertPredicate("${in.header.foo} !=~ 'Def'", true); + assertPredicate("${in.header.foo} !=~ '1'", true); + + // integer to string comparison + assertPredicate("${in.header.bar} !=~ '123'", false); + assertPredicate("${in.header.bar} !=~ 123", false); + assertPredicate("${in.header.bar} !=~ '444'", true); + assertPredicate("${in.header.bar} !=~ 444", true); + assertPredicate("${in.header.bar} !=~ '1'", true); + } + + @Test + public void testFloatingNumber() throws Exception { + // set a String value + exchange.getIn().setBody("0.02"); + + assertPredicate("${body} > 0", true); + assertPredicate("${body} < 0", false); + + assertPredicate("${body} > 0.00", true); + assertPredicate("${body} < 0.00", false); + + assertPredicate("${body} > 0.01", true); + assertPredicate("${body} < 0.01", false); + + assertPredicate("${body} > 0.02", false); + assertPredicate("${body} < 0.02", false); + + assertPredicate("${body} == 0.02", true); + } + + @Test + public void testGreaterThanOperator() throws Exception { + // string to string comparison + assertPredicate("${in.header.foo} > 'aaa'", true); + assertPredicate("${in.header.foo} > 'def'", false); + + // integer to string comparison + assertPredicate("${in.header.bar} > '100'", true); + assertPredicate("${in.header.bar} > 100", true); + assertPredicate("${in.header.bar} > '123'", false); + assertPredicate("${in.header.bar} > 123", false); + assertPredicate("${in.header.bar} > '200'", false); + } + + @Test + public void testGreaterThanStringToInt() throws Exception { + // set a String value + exchange.getIn().setHeader("num", "70"); + + // string to int comparison + assertPredicate("${in.header.num} > 100", false); + assertPredicate("${in.header.num} > 100", false); + assertPredicate("${in.header.num} > 80", false); + assertPredicate("${in.header.num} > 800", false); + assertPredicate("${in.header.num} > 1", true); + assertPredicate("${in.header.num} > 8", true); + assertPredicate("${in.header.num} > 48", true); + assertPredicate("${in.header.num} > 69", true); + assertPredicate("${in.header.num} > 71", false); + assertPredicate("${in.header.num} > 88", false); + assertPredicate("${in.header.num} > 777", false); + } + + @Test + public void testLessThanStringToInt() throws Exception { + // set a String value + exchange.getIn().setHeader("num", "70"); + + // string to int comparison + assertPredicate("${in.header.num} < 100", true); + assertPredicate("${in.header.num} < 100", true); + assertPredicate("${in.header.num} < 80", true); + assertPredicate("${in.header.num} < 800", true); + assertPredicate("${in.header.num} < 1", false); + assertPredicate("${in.header.num} < 8", false); + assertPredicate("${in.header.num} < 48", false); + assertPredicate("${in.header.num} < 69", false); + assertPredicate("${in.header.num} < 71", true); + assertPredicate("${in.header.num} < 88", true); + assertPredicate("${in.header.num} < 777", true); + } + + @Test + public void testGreaterThanOrEqualOperator() throws Exception { + // string to string comparison + assertPredicate("${in.header.foo} >= 'aaa'", true); + assertPredicate("${in.header.foo} >= 'abc'", true); + assertPredicate("${in.header.foo} >= 'def'", false); + + // integer to string comparison + assertPredicate("${in.header.bar} >= '100'", true); + assertPredicate("${in.header.bar} >= 100", true); + assertPredicate("${in.header.bar} >= '123'", true); + assertPredicate("${in.header.bar} >= 123", true); + assertPredicate("${in.header.bar} >= '200'", false); + } + + @Test + public void testLessThanOperator() throws Exception { + // string to string comparison + assertPredicate("${in.header.foo} < 'aaa'", false); + assertPredicate("${in.header.foo} < 'def'", true); + + // integer to string comparison + assertPredicate("${in.header.bar} < '100'", false); + assertPredicate("${in.header.bar} < 100", false); + assertPredicate("${in.header.bar} < '123'", false); + assertPredicate("${in.header.bar} < 123", false); + assertPredicate("${in.header.bar} < '200'", true); + } + + @Test + public void testAgainstNegativeValue() throws Exception { + assertPredicate("${in.header.bar} == 123", true); + assertPredicate("${in.header.bar} == -123", false); + assertPredicate("${in.header.bar} =~ 123", true); + assertPredicate("${in.header.bar} =~ -123", false); + assertPredicate("${in.header.bar} > -123", true); + assertPredicate("${in.header.bar} >= -123", true); + assertPredicate("${in.header.bar} > 123", false); + assertPredicate("${in.header.bar} >= 123", true); + assertPredicate("${in.header.bar} < -123", false); + assertPredicate("${in.header.bar} <= -123", false); + assertPredicate("${in.header.bar} < 123", false); + assertPredicate("${in.header.bar} <= 123", true); + + exchange.getIn().setHeader("strNum", "123"); + assertPredicate("${in.header.strNum} contains '123'", true); + assertPredicate("${in.header.strNum} !contains '123'", false); + assertPredicate("${in.header.strNum} contains '-123'", false); + assertPredicate("${in.header.strNum} !contains '-123'", true); + assertPredicate("${in.header.strNum} ~~ '123'", true); + assertPredicate("${in.header.strNum} ~~ '-123'", false); + + exchange.getIn().setHeader("num", -123); + assertPredicate("${in.header.num} == -123", true); + assertPredicate("${in.header.num} == 123", false); + assertPredicate("${in.header.num} =~ -123", true); + assertPredicate("${in.header.num} =~ 123", false); + assertPredicate("${in.header.num} > -123", false); + assertPredicate("${in.header.num} >= -123", true); + assertPredicate("${in.header.num} > 123", false); + assertPredicate("${in.header.num} >= 123", false); + assertPredicate("${in.header.num} < -123", false); + assertPredicate("${in.header.num} <= -123", true); + assertPredicate("${in.header.num} < 123", true); + assertPredicate("${in.header.num} <= 123", true); + + exchange.getIn().setHeader("strNumNegative", "-123"); + assertPredicate("${in.header.strNumNegative} contains '123'", true); + assertPredicate("${in.header.strNumNegative} !contains '123'", false); + assertPredicate("${in.header.strNumNegative} contains '-123'", true); + assertPredicate("${in.header.strNumNegative} !contains '-123'", false); + assertPredicate("${in.header.strNumNegative} ~~ '123'", true); + assertPredicate("${in.header.strNumNegative} ~~ '-123'", true); + } + + @Test + public void testLessThanOrEqualOperator() throws Exception { + context.getTypeConverterRegistry().getStatistics().setStatisticsEnabled(true); + context.getTypeConverterRegistry().getStatistics().reset(); + + // string to string comparison + assertPredicate("${in.header.foo} <= 'aaa'", false); + assertPredicate("${in.header.foo} <= 'abc'", true); + assertPredicate("${in.header.foo} <= 'def'", true); + + // string to string + exchange.getIn().setHeader("dude", "555"); + exchange.getIn().setHeader("dude2", "0099"); + assertPredicate("${in.header.dude} <= ${in.header.dude}", true); + assertPredicate("${in.header.dude2} <= ${in.header.dude}", true); + + // integer to string comparison + assertPredicate("${in.header.bar} <= '100'", false); + assertPredicate("${in.header.bar} <= 100", false); + assertPredicate("${in.header.bar} <= '123'", true); + assertPredicate("${in.header.bar} <= 123", true); + assertPredicate("${in.header.bar} <= '200'", true); + + // should not need type conversion + assertEquals(0, context.getTypeConverterRegistry().getStatistics().getAttemptCounter()); + } + + @Test + public void testTypeCoerceNoConversionNeeded() throws Exception { + context.getTypeConverterRegistry().getStatistics().setStatisticsEnabled(true); + context.getTypeConverterRegistry().getStatistics().reset(); + + // int to int comparison + exchange.getIn().setHeader("num", 70); + assertPredicate("${in.header.num} > 100", false); + assertPredicate("${in.header.num} < 100", true); + assertPredicate("${in.header.num} == 70", true); + assertPredicate("${in.header.num} != 70", false); + assertPredicate("${in.header.num} > 100", false); + assertPredicate("${in.header.num} > 80", false); + assertPredicate("${in.header.num} > 800", false); + assertPredicate("${in.header.num} < 800", true); + assertPredicate("${in.header.num} > 1", true); + assertPredicate("${in.header.num} > 8", true); + assertPredicate("${in.header.num} > 48", true); + assertPredicate("${in.header.num} > 69", true); + assertPredicate("${in.header.num} > 71", false); + assertPredicate("${in.header.num} < 71", true); + assertPredicate("${in.header.num} > 88", false); + assertPredicate("${in.header.num} > 777", false); + + // String to int comparison + exchange.getIn().setHeader("num", "70"); + assertPredicate("${in.header.num} > 100", false); + assertPredicate("${in.header.num} < 100", true); + assertPredicate("${in.header.num} == 70", true); + assertPredicate("${in.header.num} != 70", false); + assertPredicate("${in.header.num} > 100", false); + assertPredicate("${in.header.num} > 80", false); + assertPredicate("${in.header.num} > 800", false); + assertPredicate("${in.header.num} < 800", true); + assertPredicate("${in.header.num} > 1", true); + assertPredicate("${in.header.num} > 8", true); + assertPredicate("${in.header.num} > 48", true); + assertPredicate("${in.header.num} > 69", true); + assertPredicate("${in.header.num} > 71", false); + assertPredicate("${in.header.num} < 71", true); + assertPredicate("${in.header.num} > 88", false); + assertPredicate("${in.header.num} > 777", false); + + // should not need type conversion + assertEquals(0, context.getTypeConverterRegistry().getStatistics().getAttemptCounter()); + } + + @Test + public void testIsNull() throws Exception { + assertPredicate("${in.header.foo} == null", false); + assertPredicate("${in.header.none} == null", true); + } + + @Test + public void testIsNotNull() throws Exception { + assertPredicate("${in.header.foo} != null", true); + assertPredicate("${in.header.none} != null", false); + } + + @Test + public void testRightOperatorIsSimpleLanguage() throws Exception { + // operator on right side is also using ${ } placeholders + assertPredicate("${in.header.foo} == ${in.header.foo}", true); + assertPredicate("${in.header.foo} == ${in.header.bar}", false); + } + + @Test + public void testRightOperatorIsBeanLanguage() throws Exception { + // operator on right side is also using ${ } placeholders + assertPredicate("${in.header.foo} == ${bean:generator.generateFilename}", true); + + assertPredicate("${in.header.bar} == ${bean:generator.generateId}", true); + assertPredicate("${in.header.bar} >= ${bean:generator.generateId}", true); + } + + @Test + public void testContains() throws Exception { + assertPredicate("${in.header.foo} contains 'a'", true); + assertPredicate("${in.header.foo} contains 'ab'", true); + assertPredicate("${in.header.foo} contains 'abc'", true); + assertPredicate("${in.header.foo} contains 'def'", false); + } + + @Test + public void testContainsNumberInString() throws Exception { + exchange.getMessage().setBody("The answer is 42 and is the answer to life the universe and everything"); + assertPredicate("${body} contains '42'", true); + assertPredicate("${body} contains 42", true); + assertPredicate("${body} contains '77'", false); + assertPredicate("${body} contains 77", false); + } + + @Test + public void testNotContains() throws Exception { + assertPredicate("${in.header.foo} not contains 'a'", false); + assertPredicate("${in.header.foo} not contains 'ab'", false); + assertPredicate("${in.header.foo} not contains 'abc'", false); + assertPredicate("${in.header.foo} not contains 'def'", true); + assertPredicate("${in.header.foo} !contains 'a'", false); + assertPredicate("${in.header.foo} !contains 'ab'", false); + assertPredicate("${in.header.foo} !contains 'abc'", false); + assertPredicate("${in.header.foo} !contains 'def'", true); + } + + @Test + public void testContainsIgnoreCase() throws Exception { + assertPredicate("${in.header.foo} ~~ 'A'", true); + assertPredicate("${in.header.foo} ~~ 'Ab'", true); + assertPredicate("${in.header.foo} ~~ 'Abc'", true); + assertPredicate("${in.header.foo} ~~ 'defG'", false); + } + + @Test + public void testNotContainsIgnoreCase() throws Exception { + assertPredicate("${in.header.foo} !~~ 'A'", false); + assertPredicate("${in.header.foo} !~~ 'Ab'", false); + assertPredicate("${in.header.foo} !~~ 'Abc'", false); + assertPredicate("${in.header.foo} !~~ 'defG'", true); + } + + @Test + public void testRegex() throws Exception { + assertPredicate("${in.header.foo} regex '^a..$'", true); + assertPredicate("${in.header.foo} regex '^ab.$'", true); + assertPredicate("${in.header.foo} regex '^ab.$'", true); + assertPredicate("${in.header.foo} regex '^d.*$'", false); + + assertPredicate("${in.header.bar} regex '^\\d{3}'", true); + assertPredicate("${in.header.bar} regex '^\\d{2}'", false); + } + + @Test + public void testNotRegex() throws Exception { + assertPredicate("${in.header.foo} not regex '^a..$'", false); + assertPredicate("${in.header.foo} not regex '^ab.$'", false); + assertPredicate("${in.header.foo} not regex '^ab.$'", false); + assertPredicate("${in.header.foo} not regex '^d.*$'", true); + + assertPredicate("${in.header.bar} not regex '^\\d{3}'", false); + assertPredicate("${in.header.bar} not regex '^\\d{2}'", true); + } + + @Test + public void testIn() throws Exception { + // string to string + assertPredicate("${in.header.foo} in 'foo,abc,def'", true); + assertPredicate("${in.header.foo} in ${bean:generator.generateFilename}", true); + assertPredicate("${in.header.foo} in 'foo,abc,def'", true); + assertPredicate("${in.header.foo} in 'foo,def'", false); + + // integer to string + assertPredicate("${in.header.bar} in '100,123,200'", true); + assertPredicate("${in.header.bar} in ${bean:generator.generateId}", true); + assertPredicate("${in.header.bar} in '100,200'", false); + } + + @Test + public void testNotIn() throws Exception { + // string to string + assertPredicate("${in.header.foo} not in 'foo,abc,def'", false); + assertPredicate("${in.header.foo} not in ${bean:generator.generateFilename}", false); + assertPredicate("${in.header.foo} not in 'foo,abc,def'", false); + assertPredicate("${in.header.foo} not in 'foo,def'", true); + assertPredicate("${in.header.foo} !in 'foo,abc,def'", false); + assertPredicate("${in.header.foo} !in ${bean:generator.generateFilename}", false); + assertPredicate("${in.header.foo} !in 'foo,abc,def'", false); + assertPredicate("${in.header.foo} !in 'foo,def'", true); + + // integer to string + assertPredicate("${in.header.bar} not in '100,123,200'", false); + assertPredicate("${in.header.bar} not in ${bean:generator.generateId}", false); + assertPredicate("${in.header.bar} not in '100,200'", true); + assertPredicate("${in.header.bar} !in '100,123,200'", false); + assertPredicate("${in.header.bar} !in ${bean:generator.generateId}", false); + assertPredicate("${in.header.bar} !in '100,200'", true); + } + + @Test + public void testIs() throws Exception { + assertPredicate("${in.header.foo} is 'java.lang.String'", true); + assertPredicate("${in.header.foo} is 'java.lang.Integer'", false); + + assertPredicate("${in.header.foo} is 'String'", true); + assertPredicate("${in.header.foo} is 'Integer'", false); + + try { + assertPredicate("${in.header.foo} is com.mycompany.DoesNotExist", false); + fail("Should have thrown an exception"); + } catch (SimpleIllegalSyntaxException e) { + assertEquals(20, e.getIndex()); + } + } + + @Test + public void testIsNot() throws Exception { + assertPredicate("${in.header.foo} not is 'java.lang.String'", false); + assertPredicate("${in.header.foo} not is 'java.lang.Integer'", true); + assertPredicate("${in.header.foo} !is 'java.lang.String'", false); + assertPredicate("${in.header.foo} !is 'java.lang.Integer'", true); + + assertPredicate("${in.header.foo} not is 'String'", false); + assertPredicate("${in.header.foo} not is 'Integer'", true); + assertPredicate("${in.header.foo} !is 'String'", false); + assertPredicate("${in.header.foo} !is 'Integer'", true); + + try { + assertPredicate("${in.header.foo} not is com.mycompany.DoesNotExist", false); + fail("Should have thrown an exception"); + } catch (SimpleIllegalSyntaxException e) { + assertEquals(24, e.getIndex()); + } + try { + assertPredicate("${in.header.foo} !is com.mycompany.DoesNotExist", false); + fail("Should have thrown an exception"); + } catch (SimpleIllegalSyntaxException e) { + assertEquals(21, e.getIndex()); + } + } + + @Test + public void testRange() throws Exception { + assertPredicate("${in.header.bar} range '100..200'", true); + assertPredicate("${in.header.bar} range '200..300'", false); + + assertPredicate("${in.header.foo} range '200..300'", false); + assertPredicate("${bean:generator.generateId} range '123..130'", true); + assertPredicate("${bean:generator.generateId} range '120..123'", true); + assertPredicate("${bean:generator.generateId} range '120..122'", false); + assertPredicate("${bean:generator.generateId} range '124..130'", false); + + try { + assertPredicate("${in.header.foo} range abc..200", false); + fail("Should have thrown an exception"); + } catch (SimpleIllegalSyntaxException e) { + assertEquals(23, e.getIndex()); + } + + try { + assertPredicate("${in.header.foo} range abc..", false); + fail("Should have thrown an exception"); + } catch (SimpleIllegalSyntaxException e) { + assertEquals(23, e.getIndex()); + } + + try { + assertPredicate("${in.header.foo} range 100.200", false); + fail("Should have thrown an exception"); + } catch (SimpleIllegalSyntaxException e) { + assertEquals(30, e.getIndex()); + } + + assertPredicate("${in.header.bar} range '100..200' && ${in.header.foo} == 'abc'", true); + assertPredicate("${in.header.bar} range '200..300' && ${in.header.foo} == 'abc'", false); + assertPredicate("${in.header.bar} range '200..300' || ${in.header.foo} == 'abc'", true); + assertPredicate("${in.header.bar} range '200..300' || ${in.header.foo} == 'def'", false); + } + + @Test + public void testNotRange() throws Exception { + assertPredicate("${in.header.bar} not range '100..200'", false); + assertPredicate("${in.header.bar} not range '200..300'", true); + assertPredicate("${in.header.bar} !range '100..200'", false); + assertPredicate("${in.header.bar} !range '200..300'", true); + + assertPredicate("${in.header.foo} not range '200..300'", true); + assertPredicate("${bean:generator.generateId} not range '123..130'", false); + assertPredicate("${bean:generator.generateId} not range '120..123'", false); + assertPredicate("${bean:generator.generateId} not range '120..122'", true); + assertPredicate("${bean:generator.generateId} not range '124..130'", true); + assertPredicate("${in.header.foo} !range '200..300'", true); + assertPredicate("${bean:generator.generateId} !range '123..130'", false); + assertPredicate("${bean:generator.generateId} !range '120..123'", false); + assertPredicate("${bean:generator.generateId} !range '120..122'", true); + assertPredicate("${bean:generator.generateId} !range '124..130'", true); + + try { + assertPredicate("${in.header.foo} not range abc..200", false); + fail("Should have thrown an exception"); + } catch (SimpleIllegalSyntaxException e) { + assertEquals(27, e.getIndex()); + } + try { + assertPredicate("${in.header.foo} !range abc..200", false); + fail("Should have thrown an exception"); + } catch (SimpleIllegalSyntaxException e) { + assertEquals(24, e.getIndex()); + } + + try { + assertPredicate("${in.header.foo} not range abc..", false); + fail("Should have thrown an exception"); + } catch (SimpleIllegalSyntaxException e) { + assertEquals(27, e.getIndex()); + } + try { + assertPredicate("${in.header.foo} !range abc..", false); + fail("Should have thrown an exception"); + } catch (SimpleIllegalSyntaxException e) { + assertEquals(24, e.getIndex()); + } + + try { + assertPredicate("${in.header.foo} not range 100.200", false); + fail("Should have thrown an exception"); + } catch (SimpleIllegalSyntaxException e) { + assertEquals(34, e.getIndex()); + } + try { + assertPredicate("${in.header.foo} !range 100.200", false); + fail("Should have thrown an exception"); + } catch (SimpleIllegalSyntaxException e) { + assertEquals(31, e.getIndex()); + } + } + + @Test + public void testUnaryInc() throws Exception { + assertExpression("${in.header.bar}++", 124); + assertExpression("+++++++++++++", "+++++++++++++"); + assertExpression("Logging ++ start ++", "Logging ++ start ++"); + assertExpression("Logging +++ start +++", "Logging +++ start +++"); + assertExpression("++ start ++", "++ start ++"); + assertExpression("+++ start +++", "+++ start +++"); + + assertPredicate("${in.header.bar}++ == 122", false); + assertPredicate("${in.header.bar}++ == 123", false); + assertPredicate("${in.header.bar}++ == 124", true); + } + + @Test + public void testUnaryDec() throws Exception { + assertExpression("${in.header.bar}--", 122); + assertExpression("-------------", "-------------"); + assertExpression("Logging -- start --", "Logging -- start --"); + assertExpression("Logging --- start ---", "Logging --- start ---"); + assertExpression("-- start --", "-- start --"); + assertExpression("--- start ---", "--- start ---"); + + assertPredicate("${in.header.bar}-- == 122", true); + assertPredicate("${in.header.bar}-- == 123", false); + assertPredicate("${in.header.bar}-- == 124", false); + } + + @Test + public void testStartsWith() throws Exception { + exchange.getIn().setBody("Hello there"); + assertPredicate("${in.body} starts with 'Hello'", true); + assertPredicate("${in.body} starts with 'H'", true); + assertPredicate("${in.body} starts with 'Hello there'", true); + assertPredicate("${in.body} starts with 'Hello ther'", true); + assertPredicate("${in.body} starts with 'ello there'", false); + assertPredicate("${in.body} starts with 'Hi'", false); + assertPredicate("${in.body} startsWith 'Hello'", true); + assertPredicate("${in.body} startsWith 'H'", true); + assertPredicate("${in.body} startsWith 'Hello there'", true); + assertPredicate("${in.body} startsWith 'Hello ther'", true); + assertPredicate("${in.body} startsWith 'ello there'", false); + assertPredicate("${in.body} startsWith 'Hi'", false); + } + + @Test + public void testEndsWith() throws Exception { + exchange.getIn().setBody("Hello there"); + assertPredicate("${in.body} ends with 'there'", true); + assertPredicate("${in.body} ends with 're'", true); + assertPredicate("${in.body} ends with ' there'", true); + assertPredicate("${in.body} ends with 'Hello there'", true); + assertPredicate("${in.body} ends with 'Hello ther'", false); + assertPredicate("${in.body} ends with 'Hi'", false); + assertPredicate("${in.body} endsWith 'there'", true); + assertPredicate("${in.body} endsWith 're'", true); + assertPredicate("${in.body} endsWith ' there'", true); + assertPredicate("${in.body} endsWith 'Hello there'", true); + assertPredicate("${in.body} endsWith 'Hello ther'", false); + assertPredicate("${in.body} endsWith 'Hi'", false); + } + + @Override + protected String getLanguageName() { + return "csimple"; + } + + public class MyFileNameGenerator { + public String generateFilename(Exchange exchange) { + return "abc"; + } + + public int generateId(Exchange exchange) { + return 123; + } + } + +} diff --git a/core/camel-core-languages/src/main/java/org/apache/camel/language/csimple/CSimpleHelper.java b/core/camel-core-languages/src/main/java/org/apache/camel/language/csimple/CSimpleHelper.java index f0a8cc2..7f78093 100644 --- a/core/camel-core-languages/src/main/java/org/apache/camel/language/csimple/CSimpleHelper.java +++ b/core/camel-core-languages/src/main/java/org/apache/camel/language/csimple/CSimpleHelper.java @@ -34,6 +34,7 @@ import java.util.regex.Pattern; import org.apache.camel.CamelContext; import org.apache.camel.CamelExchangeException; import org.apache.camel.Exchange; +import org.apache.camel.Expression; import org.apache.camel.ExpressionIllegalSyntaxException; import org.apache.camel.InvalidPayloadException; import org.apache.camel.Message; @@ -424,7 +425,9 @@ public final class CSimpleHelper { properties[3] = ref; properties[1] = method; properties[4] = scope; - return bean.createExpression(null, properties).evaluate(exchange, Object.class); + Expression exp = bean.createExpression(null, properties); + exp.init(exchange.getContext()); + return exp.evaluate(exchange, Object.class); } private static Language getOrCreateBeanLanguage(CamelContext camelContext) { diff --git a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionParser.java b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionParser.java index 7b5740d..ca600d8 100644 --- a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionParser.java +++ b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionParser.java @@ -228,6 +228,10 @@ public class SimpleExpressionParser extends BaseSimpleParser { exp = exp.replaceAll("\n", "\\\\n"); exp = exp.replaceAll("\t", "\\\\t"); exp = exp.replaceAll("\r", "\\\\r"); + if (exp.endsWith("\\") && !exp.endsWith("\\\\")) { + // there is a single trailing slash which we need to escape + exp += "\\"; + } sb.append(exp); sb.append("\""); } else { diff --git a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimplePredicateParser.java b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimplePredicateParser.java index 71d173c..c928f08 100644 --- a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimplePredicateParser.java +++ b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimplePredicateParser.java @@ -178,6 +178,10 @@ public class SimplePredicateParser extends BaseSimpleParser { exp = exp.replaceAll("\n", "\\\\n"); exp = exp.replaceAll("\t", "\\\\t"); exp = exp.replaceAll("\r", "\\\\r"); + if (exp.endsWith("\\") && !exp.endsWith("\\\\")) { + // there is a single trailing slash which we need to escape + exp += "\\"; + } sb.append(exp); sb.append("\""); } else { diff --git a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/BinaryExpression.java b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/BinaryExpression.java index 4afdb65..9ed7a9c 100644 --- a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/BinaryExpression.java +++ b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/BinaryExpression.java @@ -305,9 +305,21 @@ public class BinaryExpression extends BaseSimpleNode { } else if (operator == BinaryOperatorType.NOT_CONTAINS_IGNORECASE) { return "!containsIgnoreCase(exchange, " + leftExp + ", " + rightExp + ")"; } else if (operator == BinaryOperatorType.IS) { - return "is(exchange, " + leftExp + ", " + rightExp + ".class" + ")"; + String type = StringHelper.removeQuotes(rightExp); + if (!type.endsWith(".class")) { + type = type + ".class"; + } + type = type.replace('$', '.'); + type = type.trim(); + return "is(exchange, " + leftExp + ", " + type + ")"; } else if (operator == BinaryOperatorType.NOT_IS) { - return "!is(exchange, " + leftExp + ", " + rightExp + ")"; + String type = StringHelper.removeQuotes(rightExp); + if (!type.endsWith(".class")) { + type = type + ".class"; + } + type = type.replace('$', '.'); + type = type.trim(); + return "!is(exchange, " + leftExp + ", " + type + ")"; } else if (operator == BinaryOperatorType.REGEX) { // regexp is a pain with escapes String escaped = StringHelper.replaceAll(rightExp, "\\", "\\\\"); 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 93dc783..9d7d871 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 @@ -178,7 +178,7 @@ public abstract class LanguageSupport implements Language, IsSingleton, CamelCon } } - return camelContext.getTypeConverter().convertTo(type, value); + return getCamelContext().getTypeConverter().convertTo(type, value); } } diff --git a/core/camel-support/src/main/java/org/apache/camel/support/ObjectHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/ObjectHelper.java index 18e477c..64f613f 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/ObjectHelper.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/ObjectHelper.java @@ -119,6 +119,17 @@ public final class ObjectHelper { Long rightNum = (Long) rightValue; return leftNum.compareTo(rightNum) == 0; } + } else if ((rightValue instanceof String) && + (leftValue instanceof Integer || leftValue instanceof Long)) { + if (leftValue instanceof Integer) { + Integer leftNum = (Integer) leftValue; + Integer rightNum = Integer.valueOf((String) rightValue); + return leftNum.compareTo(rightNum) == 0; + } else { + Long leftNum = (Long) leftValue; + Long rightNum = Long.valueOf((String) rightValue); + return leftNum.compareTo(rightNum) == 0; + } } else if (rightValue instanceof Double && leftValue instanceof String && isFloatingNumber((String) leftValue)) { Double leftNum = Double.valueOf((String) leftValue); Double rightNum = (Double) rightValue; @@ -208,6 +219,17 @@ public final class ObjectHelper { Long rightNum = (Long) rightValue; return leftNum.compareTo(rightNum); } + } else if ((rightValue instanceof String) && + (leftValue instanceof Integer || leftValue instanceof Long)) { + if (leftValue instanceof Integer) { + Integer leftNum = (Integer) leftValue; + Integer rightNum = Integer.valueOf((String) rightValue); + return leftNum.compareTo(rightNum); + } else { + Long leftNum = (Long) leftValue; + Long rightNum = Long.valueOf((String) rightValue); + return leftNum.compareTo(rightNum); + } } else if (rightValue instanceof Double && leftValue instanceof String && isFloatingNumber((String) leftValue)) { Double leftNum = Double.valueOf((String) leftValue); Double rightNum = (Double) rightValue;