You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2017/01/13 11:30:50 UTC

[1/3] camel git commit: CAMEL-10702: camel-jsonpath - Have an easy way of defining predicates with a single operator instead of having to grok the half complex style of jsonpath.

Repository: camel
Updated Branches:
  refs/heads/master 83c3e86d5 -> 73907c022


CAMEL-10702: camel-jsonpath - Have an easy way of defining predicates with a single operator instead of having to grok the half complex style of jsonpath.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/73907c02
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/73907c02
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/73907c02

Branch: refs/heads/master
Commit: 73907c022cbebf128e65dd79e2770906cfbe6326
Parents: cfbe791
Author: Claus Ibsen <da...@apache.org>
Authored: Fri Jan 13 12:25:11 2017 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Fri Jan 13 12:30:42 2017 +0100

----------------------------------------------------------------------
 .../model/language/JsonPathExpression.java      | 19 +++++
 .../JsonPathLanguageConfiguration.java          | 12 +++
 .../src/main/docs/jsonpath-language.adoc        | 36 ++++++++-
 .../camel/jsonpath/JsonPathExpression.java      | 26 +++++-
 .../easypredicate/EasyPredicateOperators.java   | 58 ++++---------
 .../easypredicate/EasyPredicateParser.java      | 85 +++++++++++++++++---
 .../apache/camel/jsonpath/JsonPathCBRTest.java  |  4 +-
 .../jsonpath/JsonPathWithEvenSimpleCBRTest.java | 80 ------------------
 .../EasyJsonPathWithRootSimpleCBRTest.java      | 80 ++++++++++++++++++
 .../EasyJsonPathWithSimpleCBRTest.java          | 80 ++++++++++++++++++
 .../src/test/resources/average.json             |  2 +-
 .../src/test/resources/cheap.json               |  2 +-
 .../src/test/resources/expensive.json           |  2 +-
 13 files changed, 341 insertions(+), 145 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/73907c02/camel-core/src/main/java/org/apache/camel/model/language/JsonPathExpression.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/language/JsonPathExpression.java b/camel-core/src/main/java/org/apache/camel/model/language/JsonPathExpression.java
