Browse Source

Merge 829469d849 into 45333e0a31

pull/839/merge
Yichen 1 year ago committed by GitHub
parent
commit
29e4ba1091
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 21
      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. 91
      json-path/src/test/java/com/jayway/jsonpath/Issue_356.java

21
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;
@ -244,9 +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) {
return right.asPredicateNode().getPredicate().apply(ctx);
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); //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;
}

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

@ -0,0 +1,91 @@
// CS304 (manually written)
// Issue link: https://github.com/json-path/JsonPath/issues/356
package com.jayway.jsonpath;
import org.junit.Test;
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 { //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() {
final Object ans = JsonPath.parse(JSON).read("$..book[?]", Filter.filter(where("price.value").matches(new Predicate() { //NOPMD - suppressed DataflowAnomalyAnalysis
@Override
public boolean apply(final PredicateContext ctx) {
// some custom logic with expecting value number in context
return ((BigDecimal) ctx.item()).doubleValue() < CONSTRAINT;
}
})));
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() {
final Object ans = JsonPath.parse(JSON).read("$..book[?]", Filter.filter(where("price").matches(new Predicate() { //NOPMD - suppressed DataflowAnomalyAnalysis
@Override
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") < CONSTRAINT;
}
})));
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