diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/EvaluatorFactory.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/EvaluatorFactory.java index 322a1719..27ef1c8c 100755 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/EvaluatorFactory.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/EvaluatorFactory.java @@ -2,6 +2,7 @@ package com.jayway.jsonpath.internal.filter; import com.jayway.jsonpath.JsonPathException; import com.jayway.jsonpath.Predicate; +import com.jayway.jsonpath.internal.path.PredicateContextImpl; import java.util.HashMap; import java.util.Iterator; @@ -246,7 +247,42 @@ public class EvaluatorFactory { private static class PredicateMatchEvaluator implements Evaluator { @Override public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) { - return right.asPredicateNode().getPredicate().apply(ctx); + Predicate.PredicateContext predicateContext = new PredicateContextImpl( + getNodeValue(left), + ctx.root(), + ctx.configuration(), + null + ); + return right.asPredicateNode().getPredicate().apply(predicateContext); + } + + public Object getNodeValue(ValueNode node) { + if(node.isPatternNode()){ + return ((ValueNodes.PatternNode) node).getCompiledPattern(); + } else if(node.isPathNode()){ + return ((ValueNodes.PathNode) node).getPath(); + } else if(node.isNumberNode()){ + return ((ValueNodes.NumberNode) node).getNumber(); + } else if(node.isStringNode()){ + return ((ValueNodes.StringNode) node).getString(); + } else if(node.isBooleanNode()){ + return ((ValueNodes.BooleanNode) node).getBoolean(); + } else if(node.isJsonNode()){ + return ((ValueNodes.JsonNode) node).getJson(); + } else if(node.isPredicateNode()){ + return ((ValueNodes.PredicateNode) node).getPredicate(); + } else if(node.isValueListNode()){ + return ((ValueNodes.ValueListNode) node).getNodes(); + } else if(node.isNullNode()){ + return node.toString(); + } else if(node.isUndefinedNode()){ + return "undefined"; + } else if(node.isClassNode()){ + return ((ValueNodes.ClassNode) node).getClazz(); + } else if(node.isOffsetDateTimeNode()){ + return ((ValueNodes.OffsetDateTimeNode) node).getDate(); + } + return null; } } diff --git a/json-path/src/test/java/com/jayway/jsonpath/Issue_356.java b/json-path/src/test/java/com/jayway/jsonpath/Issue_356.java new file mode 100644 index 00000000..004f3262 --- /dev/null +++ b/json-path/src/test/java/com/jayway/jsonpath/Issue_356.java @@ -0,0 +1,73 @@ +package com.jayway.jsonpath; + +import org.junit.Test; + +import java.math.BigDecimal; +import java.util.LinkedHashMap; + +import static com.jayway.jsonpath.Criteria.where; + +/** + * Test for issue 356 + */ +public class Issue_356 { + private final static String json = "{\n" + + " \"store\": {\n" + + " \"book\": [\n" + + " {\n" + + " \"title\": \"Sayings of the Century\",\n" + + " \"price\": {\n" + + " \"value\": 8.95,\n" + + " \"currency\": \"usd\"\n" + + " }\n" + + " },\n" + + " {\n" + + " \"title\": \"Sword of Honour\",\n" + + " \"price\": {\n" + + " \"value\": 12.99,\n" + + " \"currency\": \"usd\"\n" + + " }\n" + + " },\n" + + " {\n" + + " \"title\": \"Moby Dick\",\n" + + " \"price\": {\n" + + " \"value\": 8.99,\n" + + " \"currency\": \"usd\"\n" + + " }\n" + + " }\n" + + " ]\n" + + " }\n" + + "}"; + @Test + public void test1(){ + Object ans = JsonPath.parse(json).read("$..book[?]", Filter.filter(where("price.value").matches(new Predicate() { + @Override + public boolean apply(PredicateContext ctx) { + // some custom logic with expecting value number in context + return ((BigDecimal)ctx.item()).doubleValue() < 9; + } + }))); + // System.out.println(ans); + assert(ans.toString().equals("[{\"title\":\"Sayings of the Century\"," + + "\"price\":{\"value\":8.95,\"currency\":\"usd\"}}," + + "{\"title\":\"Moby Dick\"," + + "\"price\":{\"value\":8.99,\"currency\":\"usd\"}}]")); + } + + @Test + public void test2(){ + Object ans = JsonPath.parse(json).read("$..book[?]", Filter.filter(where("price").matches(new Predicate() { + @Override + public boolean apply(PredicateContext ctx) { + // some custom logic with expecting value number in context + return ((LinkedHashMap) ctx.item()).get("value") < 9; + } + }))); + // System.out.println(ans); + assert(ans.toString().equals("[{\"title\":\"Sayings of the Century\"," + + "\"price\":{\"value\":8.95,\"currency\":\"usd\"}}," + + "{\"title\":\"Moby Dick\"," + + "\"price\":{\"value\":8.99,\"currency\":\"usd\"}}]")); + } + +}