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;

Reply via email to