Browse Source

'AND' (&&) support in ArrayEvalFilter.

pull/10/merge
Kalle Stenflo 11 years ago
parent
commit
a83f32caba
  1. 43
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayEvalFilter.java
  2. 5
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterFactory.java
  3. 20
      json-path/src/test/java/com/jayway/jsonpath/ExpressionEvalTest.java
  4. 6
      json-path/src/test/java/com/jayway/jsonpath/HttpProviderTest.java
  5. 3
      json-path/src/test/java/com/jayway/jsonpath/IssuesTest.java
  6. 39
      json-path/src/test/java/com/jayway/jsonpath/internal/filter/ArrayEvalFilterTest.java

43
json-path/src/main/java/com/jayway/jsonpath/internal/filter/ArrayEvalFilter.java

@ -29,13 +29,28 @@ import java.util.regex.Pattern;
*/
public class ArrayEvalFilter extends PathTokenFilter {
private static final Pattern PATTERN = Pattern.compile("\\[\\s?\\?\\(\\s?(@.*?)\\s?([!=<>]+)\\s?(.*?)\\s?\\)\\s?]");
private static final Pattern CONDITION_STATEMENT_PATTERN = Pattern.compile("\\[\\s?\\?\\(.*?[!=<>]+.*?\\)\\s?]");
private static final Pattern PATTERN = Pattern.compile("\\s?(@.*?)\\s?([!=<>]+)\\s?(.*?)\\s?");
private final ConditionStatement conditionStatement;
public ArrayEvalFilter(ConditionStatement statement) {
super(statement.condition);
this.conditionStatement = statement;
private ConditionStatement[] conditionStatements;
public ArrayEvalFilter(String condition) {
super(condition);
// [?(@.name == 'Luke Skywalker' && @.occupation == 'Farm boy')]
// [?(@.name == 'Luke Skywalker')]
condition = condition.trim();
condition = condition.substring(3, condition.length()-2);
String[] split = condition.split("&&");
conditionStatements = new ConditionStatement[split.length];
for(int i = 0; i < split.length; i++){
conditionStatements[i] = createConditionStatement(split[i]);
}
}
@ -51,7 +66,7 @@ public class ArrayEvalFilter extends PathTokenFilter {
}
Object result = jsonProvider.createArray();
for (Object item : src) {
if (isMatch(item, conditionStatement, configuration)) {
if (isMatch(item, configuration, conditionStatements)) {
jsonProvider.setProperty(result, jsonProvider.length(result), item);
}
}
@ -68,10 +83,16 @@ public class ArrayEvalFilter extends PathTokenFilter {
return true;
}
private boolean isMatch(Object check, ConditionStatement conditionStatement, Configuration configuration) {
private boolean isMatch(Object check, Configuration configuration, ConditionStatement... conditionStatements) {
try {
Object value = conditionStatement.path.read(check, configuration.options(Option.THROW_ON_MISSING_PROPERTY));
return ExpressionEvaluator.eval(value, conditionStatement.getOperator(), conditionStatement.getExpected());
for (ConditionStatement conditionStatement : conditionStatements) {
Object value = conditionStatement.path.read(check, configuration.options(Option.THROW_ON_MISSING_PROPERTY));
boolean match = ExpressionEvaluator.eval(value, conditionStatement.getOperator(), conditionStatement.getExpected());
if(!match){
return false;
}
}
return true;
} catch (PathNotFoundException e){
return false;
} catch (RuntimeException e){
@ -80,6 +101,10 @@ public class ArrayEvalFilter extends PathTokenFilter {
}
}
static boolean isConditionStatement(String condition) {
return CONDITION_STATEMENT_PATTERN.matcher(condition).matches();
}
static ConditionStatement createConditionStatement(String condition) {
Matcher matcher = PATTERN.matcher(condition);
if (matcher.matches()) {

5
json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterFactory.java

@ -60,9 +60,8 @@ public class FilterFactory {
if (pathFragment.startsWith("[?")) {
ArrayEvalFilter.ConditionStatement conditionStatement = ArrayEvalFilter.createConditionStatement(pathFragment);
if(conditionStatement != null){
return new ArrayEvalFilter(conditionStatement);
if(ArrayEvalFilter.isConditionStatement(pathFragment)){
return new ArrayEvalFilter(pathFragment);
} else if (!pathFragment.contains("=") && !pathFragment.contains("<") && !pathFragment.contains(">")) {
//[?(@.isbn)]
return new HasFieldFilter(pathFragment);

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

@ -189,6 +189,26 @@ public class ExpressionEvalTest {
assertTrue(ExpressionEvaluator.eval(null, "!=", "10"));
}
@Test
public void and_operator_in_filter() {
Object o = JsonPath.read(DOCUMENT, "$.characters[?(@.name == 'Luke Skywalker' && @.occupation == 'Farm boy')]");
assertEquals("[{\"occupation\":\"Farm boy\",\"name\":\"Luke Skywalker\",\"aliases\":[\"Nerf herder\"],\"offspring\":null}]", o.toString());
}
@Test
public void not_equal_in_and_operator_filter() {
Object o = JsonPath.read(DOCUMENT, "$.characters[?(@.name == 'Luke Skywalker' && @.occupation != 'Farm boy')]");
assertEquals("[]", o.toString());
o = JsonPath.read(DOCUMENT, "$.characters[?(@.name == 'Luke Skywalker' && @.occupation != 'City boy')]");
assertEquals("[{\"occupation\":\"Farm boy\",\"name\":\"Luke Skywalker\",\"aliases\":[\"Nerf herder\"],\"offspring\":null}]", o.toString());
}
@Test
public void nulls_filter() {

6
json-path/src/test/java/com/jayway/jsonpath/HttpProviderTest.java

@ -17,19 +17,19 @@ import static junit.framework.Assert.assertEquals;
* Date: 3/10/12
* Time: 8:12 AM
*/
@Ignore
//@Ignore
public class HttpProviderTest {
private static final String EXPECTED = "{\n" +
" \"results\" : [],\n" +
" \"status\" : \"REQUEST_DENIED\"\n" +
" \"status\" : \"ZERO_RESULTS\"\n" +
"}";
@Test
public void http_get() throws Exception {
URL url = new URL("http://maps.googleapis.com/maps/api/geocode/json");
URL url = new URL("http://maps.googleapis.com/maps/api/geocode/json?sensor=false");
InputStream inputStream = null;
try {

3
json-path/src/test/java/com/jayway/jsonpath/IssuesTest.java

@ -28,7 +28,6 @@ public class IssuesTest {
@Test
public void issue_36() {
String json = "{\n" +
"\n" +
" \"arrayOfObjectsAndArrays\" : [ { \"k\" : [\"json\"] }, { \"k\":[\"path\"] }, { \"k\" : [\"is\"] }, { \"k\" : [\"cool\"] } ],\n" +
@ -42,8 +41,6 @@ public class IssuesTest {
assertEquals("[[\"json\"],[\"path\"],[\"is\"],[\"cool\"]]", o1.toString());
assertEquals("[\"json\",\"path\",\"is\",\"cool\"]", o2.toString());
}
@Test(expected = PathNotFoundException.class)

39
json-path/src/test/java/com/jayway/jsonpath/internal/filter/ArrayEvalFilterTest.java

@ -3,6 +3,8 @@ package com.jayway.jsonpath.internal.filter;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/**
* User: kalle
@ -11,33 +13,44 @@ import static org.junit.Assert.assertEquals;
*/
public class ArrayEvalFilterTest {
@Test
public void can_determine_condition_statement() {
assertTrue(ArrayEvalFilter.isConditionStatement("[?(@.id == 5 && @.name == 'kalle')]"));
assertTrue(ArrayEvalFilter.isConditionStatement("[?( @==5)]"));
assertTrue(ArrayEvalFilter.isConditionStatement("[?(@.id == 5)]"));
}
@Test
public void condition_statements_can_be_parsed() {
//assertEquals(new ArrayEvalFilter.ConditionStatement("@.length", ">", "0"), ArrayEvalFilter.createConditionStatement("[?(@.length>0)]"));
//int array
assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "5"), ArrayEvalFilter.createConditionStatement("[?(@==5)]"));
assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "5"), ArrayEvalFilter.createConditionStatement("[?(@ == 5)]"));
assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "5"), ArrayEvalFilter.createConditionStatement("[ ?(@ == 5) ]"));
assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "5"), ArrayEvalFilter.createConditionStatement("[ ?( @ == 5) ]"));
assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "5"), ArrayEvalFilter.createConditionStatement("[ ?( @ == 5 ) ]"));
assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "5"), ArrayEvalFilter.createConditionStatement("@==5"));
assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "5"), ArrayEvalFilter.createConditionStatement("@ == 5"));
assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "5"), ArrayEvalFilter.createConditionStatement(" @ == 5 "));
assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "5"), ArrayEvalFilter.createConditionStatement("@ ==5"));
assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "5"), ArrayEvalFilter.createConditionStatement("@== 5 "));
//String array
assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "one"), ArrayEvalFilter.createConditionStatement("[?(@=='one')]"));
assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "one monkey"), ArrayEvalFilter.createConditionStatement("[?(@ == 'one monkey')]"));
assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "two"), ArrayEvalFilter.createConditionStatement("[?(@ == 'two')]"));
assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "one"), ArrayEvalFilter.createConditionStatement("@=='one'"));
assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "one monkey"), ArrayEvalFilter.createConditionStatement("@ == 'one monkey' "));
assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "two"), ArrayEvalFilter.createConditionStatement("@ == 'two'"));
//Sub item dot notation
assertEquals(new ArrayEvalFilter.ConditionStatement("@.name", "==", "true"), ArrayEvalFilter.createConditionStatement("[?(@.name == true)]"));
assertEquals(new ArrayEvalFilter.ConditionStatement("@.name", "==", "true"), ArrayEvalFilter.createConditionStatement("@.name == true"));
//Sub item bracket notation
assertEquals(new ArrayEvalFilter.ConditionStatement("@['name']", "==", "true"), ArrayEvalFilter.createConditionStatement("[?(@['name'] == true)]"));
assertEquals(new ArrayEvalFilter.ConditionStatement("@.['name']", "==", "true"), ArrayEvalFilter.createConditionStatement("[?(@.['name'] == true)]"));
assertEquals(new ArrayEvalFilter.ConditionStatement("@['name']", "==", "true"), ArrayEvalFilter.createConditionStatement("@['name'] == true"));
assertEquals(new ArrayEvalFilter.ConditionStatement("@.['name']", "==", "true"), ArrayEvalFilter.createConditionStatement("@.['name'] == true"));
//Sub path notation
assertEquals(new ArrayEvalFilter.ConditionStatement("@['name']['age']", "!=", "true"), ArrayEvalFilter.createConditionStatement("[?(@['name']['age'] != true)]"));
assertEquals(new ArrayEvalFilter.ConditionStatement("@.['name'].age", ">", "true"), ArrayEvalFilter.createConditionStatement("[?(@.['name'].age > true)]"));
assertEquals(new ArrayEvalFilter.ConditionStatement("@['name']['age']", "!=", "true"), ArrayEvalFilter.createConditionStatement("@['name']['age'] != true"));
assertEquals(new ArrayEvalFilter.ConditionStatement("@.['name'].age", ">", "true"), ArrayEvalFilter.createConditionStatement("@.['name'].age > true"));
}

Loading…
Cancel
Save