|
|
@ -14,6 +14,8 @@ |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
package com.jayway.jsonpath.internal.filter.eval; |
|
|
|
package com.jayway.jsonpath.internal.filter.eval; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.math.BigDecimal; |
|
|
|
|
|
|
|
import java.math.BigInteger; |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
@ -22,151 +24,198 @@ import java.util.Map; |
|
|
|
* @author Kalle Stenflo |
|
|
|
* @author Kalle Stenflo |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public class ExpressionEvaluator { |
|
|
|
public class ExpressionEvaluator { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public enum Operator { |
|
|
|
public enum Operator { |
|
|
|
equal("=="), not_equal("!="), less_or_greater_than("<>"),greater_than(">"), greater_than_or_equal(">="), less_than("<"), less_than_or_equal("<="); |
|
|
|
equal("=="), not_equal("!="), less_or_greater_than("<>"), greater_than(">"), greater_than_or_equal(">="), less_than("<"), less_than_or_equal("<="); |
|
|
|
|
|
|
|
|
|
|
|
private final String representation; |
|
|
|
private final String representation; |
|
|
|
|
|
|
|
|
|
|
|
private Operator(String representation) { |
|
|
|
private Operator(String representation) { |
|
|
|
this.representation = representation; |
|
|
|
this.representation = representation; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public String getRepresentation() { |
|
|
|
public String getRepresentation() { |
|
|
|
return representation; |
|
|
|
return representation; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static Map<String, Operator> operatorsByRepresentation; |
|
|
|
private static Map<String, Operator> operatorsByRepresentation; |
|
|
|
|
|
|
|
|
|
|
|
static { |
|
|
|
static { |
|
|
|
Map<String, Operator> map = new HashMap<String, Operator>(); |
|
|
|
Map<String, Operator> map = new HashMap<String, Operator>(); |
|
|
|
for (Operator op : Operator.values()){ |
|
|
|
for (Operator op : Operator.values()) { |
|
|
|
map.put(op.getRepresentation(), op); |
|
|
|
map.put(op.getRepresentation(), op); |
|
|
|
} |
|
|
|
} |
|
|
|
ExpressionEvaluator.operatorsByRepresentation = Collections.unmodifiableMap(map); |
|
|
|
ExpressionEvaluator.operatorsByRepresentation = Collections.unmodifiableMap(map); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static <T> boolean eval(T actual, String comparator, String expected) { |
|
|
|
public static <T> boolean eval(T actual, String comparator, String expected) { |
|
|
|
|
|
|
|
|
|
|
|
Operator operator = operatorsByRepresentation.get(comparator); |
|
|
|
Operator operator = operatorsByRepresentation.get(comparator); |
|
|
|
if (operator == null){ |
|
|
|
if (operator == null) { |
|
|
|
throw new IllegalArgumentException("Unsupported operator " + comparator); |
|
|
|
throw new IllegalArgumentException("Unsupported operator " + comparator); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (actual instanceof Long) { |
|
|
|
if (actual instanceof Long) { |
|
|
|
|
|
|
|
|
|
|
|
Long a = (Long) actual; |
|
|
|
Long a = (Long) actual; |
|
|
|
Long e = Long.parseLong(expected.trim()); |
|
|
|
Long e = Long.parseLong(expected.trim()); |
|
|
|
switch (operator){ |
|
|
|
switch (operator) { |
|
|
|
case equal: |
|
|
|
case equal: |
|
|
|
return a.longValue() == e.longValue(); |
|
|
|
return a.longValue() == e.longValue(); |
|
|
|
case not_equal: |
|
|
|
case not_equal: |
|
|
|
case less_or_greater_than: |
|
|
|
case less_or_greater_than: |
|
|
|
return a.longValue() != e.longValue(); |
|
|
|
return a.longValue() != e.longValue(); |
|
|
|
case greater_than: |
|
|
|
case greater_than: |
|
|
|
return a > e; |
|
|
|
return a > e; |
|
|
|
case greater_than_or_equal: |
|
|
|
case greater_than_or_equal: |
|
|
|
return a >= e; |
|
|
|
return a >= e; |
|
|
|
case less_than: |
|
|
|
case less_than: |
|
|
|
return a < e; |
|
|
|
return a < e; |
|
|
|
case less_than_or_equal: |
|
|
|
case less_than_or_equal: |
|
|
|
return a <= e; |
|
|
|
return a <= e; |
|
|
|
default: |
|
|
|
default: |
|
|
|
throw new UnsupportedOperationException("Cannot handle operator " + operator); |
|
|
|
throw new UnsupportedOperationException("Cannot handle operator " + operator); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else if (actual instanceof Integer) { |
|
|
|
} else if (actual instanceof Integer) { |
|
|
|
Integer a = (Integer) actual; |
|
|
|
Integer a = (Integer) actual; |
|
|
|
Integer e = Integer.parseInt(expected.trim()); |
|
|
|
Integer e = Integer.parseInt(expected.trim()); |
|
|
|
|
|
|
|
|
|
|
|
switch (operator){ |
|
|
|
switch (operator) { |
|
|
|
case equal: |
|
|
|
case equal: |
|
|
|
return a.intValue() == e.intValue(); |
|
|
|
return a.intValue() == e.intValue(); |
|
|
|
case not_equal: |
|
|
|
case not_equal: |
|
|
|
case less_or_greater_than: |
|
|
|
case less_or_greater_than: |
|
|
|
return a.intValue() != e.intValue(); |
|
|
|
return a.intValue() != e.intValue(); |
|
|
|
case greater_than: |
|
|
|
case greater_than: |
|
|
|
return a > e; |
|
|
|
return a > e; |
|
|
|
case greater_than_or_equal: |
|
|
|
case greater_than_or_equal: |
|
|
|
return a >= e; |
|
|
|
return a >= e; |
|
|
|
case less_than: |
|
|
|
case less_than: |
|
|
|
return a < e; |
|
|
|
return a < e; |
|
|
|
case less_than_or_equal: |
|
|
|
case less_than_or_equal: |
|
|
|
return a <= e; |
|
|
|
return a <= e; |
|
|
|
default: |
|
|
|
default: |
|
|
|
throw new UnsupportedOperationException("Cannot handle operator " + operator); |
|
|
|
throw new UnsupportedOperationException("Cannot handle operator " + operator); |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (actual instanceof Double) { |
|
|
|
} else if (actual instanceof Double) { |
|
|
|
|
|
|
|
|
|
|
|
Double a = (Double) actual; |
|
|
|
Double a = (Double) actual; |
|
|
|
Double e = Double.parseDouble(expected.trim()); |
|
|
|
Double e = Double.parseDouble(expected.trim()); |
|
|
|
|
|
|
|
|
|
|
|
switch (operator){ |
|
|
|
switch (operator) { |
|
|
|
case equal: |
|
|
|
case equal: |
|
|
|
return a.doubleValue() == e.doubleValue(); |
|
|
|
return a.doubleValue() == e.doubleValue(); |
|
|
|
case not_equal: |
|
|
|
case not_equal: |
|
|
|
case less_or_greater_than: |
|
|
|
case less_or_greater_than: |
|
|
|
return a.doubleValue() != e.doubleValue(); |
|
|
|
return a.doubleValue() != e.doubleValue(); |
|
|
|
case greater_than: |
|
|
|
case greater_than: |
|
|
|
return a > e; |
|
|
|
return a > e; |
|
|
|
case greater_than_or_equal: |
|
|
|
case greater_than_or_equal: |
|
|
|
return a >= e; |
|
|
|
return a >= e; |
|
|
|
case less_than: |
|
|
|
case less_than: |
|
|
|
return a < e; |
|
|
|
return a < e; |
|
|
|
case less_than_or_equal: |
|
|
|
case less_than_or_equal: |
|
|
|
return a <= e; |
|
|
|
return a <= e; |
|
|
|
default: |
|
|
|
default: |
|
|
|
throw new UnsupportedOperationException("Cannot handle operator " + operator); |
|
|
|
throw new UnsupportedOperationException("Cannot handle operator " + operator); |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (actual instanceof String) { |
|
|
|
} else if (actual instanceof String) { |
|
|
|
|
|
|
|
|
|
|
|
switch (operator){ |
|
|
|
switch (operator) { |
|
|
|
case greater_than: |
|
|
|
case greater_than: |
|
|
|
case greater_than_or_equal: |
|
|
|
case greater_than_or_equal: |
|
|
|
case less_than: |
|
|
|
case less_than: |
|
|
|
case less_than_or_equal: |
|
|
|
case less_than_or_equal: |
|
|
|
// we might want to throw an exception here
|
|
|
|
// we might want to throw an exception here
|
|
|
|
return false; |
|
|
|
return false; |
|
|
|
case equal: |
|
|
|
case equal: |
|
|
|
case not_equal: |
|
|
|
case not_equal: |
|
|
|
case less_or_greater_than: |
|
|
|
case less_or_greater_than: |
|
|
|
String a = (String)actual; |
|
|
|
String a = (String) actual; |
|
|
|
String expectedTrimmed = expected.trim(); |
|
|
|
String expectedTrimmed = expected.trim(); |
|
|
|
if(expectedTrimmed.startsWith("'")) { |
|
|
|
if (expectedTrimmed.startsWith("'")) { |
|
|
|
expectedTrimmed = expectedTrimmed.substring(1); |
|
|
|
expectedTrimmed = expectedTrimmed.substring(1); |
|
|
|
} |
|
|
|
} |
|
|
|
if(expectedTrimmed.endsWith("'")){ |
|
|
|
if (expectedTrimmed.endsWith("'")) { |
|
|
|
expectedTrimmed = expectedTrimmed.substring(0, expected.length()-1); |
|
|
|
expectedTrimmed = expectedTrimmed.substring(0, expected.length() - 1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (operator == Operator.equal) { |
|
|
|
if (operator == Operator.equal) { |
|
|
|
return a.equals(expectedTrimmed); |
|
|
|
return a.equals(expectedTrimmed); |
|
|
|
} else if (operator == Operator.not_equal || operator == Operator.less_or_greater_than) { |
|
|
|
} else if (operator == Operator.not_equal || operator == Operator.less_or_greater_than) { |
|
|
|
return !a.equals(expectedTrimmed); |
|
|
|
return !a.equals(expectedTrimmed); |
|
|
|
} |
|
|
|
} |
|
|
|
default: |
|
|
|
default: |
|
|
|
throw new UnsupportedOperationException("Cannot handle operator " + operator); |
|
|
|
throw new UnsupportedOperationException("Cannot handle operator " + operator); |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (actual instanceof Boolean) { |
|
|
|
} else if (actual instanceof Boolean) { |
|
|
|
switch (operator){ |
|
|
|
switch (operator) { |
|
|
|
case equal: |
|
|
|
case equal: |
|
|
|
case not_equal: |
|
|
|
case not_equal: |
|
|
|
case less_or_greater_than: |
|
|
|
case less_or_greater_than: |
|
|
|
Boolean a = (Boolean) actual; |
|
|
|
Boolean a = (Boolean) actual; |
|
|
|
Boolean e = Boolean.valueOf(expected); |
|
|
|
Boolean e = Boolean.valueOf(expected); |
|
|
|
if (operator == Operator.equal) { |
|
|
|
if (operator == Operator.equal) { |
|
|
|
return a.equals(e); |
|
|
|
return a.equals(e); |
|
|
|
} else if (operator == Operator.not_equal || operator == Operator.less_or_greater_than) { |
|
|
|
} else if (operator == Operator.not_equal || operator == Operator.less_or_greater_than) { |
|
|
|
return !a.equals(e); |
|
|
|
return !a.equals(e); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
throw new UnsupportedOperationException("Cannot handle operator " + operator); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else if (actual instanceof BigInteger) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BigInteger a = (BigInteger) actual; |
|
|
|
|
|
|
|
BigInteger e = new BigInteger(expected.trim()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (operator){ |
|
|
|
|
|
|
|
case equal: |
|
|
|
|
|
|
|
return a.compareTo(e) == 0; |
|
|
|
|
|
|
|
case not_equal: |
|
|
|
|
|
|
|
return a.compareTo(e) != 0; |
|
|
|
|
|
|
|
case less_or_greater_than: |
|
|
|
|
|
|
|
return a.compareTo(e) != 0; |
|
|
|
|
|
|
|
case greater_than: |
|
|
|
|
|
|
|
return a.compareTo(e) > 0; |
|
|
|
|
|
|
|
case greater_than_or_equal: |
|
|
|
|
|
|
|
return a.compareTo(e) >= 0; |
|
|
|
|
|
|
|
case less_than: |
|
|
|
|
|
|
|
return a.compareTo(e) < 0; |
|
|
|
|
|
|
|
case less_than_or_equal: |
|
|
|
|
|
|
|
return a.compareTo(e) <= 0; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
throw new UnsupportedOperationException("Cannot handle operator " + operator); |
|
|
|
} |
|
|
|
} |
|
|
|
default: |
|
|
|
} else if (actual instanceof BigDecimal) { |
|
|
|
throw new UnsupportedOperationException("Cannot handle operator " + operator); |
|
|
|
|
|
|
|
} |
|
|
|
BigDecimal a = (BigDecimal) actual; |
|
|
|
|
|
|
|
BigDecimal e = new BigDecimal(expected); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (operator){ |
|
|
|
|
|
|
|
case equal: |
|
|
|
|
|
|
|
return a.compareTo(e) == 0; |
|
|
|
|
|
|
|
case not_equal: |
|
|
|
|
|
|
|
return a.compareTo(e) != 0; |
|
|
|
|
|
|
|
case less_or_greater_than: |
|
|
|
|
|
|
|
return a.compareTo(e) != 0; |
|
|
|
|
|
|
|
case greater_than: |
|
|
|
|
|
|
|
return a.compareTo(e) > 0; |
|
|
|
|
|
|
|
case greater_than_or_equal: |
|
|
|
|
|
|
|
return a.compareTo(e) >= 0; |
|
|
|
|
|
|
|
case less_than: |
|
|
|
|
|
|
|
return a.compareTo(e) < 0; |
|
|
|
|
|
|
|
case less_than_or_equal: |
|
|
|
|
|
|
|
return a.compareTo(e) <= 0; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
throw new UnsupportedOperationException("Cannot handle operator " + operator); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |