Browse Source

implemented naive eval function to remove java ScriptEngine dependency (support for java 5)

pull/1/merge
kalle 14 years ago
parent
commit
759ecf35b6
  1. 4
      json-path/src/main/java/com/jayway/jsonpath/PathUtil.java
  2. 88
      json-path/src/main/java/com/jayway/jsonpath/eval/Expression.java
  3. 3
      json-path/src/main/java/com/jayway/jsonpath/filter/JsonPathFilterFactory.java
  4. 47
      json-path/src/main/java/com/jayway/jsonpath/filter/ListFilter.java
  5. 65
      json-path/src/test/java/com/jayway/jsonpath/ExpressionEvalTest.java
  6. 1
      json-path/src/test/java/com/jayway/jsonpath/JsonPathTest.java

4
json-path/src/main/java/com/jayway/jsonpath/PathUtil.java

@ -53,7 +53,9 @@ public class PathUtil {
jsonPath = jsonPath.replace("..", ".~.")
.replace("[", ".[")
.replace("@.", "@");
.replace("@.", "@")
.replace("['", "")
.replace("']", "");
String[] split = jsonPath.split("\\.");

88
json-path/src/main/java/com/jayway/jsonpath/eval/Expression.java

@ -0,0 +1,88 @@
package com.jayway.jsonpath.eval;
/**
* User: kalle stenflo
* Date: 2/4/11
* Time: 9:21 PM
*/
public class Expression {
public static <T> boolean eval(T actual, String comparator, String expected) {
comparator = comparator.trim();
if (actual instanceof Long) {
Long a = (Long) actual;
Long e = Long.parseLong(expected.trim());
if ("=".equals(comparator)) {
return a.longValue() == e.longValue();
} else if ("!=".equals(comparator) || "<>".equals(comparator)) {
return a.longValue() != e.longValue();
} else if (">".equals(comparator)) {
return a.longValue() > e.longValue();
} else if (">=".equals(comparator)) {
return a.longValue() >= e.longValue();
} else if ("<".equals(comparator)) {
return a.longValue() < e.longValue();
} else if ("<=".equals(comparator)) {
return a.longValue() <= e.longValue();
}
} else if (actual instanceof Integer) {
Integer a = (Integer) actual;
Integer e = Integer.parseInt(expected.trim());
if ("=".equals(comparator)) {
return a.longValue() == e.longValue();
} else if ("!=".equals(comparator) || "<>".equals(comparator)) {
return a.longValue() != e.longValue();
} else if (">".equals(comparator)) {
return a.longValue() > e.longValue();
} else if (">=".equals(comparator)) {
return a.longValue() >= e.longValue();
} else if ("<".equals(comparator)) {
return a.longValue() < e.longValue();
} else if ("<=".equals(comparator)) {
return a.longValue() <= e.longValue();
}
} else if (actual instanceof Double) {
Double a = (Double) actual;
Double e = Double.parseDouble(expected.trim());
if ("=".equals(comparator)) {
return a.longValue() == e.longValue();
} else if ("!=".equals(comparator) || "<>".equals(comparator)) {
return a.longValue() != e.longValue();
} else if (">".equals(comparator)) {
return a.longValue() > e.longValue();
} else if (">=".equals(comparator)) {
return a.longValue() >= e.longValue();
} else if ("<".equals(comparator)) {
return a.longValue() < e.longValue();
} else if ("<=".equals(comparator)) {
return a.longValue() <= e.longValue();
}
} else if (actual instanceof String) {
String a = (String)actual;
expected = expected.trim();
if(expected.startsWith("'")) {
expected = expected.substring(1);
}
if(expected.endsWith("'")){
expected = expected.substring(0, expected.length()-1);
}
if ("=".equals(comparator)) {
return a.equals(expected);
} else if ("!=".equals(comparator) || "<>".equals(comparator)) {
return !a.equals(expected);
}
}
return false;
}
}

3
json-path/src/main/java/com/jayway/jsonpath/filter/JsonPathFilterFactory.java

@ -10,7 +10,8 @@ import java.util.regex.Pattern;
public class JsonPathFilterFactory {
private final static Pattern ROOT_FILTER_PATTERN = Pattern.compile("\\$");
private final static Pattern PROPERTY_FILTER_PATTERN = Pattern.compile("\\w+");
private final static Pattern PROPERTY_FILTER_PATTERN = Pattern.compile("(\\w+)|\\['(\\w+)'\\]");
//private final static Pattern PROPERTY_FILTER_PATTERN = Pattern.compile("\\w+");
private final static Pattern WILDCARD_PROPERTY_FILTER_PATTERN = Pattern.compile("\\*");
private final static Pattern LIST_FILTER_PATTERN = Pattern.compile("\\[.*?\\]");
private final static Pattern TRAVERSE_FILTER_PATTERN = Pattern.compile("\\.\\.");

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

@ -1,11 +1,11 @@
package com.jayway.jsonpath.filter;
import com.jayway.jsonpath.JsonUtil;
import com.jayway.jsonpath.eval.Expression;
import org.json.simple.JSONArray;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
//import javax.script.ScriptEngine;
//import javax.script.ScriptEngineManager;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@ -20,7 +20,7 @@ import java.util.regex.Pattern;
*/
public class ListFilter extends JsonPathFilterBase {
private static ScriptEngine SCRIPT_ENGINE = new ScriptEngineManager().getEngineByName("js");
//private static ScriptEngine SCRIPT_ENGINE = new ScriptEngineManager().getEngineByName("js");
private static final Pattern LIST_INDEX_PATTERN = Pattern.compile("\\[(\\s?\\d+\\s?,?)+\\]"); //[1] OR [1,2,3]
private static final Pattern LIST_PULL_PATTERN = Pattern.compile("\\[\\s?:(\\d+)\\s?\\]"); //[ :2 ]
@ -51,8 +51,7 @@ public class ListFilter extends JsonPathFilterBase {
return filterByPullIndex(items);
} else if (LIST_ITEM_HAS_PROPERTY_PATTERN.matcher(pathFragment).matches()) {
return filterByItemProperty(items);
}
else if (LIST_ITEM_MATCHES_EVAL.matcher(pathFragment).matches()) {
} else if (LIST_ITEM_MATCHES_EVAL.matcher(pathFragment).matches()) {
return filterByItemEvalMatch(items);
}
@ -64,7 +63,7 @@ public class ListFilter extends JsonPathFilterBase {
for (Object current : items) {
for (Object item : JsonUtil.toList(current)) {
if(isEvalMatch(item)){
if (isEvalMatch(item)) {
result.add(item);
}
}
@ -81,8 +80,8 @@ public class ListFilter extends JsonPathFilterBase {
for (Object current : items) {
for (Object item : JsonUtil.toList(current)) {
if(JsonUtil.isMap(item)){
if(JsonUtil.toMap(item).containsKey(prop)) {
if (JsonUtil.isMap(item)) {
if (JsonUtil.toMap(item).containsKey(prop)) {
result.add(item);
}
}
@ -142,43 +141,31 @@ public class ListFilter extends JsonPathFilterBase {
Matcher matcher = LIST_ITEM_MATCHES_EVAL.matcher(pathFragment);
if (matcher.matches()) {
String property = matcher.group(1);
String operator = matcher.group(2);
String expected = matcher.group(3);
String property = matcher.group(1);
String operator = matcher.group(2);
String expected = matcher.group(3);
if(!JsonUtil.isMap(check)){
if (!JsonUtil.isMap(check)) {
return false;
}
Map obj = JsonUtil.toMap(check);
if(!obj.containsKey(property)){
if (!obj.containsKey(property)) {
return false;
}
Object propertyValue = obj.get(property);
if(JsonUtil.isContainer(propertyValue)){
if (JsonUtil.isContainer(propertyValue)) {
return false;
}
if(propertyValue instanceof String){
propertyValue = "'" + propertyValue + "'";
}
if(operator.trim().equals("=")){
operator = "===";
}
String expression = propertyValue + " " + operator + " " + expected;
System.out.println("EVAL" + expression);
try {
return (Boolean) SCRIPT_ENGINE.eval(expression);
} catch (ScriptException e) {
return false;
}
return Expression.eval(propertyValue, operator, expected);
}
return false;
}

65
json-path/src/test/java/com/jayway/jsonpath/ExpressionEvalTest.java

@ -0,0 +1,65 @@
package com.jayway.jsonpath;
import com.jayway.jsonpath.eval.Expression;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* Created by IntelliJ IDEA.
* User: kallestenflo
* Date: 2/4/11
* Time: 9:32 PM
*/
public class ExpressionEvalTest {
@Test
public void long_eval() throws Exception {
assertTrue(Expression.eval(1L, "=", "1"));
assertTrue(Expression.eval(2L, "!=", "1"));
assertTrue(Expression.eval(2L, ">", "1"));
assertTrue(Expression.eval(2L, ">=", "1"));
assertTrue(Expression.eval(2L, ">=", "2"));
assertTrue(Expression.eval(1L, "<", "2"));
assertTrue(Expression.eval(2L, "<=", "2"));
assertFalse(Expression.eval(1, ">", "2"));
assertFalse(Expression.eval(1, ">=", "2"));
assertFalse(Expression.eval(2, "<", "1"));
assertFalse(Expression.eval(2, "<=", "1"));
assertFalse(Expression.eval(1, "=", "2"));
assertFalse(Expression.eval(1, "!=", "1"));
}
@Test
public void double_eval() throws Exception {
assertTrue(Expression.eval(1D, "=", "1"));
assertTrue(Expression.eval(2D, "!=", "1"));
assertTrue(Expression.eval(2D, ">", "1"));
assertTrue(Expression.eval(2D, ">=", "1"));
assertTrue(Expression.eval(2D, ">=", "2"));
assertTrue(Expression.eval(1D, "<", "2"));
assertTrue(Expression.eval(2D, "<=", "2"));
assertFalse(Expression.eval(1D, ">", "2"));
assertFalse(Expression.eval(1D, ">=", "2"));
assertFalse(Expression.eval(2D, "<", "1"));
assertFalse(Expression.eval(2D, "<=", "1"));
assertFalse(Expression.eval(1D, "=", "2"));
assertFalse(Expression.eval(1D, "!=", "1"));
}
@Test
public void string_eval() throws Exception {
assertTrue(Expression.eval("A", "=", "A"));
assertTrue(Expression.eval("B", "!=", "A"));
}
}

1
json-path/src/test/java/com/jayway/jsonpath/JsonPathTest.java

@ -86,6 +86,7 @@ public class JsonPathTest {
@Test
public void read_store_book_author() throws Exception {
assertThat(JsonPath.<String>read(DOCUMENT, "$.store.book[*].author"), hasItems("Nigel Rees", "Evelyn Waugh", "Herman Melville", "J. R. R. Tolkien"));
assertThat(JsonPath.<String>read(DOCUMENT, "$.['store'].['book'][*].['author']"), hasItems("Nigel Rees", "Evelyn Waugh", "Herman Melville", "J. R. R. Tolkien"));
}

Loading…
Cancel
Save