Browse Source

fix Issue_356

pull/839/head
LiYichen99 3 years ago
parent
commit
829469d849
  1. 47
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/EvaluatorFactory.java
  2. 10
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java
  3. 61
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNodes.java
  4. 110
      json-path/src/test/java/com/jayway/jsonpath/Issue_356.java

47
json-path/src/main/java/com/jayway/jsonpath/internal/filter/EvaluatorFactory.java

@ -245,44 +245,25 @@ public class EvaluatorFactory {
}
private static class PredicateMatchEvaluator implements Evaluator {
/**
* Evaluate the match operation of predicate.
*
* @param left the ValueNode
* @param right the ValueNode
* @param ctx the PredicateContext
* @return boolean
*/
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
Predicate.PredicateContext predicateContext = new PredicateContextImpl(
getNodeValue(left),
public boolean evaluate(final ValueNode left, final ValueNode right, final Predicate.PredicateContext ctx) {
// CS304 Issue link: https://github.com/json-path/JsonPath/issues/356
// Create new predicateContext according to the left ValueNode
final Predicate.PredicateContext predicateContext = new PredicateContextImpl(
left.getValue(),
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;
return right.asPredicateNode().getPredicate().apply(predicateContext); //NOPMD - suppressed LawOfDemeter //NOPMD - suppressed LawOfDemeter
}
}

10
json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java

@ -16,6 +16,15 @@ public abstract class ValueNode {
public abstract Class<?> type(Predicate.PredicateContext ctx);
/**
* Get the value of ValueNode.
* The class of return Object depends on the type of ValueNode.
*
* @return Object
*/
// CS304 Issue link: https://github.com/json-path/JsonPath/issues/356
public abstract Object getValue();
public boolean isPatternNode() {
return false;
}
@ -157,6 +166,7 @@ public abstract class ValueNode {
//----------------------------------------------------
//
// Factory methods

61
json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNodes.java

@ -71,6 +71,11 @@ public interface ValueNodes {
return Void.TYPE;
}
@Override
public Object getValue() {
return compiledPattern;
}
public boolean isPatternNode() {
return true;
}
@ -125,6 +130,11 @@ public interface ValueNodes {
else return Void.class;
}
@Override
public Object getValue() {
return json;
}
public boolean isJsonNode() {
return true;
}
@ -248,6 +258,11 @@ public interface ValueNodes {
return String.class;
}
@Override
public Object getValue() {
return string;
}
public boolean isStringNode() {
return true;
}
@ -301,6 +316,11 @@ public interface ValueNodes {
return Number.class;
}
@Override
public Object getValue() {
return number;
}
public boolean isNumberNode() {
return true;
}
@ -357,6 +377,11 @@ public interface ValueNodes {
return OffsetDateTimeNode.class;
}
@Override
public Object getValue() {
return dateTime;
}
public boolean isOffsetDateTimeNode() {
return true;
}
@ -393,6 +418,11 @@ public interface ValueNodes {
return Boolean.class;
}
@Override
public Object getValue() {
return value;
}
public boolean isBooleanNode() {
return true;
}
@ -437,6 +467,11 @@ public interface ValueNodes {
return Class.class;
}
@Override
public Object getValue() {
return clazz;
}
public boolean isClassNode() {
return true;
}
@ -474,6 +509,11 @@ public interface ValueNodes {
return Void.class;
}
@Override
public Object getValue() {
return null;
}
@Override
public boolean isNullNode() {
return true;
@ -505,6 +545,11 @@ public interface ValueNodes {
return Void.class;
}
@Override
public Object getValue() {
return null;
}
public UndefinedNode asUndefinedNode() {
return this;
}
@ -540,6 +585,11 @@ public interface ValueNodes {
return Void.class;
}
@Override
public Object getValue() {
return predicate;
}
public boolean isPredicateNode() {
return true;
}
@ -587,6 +637,12 @@ public interface ValueNodes {
return List.class;
}
@Override
public Object getValue() {
List<ValueNode> valueNodes = new ArrayList<>(nodes);
return valueNodes;
}
public boolean isValueListNode() {
return true;
}
@ -656,6 +712,11 @@ public interface ValueNodes {
return Void.class;
}
@Override
public Object getValue() {
return path;
}
public boolean isPathNode() {
return true;
}

110
json-path/src/test/java/com/jayway/jsonpath/Issue_356.java

@ -1,3 +1,5 @@
// CS304 (manually written)
// Issue link: https://github.com/json-path/JsonPath/issues/356
package com.jayway.jsonpath;
import org.junit.Test;
@ -6,68 +8,84 @@ import java.math.BigDecimal;
import java.util.LinkedHashMap;
import static com.jayway.jsonpath.Criteria.where;
import static org.assertj.core.api.Assertions.assertThat;
/**
* 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" +
"}";
public class Issue_356 { //NOPMD - suppressed AtLeastOneConstructor //NOPMD - suppressed ClassNamingConventions
/**
* The json data for testing
*/
private static final 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"
+ "}";
/**
* The constraint for testing
*/
private static final double CONSTRAINT = 9;
/**
* test1 for "...price.value" PredicateContext,
* it will return the book with the price value less than 9
*/
@Test
public void test1(){
Object ans = JsonPath.parse(json).read("$..book[?]", Filter.filter(where("price.value").matches(new Predicate() {
public void test1() {
final Object ans = JsonPath.parse(JSON).read("$..book[?]", Filter.filter(where("price.value").matches(new Predicate() { //NOPMD - suppressed DataflowAnomalyAnalysis
@Override
public boolean apply(PredicateContext ctx) {
public boolean apply(final PredicateContext ctx) {
// some custom logic with expecting value number in context
return ((BigDecimal)ctx.item()).doubleValue() < 9;
return ((BigDecimal) ctx.item()).doubleValue() < CONSTRAINT;
}
})));
// 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\"}}]"));
assertThat(ans.toString().equals("[{\"title\":\"Sayings of the Century\"," //NOPMD - suppressed LawOfDemeter
+ "\"price\":{\"value\":8.95,\"currency\":\"usd\"}},"
+ "{\"title\":\"Moby Dick\","
+ "\"price\":{\"value\":8.99,\"currency\":\"usd\"}}]")).isTrue();
}
/**
* test2 for "...price" PredicateContext,
* it will return the book with the price value less than 9
*/
@Test
public void test2(){
Object ans = JsonPath.parse(json).read("$..book[?]", Filter.filter(where("price").matches(new Predicate() {
public void test2() {
final Object ans = JsonPath.parse(JSON).read("$..book[?]", Filter.filter(where("price").matches(new Predicate() { //NOPMD - suppressed DataflowAnomalyAnalysis
@Override
public boolean apply(PredicateContext ctx) {
public boolean apply(final PredicateContext ctx) { //NOPMD - suppressed CommentRequired
// some custom logic with expecting value number in context
return ((LinkedHashMap<String, Double>) ctx.item()).get("value") < 9;
return ((LinkedHashMap<String, Double>) ctx.item()).get("value") < CONSTRAINT;
}
})));
// 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\"}}]"));
assertThat(ans.toString().equals("[{\"title\":\"Sayings of the Century\"," //NOPMD - suppressed LawOfDemeter
+ "\"price\":{\"value\":8.95,\"currency\":\"usd\"}},"
+ "{\"title\":\"Moby Dick\","
+ "\"price\":{\"value\":8.99,\"currency\":\"usd\"}}]")).isTrue();
}
}

Loading…
Cancel
Save