index 8c9f786..e06641a 100644
--- a/camel-core/src/main/java/org/apache/camel/model/language/JsonPathExpression.java
+++ b/camel-core/src/main/java/org/apache/camel/model/language/JsonPathExpression.java
@@ -46,6 +46,8 @@ public class JsonPathExpression extends ExpressionDefinition {
     private Boolean suppressExceptions;
     @XmlAttribute @Metadata(defaultValue = "true")
     private Boolean allowSimple;
+    @XmlAttribute @Metadata(defaultValue = "true")
+    private Boolean allowEasyPredicate;
 
     public JsonPathExpression() {
     }
@@ -91,6 +93,17 @@ public class JsonPathExpression extends ExpressionDefinition {
         this.allowSimple = allowSimple;
     }
 
+    public Boolean getAllowEasyPredicate() {
+        return allowEasyPredicate;
+    }
+
+    /**
+     * Whether to allow using the easy predicate parser to pre-parse predicates.
+     */
+    public void setAllowEasyPredicate(Boolean allowEasyPredicate) {
+        this.allowEasyPredicate = allowEasyPredicate;
+    }
+
     /**
      * Whether to suppress exceptions such as PathNotFoundException.
      */
@@ -125,6 +138,9 @@ public class JsonPathExpression extends ExpressionDefinition {
         if (allowSimple != null) {
             setProperty(expression, "allowSimple", allowSimple);
         }
+        if (allowEasyPredicate != null) {
+            setProperty(expression, "allowEasyPredicate", allowEasyPredicate);
+        }
         super.configureExpression(camelContext, expression);
     }
 
@@ -139,6 +155,9 @@ public class JsonPathExpression extends ExpressionDefinition {
         if (allowSimple != null) {
             setProperty(predicate, "allowSimple", allowSimple);
         }
+        if (allowEasyPredicate != null) {
+            setProperty(predicate, "allowEasyPredicate", allowEasyPredicate);
+        }
         super.configurePredicate(camelContext, predicate);
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/73907c02/components-starter/camel-jsonpath-starter/src/main/java/org/apache/camel/jsonpath/springboot/JsonPathLanguageConfiguration.java
----------------------------------------------------------------------
diff --git a/components-starter/camel-jsonpath-starter/src/main/java/org/apache/camel/jsonpath/springboot/JsonPathLanguageConfiguration.java b/components-starter/camel-jsonpath-starter/src/main/java/org/apache/camel/jsonpath/springboot/JsonPathLanguageConfiguration.java
index 36ced8f..616362d 100644
--- a/components-starter/camel-jsonpath-starter/src/main/java/org/apache/camel/jsonpath/springboot/JsonPathLanguageConfiguration.java
+++ b/components-starter/camel-jsonpath-starter/src/main/java/org/apache/camel/jsonpath/springboot/JsonPathLanguageConfiguration.java
@@ -35,6 +35,10 @@ public class JsonPathLanguageConfiguration {
      */
     private Boolean allowSimple = true;
     /**
+     * Whether to allow using the easy predicate parser to pre-parse predicates.
+     */
+    private Boolean allowEasyPredicate = true;
+    /**
      * Whether to trim the value to remove leading and trailing whitespaces and
      * line breaks
      */
@@ -56,6 +60,14 @@ public class JsonPathLanguageConfiguration {
         this.allowSimple = allowSimple;
     }
 
+    public Boolean getAllowEasyPredicate() {
+        return allowEasyPredicate;
+    }
+
+    public void setAllowEasyPredicate(Boolean allowEasyPredicate) {
+        this.allowEasyPredicate = allowEasyPredicate;
+    }
+
     public Boolean getTrim() {
         return trim;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/73907c02/components/camel-jsonpath/src/main/docs/jsonpath-language.adoc
----------------------------------------------------------------------
diff --git a/components/camel-jsonpath/src/main/docs/jsonpath-language.adoc b/components/camel-jsonpath/src/main/docs/jsonpath-language.adoc
index 57f6fec..d45881c 100644
--- a/components/camel-jsonpath/src/main/docs/jsonpath-language.adoc
+++ b/components/camel-jsonpath/src/main/docs/jsonpath-language.adoc
@@ -22,7 +22,7 @@ from("queue:books.new")
 
 
 // language options: START
-The JSonPath language supports 4 options which are listed below.
+The JSonPath language supports 5 options which are listed below.
 
 
 
@@ -33,6 +33,7 @@ The JSonPath language supports 4 options which are listed below.
 | resultType |  | String | Sets the class name of the result type (type from output)
 | suppressExceptions | false | Boolean | Whether to suppress exceptions such as PathNotFoundException.
 | allowSimple | true | Boolean | Whether to allow in inlined simple exceptions in the json path expression
+| allowEasyPredicate | true | Boolean | Whether to allow using the easy predicate parser to pre-parse predicates.
 | trim | true | Boolean | Whether to trim the value to remove leading and trailing whitespaces and line breaks
 |=======================================================================
 {% endraw %}
@@ -73,6 +74,37 @@ follows
 See the https://code.google.com/p/json-path/[JSonPath] project page for
 further examples.
 
+### Easy Syntax
+
+*Available as of Camel 2.19*
+
+When you just want to define a basic predicate using jsonpath syntax it can be a bit hard to remember the syntax.
+ So for example to find out all the cheap books you have to do
+
+    $.store.book[?(@.price < 20)]
+
+However what if you could just write it as
+
+    store.book.price < 20
+
+And you can omit the path if you just want to look at nodes with a price key
+
+    price < 20
+
+To support this there is a `EasyPredicateParser` which kicks-in if you have define the predicate
+  using a basic style. That means the predicate must not start with the `$` sign, and only include one operator.
+
+The easy syntax is:
+
+   left OP right
+
+You can use Camel simple language in the right operator, eg
+
+    store.book.price < ${header.limit}
+
+
+
+
 ### Supported message body types
 
 Camel JSonPath supports message body using the following types:
@@ -240,4 +272,4 @@ link:download.html[the download page for the latest versions]).
   <artifactId>camel-jsonpath</artifactId>
   <version>x.x.x</version>
 </dependency>
------------------------------------------
\ No newline at end of file
+-----------------------------------------

http://git-wip-us.apache.org/repos/asf/camel/blob/73907c02/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java
----------------------------------------------------------------------
diff --git a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java
index 3e79f9a..3e46a98 100644
--- a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java
+++ b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java
@@ -24,9 +24,13 @@ import org.apache.camel.ExpressionEvaluationException;
 import org.apache.camel.ExpressionIllegalSyntaxException;
 import org.apache.camel.jsonpath.easypredicate.EasyPredicateParser;
 import org.apache.camel.support.ExpressionAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class JsonPathExpression extends ExpressionAdapter implements AfterPropertiesConfigured {
 
+    private static final Logger LOG = LoggerFactory.getLogger(JsonPathExpression.class);
+
     private final String expression;
     private JsonPathEngine engine;
 
@@ -34,6 +38,7 @@ public class JsonPathExpression extends ExpressionAdapter implements AfterProper
     private Class<?> resultType;
     private boolean suppressExceptions;
     private boolean allowSimple = true;
+    private boolean allowEasyPredicate = true;
     private Option[] options;
 
     public JsonPathExpression(String expression) {
@@ -84,6 +89,18 @@ public class JsonPathExpression extends ExpressionAdapter implements AfterProper
         this.allowSimple = allowSimple;
     }
 
+    public boolean isAllowEasyPredicate() {
+        return allowEasyPredicate;
+    }
+
+    /**
+     * Whether to allow using the easy predicate parser to pre-parse predicates.
+     * See {@link EasyPredicateParser} for more details.
+     */
+    public void setAllowEasyPredicate(boolean allowEasyPredicate) {
+        this.allowEasyPredicate = allowEasyPredicate;
+    }
+
     public Option[] getOptions() {
         return options;
     }
@@ -116,10 +133,17 @@ public class JsonPathExpression extends ExpressionAdapter implements AfterProper
 
     public void init() {
         String exp = expression;
-        if (predicate) {
+
+        if (predicate && isAllowEasyPredicate()) {
             EasyPredicateParser parser = new EasyPredicateParser();
             exp = parser.parse(expression);
+
+            if (!exp.equals(expression)) {
+                LOG.debug("EasyPredicateParser parsed {} -> {}", expression, exp);
+            }
         }
+
+        LOG.debug("Initializing {} using: {}", predicate ? "predicate" : "expression", exp);
         try {
             engine = new JsonPathEngine(exp, suppressExceptions, allowSimple, options);
         } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/camel/blob/73907c02/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/easypredicate/EasyPredicateOperators.java
----------------------------------------------------------------------
diff --git a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/easypredicate/EasyPredicateOperators.java b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/easypredicate/EasyPredicateOperators.java
index 4f49504..cd38cea 100644
--- a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/easypredicate/EasyPredicateOperators.java
+++ b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/easypredicate/EasyPredicateOperators.java
@@ -5,9 +5,9 @@
  * 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
+ *
+ *      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.
@@ -16,14 +16,13 @@
  */
 package org.apache.camel.jsonpath.easypredicate;
 
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.List;
 import java.util.Objects;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
 
-public class EasyPredicateOperators {
+/**
+ * Json path operators
+ */
+public final class EasyPredicateOperators {
 
     private static final String EQ = "==";
     private static final String NE = "!=";
@@ -39,58 +38,29 @@ public class EasyPredicateOperators {
 
     private static final String[] OPS = new String[]{EQ, NE, LT, LE, GT, GE, REG, IN, NIN, SIZE, EMPTY};
 
-    private static final Pattern PATTERN = Pattern.compile("\\s(" + Arrays.stream(OPS).collect(Collectors.joining("|")) + ")\\s");
+    private EasyPredicateOperators() {
+    }
 
     /**
-     * Does the expression have any operator?
+     * Does the expression have any operator (with single space around)?
      */
-    public static boolean hasOperator(String exp) {
+    static boolean hasOperator(String exp) {
+        // need to have space around operator to not match eg in used in some other word
         return Arrays.stream(OPS).anyMatch(o -> exp.contains(" " + o + ""));
     }
 
     /**
-     * Is this an operator
+     * Is this an operator (with no space around)
      */
     static boolean isOperator(String exp) {
         return Arrays.stream(OPS).anyMatch(s -> Objects.equals(s, exp));
     }
 
     /**
-     * Gets the operator
+     * Gets the operator (with single space around)
      */
     static String getOperatorAtStart(String exp) {
         return Arrays.stream(OPS).filter(o -> exp.startsWith(" " + o + "")).findFirst().orElse(null);
     }
 
-    public static String[] tokens(String exp) {
-        List<String> list = new ArrayList<>();
-
-        StringBuilder part = new StringBuilder();
-        for (int i = 0; i < exp.length(); i++) {
-
-            // is there a new operator
-            String s = exp.substring(i);
-            String op = getOperatorAtStart(s);
-            if (op != null) {
-                if (part.length() > 0) {
-                    list.add(part.toString());
-                    part.setLength(0);
-                }
-                list.add(op.trim());
-                // move i ahead
-                i = i + op.length() + 1;
-            } else {
-                char ch = exp.charAt(i);
-                part.append(ch);
-            }
-        }
-
-        // ant leftovers
-        if (part.length() > 0) {
-            list.add(part.toString());
-        }
-
-        return list.toArray(new String[list.size()]);
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/73907c02/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/easypredicate/EasyPredicateParser.java
----------------------------------------------------------------------
diff --git a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/easypredicate/EasyPredicateParser.java b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/easypredicate/EasyPredicateParser.java
index f523f46..fd866dc 100644
--- a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/easypredicate/EasyPredicateParser.java
+++ b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/easypredicate/EasyPredicateParser.java
@@ -5,9 +5,9 @@
  * 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
+ *
+ *      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.
@@ -16,27 +16,42 @@
  */
 package org.apache.camel.jsonpath.easypredicate;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import static org.apache.camel.jsonpath.easypredicate.EasyPredicateOperators.hasOperator;
 import static org.apache.camel.jsonpath.easypredicate.EasyPredicateOperators.isOperator;
-import static org.apache.camel.jsonpath.easypredicate.EasyPredicateOperators.tokens;
 
+/**
+ * To allow defining very easy jsonpath predicates using the syntax: left OP right
+ * <p/>
+ * The easy parser is only in use if the predicate do not start with the <tt>$</tt> sign which is used by jsonpath.
+ * The parser is intended for predicates only.
+ */
 public class EasyPredicateParser {
 
-    public String parse(String exp) {
-        if (exp.startsWith("$")) {
+    /**
+     * Parses the predicate
+     *
+     * @param predicate the predicate
+     * @return the parsed predicate or the original predicate if easy parser did not kick-in
+     */
+    public String parse(String predicate) {
+
+        if (predicate.startsWith("$")) {
             // regular json path so skip
-            return exp;
+            return predicate;
         }
 
         // must have an operator
-        if (!hasOperator(exp)) {
-            return exp;
+        if (!hasOperator(predicate)) {
+            return predicate;
         }
 
         StringBuilder sb = new StringBuilder();
 
         // grab before operator
-        String[] parts = tokens(exp);
+        String[] parts = tokens(predicate);
 
         // only support one operator currently
         if (parts.length == 3) {
@@ -44,9 +59,16 @@ public class EasyPredicateParser {
             String op = parts[1];
             String next = parts[2];
             if (isOperator(op)) {
+                String before;
+                String after;
                 int pos = prev.lastIndexOf(".");
-                String before = prev.substring(0, pos);
-                String after = prev.substring(pos + 1);
+                if (pos == -1) {
+                    before = "..*";
+                    after = prev;
+                } else {
+                    before = prev.substring(0, pos);
+                    after = prev.substring(pos + 1);
+                }
                 sb.append("$");
                 if (!before.startsWith(".")) {
                     sb.append(".");
@@ -64,7 +86,44 @@ public class EasyPredicateParser {
         }
 
         // not able to parse so return as-is
-        return exp;
+        return predicate;
+    }
+
+    /**
+     * Splits the predicate into: left OP right
+     *
+     * @param predicate the predicate
+     * @return the splitted parts
+     */
+    private static String[] tokens(String predicate) {
+        List<String> list = new ArrayList<>();
+
+        StringBuilder part = new StringBuilder();
+        for (int i = 0; i < predicate.length(); i++) {
+
+            // is there a new operator
+            String s = predicate.substring(i);
+            String op = EasyPredicateOperators.getOperatorAtStart(s);
+            if (op != null) {
+                if (part.length() > 0) {
+                    list.add(part.toString());
+                    part.setLength(0);
+                }
+                list.add(op.trim());
+                // move i ahead
+                i = i + op.length() + 1;
+            } else {
+                char ch = predicate.charAt(i);
+                part.append(ch);
+            }
+        }
+
+        // ant leftovers
+        if (part.length() > 0) {
+            list.add(part.toString());
+        }
+
+        return list.toArray(new String[list.size()]);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/73907c02/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathCBRTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathCBRTest.java b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathCBRTest.java
index 4e85260..b9b5654 100644
--- a/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathCBRTest.java
+++ b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathCBRTest.java
@@ -49,7 +49,7 @@ public class JsonPathCBRTest extends CamelTestSupport {
                 
                 from("direct:bicycle2")
                     .choice()
-                    .when(PredicateBuilder.isLessThan(ExpressionBuilder.languageExpression("jsonpath", "$.store.bicycle.price"), ExpressionBuilder.constantExpression(20)))
+                    .when(PredicateBuilder.isLessThan(ExpressionBuilder.languageExpression("jsonpath", "$.store.bicycle.price"), ExpressionBuilder.constantExpression(100)))
                         .to("mock:cheap")
                     .otherwise()
                         .to("mock:expensive");
@@ -59,7 +59,7 @@ public class JsonPathCBRTest extends CamelTestSupport {
     
     public static class BeanPredicate {
         public boolean checkPrice(@JsonPath("$.store.bicycle.price") double price) {
-            return price < 20;
+            return price < 100;
         }
     }
     

http://git-wip-us.apache.org/repos/asf/camel/blob/73907c02/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathWithEvenSimpleCBRTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathWithEvenSimpleCBRTest.java b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathWithEvenSimpleCBRTest.java
deleted file mode 100644
index 8db54d5..0000000
--- a/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathWithEvenSimpleCBRTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * 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.jsonpath;
-
-import java.io.File;
-
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.test.junit4.CamelTestSupport;
-import org.junit.Test;
-
-public class JsonPathWithEvenSimpleCBRTest extends CamelTestSupport {
-
-    @Override
-    protected RouteBuilder createRouteBuilder() throws Exception {
-        return new RouteBuilder() {
-            @Override
-            public void configure() throws Exception {
-                from("direct:start")
-                    .choice()
-                        .when().jsonpath("store.book.price < ${header.cheap}")
-                            .to("mock:cheap")
-                        .when().jsonpath("store.book.price < ${header.average}")
-                            .to("mock:average")
-                        .otherwise()
-                            .to("mock:expensive");
-            }
-        };
-    }
-    
-    @Test
-    public void testCheap() throws Exception {
-        getMockEndpoint("mock:cheap").expectedMessageCount(1);
-        getMockEndpoint("mock:average").expectedMessageCount(0);
-        getMockEndpoint("mock:expensive").expectedMessageCount(0);
-
-        fluentTemplate.withHeader("cheap", 10).withHeader("average", 30).withBody(new File("src/test/resources/cheap.json"))
-                .to("direct:start").send();
-
-        assertMockEndpointsSatisfied();
-    }
-
-    @Test
-    public void testAverage() throws Exception {
-        getMockEndpoint("mock:cheap").expectedMessageCount(0);
-        getMockEndpoint("mock:average").expectedMessageCount(1);
-        getMockEndpoint("mock:expensive").expectedMessageCount(0);
-
-        fluentTemplate.withHeader("cheap", 10).withHeader("average", 30).withBody(new File("src/test/resources/average.json"))
-                .to("direct:start").send();
-
-        assertMockEndpointsSatisfied();
-    }
-
-    @Test
-    public void testExpensive() throws Exception {
-        getMockEndpoint("mock:cheap").expectedMessageCount(0);
-        getMockEndpoint("mock:average").expectedMessageCount(0);
-        getMockEndpoint("mock:expensive").expectedMessageCount(1);
-
-        fluentTemplate.withHeader("cheap", 10).withHeader("average", 30).withBody(new File("src/test/resources/expensive.json"))
-                .to("direct:start").send();
-
-        assertMockEndpointsSatisfied();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/73907c02/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/easypredicate/EasyJsonPathWithRootSimpleCBRTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/easypredicate/EasyJsonPathWithRootSimpleCBRTest.java b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/easypredicate/EasyJsonPathWithRootSimpleCBRTest.java
new file mode 100644
index 0000000..1d56bb4
--- /dev/null
+++ b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/easypredicate/EasyJsonPathWithRootSimpleCBRTest.java
@@ -0,0 +1,80 @@
+/**
+ * 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.jsonpath.easypredicate;
+
+import java.io.File;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+public class EasyJsonPathWithRootSimpleCBRTest extends CamelTestSupport {
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                    .choice()
+                        .when().jsonpath("price < ${header.cheap}")
+                            .to("mock:cheap")
+                        .when().jsonpath("price < ${header.average}")
+                            .to("mock:average")
+                        .otherwise()
+                            .to("mock:expensive");
+            }
+        };
+    }
+    
+    @Test
+    public void testCheap() throws Exception {
+        getMockEndpoint("mock:cheap").expectedMessageCount(1);
+        getMockEndpoint("mock:average").expectedMessageCount(0);
+        getMockEndpoint("mock:expensive").expectedMessageCount(0);
+
+        fluentTemplate.withHeader("cheap", 10).withHeader("average", 30).withBody(new File("src/test/resources/cheap.json"))
+                .to("direct:start").send();
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testAverage() throws Exception {
+        getMockEndpoint("mock:cheap").expectedMessageCount(0);
+        getMockEndpoint("mock:average").expectedMessageCount(1);
+        getMockEndpoint("mock:expensive").expectedMessageCount(0);
+
+        fluentTemplate.withHeader("cheap", 10).withHeader("average", 30).withBody(new File("src/test/resources/average.json"))
+                .to("direct:start").send();
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testExpensive() throws Exception {
+        getMockEndpoint("mock:cheap").expectedMessageCount(0);
+        getMockEndpoint("mock:average").expectedMessageCount(0);
+        getMockEndpoint("mock:expensive").expectedMessageCount(1);
+
+        fluentTemplate.withHeader("cheap", 10).withHeader("average", 30).withBody(new File("src/test/resources/expensive.json"))
+                .to("direct:start").send();
+
+        assertMockEndpointsSatisfied();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/73907c02/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/easypredicate/EasyJsonPathWithSimpleCBRTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/easypredicate/EasyJsonPathWithSimpleCBRTest.java b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/easypredicate/EasyJsonPathWithSimpleCBRTest.java
new file mode 100644
index 0000000..5c90001
--- /dev/null
+++ b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/easypredicate/EasyJsonPathWithSimpleCBRTest.java
@@ -0,0 +1,80 @@
+/**
+ * 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.jsonpath.easypredicate;
+
+import java.io.File;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+public class EasyJsonPathWithSimpleCBRTest extends CamelTestSupport {
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                    .choice()
+                        .when().jsonpath("store.book.price < ${header.cheap}")
+                            .to("mock:cheap")
+                        .when().jsonpath("store.book.price < ${header.average}")
+                            .to("mock:average")
+                        .otherwise()
+                            .to("mock:expensive");
+            }
+        };
+    }
+    
+    @Test
+    public void testCheap() throws Exception {
+        getMockEndpoint("mock:cheap").expectedMessageCount(1);
+        getMockEndpoint("mock:average").expectedMessageCount(0);
+        getMockEndpoint("mock:expensive").expectedMessageCount(0);
+
+        fluentTemplate.withHeader("cheap", 10).withHeader("average", 30).withBody(new File("src/test/resources/cheap.json"))
+                .to("direct:start").send();
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testAverage() throws Exception {
+        getMockEndpoint("mock:cheap").expectedMessageCount(0);
+        getMockEndpoint("mock:average").expectedMessageCount(1);
+        getMockEndpoint("mock:expensive").expectedMessageCount(0);
+
+        fluentTemplate.withHeader("cheap", 10).withHeader("average", 30).withBody(new File("src/test/resources/average.json"))
+                .to("direct:start").send();
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testExpensive() throws Exception {
+        getMockEndpoint("mock:cheap").expectedMessageCount(0);
+        getMockEndpoint("mock:average").expectedMessageCount(0);
+        getMockEndpoint("mock:expensive").expectedMessageCount(1);
+
+        fluentTemplate.withHeader("cheap", 10).withHeader("average", 30).withBody(new File("src/test/resources/expensive.json"))
+                .to("direct:start").send();
+
+        assertMockEndpointsSatisfied();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/73907c02/components/camel-jsonpath/src/test/resources/average.json
----------------------------------------------------------------------
diff --git a/components/camel-jsonpath/src/test/resources/average.json b/components/camel-jsonpath/src/test/resources/average.json
index bd888dc..cd71d97 100644
--- a/components/camel-jsonpath/src/test/resources/average.json
+++ b/components/camel-jsonpath/src/test/resources/average.json
@@ -11,7 +11,7 @@
         ],
         "bicycle": {
             "color": "red",
-            "price": 19.95
+            "price": 99.95
         }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/73907c02/components/camel-jsonpath/src/test/resources/cheap.json
----------------------------------------------------------------------
diff --git a/components/camel-jsonpath/src/test/resources/cheap.json b/components/camel-jsonpath/src/test/resources/cheap.json
index 02df81c..a9783a7 100644
--- a/components/camel-jsonpath/src/test/resources/cheap.json
+++ b/components/camel-jsonpath/src/test/resources/cheap.json
@@ -10,7 +10,7 @@
         ],
         "bicycle": {
             "color": "red",
-            "price": 19.95
+            "price": 99.95
         }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/73907c02/components/camel-jsonpath/src/test/resources/expensive.json
----------------------------------------------------------------------
diff --git a/components/camel-jsonpath/src/test/resources/expensive.json b/components/camel-jsonpath/src/test/resources/expensive.json
index 589da85..df24270 100644
--- a/components/camel-jsonpath/src/test/resources/expensive.json
+++ b/components/camel-jsonpath/src/test/resources/expensive.json
@@ -11,7 +11,7 @@
         ],
         "bicycle": {
             "color": "red",
-            "price": 19.95
+            "price": 99.95
         }
     }
 }
\ No newline at end of file


[3/3] camel git commit: Typo

Posted by da...@apache.org.
Typo


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/69a19a32
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/69a19a32
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/69a19a32

Branch: refs/heads/master
Commit: 69a19a32090d5ce24f3060ae14441633520e77eb
Parents: 83c3e86
Author: Claus Ibsen <da...@apache.org>
Authored: Fri Jan 13 11:00:06 2017 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Fri Jan 13 12:30:42 2017 +0100

----------------------------------------------------------------------
 .../org/apache/camel/language/simple/SimpleExpressionParser.java   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/69a19a32/camel-core/src/main/java/org/apache/camel/language/simple/SimpleExpressionParser.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/language/simple/SimpleExpressionParser.java b/camel-core/src/main/java/org/apache/camel/language/simple/SimpleExpressionParser.java
index c10e078..bf5fe8d 100644
--- a/camel-core/src/main/java/org/apache/camel/language/simple/SimpleExpressionParser.java
+++ b/camel-core/src/main/java/org/apache/camel/language/simple/SimpleExpressionParser.java
@@ -72,7 +72,7 @@ public class SimpleExpressionParser extends BaseSimpleParser {
         }
 
         // now after parsing we need a bit of work to do, to make it easier to turn the tokens
-        // into and ast, and then from the ast, to Camel expression(s).
+        // into an ast, and then from the ast, to Camel expression(s).
         // hence why there is a number of tasks going on below to accomplish this
 
         // turn the tokens into the ast model


[2/3] camel git commit: CAMEL-10702: camel-jsonpath - Have an easy way of defining predicates with a single operator instead of having to grok the half complex style of jsonpath.

Posted by da...@apache.org.
CAMEL-10702: camel-jsonpath - Have an easy way of defining predicates with a single operator instead of having to grok the half complex style of jsonpath.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/cfbe791d
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/cfbe791d
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/cfbe791d

Branch: refs/heads/master
Commit: cfbe791d6f08f5a4063f7b93555563e041adf98c
Parents: 69a19a3
Author: Claus Ibsen <da...@apache.org>
Authored: Fri Jan 13 11:33:15 2017 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Fri Jan 13 12:30:42 2017 +0100

----------------------------------------------------------------------
 .../camel/jsonpath/JsonPathExpression.java      | 22 ++++-
 .../apache/camel/jsonpath/JsonPathLanguage.java |  2 +
 .../easypredicate/EasyPredicateOperators.java   | 96 ++++++++++++++++++++
 .../easypredicate/EasyPredicateParser.java      | 70 ++++++++++++++
 .../jsonpath/JsonPathWithEvenSimpleCBRTest.java | 80 ++++++++++++++++
 5 files changed, 268 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/cfbe791d/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java
----------------------------------------------------------------------
diff --git a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java
index 37eeab1..3e79f9a 100644
--- a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java
+++ b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java
@@ -22,6 +22,7 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.ExpressionEvaluationException;
 import org.apache.camel.ExpressionIllegalSyntaxException;
+import org.apache.camel.jsonpath.easypredicate.EasyPredicateParser;
 import org.apache.camel.support.ExpressionAdapter;
 
 public class JsonPathExpression extends ExpressionAdapter implements AfterPropertiesConfigured {
@@ -29,6 +30,7 @@ public class JsonPathExpression extends ExpressionAdapter implements AfterProper
     private final String expression;
     private JsonPathEngine engine;
 
+    private boolean predicate;
     private Class<?> resultType;
     private boolean suppressExceptions;
     private boolean allowSimple = true;
@@ -38,6 +40,17 @@ public class JsonPathExpression extends ExpressionAdapter implements AfterProper
         this.expression = expression;
     }
 
+    public boolean isPredicate() {
+        return predicate;
+    }
+
+    /**
+     * Whether to be evaluated as a predicate
+     */
+    public void setPredicate(boolean predicate) {
+        this.predicate = predicate;
+    }
+
     public Class<?> getResultType() {
         return resultType;
     }
@@ -102,10 +115,15 @@ public class JsonPathExpression extends ExpressionAdapter implements AfterProper
     }
 
     public void init() {
+        String exp = expression;
+        if (predicate) {
+            EasyPredicateParser parser = new EasyPredicateParser();
+            exp = parser.parse(expression);
+        }
         try {
-            engine = new JsonPathEngine(expression, suppressExceptions, allowSimple, options);
+            engine = new JsonPathEngine(exp, suppressExceptions, allowSimple, options);
         } catch (Exception e) {
-            throw new ExpressionIllegalSyntaxException(expression, e);
+            throw new ExpressionIllegalSyntaxException(exp, e);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/cfbe791d/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathLanguage.java
----------------------------------------------------------------------
diff --git a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathLanguage.java b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathLanguage.java
index 297823b..d2e4d0b 100644
--- a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathLanguage.java
+++ b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathLanguage.java
@@ -58,6 +58,7 @@ public class JsonPathLanguage extends LanguageSupport {
     @Override
     public Predicate createPredicate(final String predicate) {
         JsonPathExpression answer = new JsonPathExpression(predicate);
+        answer.setPredicate(true);
         answer.setResultType(resultType);
         answer.setSuppressExceptions(suppressExceptions);
         answer.setOptions(options);
@@ -68,6 +69,7 @@ public class JsonPathLanguage extends LanguageSupport {
     @Override
     public Expression createExpression(final String expression) {
         JsonPathExpression answer = new JsonPathExpression(expression);
+        answer.setPredicate(false);
         answer.setResultType(resultType);
         answer.setSuppressExceptions(suppressExceptions);
         answer.setOptions(options);

http://git-wip-us.apache.org/repos/asf/camel/blob/cfbe791d/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/easypredicate/EasyPredicateOperators.java
----------------------------------------------------------------------
diff --git a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/easypredicate/EasyPredicateOperators.java b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/easypredicate/EasyPredicateOperators.java
new file mode 100644
index 0000000..4f49504
--- /dev/null
+++ b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/easypredicate/EasyPredicateOperators.java
@@ -0,0 +1,96 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.jsonpath.easypredicate;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+public class EasyPredicateOperators {
+
+    private static final String EQ = "==";
+    private static final String NE = "!=";
+    private static final String LT = "<";
+    private static final String LE = "<=";
+    private static final String GT = ">";
+    private static final String GE = ">=";
+    private static final String REG = "=~";
+    private static final String IN = "in";
+    private static final String NIN = "nin";
+    private static final String SIZE = "size";
+    private static final String EMPTY = "empty";
+
+    private static final String[] OPS = new String[]{EQ, NE, LT, LE, GT, GE, REG, IN, NIN, SIZE, EMPTY};
+
+    private static final Pattern PATTERN = Pattern.compile("\\s(" + Arrays.stream(OPS).collect(Collectors.joining("|")) + ")\\s");
+
+    /**
+     * Does the expression have any operator?
+     */
+    public static boolean hasOperator(String exp) {
+        return Arrays.stream(OPS).anyMatch(o -> exp.contains(" " + o + ""));
+    }
+
+    /**
+     * Is this an operator
+     */
+    static boolean isOperator(String exp) {
+        return Arrays.stream(OPS).anyMatch(s -> Objects.equals(s, exp));
+    }
+
+    /**
+     * Gets the operator
+     */
+    static String getOperatorAtStart(String exp) {
+        return Arrays.stream(OPS).filter(o -> exp.startsWith(" " + o + "")).findFirst().orElse(null);
+    }
+
+    public static String[] tokens(String exp) {
+        List<String> list = new ArrayList<>();
+
+        StringBuilder part = new StringBuilder();
+        for (int i = 0; i < exp.length(); i++) {
+
+            // is there a new operator
+            String s = exp.substring(i);
+            String op = getOperatorAtStart(s);
+            if (op != null) {
+                if (part.length() > 0) {
+                    list.add(part.toString());
+                    part.setLength(0);
+                }
+                list.add(op.trim());
+                // move i ahead
+                i = i + op.length() + 1;
+            } else {
+                char ch = exp.charAt(i);
+                part.append(ch);
+            }
+        }
+
+        // ant leftovers
+        if (part.length() > 0) {
+            list.add(part.toString());
+        }
+
+        return list.toArray(new String[list.size()]);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/cfbe791d/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/easypredicate/EasyPredicateParser.java
----------------------------------------------------------------------
diff --git a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/easypredicate/EasyPredicateParser.java b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/easypredicate/EasyPredicateParser.java
new file mode 100644
index 0000000..f523f46
--- /dev/null
+++ b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/easypredicate/EasyPredicateParser.java
@@ -0,0 +1,70 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.jsonpath.easypredicate;
+
+import static org.apache.camel.jsonpath.easypredicate.EasyPredicateOperators.hasOperator;
+import static org.apache.camel.jsonpath.easypredicate.EasyPredicateOperators.isOperator;
+import static org.apache.camel.jsonpath.easypredicate.EasyPredicateOperators.tokens;
+
+public class EasyPredicateParser {
+
+    public String parse(String exp) {
+        if (exp.startsWith("$")) {
+            // regular json path so skip
+            return exp;
+        }
+
+        // must have an operator
+        if (!hasOperator(exp)) {
+            return exp;
+        }
+
+        StringBuilder sb = new StringBuilder();
+
+        // grab before operator
+        String[] parts = tokens(exp);
+
+        // only support one operator currently
+        if (parts.length == 3) {
+            String prev = parts[0];
+            String op = parts[1];
+            String next = parts[2];
+            if (isOperator(op)) {
+                int pos = prev.lastIndexOf(".");
+                String before = prev.substring(0, pos);
+                String after = prev.substring(pos + 1);
+                sb.append("$");
+                if (!before.startsWith(".")) {
+                    sb.append(".");
+                }
+                sb.append(before);
+                sb.append("[?(@.");
+                sb.append(after);
+                sb.append(" ");
+                sb.append(op);
+                sb.append(" ");
+                sb.append(next);
+                sb.append(")]");
+            }
+            return sb.toString();
+        }
+
+        // not able to parse so return as-is
+        return exp;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/cfbe791d/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathWithEvenSimpleCBRTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathWithEvenSimpleCBRTest.java b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathWithEvenSimpleCBRTest.java
new file mode 100644
index 0000000..8db54d5
--- /dev/null
+++ b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathWithEvenSimpleCBRTest.java
@@ -0,0 +1,80 @@
+/**
+ * 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.jsonpath;
+
+import java.io.File;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+public class JsonPathWithEvenSimpleCBRTest extends CamelTestSupport {
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                    .choice()
+                        .when().jsonpath("store.book.price < ${header.cheap}")
+                            .to("mock:cheap")
+                        .when().jsonpath("store.book.price < ${header.average}")
+                            .to("mock:average")
+                        .otherwise()
+                            .to("mock:expensive");
+            }
+        };
+    }
+    
+    @Test
+    public void testCheap() throws Exception {
+        getMockEndpoint("mock:cheap").expectedMessageCount(1);
+        getMockEndpoint("mock:average").expectedMessageCount(0);
+        getMockEndpoint("mock:expensive").expectedMessageCount(0);
+
+        fluentTemplate.withHeader("cheap", 10).withHeader("average", 30).withBody(new File("src/test/resources/cheap.json"))
+                .to("direct:start").send();
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testAverage() throws Exception {
+        getMockEndpoint("mock:cheap").expectedMessageCount(0);
+        getMockEndpoint("mock:average").expectedMessageCount(1);
+        getMockEndpoint("mock:expensive").expectedMessageCount(0);
+
+        fluentTemplate.withHeader("cheap", 10).withHeader("average", 30).withBody(new File("src/test/resources/average.json"))
+                .to("direct:start").send();
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testExpensive() throws Exception {
+        getMockEndpoint("mock:cheap").expectedMessageCount(0);
+        getMockEndpoint("mock:average").expectedMessageCount(0);
+        getMockEndpoint("mock:expensive").expectedMessageCount(1);
+
+        fluentTemplate.withHeader("cheap", 10).withHeader("average", 30).withBody(new File("src/test/resources/expensive.json"))
+                .to("direct:start").send();
+
+        assertMockEndpointsSatisfied();
+    }
+
+}