Browse Source

Anyof criteria fixed, ZonedDateTime Support, Multiple Filters for date and time, Number List filters for list to list comparison, Right to left filters for subset, anyof, noneof and all.

pull/796/head
vaobhav1993 3 years ago
parent
commit
5fcde2a675
  1. 543
      json-path/src/main/java/com/jayway/jsonpath/Criteria.java
  2. 829
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/EvaluatorFactory.java
  3. 32
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/RelationalOperator.java
  4. 15
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java
  5. 66
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNodes.java
  6. 265
      json-path/src/test/java/com/jayway/jsonpath/FilterParseTest.java

543
json-path/src/main/java/com/jayway/jsonpath/Criteria.java

@ -157,6 +157,94 @@ public class Criteria implements Predicate {
return this; return this;
} }
/**
* Creates a criterion using the <b>&ltall;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria ltall(Object... o) {
return ltall(Arrays.asList(o));
}
/**
* Creates a criterion using the <b>&ltall;</b> operator
*
* @param c
* @return the criteria
*/
public Criteria ltall(Collection<?> c) {
this.criteriaType = RelationalOperator.LTALL;
this.right = new ValueListNode(c);
return this;
}
/**
* Creates a criterion using the <b>&lteall;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria lteall(Object... o) {
return lteall(Arrays.asList(o));
}
/**
* Creates a criterion using the <b>&lteall;</b> operator
*
* @param c
* @return the criteria
*/
public Criteria lteall(Collection<?> c) {
this.criteriaType = RelationalOperator.LTEALL;
this.right = new ValueListNode(c);
return this;
}
/**
* Creates a criterion using the <b>&ltany;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria ltany(Object... o) {
return ltany(Arrays.asList(o));
}
/**
* Creates a criterion using the <b>&ltany;</b> operator
*
* @param c
* @return the criteria
*/
public Criteria ltany(Collection<?> c) {
this.criteriaType = RelationalOperator.LTANY;
this.right = new ValueListNode(c);
return this;
}
/**
* Creates a criterion using the <b>&lteany;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria lteany(Object... o) {
return lteany(Arrays.asList(o));
}
/**
* Creates a criterion using the <b>&lteany;</b> operator
*
* @param c
* @return the criteria
*/
public Criteria lteany(Collection<?> c) {
this.criteriaType = RelationalOperator.LTEANY;
this.right = new ValueListNode(c);
return this;
}
/** /**
* Creates a criterion using the <b>&lt;=</b> operator * Creates a criterion using the <b>&lt;=</b> operator
* *
@ -181,6 +269,94 @@ public class Criteria implements Predicate {
return this; return this;
} }
/**
* Creates a criterion using the <b>&gtall;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria gtall(Object... o) {
return gtall(Arrays.asList(o));
}
/**
* Creates a criterion using the <b>&gtall;</b> operator
*
* @param c
* @return the criteria
*/
public Criteria gtall(Collection<?> c) {
this.criteriaType = RelationalOperator.GTALL;
this.right = new ValueListNode(c);
return this;
}
/**
* Creates a criterion using the <b>&gteall;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria gteall(Object... o) {
return gteall(Arrays.asList(o));
}
/**
* Creates a criterion using the <b>&gteall;</b> operator
*
* @param c
* @return the criteria
*/
public Criteria gteall(Collection<?> c) {
this.criteriaType = RelationalOperator.GTEALL;
this.right = new ValueListNode(c);
return this;
}
/**
* Creates a criterion using the <b>&gtany;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria gtany(Object... o) {
return gtany(Arrays.asList(o));
}
/**
* Creates a criterion using the <b>&gtany;</b> operator
*
* @param c
* @return the criteria
*/
public Criteria gtany(Collection<?> c) {
this.criteriaType = RelationalOperator.GTANY;
this.right = new ValueListNode(c);
return this;
}
/**
* Creates a criterion using the <b>&gteany;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria gteany(Object... o) {
return gteany(Arrays.asList(o));
}
/**
* Creates a criterion using the <b>&gteany;</b> operator
*
* @param c
* @return the criteria
*/
public Criteria gteany(Collection<?> c) {
this.criteriaType = RelationalOperator.GTEANY;
this.right = new ValueListNode(c);
return this;
}
/** /**
* Creates a criterion using the <b>&gt;=</b> operator * Creates a criterion using the <b>&gt;=</b> operator
* *
@ -304,7 +480,7 @@ public class Criteria implements Predicate {
* @return the criteria * @return the criteria
*/ */
public Criteria anyof(Object... o) { public Criteria anyof(Object... o) {
return subsetof(Arrays.asList(o)); return anyof(Arrays.asList(o));
} }
/** /**
@ -371,6 +547,371 @@ public class Criteria implements Predicate {
return this; return this;
} }
/**
* Creates a criterion using the <b>&dateeq;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria dateeq(Object o) {
this.criteriaType = RelationalOperator.DATEEQ;
this.right = ValueNode.toValueNode(o);
return this;
}
/**
* Creates a criterion using the <b>&dayeq;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria dayeq(Object o) {
this.criteriaType = RelationalOperator.DAYEQ;
this.right = ValueNode.toValueNode(o);
return this;
}
/**
* Creates a criterion using the <b>&montheq;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria montheq(Object o) {
this.criteriaType = RelationalOperator.MONTHEQ;
this.right = ValueNode.toValueNode(o);
return this;
}
/**
* Creates a criterion using the <b>&yeareq;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria yeareq(Object o) {
this.criteriaType = RelationalOperator.YEAREQ;
this.right = ValueNode.toValueNode(o);
return this;
}
/**
* Creates a criterion using the <b>&dayin;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria dayin(Object... o) {
return dayin(Arrays.asList(o));
}
/**
* Creates a criterion using the <b>&dayin;</b> operator
*
* @param c
* @return the criteria
*/
public Criteria dayin(Collection<?> c) {
this.criteriaType = RelationalOperator.DAYIN;
this.right = new ValueListNode(c);
return this;
}
/**
* Creates a criterion using the <b>&monthin;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria monthin(Object... o) {
return monthin(Arrays.asList(o));
}
/**
* Creates a criterion using the <b>&monthin;</b> operator
*
* @param c
* @return the criteria
*/
public Criteria monthin(Collection<?> c) {
this.criteriaType = RelationalOperator.MONTHIN;
this.right = new ValueListNode(c);
return this;
}
/**
* Creates a criterion using the <b>&yearin;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria yearin(Object... o) {
return yearin(Arrays.asList(o));
}
/**
* Creates a criterion using the <b>&yearin;</b> operator
*
* @param c
* @return the criteria
*/
public Criteria yearin(Collection<?> c) {
this.criteriaType = RelationalOperator.YEARIN;
this.right = new ValueListNode(c);
return this;
}
/**
* Creates a criterion using the <b>&before;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria before(Object o) {
this.criteriaType = RelationalOperator.BEFORE;
this.right = ValueNode.toValueNode(o);
return this;
}
/**
* Creates a criterion using the <b>&after;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria after(Object o) {
this.criteriaType = RelationalOperator.AFTER;
this.right = ValueNode.toValueNode(o);
return this;
}
/**
* Creates a criterion using the <b>&houreq;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria houreq(Object o) {
this.criteriaType = RelationalOperator.HOUREQ;
this.right = ValueNode.toValueNode(o);
return this;
}
/**
* Creates a criterion using the <b>&hourin;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria hourin(Object... o) {
return hourin(Arrays.asList(o));
}
/**
* Creates a criterion using the <b>&hourin;</b> operator
*
* @param c
* @return the criteria
*/
public Criteria hourin(Collection<?> c) {
this.criteriaType = RelationalOperator.HOURIN;
this.right = new ValueListNode(c);
return this;
}
/**
* Creates a criterion using the <b>&timebefore;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria timebefore(Object o) {
this.criteriaType = RelationalOperator.TIMEBEFORE;
this.right = ValueNode.toValueNode(o);
return this;
}
/**
* Creates a criterion using the <b>&timeafter;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria timeafter(Object o) {
this.criteriaType = RelationalOperator.TIMEAFTER;
this.right = ValueNode.toValueNode(o);
return this;
}
/**
* The <code>allmatch</code> operator selects objects for which the specified field is
* an array whose elements comprise a subset of the set comprised by the elements of
* the specified array.
*
* @param o the values to match against
* @return the criteria
*/
public Criteria allmatch(Object... o) {
return allmatch(Arrays.asList(o));
}
/**
* The <code>allmatch</code> operator selects objects for which the specified field is
* an array whose elements comprise a subset of the set comprised by the elements of
* the specified array.
*
* @param c the values to match against
* @return the criteria
*/
public Criteria allmatch(Collection<?> c) {
notNull(c, "collection can not be null");
this.criteriaType = RelationalOperator.ALLMATCH;
this.right = new ValueListNode(c);
return this;
}
/**
* The <code>anymatch</code> operator selects objects for which the specified field is
* an array whose elements comprise a subset of the set comprised by the elements of
* the specified array.
*
* @param o the values to match against
* @return the criteria
*/
public Criteria anymatch(Object... o) {
return anymatch(Arrays.asList(o));
}
/**
* The <code>anymatch</code> operator selects objects for which the specified field is
* an array whose elements comprise a subset of the set comprised by the elements of
* the specified array.
*
* @param c the values to match against
* @return the criteria
*/
public Criteria anymatch(Collection<?> c) {
notNull(c, "collection can not be null");
this.criteriaType = RelationalOperator.ANYMATCH;
this.right = new ValueListNode(c);
return this;
}
/**
* The <code>nonematch</code> operator selects objects for which the specified field is
* an array whose elements comprise a subset of the set comprised by the elements of
* the specified array.
*
* @param o the values to match against
* @return the criteria
*/
public Criteria nonematch(Object... o) {
return nonematch(Arrays.asList(o));
}
/**
* The <code>nonematch</code> operator selects objects for which the specified field is
* an array whose elements comprise a subset of the set comprised by the elements of
* the specified array.
*
* @param c the values to match against
* @return the criteria
*/
public Criteria nonematch(Collection<?> c) {
notNull(c, "collection can not be null");
this.criteriaType = RelationalOperator.NONEMATCH;
this.right = new ValueListNode(c);
return this;
}
/**
* The <code>exactmatch</code> operator selects objects for which the specified field is
* an array whose elements comprise a subset of the set comprised by the elements of
* the specified array.
*
* @param o the values to match against
* @return the criteria
*/
public Criteria exactmatch(Object... o) {
return exactmatch(Arrays.asList(o));
}
/**
* The <code>exactmatch</code> operator selects objects for which the specified field is
* an array whose elements comprise a subset of the set comprised by the elements of
* the specified array.
*
* @param c the values to match against
* @return the criteria
*/
public Criteria exactmatch(Collection<?> c) {
notNull(c, "collection can not be null");
this.criteriaType = RelationalOperator.EXACTMATCH;
this.right = new ValueListNode(c);
return this;
}
/**
* Creates a criterion using the <b>&windowin;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria windowin(Object o) {
this.criteriaType = RelationalOperator.WINDOWIN;
this.right = ValueNode.toValueNode(o);
return this;
}
/**
* Creates a criterion using the <b>&windowout;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria windowout(Object o) {
this.criteriaType = RelationalOperator.WINDOWOUT;
this.right = ValueNode.toValueNode(o);
return this;
}
/**
* Creates a criterion using the <b>&windowtimein;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria windowtimein(Object o) {
this.criteriaType = RelationalOperator.WINDOWTIMEIN;
this.right = ValueNode.toValueNode(o);
return this;
}
/**
* Creates a criterion using the <b>&windowtimeout;</b> operator
*
* @param o
* @return the criteria
*/
public Criteria windowtimeout(Object o) {
this.criteriaType = RelationalOperator.WINDOWTIMEOUT;
this.right = ValueNode.toValueNode(o);
return this;
}
/**
* The <code>notcontains</code> operator asserts that the provided object is not contained
* in the result. The object that should contain the input can be either an object or a String.
*
* @param o that should not exists in given collection or
* @return the criteria
*/
public Criteria notcontains(Object o) {
this.criteriaType = RelationalOperator.NOTCONTAINS;
this.right = ValueNode.toValueNode(o);
return this;
}
/** /**
* The <code>size</code> operator matches: * The <code>size</code> operator matches:
* <p/> * <p/>

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

@ -1,8 +1,16 @@
package com.jayway.jsonpath.internal.filter; package com.jayway.jsonpath.internal.filter;
import com.jayway.jsonpath.InvalidPathException;
import com.jayway.jsonpath.JsonPathException; import com.jayway.jsonpath.JsonPathException;
import com.jayway.jsonpath.Predicate; import com.jayway.jsonpath.Predicate;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Month;
import java.time.ZonedDateTime;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -35,16 +43,46 @@ public class EvaluatorFactory {
evaluators.put(RelationalOperator.SUBSETOF, new SubsetOfEvaluator()); evaluators.put(RelationalOperator.SUBSETOF, new SubsetOfEvaluator());
evaluators.put(RelationalOperator.ANYOF, new AnyOfEvaluator()); evaluators.put(RelationalOperator.ANYOF, new AnyOfEvaluator());
evaluators.put(RelationalOperator.NONEOF, new NoneOfEvaluator()); evaluators.put(RelationalOperator.NONEOF, new NoneOfEvaluator());
evaluators.put(RelationalOperator.GTALL, new GreaterThanAllEvaluator());
evaluators.put(RelationalOperator.GTEALL, new GreaterThanEqualsAllEvaluator());
evaluators.put(RelationalOperator.GTANY, new GreaterThanAnyEvaluator());
evaluators.put(RelationalOperator.GTEANY, new GreaterThanEqualsAnyEvaluator());
evaluators.put(RelationalOperator.LTALL, new LessThanAllEvaluator());
evaluators.put(RelationalOperator.LTEALL, new LessThanEqualsAllEvaluator());
evaluators.put(RelationalOperator.LTANY, new LessThanAnyEvaluator());
evaluators.put(RelationalOperator.LTEANY, new LessThanEqualsAnyEvaluator());
evaluators.put(RelationalOperator.DATEEQ, new DateMatchEvaluator());
evaluators.put(RelationalOperator.DAYEQ, new DayMatchEvaluator());
evaluators.put(RelationalOperator.DAYIN, new DayInEvaluator());
evaluators.put(RelationalOperator.MONTHEQ, new MonthMatchEvaluator());
evaluators.put(RelationalOperator.MONTHIN, new MonthInEvaluator());
evaluators.put(RelationalOperator.YEAREQ, new YearMatchEvaluator());
evaluators.put(RelationalOperator.YEARIN, new YearInEvaluator());
evaluators.put(RelationalOperator.BEFORE, new BeforeEvaluator());
evaluators.put(RelationalOperator.AFTER, new AfterEvaluator());
evaluators.put(RelationalOperator.HOUREQ, new HourMatchEvaluator());
evaluators.put(RelationalOperator.HOURIN, new HourInEvaluator());
evaluators.put(RelationalOperator.TIMEBEFORE, new TimeBeforeEvaluator());
evaluators.put(RelationalOperator.TIMEAFTER, new TimeAfterEvaluator());
evaluators.put(RelationalOperator.NOTCONTAINS, new NotContainsEvaluator());
evaluators.put(RelationalOperator.ALLMATCH, new AllMatchEvaluator());
evaluators.put(RelationalOperator.ANYMATCH, new AnyMatchEvaluator());
evaluators.put(RelationalOperator.NONEMATCH, new NoneMatchEvaluator());
evaluators.put(RelationalOperator.EXACTMATCH, new ExactMatchEvaluator());
evaluators.put(RelationalOperator.WINDOWIN, new WindowInEvaluator());
evaluators.put(RelationalOperator.WINDOWOUT, new WindowOutEvaluator());
evaluators.put(RelationalOperator.WINDOWTIMEIN, new WindowTimeInEvaluator());
evaluators.put(RelationalOperator.WINDOWTIMEOUT, new WindowTimeOutEvaluator());
} }
public static Evaluator createEvaluator(RelationalOperator operator){ public static Evaluator createEvaluator(RelationalOperator operator) {
return evaluators.get(operator); return evaluators.get(operator);
} }
private static class ExistsEvaluator implements Evaluator { private static class ExistsEvaluator implements Evaluator {
@Override @Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) { public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
if(!left.isBooleanNode() && !right.isBooleanNode()){ if (!left.isBooleanNode() && !right.isBooleanNode()) {
throw new JsonPathException("Failed to evaluate exists expression"); throw new JsonPathException("Failed to evaluate exists expression");
} }
return left.asBooleanNode().getBoolean() == right.asBooleanNode().getBoolean(); return left.asBooleanNode().getBoolean() == right.asBooleanNode().getBoolean();
@ -68,7 +106,7 @@ public class EvaluatorFactory {
private static class EqualsEvaluator implements Evaluator { private static class EqualsEvaluator implements Evaluator {
@Override @Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) { public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
if(left.isJsonNode() && right.isJsonNode()){ if (left.isJsonNode() && right.isJsonNode()) {
return left.asJsonNode().equals(right.asJsonNode(), ctx); return left.asJsonNode().equals(right.asJsonNode(), ctx);
} else { } else {
return left.equals(right); return left.equals(right);
@ -79,7 +117,7 @@ public class EvaluatorFactory {
private static class TypeSafeEqualsEvaluator implements Evaluator { private static class TypeSafeEqualsEvaluator implements Evaluator {
@Override @Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) { public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
if(!left.getClass().equals(right.getClass())){ if (!left.getClass().equals(right.getClass())) {
return false; return false;
} }
return evaluators.get(RelationalOperator.EQ).evaluate(left, right, ctx); return evaluators.get(RelationalOperator.EQ).evaluate(left, right, ctx);
@ -96,70 +134,378 @@ public class EvaluatorFactory {
private static class LessThanEvaluator implements Evaluator { private static class LessThanEvaluator implements Evaluator {
@Override @Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) { public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
if(left.isNumberNode() && right.isNumberNode()){ if (left.isNumberNode() && right.isNumberNode()) {
return left.asNumberNode().getNumber().compareTo(right.asNumberNode().getNumber()) < 0; return left.asNumberNode().getNumber().compareTo(right.asNumberNode().getNumber()) < 0;
} if(left.isStringNode() && right.isStringNode()){ }
if (left.isStringNode() && right.isStringNode()) {
return left.asStringNode().getString().compareTo(right.asStringNode().getString()) < 0; return left.asStringNode().getString().compareTo(right.asStringNode().getString()) < 0;
} if (left.isOffsetDateTimeNode() && right.isOffsetDateTimeNode()){ //workaround for issue: https://github.com/json-path/JsonPath/issues/613 }
if (left.isOffsetDateTimeNode() && right.isOffsetDateTimeNode()) { //workaround for issue: https://github.com/json-path/JsonPath/issues/613
return left.asOffsetDateTimeNode().getDate().compareTo(right.asOffsetDateTimeNode().getDate()) < 0; return left.asOffsetDateTimeNode().getDate().compareTo(right.asOffsetDateTimeNode().getDate()) < 0;
} }
return false; return false;
} }
} }
private static class LessThanAllEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ValueListNode leftListNode = left.isValueListNode() ? left.asValueListNode() : null;
ValueListNode rightListNode = right.isValueListNode() ? right.asValueListNode() : null;
if (leftListNode == null) {
leftListNode = convertJsonNodeToListNode(left, ctx);
}
if (rightListNode == null) {
rightListNode = convertJsonNodeToListNode(right, ctx);
}
if (leftListNode == null || rightListNode == null) {
return false;
}
if (leftListNode.getNodes().get(0).isNumberNode() && rightListNode.getNodes().get(0).isNumberNode()) {
BigDecimal smallest = leftListNode.getNodes().stream().map(node ->
node.asNumberNode().getNumber()).min(Comparator.naturalOrder()).get();
return rightListNode.getNodes().stream().allMatch(node -> node.asNumberNode()
.getNumber().compareTo(smallest) < 0);
}
return false;
}
private ValueListNode convertJsonNodeToListNode(ValueNode node, Predicate.PredicateContext ctx) {
ValueListNode valueListNode = null;
ValueNode vn = node.isNumberNode() || node.isStringNode() ?
new ValueListNode(Collections.singleton(node.asNumberNode())) :
node.asJsonNode().asValueListNode(ctx);
if (!vn.isUndefinedNode()) {
valueListNode = vn.asValueListNode();
}
return valueListNode;
}
}
private static class LessThanAnyEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ValueListNode leftListNode = left.isValueListNode() ? left.asValueListNode() : null;
ValueListNode rightListNode = right.isValueListNode() ? right.asValueListNode() : null;
if (leftListNode == null) {
leftListNode = convertJsonNodeToListNode(left, ctx);
}
if (rightListNode == null) {
rightListNode = convertJsonNodeToListNode(right, ctx);
}
if (leftListNode == null || rightListNode == null) {
return false;
}
if (leftListNode.getNodes().get(0).isNumberNode() && rightListNode.getNodes().get(0).isNumberNode()) {
boolean res = false;
for (ValueNode field : leftListNode.getNodes()) {
for (ValueNode value : rightListNode.getNodes()) {
if (field.asNumberNode().getNumber().compareTo(value.asNumberNode().getNumber()) < 0) {
res = true;
break;
}
}
}
return res;
}
return false;
}
private ValueListNode convertJsonNodeToListNode(ValueNode node, Predicate.PredicateContext ctx) {
ValueListNode valueListNode = null;
ValueNode vn = node.isNumberNode() || node.isStringNode() ?
new ValueListNode(Collections.singleton(node.asNumberNode())) :
node.asJsonNode().asValueListNode(ctx);
if (!vn.isUndefinedNode()) {
valueListNode = vn.asValueListNode();
}
return valueListNode;
}
}
private static class LessThanEqualsEvaluator implements Evaluator { private static class LessThanEqualsEvaluator implements Evaluator {
@Override @Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) { public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
if(left.isNumberNode() && right.isNumberNode()){ if (left.isNumberNode() && right.isNumberNode()) {
return left.asNumberNode().getNumber().compareTo(right.asNumberNode().getNumber()) <= 0; return left.asNumberNode().getNumber().compareTo(right.asNumberNode().getNumber()) <= 0;
} if(left.isStringNode() && right.isStringNode()){ }
if (left.isStringNode() && right.isStringNode()) {
return left.asStringNode().getString().compareTo(right.asStringNode().getString()) <= 0; return left.asStringNode().getString().compareTo(right.asStringNode().getString()) <= 0;
} if (left.isOffsetDateTimeNode() && right.isOffsetDateTimeNode()){ //workaround for issue: https://github.com/json-path/JsonPath/issues/613 }
if (left.isOffsetDateTimeNode() && right.isOffsetDateTimeNode()) { //workaround for issue: https://github.com/json-path/JsonPath/issues/613
return left.asOffsetDateTimeNode().getDate().compareTo(right.asOffsetDateTimeNode().getDate()) <= 0; return left.asOffsetDateTimeNode().getDate().compareTo(right.asOffsetDateTimeNode().getDate()) <= 0;
} }
return false; return false;
} }
} }
private static class LessThanEqualsAllEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ValueListNode leftListNode = left.isValueListNode() ? left.asValueListNode() : null;
ValueListNode rightListNode = right.isValueListNode() ? right.asValueListNode() : null;
if (leftListNode == null) {
leftListNode = convertJsonNodeToListNode(left, ctx);
}
if (rightListNode == null) {
rightListNode = convertJsonNodeToListNode(right, ctx);
}
if (leftListNode == null || rightListNode == null) {
return false;
}
if (leftListNode.getNodes().get(0).isNumberNode() && rightListNode.getNodes().get(0).isNumberNode()) {
BigDecimal smallest = leftListNode.getNodes().stream().map(node ->
node.asNumberNode().getNumber()).min(Comparator.naturalOrder()).get();
return rightListNode.getNodes().stream().allMatch(node -> node.asNumberNode()
.getNumber().compareTo(smallest) <= 0);
}
return false;
}
private ValueListNode convertJsonNodeToListNode(ValueNode node, Predicate.PredicateContext ctx) {
ValueListNode valueListNode = null;
ValueNode vn = node.isNumberNode() || node.isStringNode() ?
new ValueListNode(Collections.singleton(node.asNumberNode())) :
node.asJsonNode().asValueListNode(ctx);
if (!vn.isUndefinedNode()) {
valueListNode = vn.asValueListNode();
}
return valueListNode;
}
}
private static class LessThanEqualsAnyEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ValueListNode leftListNode = left.isValueListNode() ? left.asValueListNode() : null;
ValueListNode rightListNode = right.isValueListNode() ? right.asValueListNode() : null;
if (leftListNode == null) {
leftListNode = convertJsonNodeToListNode(left, ctx);
}
if (rightListNode == null) {
rightListNode = convertJsonNodeToListNode(right, ctx);
}
if (leftListNode == null || rightListNode == null) {
return false;
}
if (leftListNode.getNodes().get(0).isNumberNode() && rightListNode.getNodes().get(0).isNumberNode()) {
boolean res = false;
for (ValueNode field : leftListNode.getNodes()) {
for (ValueNode value : rightListNode.getNodes()) {
if (field.asNumberNode().getNumber().compareTo(value.asNumberNode().getNumber()) <= 0) {
res = true;
break;
}
}
}
return res;
}
return false;
}
private ValueListNode convertJsonNodeToListNode(ValueNode node, Predicate.PredicateContext ctx) {
ValueListNode valueListNode = null;
ValueNode vn = node.isNumberNode() || node.isStringNode() ?
new ValueListNode(Collections.singleton(node.asNumberNode())) :
node.asJsonNode().asValueListNode(ctx);
if (!vn.isUndefinedNode()) {
valueListNode = vn.asValueListNode();
}
return valueListNode;
}
}
private static class GreaterThanEvaluator implements Evaluator { private static class GreaterThanEvaluator implements Evaluator {
@Override @Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) { public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
if(left.isNumberNode() && right.isNumberNode()){ if (left.isNumberNode() && right.isNumberNode()) {
return left.asNumberNode().getNumber().compareTo(right.asNumberNode().getNumber()) > 0; return left.asNumberNode().getNumber().compareTo(right.asNumberNode().getNumber()) > 0;
} else if(left.isStringNode() && right.isStringNode()){ } else if (left.isStringNode() && right.isStringNode()) {
return left.asStringNode().getString().compareTo(right.asStringNode().getString()) > 0; return left.asStringNode().getString().compareTo(right.asStringNode().getString()) > 0;
} else if (left.isOffsetDateTimeNode() && right.isOffsetDateTimeNode()){ //workaround for issue: https://github.com/json-path/JsonPath/issues/613 } else if (left.isOffsetDateTimeNode() && right.isOffsetDateTimeNode()) { //workaround for issue: https://github.com/json-path/JsonPath/issues/613
return left.asOffsetDateTimeNode().getDate().compareTo(right.asOffsetDateTimeNode().getDate()) > 0; return left.asOffsetDateTimeNode().getDate().compareTo(right.asOffsetDateTimeNode().getDate()) > 0;
} }
return false; return false;
} }
} }
private static class GreaterThanAllEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ValueListNode leftListNode = left.isValueListNode() ? left.asValueListNode() : null;
ValueListNode rightListNode = right.isValueListNode() ? right.asValueListNode() : null;
if (leftListNode == null) {
leftListNode = convertJsonNodeToListNode(left, ctx);
}
if (rightListNode == null) {
rightListNode = convertJsonNodeToListNode(right, ctx);
}
if (leftListNode == null || rightListNode == null) {
return false;
}
if (leftListNode.getNodes().get(0).isNumberNode() && rightListNode.getNodes().get(0).isNumberNode()) {
BigDecimal largest = leftListNode.getNodes().stream().map(node ->
node.asNumberNode().getNumber()).max(Comparator.naturalOrder()).get();
return rightListNode.getNodes().stream().allMatch(node -> node.asNumberNode()
.getNumber().compareTo(largest) < 0);
}
return false;
}
private ValueListNode convertJsonNodeToListNode(ValueNode node, Predicate.PredicateContext ctx) {
ValueListNode valueListNode = null;
ValueNode vn = node.isNumberNode() || node.isStringNode() ?
new ValueListNode(Collections.singleton(node.asNumberNode())) :
node.asJsonNode().asValueListNode(ctx);
if (!vn.isUndefinedNode()) {
valueListNode = vn.asValueListNode();
}
return valueListNode;
}
}
private static class GreaterThanAnyEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ValueListNode leftListNode = left.isValueListNode() ? left.asValueListNode() : null;
ValueListNode rightListNode = right.isValueListNode() ? right.asValueListNode() : null;
if (leftListNode == null) {
leftListNode = convertJsonNodeToListNode(left, ctx);
}
if (rightListNode == null) {
rightListNode = convertJsonNodeToListNode(right, ctx);
}
if (leftListNode == null || rightListNode == null) {
return false;
}
if (leftListNode.getNodes().get(0).isNumberNode() && rightListNode.getNodes().get(0).isNumberNode()) {
boolean res = false;
for (ValueNode field : leftListNode.getNodes()) {
for (ValueNode value : rightListNode.getNodes()) {
if (field.asNumberNode().getNumber().compareTo(value.asNumberNode().getNumber()) > 0) {
res = true;
break;
}
}
}
return res;
}
return false;
}
private ValueListNode convertJsonNodeToListNode(ValueNode node, Predicate.PredicateContext ctx) {
ValueListNode valueListNode = null;
ValueNode vn = node.isNumberNode() || node.isStringNode() ?
new ValueListNode(Collections.singleton(node.asNumberNode())) :
node.asJsonNode().asValueListNode(ctx);
if (!vn.isUndefinedNode()) {
valueListNode = vn.asValueListNode();
}
return valueListNode;
}
}
private static class GreaterThanEqualsEvaluator implements Evaluator { private static class GreaterThanEqualsEvaluator implements Evaluator {
@Override @Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) { public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
if(left.isNumberNode() && right.isNumberNode()){ if (left.isNumberNode() && right.isNumberNode()) {
return left.asNumberNode().getNumber().compareTo(right.asNumberNode().getNumber()) >= 0; return left.asNumberNode().getNumber().compareTo(right.asNumberNode().getNumber()) >= 0;
} else if(left.isStringNode() && right.isStringNode()){ } else if (left.isStringNode() && right.isStringNode()) {
return left.asStringNode().getString().compareTo(right.asStringNode().getString()) >= 0; return left.asStringNode().getString().compareTo(right.asStringNode().getString()) >= 0;
} else if (left.isOffsetDateTimeNode() && right.isOffsetDateTimeNode()){ //workaround for issue: https://github.com/json-path/JsonPath/issues/613 } else if (left.isOffsetDateTimeNode() && right.isOffsetDateTimeNode()) { //workaround for issue: https://github.com/json-path/JsonPath/issues/613
return left.asOffsetDateTimeNode().getDate().compareTo(right.asOffsetDateTimeNode().getDate()) >= 0; return left.asOffsetDateTimeNode().getDate().compareTo(right.asOffsetDateTimeNode().getDate()) >= 0;
} }
return false; return false;
} }
} }
private static class GreaterThanEqualsAllEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ValueListNode leftListNode = left.isValueListNode() ? left.asValueListNode() : null;
ValueListNode rightListNode = right.isValueListNode() ? right.asValueListNode() : null;
if (leftListNode == null) {
leftListNode = convertJsonNodeToListNode(left, ctx);
}
if (rightListNode == null) {
rightListNode = convertJsonNodeToListNode(right, ctx);
}
if (leftListNode == null || rightListNode == null) {
return false;
}
if (leftListNode.getNodes().get(0).isNumberNode() && rightListNode.getNodes().get(0).isNumberNode()) {
BigDecimal largest = leftListNode.getNodes().stream().map(node ->
node.asNumberNode().getNumber()).max(Comparator.naturalOrder()).get();
return rightListNode.getNodes().stream().allMatch(node -> node.asNumberNode()
.getNumber().compareTo(largest) <= 0);
}
return false;
}
private ValueListNode convertJsonNodeToListNode(ValueNode node, Predicate.PredicateContext ctx) {
ValueListNode valueListNode = null;
ValueNode vn = node.isNumberNode() || node.isStringNode() ?
new ValueListNode(Collections.singleton(node.asNumberNode())) :
node.asJsonNode().asValueListNode(ctx);
if (!vn.isUndefinedNode()) {
valueListNode = vn.asValueListNode();
}
return valueListNode;
}
}
private static class GreaterThanEqualsAnyEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ValueListNode leftListNode = left.isValueListNode() ? left.asValueListNode() : null;
ValueListNode rightListNode = right.isValueListNode() ? right.asValueListNode() : null;
if (leftListNode == null) {
leftListNode = convertJsonNodeToListNode(left, ctx);
}
if (rightListNode == null) {
rightListNode = convertJsonNodeToListNode(right, ctx);
}
if (leftListNode == null || rightListNode == null) {
return false;
}
if (leftListNode.getNodes().get(0).isNumberNode() && rightListNode.getNodes().get(0).isNumberNode()) {
boolean res = false;
for (ValueNode field : leftListNode.getNodes()) {
for (ValueNode value : rightListNode.getNodes()) {
if (field.asNumberNode().getNumber().compareTo(value.asNumberNode().getNumber()) >= 0) {
res = true;
break;
}
}
}
return res;
}
return false;
}
private ValueListNode convertJsonNodeToListNode(ValueNode node, Predicate.PredicateContext ctx) {
ValueListNode valueListNode = null;
ValueNode vn = node.isNumberNode() || node.isStringNode() ?
new ValueListNode(Collections.singleton(node.asNumberNode())) :
node.asJsonNode().asValueListNode(ctx);
if (!vn.isUndefinedNode()) {
valueListNode = vn.asValueListNode();
}
return valueListNode;
}
}
private static class SizeEvaluator implements Evaluator { private static class SizeEvaluator implements Evaluator {
@Override @Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) { public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
if (! right.isNumberNode()) { if (!right.isNumberNode()) {
return false; return false;
} }
int expectedSize = right.asNumberNode().getNumber().intValue(); int expectedSize = right.asNumberNode().getNumber().intValue();
if(left.isStringNode()){ if (left.isStringNode()) {
return left.asStringNode().length() == expectedSize; return left.asStringNode().length() == expectedSize;
} else if(left.isJsonNode()){ } else if (left.isJsonNode()) {
return left.asJsonNode().length(ctx) == expectedSize; return left.asJsonNode().length(ctx) == expectedSize;
} }
return false; return false;
@ -169,9 +515,9 @@ public class EvaluatorFactory {
private static class EmptyEvaluator implements Evaluator { private static class EmptyEvaluator implements Evaluator {
@Override @Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) { public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
if(left.isStringNode()){ if (left.isStringNode()) {
return left.asStringNode().isEmpty() == right.asBooleanNode().getBoolean(); return left.asStringNode().isEmpty() == right.asBooleanNode().getBoolean();
} else if(left.isJsonNode()){ } else if (left.isJsonNode()) {
return left.asJsonNode().isEmpty(ctx) == right.asBooleanNode().getBoolean(); return left.asJsonNode().isEmpty(ctx) == right.asBooleanNode().getBoolean();
} }
return false; return false;
@ -182,9 +528,9 @@ public class EvaluatorFactory {
@Override @Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) { public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ValueListNode valueListNode; ValueListNode valueListNode;
if(right.isJsonNode()){ if (right.isJsonNode()) {
ValueNode vn = right.asJsonNode().asValueListNode(ctx); ValueNode vn = right.asJsonNode().asValueListNode(ctx);
if(vn.isUndefinedNode()){ if (vn.isUndefinedNode()) {
return false; return false;
} else { } else {
valueListNode = vn.asValueListNode(); valueListNode = vn.asValueListNode();
@ -208,12 +554,12 @@ public class EvaluatorFactory {
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) { public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ValueListNode requiredValues = right.asValueListNode(); ValueListNode requiredValues = right.asValueListNode();
if(left.isJsonNode()){ if (left.isJsonNode()) {
ValueNode valueNode = left.asJsonNode().asValueListNode(ctx); //returns UndefinedNode if conversion is not possible ValueNode valueNode = left.asJsonNode().asValueListNode(ctx); //returns UndefinedNode if conversion is not possible
if(valueNode.isValueListNode()){ if (valueNode.isValueListNode()) {
ValueListNode shouldContainAll = valueNode.asValueListNode(); ValueListNode shouldContainAll = valueNode.asValueListNode();
for (ValueNode required : requiredValues) { for (ValueNode required : requiredValues) {
if(!shouldContainAll.contains(required)){ if (!shouldContainAll.contains(required)) {
return false; return false;
} }
} }
@ -227,14 +573,29 @@ public class EvaluatorFactory {
private static class ContainsEvaluator implements Evaluator { private static class ContainsEvaluator implements Evaluator {
@Override @Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) { public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
if(left.isStringNode() && right.isStringNode()){ if (left.isStringNode() && right.isStringNode()) {
return left.asStringNode().contains(right.asStringNode().getString()); return left.asStringNode().contains(right.asStringNode().getString());
} else if(left.isJsonNode()){ } else if (left.isJsonNode()) {
ValueNode valueNode = left.asJsonNode().asValueListNode(ctx);
if (valueNode.isUndefinedNode()) return false;
else {
return valueNode.asValueListNode().contains(right);
}
}
return false;
}
}
private static class NotContainsEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
if (left.isStringNode() && right.isStringNode()) {
return !(left.asStringNode().contains(right.asStringNode().getString()));
} else if (left.isJsonNode()) {
ValueNode valueNode = left.asJsonNode().asValueListNode(ctx); ValueNode valueNode = left.asJsonNode().asValueListNode(ctx);
if(valueNode.isUndefinedNode()) return false; if (valueNode.isUndefinedNode()) return false;
else { else {
boolean res = valueNode.asValueListNode().contains(right); return !(valueNode.asValueListNode().contains(right));
return res;
} }
} }
return false; return false;
@ -251,7 +612,7 @@ public class EvaluatorFactory {
private static class RegexpEvaluator implements Evaluator { private static class RegexpEvaluator implements Evaluator {
@Override @Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) { public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
if(!(left.isPatternNode() ^ right.isPatternNode())){ if (!(left.isPatternNode() ^ right.isPatternNode())) {
return false; return false;
} }
@ -280,33 +641,33 @@ public class EvaluatorFactory {
} }
private static class SubsetOfEvaluator implements Evaluator { private static class SubsetOfEvaluator implements Evaluator {
@Override @Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) { public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ValueListNode rightValueListNode; ValueListNode rightValueListNode;
if(right.isJsonNode()){ if (right.isJsonNode()) {
ValueNode vn = right.asJsonNode().asValueListNode(ctx); ValueNode vn = right.asJsonNode().asValueListNode(ctx);
if(vn.isUndefinedNode()){ if (vn.isUndefinedNode()) {
return false; return false;
} else { } else {
rightValueListNode = vn.asValueListNode(); rightValueListNode = vn.asValueListNode();
} }
} else { } else {
rightValueListNode = right.asValueListNode(); rightValueListNode = right.asValueListNode();
} }
ValueListNode leftValueListNode; ValueListNode leftValueListNode;
if(left.isJsonNode()){ if (left.isJsonNode()) {
ValueNode vn = left.asJsonNode().asValueListNode(ctx); ValueNode vn = left.asJsonNode().asValueListNode(ctx);
if(vn.isUndefinedNode()){ if (vn.isUndefinedNode()) {
return false; return false;
} else { } else {
leftValueListNode = vn.asValueListNode(); leftValueListNode = vn.asValueListNode();
} }
} else { } else {
leftValueListNode = left.asValueListNode(); leftValueListNode = left.asValueListNode();
} }
return leftValueListNode.subsetof(rightValueListNode); return leftValueListNode.subsetof(rightValueListNode);
} }
} }
private static class AnyOfEvaluator implements Evaluator { private static class AnyOfEvaluator implements Evaluator {
@Override @Override
@ -381,4 +742,354 @@ public class EvaluatorFactory {
return true; return true;
} }
} }
private static class DateMatchEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ZonedDateTime compDate = left.asDateNode().getDate();
ZonedDateTime evalDate = right.asDateNode().getDate().withZoneSameLocal(compDate.getZone());
return compDate.toLocalDate().compareTo(evalDate.toLocalDate()) == 0;
}
}
private static class MonthMatchEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
try {
ZonedDateTime compDate = left.asDateNode().getDate();
ZonedDateTime evalDate = right.asDateNode().getDate().withZoneSameLocal(compDate.getZone());
return compDate.getMonth().compareTo(evalDate.getMonth()) == 0;
} catch (InvalidPathException e) {
Month month;
if (right.isStringNode()) {
month = Month.valueOf(right.asStringNode().getString());
} else {
month = Month.of(right.asNumberNode().getNumber().intValue());
}
return left.asDateNode().getDate().getMonth() == month;
}
}
}
private static class MonthInEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ValueNodes.DateNode leftListNode = left.isDateNode() ? left.asDateNode() : null;
ValueListNode rightListNode = right.isValueListNode() ? right.asValueListNode() : null;
if (rightListNode == null) {
rightListNode = convertJsonNodeToListNode(right, ctx);
}
if (leftListNode == null || rightListNode == null) {
return false;
}
ZonedDateTime compDate = leftListNode.getDate();
int month = compDate.getMonthValue();
if (rightListNode.getNodes().get(0).isDateNode()) {
return rightListNode.getNodes().stream().anyMatch(node ->
node.asDateNode().getDate().withZoneSameLocal(compDate.getZone()).getMonthValue() == month);
} else if (rightListNode.getNodes().get(0).isStringNode()) {
return rightListNode.getNodes().stream().anyMatch(node ->
Month.valueOf(node.asStringNode().getString()).getValue() == month);
} else if (rightListNode.getNodes().get(0).isNumberNode()) {
return rightListNode.getNodes().stream().anyMatch(node ->
Month.of(node.asNumberNode().getNumber().intValue()).getValue() == month);
}
return false;
}
private ValueListNode convertJsonNodeToListNode(ValueNode node, Predicate.PredicateContext ctx) {
ValueListNode valueListNode = null;
ValueNode vn;
try {
vn = new ValueListNode(Collections.singleton(node.asDateNode()));
} catch (InvalidPathException e) {
if (node.isStringNode()) {
vn = new ValueListNode(Collections.singleton(node.asStringNode()));
} else if (node.isJsonNode()) {
vn = node.asJsonNode().asValueListNode(ctx);
} else {
vn = new ValueListNode(Collections.singleton(node.asNumberNode()));
}
}
if (!vn.isUndefinedNode()) {
valueListNode = vn.asValueListNode();
}
return valueListNode;
}
}
private static class DayMatchEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
try {
ZonedDateTime compDate = left.asDateNode().getDate();
ZonedDateTime evalDate = right.asDateNode().getDate().withZoneSameLocal(compDate.getZone());
return compDate.getDayOfMonth() == evalDate.getDayOfMonth();
} catch (InvalidPathException e) {
return left.asDateNode().getDate().getDayOfMonth() == right.asNumberNode().getNumber().intValue();
}
}
}
private static class DayInEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ValueNodes.DateNode leftListNode = left.isDateNode() ? left.asDateNode() : null;
ValueListNode rightListNode = right.isValueListNode() ? right.asValueListNode() : null;
if (rightListNode == null) {
rightListNode = convertJsonNodeToListNode(right, ctx);
}
if (leftListNode == null || rightListNode == null) {
return false;
}
ZonedDateTime compDate = leftListNode.getDate();
int day = compDate.getDayOfMonth();
if (rightListNode.getNodes().get(0).isDateNode()) {
return rightListNode.getNodes().stream().anyMatch(node ->
node.asDateNode().getDate().withZoneSameLocal(compDate.getZone()).getDayOfMonth() == day);
}
return rightListNode.getNodes().stream()
.anyMatch(node -> node.asNumberNode().getNumber().intValue() == day);
}
private ValueListNode convertJsonNodeToListNode(ValueNode node, Predicate.PredicateContext ctx) {
ValueListNode valueListNode = null;
ValueNode vn;
try {
vn = new ValueListNode(Collections.singleton(node.asDateNode()));
} catch (InvalidPathException e) {
if (node.isStringNode()) {
vn = new ValueListNode(Collections.singleton(node.asStringNode()));
} else if (node.isJsonNode()) {
vn = node.asJsonNode().asValueListNode(ctx);
} else {
vn = new ValueListNode(Collections.singleton(node.asNumberNode()));
}
}
if (!vn.isUndefinedNode()) {
valueListNode = vn.asValueListNode();
}
return valueListNode;
}
}
private static class YearMatchEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
try {
ZonedDateTime compDate = left.asDateNode().getDate();
ZonedDateTime evalDate = right.asDateNode().getDate().withZoneSameLocal(compDate.getZone());
return compDate.getYear() == evalDate.getYear();
} catch (InvalidPathException e) {
return left.asDateNode().getDate().getYear() == right.asNumberNode().getNumber().intValue();
}
}
}
private static class YearInEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ValueNodes.DateNode leftListNode = left.isDateNode() ? left.asDateNode() : null;
ValueListNode rightListNode = right.isValueListNode() ? right.asValueListNode() : null;
if (rightListNode == null) {
rightListNode = convertJsonNodeToListNode(right, ctx);
}
if (leftListNode == null || rightListNode == null) {
return false;
}
ZonedDateTime compDate = leftListNode.getDate();
int year = compDate.getYear();
if (rightListNode.getNodes().get(0).isDateNode()) {
return rightListNode.getNodes().stream().anyMatch(node ->
node.asDateNode().getDate().withZoneSameLocal(compDate.getZone()).getYear() == year);
}
return rightListNode.getNodes().stream()
.anyMatch(node -> node.asNumberNode().getNumber().intValue() == year);
}
private ValueListNode convertJsonNodeToListNode(ValueNode node, Predicate.PredicateContext ctx) {
ValueListNode valueListNode = null;
ValueNode vn;
try {
vn = new ValueListNode(Collections.singleton(node.asDateNode()));
} catch (InvalidPathException e) {
if (node.isStringNode()) {
vn = new ValueListNode(Collections.singleton(node.asStringNode()));
} else if (node.isJsonNode()) {
vn = node.asJsonNode().asValueListNode(ctx);
} else {
vn = new ValueListNode(Collections.singleton(node.asNumberNode()));
}
}
if (!vn.isUndefinedNode()) {
valueListNode = vn.asValueListNode();
}
return valueListNode;
}
}
private static class BeforeEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ZonedDateTime compDate = left.asDateNode().getDate();
ZonedDateTime evalDate = right.asDateNode().getDate().withZoneSameLocal(compDate.getZone());
return compDate.isBefore(evalDate);
}
}
private static class AfterEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ZonedDateTime compDate = left.asDateNode().getDate();
ZonedDateTime evalDate = right.asDateNode().getDate().withZoneSameLocal(compDate.getZone());
return compDate.isAfter(evalDate);
}
}
private static class HourMatchEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
try {
ZonedDateTime compDate = left.asDateNode().getDate();
ZonedDateTime evalDate = right.asDateNode().getDate().withZoneSameLocal(compDate.getZone());
return compDate.getHour() == evalDate.getHour();
} catch (InvalidPathException e) {
return left.asDateNode().getDate().getHour() == right.asNumberNode().getNumber().intValue();
}
}
}
private static class HourInEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ValueNodes.DateNode leftListNode = left.isDateNode() ? left.asDateNode() : null;
ValueListNode rightListNode = right.isValueListNode() ? right.asValueListNode() : null;
if (rightListNode == null) {
rightListNode = convertJsonNodeToListNode(right, ctx);
}
if (leftListNode == null || rightListNode == null) {
return false;
}
ZonedDateTime compDate = leftListNode.getDate();
int hour = compDate.getHour();
if (rightListNode.getNodes().get(0).isDateNode()) {
return rightListNode.getNodes().stream().anyMatch(node ->
node.asDateNode().getDate().withZoneSameLocal(compDate.getZone()).getHour() == hour);
}
return rightListNode.getNodes().stream()
.anyMatch(node -> node.asNumberNode().getNumber().intValue() == hour);
}
private ValueListNode convertJsonNodeToListNode(ValueNode node, Predicate.PredicateContext ctx) {
ValueListNode valueListNode = null;
ValueNode vn;
try {
vn = new ValueListNode(Collections.singleton(node.asDateNode()));
} catch (InvalidPathException e) {
if (node.isStringNode()) {
vn = new ValueListNode(Collections.singleton(node.asStringNode()));
} else if (node.isJsonNode()) {
vn = node.asJsonNode().asValueListNode(ctx);
} else {
vn = new ValueListNode(Collections.singleton(node.asNumberNode()));
}
}
if (!vn.isUndefinedNode()) {
valueListNode = vn.asValueListNode();
}
return valueListNode;
}
}
private static class TimeBeforeEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ZonedDateTime date = left.asDateNode().getDate();
String[] time = right.asStringNode().getString().split(":");
ZonedDateTime evalDate = date.with(LocalTime.of(Integer.parseInt(time[0]), Integer.parseInt(time[1])));
return date.isBefore(evalDate);
}
}
private static class TimeAfterEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ZonedDateTime date = left.asDateNode().getDate();
String[] time = right.asStringNode().getString().split(":");
ZonedDateTime evalDate = date.with(LocalTime.of(Integer.parseInt(time[0]), Integer.parseInt(time[1])));
return date.isAfter(evalDate);
}
}
private static class AllMatchEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
return evaluators.get(RelationalOperator.SUBSETOF).evaluate(right, left, ctx);
}
}
private static class AnyMatchEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
return evaluators.get(RelationalOperator.ANYOF).evaluate(right, left, ctx);
}
}
private static class NoneMatchEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
return evaluators.get(RelationalOperator.NONEOF).evaluate(right, left, ctx);
}
}
private static class ExactMatchEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
return evaluators.get(RelationalOperator.ALL).evaluate(right, left, ctx);
}
}
private static class WindowInEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ZonedDateTime date = left.asDateNode().getDate();
ZonedDateTime now = ZonedDateTime.now(date.getZone());
int window = right.asNumberNode().getNumber().intValue();
LocalDate finalDate = now.toLocalDate().minusDays(window);
return date.toLocalDate().isAfter(finalDate);
}
}
private static class WindowOutEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ZonedDateTime date = left.asDateNode().getDate();
ZonedDateTime now = ZonedDateTime.now(date.getZone());
int window = right.asNumberNode().getNumber().intValue();
LocalDate finalDate = date.toLocalDate().minusDays(window);
return finalDate.isAfter(now.toLocalDate());
}
}
private static class WindowTimeInEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ZonedDateTime date = left.asDateNode().getDate();
ZonedDateTime now = ZonedDateTime.now(date.getZone());
int window = right.asNumberNode().getNumber().intValue();
ZonedDateTime finalDate = now.minusDays(window);
return date.isAfter(finalDate);
}
}
private static class WindowTimeOutEvaluator implements Evaluator {
@Override
public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {
ZonedDateTime date = left.asDateNode().getDate();
ZonedDateTime now = ZonedDateTime.now(date.getZone());
int window = right.asNumberNode().getNumber().intValue();
ZonedDateTime finalDate = date.minusDays(window);
return finalDate.isAfter(now);
}
}
} }

32
json-path/src/main/java/com/jayway/jsonpath/internal/filter/RelationalOperator.java

@ -34,7 +34,37 @@ public enum RelationalOperator {
EMPTY("EMPTY"), EMPTY("EMPTY"),
SUBSETOF("SUBSETOF"), SUBSETOF("SUBSETOF"),
ANYOF("ANYOF"), ANYOF("ANYOF"),
NONEOF("NONEOF"); NONEOF("NONEOF"),
GTALL("GTALL"),
GTEALL("GTEALL"),
GTANY("GTANY"),
GTEANY("GTEANY"),
LTALL("LTALL"),
LTEALL("LTEALL"),
LTANY("LTANY"),
LTEANY("LTEANY"),
DATEEQ("DATEEQ"),
MONTHEQ("MONTHEQ"),
DAYEQ("DAYEQ"),
YEAREQ("YEAREQ"),
MONTHIN("MONTHIN"),
DAYIN("DAYIN"),
YEARIN("YEARIN"),
BEFORE("BEFORE"),
AFTER("AFTER"),
HOUREQ("HOUREQ"),
HOURIN("HOURIN"),
TIMEBEFORE("TIMEBEFORE"),
TIMEAFTER("TIMEAFTER"),
NOTCONTAINS("NOTCONTAINS"),
ALLMATCH("ALLMATCH"),
ANYMATCH("ANYMATCH"),
NONEMATCH("NONEMATCH"),
EXACTMATCH("EXACTMATCH"),
WINDOWIN("WINDOWIN"),
WINDOWOUT("WINDOWOUT"),
WINDOWTIMEIN("WINDOWTIMEIN"),
WINDOWTIMEOUT("WINDOWTIMEOUT");
private final String operatorString; private final String operatorString;

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

@ -8,6 +8,8 @@ import com.jayway.jsonpath.internal.path.PathCompiler;
import net.minidev.json.parser.JSONParser; import net.minidev.json.parser.JSONParser;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static com.jayway.jsonpath.internal.filter.ValueNodes.*; import static com.jayway.jsonpath.internal.filter.ValueNodes.*;
@ -113,6 +115,13 @@ public abstract class ValueNode {
throw new InvalidPathException("Expected offsetDateTime node"); throw new InvalidPathException("Expected offsetDateTime node");
} }
public boolean isDateNode(){
return false;
}
public DateNode asDateNode(){
throw new InvalidPathException("Expected date node");
}
private static boolean isPath(Object o) { private static boolean isPath(Object o) {
if(o == null || !(o instanceof String)){ if(o == null || !(o instanceof String)){
@ -163,7 +172,7 @@ public abstract class ValueNode {
// //
//---------------------------------------------------- //----------------------------------------------------
public static ValueNode toValueNode(Object o){ public static ValueNode toValueNode(Object o){
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MMM yyyy HH:mm:ss VV");
if(o == null) return NULL_NODE; if(o == null) return NULL_NODE;
if(o instanceof ValueNode) return (ValueNode)o; if(o instanceof ValueNode) return (ValueNode)o;
if(o instanceof Class) return createClassNode((Class)o); if(o instanceof Class) return createClassNode((Class)o);
@ -175,6 +184,7 @@ public abstract class ValueNode {
else if(o instanceof Boolean) return createBooleanNode(o.toString()); else if(o instanceof Boolean) return createBooleanNode(o.toString());
else if(o instanceof Pattern) return createPatternNode((Pattern)o); else if(o instanceof Pattern) return createPatternNode((Pattern)o);
else if (o instanceof OffsetDateTime) return createOffsetDateTimeNode(o.toString()); //workaround for issue: https://github.com/json-path/JsonPath/issues/613 else if (o instanceof OffsetDateTime) return createOffsetDateTimeNode(o.toString()); //workaround for issue: https://github.com/json-path/JsonPath/issues/613
else if (o instanceof ZonedDateTime) return createDateNode(((ZonedDateTime) o).format(formatter));
else throw new JsonPathException("Could not determine value type"); else throw new JsonPathException("Could not determine value type");
} }
@ -220,6 +230,9 @@ public abstract class ValueNode {
return new OffsetDateTimeNode(charSequence); return new OffsetDateTimeNode(charSequence);
} }
public static DateNode createDateNode(String date) {
return new DateNode(date);
}
public static UndefinedNode createUndefinedNode() { public static UndefinedNode createUndefinedNode() {
return UNDEFINED; return UNDEFINED;

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

@ -2,14 +2,12 @@ package com.jayway.jsonpath.internal.filter;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.*;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import com.jayway.jsonpath.Configuration; import com.jayway.jsonpath.*;
import com.jayway.jsonpath.JsonPathException;
import com.jayway.jsonpath.Option;
import com.jayway.jsonpath.PathNotFoundException;
import com.jayway.jsonpath.Predicate;
import com.jayway.jsonpath.internal.Path; import com.jayway.jsonpath.internal.Path;
import com.jayway.jsonpath.internal.Utils; import com.jayway.jsonpath.internal.Utils;
import com.jayway.jsonpath.internal.path.PathCompiler; import com.jayway.jsonpath.internal.path.PathCompiler;
@ -227,6 +225,17 @@ public interface ValueNodes {
return new NumberNode(number); return new NumberNode(number);
} }
@Override
public DateNode asDateNode() {
DateNode node;
try {
node = new DateNode(string);
} catch (IllegalArgumentException e) {
throw new InvalidPathException("Expected Timestamp format: dd MMM yyyy HH:mm:ss VV");
}
return node;
}
public String getString() { public String getString() {
return string; return string;
} }
@ -379,7 +388,54 @@ public interface ValueNodes {
} }
} }
class DateNode extends ValueNode {
private final ZonedDateTime dateTime;
private final static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MMM yyyy HH:mm:ss VV");
DateNode(ZonedDateTime dateTime) {
this.dateTime = dateTime;
}
DateNode(String date) {
dateTime = ZonedDateTime.parse(date, formatter);
}
@Override
public StringNode asStringNode() {
return new StringNode(dateTime.format(formatter), false);
}
public ZonedDateTime getDate() {
return dateTime;
}
@Override
public Class<?> type(Predicate.PredicateContext ctx) {
return DateNode.class;
}
public boolean isDateNode() {
return true;
}
public DateNode asDateNode() {
return this;
}
@Override
public String toString() {
return dateTime.toString();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof OffsetDateTimeNode) && !(o instanceof StringNode)) return false;
DateNode that = ((ValueNode) o).asDateNode();
return dateTime.compareTo(that.dateTime) == 0;
}
}
class BooleanNode extends ValueNode { class BooleanNode extends ValueNode {
private final Boolean value; private final Boolean value;

265
json-path/src/test/java/com/jayway/jsonpath/FilterParseTest.java

@ -91,6 +91,34 @@ public class FilterParseTest {
assertThat(filter).isEqualTo(parsed); assertThat(filter).isEqualTo(parsed);
} }
@Test
public void a_ltall_filter_can_be_serialized() {
String filter = filter(where("a").ltall(1)).toString();
String parsed = parse("[?(@['a'] LTALL [1])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_lteall_filter_can_be_serialized() {
String filter = filter(where("a").lteall(1)).toString();
String parsed = parse("[?(@['a'] LTEALL [1])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_ltany_filter_can_be_serialized() {
String filter = filter(where("a").ltany(1)).toString();
String parsed = parse("[?(@['a'] LTANY [1])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_lteany_filter_can_be_serialized() {
String filter = filter(where("a").lteany(1)).toString();
String parsed = parse("[?(@['a'] LTEANY [1])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test @Test
public void a_gt_filter_can_be_serialized() { public void a_gt_filter_can_be_serialized() {
@ -100,6 +128,34 @@ public class FilterParseTest {
assertThat(filter).isEqualTo(parsed); assertThat(filter).isEqualTo(parsed);
} }
@Test
public void a_gtall_filter_can_be_serialized() {
String filter = filter(where("a").gtall(1)).toString();
String parsed = parse("[?(@['a'] GTALL [1])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_gteall_filter_can_be_serialized() {
String filter = filter(where("a").gteall(1)).toString();
String parsed = parse("[?(@['a'] GTEALL [1])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_gtany_filter_can_be_serialized() {
String filter = filter(where("a").gtany(1)).toString();
String parsed = parse("[?(@['a'] GTANY [1])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_gteany_filter_can_be_serialized() {
String filter = filter(where("a").gteany(1)).toString();
String parsed = parse("[?(@['a'] GTEANY [1])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test @Test
public void a_nin_filter_can_be_serialized() { public void a_nin_filter_can_be_serialized() {
String filter = filter(where("a").nin(1)).toString(); String filter = filter(where("a").nin(1)).toString();
@ -125,6 +181,13 @@ public class FilterParseTest {
assertThat(filter).isEqualTo(parsed); assertThat(filter).isEqualTo(parsed);
} }
@Test
public void a_notcontains_filter_can_be_serialized() {
String filter = filter(where("a").notcontains("a")).toString();
String parsed = parse("[?(@['a'] NOTCONTAINS 'a')]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test @Test
public void a_all_filter_can_be_serialized() { public void a_all_filter_can_be_serialized() {
@ -152,6 +215,15 @@ public class FilterParseTest {
assertThat(filter).isEqualTo(parsed); assertThat(filter).isEqualTo(parsed);
} }
@Test
public void a_subsetof_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").subsetof("a")).toString();
String parsed = parse("[?(@['a'] SUBSETOF ['a'])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test @Test
public void a_anyof_filter_can_be_serialized() { public void a_anyof_filter_can_be_serialized() {
@ -161,6 +233,15 @@ public class FilterParseTest {
assertThat(filter).isEqualTo(parsed); assertThat(filter).isEqualTo(parsed);
} }
@Test
public void a_anyof_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").anyof("a")).toString();
String parsed = parse("[?(@['a'] ANYOF ['a'])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test @Test
public void a_noneof_filter_can_be_serialized() { public void a_noneof_filter_can_be_serialized() {
@ -170,6 +251,15 @@ public class FilterParseTest {
assertThat(filter).isEqualTo(parsed); assertThat(filter).isEqualTo(parsed);
} }
@Test
public void a_noneof_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").noneof("a")).toString();
String parsed = parse("[?(@['a'] NONEOF ['a'])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test @Test
public void a_exists_filter_can_be_serialized() { public void a_exists_filter_can_be_serialized() {
@ -275,4 +365,179 @@ public class FilterParseTest {
assertThat(filter).isEqualTo(parsed); assertThat(filter).isEqualTo(parsed);
} }
@Test
public void a_allmatch_filter_can_be_serialized() {
String filter = filter(where("a").allmatch(Collections.emptyList())).toString();
String parsed = parse("[?(@['a'] ALLMATCH [])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_anymatch_filter_can_be_serialized() {
String filter = filter(where("a").anymatch(Collections.emptyList())).toString();
String parsed = parse("[?(@['a'] ANYMATCH [])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_nonematch_filter_can_be_serialized() {
String filter = filter(where("a").nonematch(Collections.emptyList())).toString();
String parsed = parse("[?(@['a'] NONEMATCH [])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_exactmatch_filter_can_be_serialized() {
String filter = filter(where("a").exactmatch(Collections.emptyList())).toString();
String parsed = parse("[?(@['a'] EXACTMATCH [])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_allmatch_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").allmatch("a")).toString();
String parsed = parse("[?(@['a'] ALLMATCH ['a'])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_anymatch_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").anymatch("a")).toString();
String parsed = parse("[?(@['a'] ANYMATCH ['a'])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_nonematch_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").nonematch("a")).toString();
String parsed = parse("[?(@['a'] NONEMATCH ['a'])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_exactmatch_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").exactmatch("a")).toString();
String parsed = parse("[?(@['a'] EXACTMATCH ['a'])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_dateeq_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").dateeq("a")).toString();
String parsed = parse("[?(@['a'] DATEEQ 'a')]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_dayeq_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").dayeq("a")).toString();
String parsed = parse("[?(@['a'] DAYEQ 'a')]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_dayin_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").dayin("a")).toString();
String parsed = parse("[?(@['a'] DAYIN ['a'])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_montheq_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").montheq("a")).toString();
String parsed = parse("[?(@['a'] MONTHEQ 'a')]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_monthin_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").monthin("a")).toString();
String parsed = parse("[?(@['a'] MONTHIN ['a'])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_yeareq_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").yeareq("a")).toString();
String parsed = parse("[?(@['a'] YEAREQ 'a')]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_yearin_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").yearin("a")).toString();
String parsed = parse("[?(@['a'] YEARIN ['a'])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_before_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").before("a")).toString();
String parsed = parse("[?(@['a'] BEFORE 'a')]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_after_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").after("a")).toString();
String parsed = parse("[?(@['a'] AFTER 'a')]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_houreq_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").houreq("a")).toString();
String parsed = parse("[?(@['a'] HOUREQ 'a')]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_hourin_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").hourin("a")).toString();
String parsed = parse("[?(@['a'] HOURIN ['a'])]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_timebefore_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").timebefore("a")).toString();
String parsed = parse("[?(@['a'] TIMEBEFORE 'a')]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_timeafter_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").timeafter("a")).toString();
String parsed = parse("[?(@['a'] TIMEAFTER 'a')]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_windowin_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").windowin("a")).toString();
String parsed = parse("[?(@['a'] WINDOWIN 'a')]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_windowout_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").windowout("a")).toString();
String parsed = parse("[?(@['a'] WINDOWOUT 'a')]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_windowtimein_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").windowtimein("a")).toString();
String parsed = parse("[?(@['a'] WINDOWTIMEIN 'a')]").toString();
assertThat(filter).isEqualTo(parsed);
}
@Test
public void a_windowtimeout_objectrange_filter_can_be_serialized() {
String filter = filter(where("a").windowtimeout("a")).toString();
String parsed = parse("[?(@['a'] WINDOWTIMEOUT 'a')]").toString();
assertThat(filter).isEqualTo(parsed);
}
} }

Loading…
Cancel
Save