Browse Source

'AND' (&&) support in ArrayEvalFilter.

pull/10/merge
Kalle Stenflo 11 years ago
parent
commit
a83f32caba
  1. 41
      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

41
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 { 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); private ConditionStatement[] conditionStatements;
this.conditionStatement = statement;
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(); Object result = jsonProvider.createArray();
for (Object item : src) { for (Object item : src) {
if (isMatch(item, conditionStatement, configuration)) { if (isMatch(item, configuration, conditionStatements)) {
jsonProvider.setProperty(result, jsonProvider.length(result), item); jsonProvider.setProperty(result, jsonProvider.length(result), item);
} }
} }
@ -68,10 +83,16 @@ public class ArrayEvalFilter extends PathTokenFilter {
return true; return true;
} }
private boolean isMatch(Object check, ConditionStatement conditionStatement, Configuration configuration) { private boolean isMatch(Object check, Configuration configuration, ConditionStatement... conditionStatements) {
try { try {
for (ConditionStatement conditionStatement : conditionStatements) {
Object value = conditionStatement.path.read(check, configuration.options(Option.THROW_ON_MISSING_PROPERTY)); Object value = conditionStatement.path.read(check, configuration.options(Option.THROW_ON_MISSING_PROPERTY));
return ExpressionEvaluator.eval(value, conditionStatement.getOperator(), conditionStatement.getExpected()); boolean match = ExpressionEvaluator.eval(value, conditionStatement.getOperator(), conditionStatement.getExpected());
if(!match){
return false;
}
}
return true;
} catch (PathNotFoundException e){ } catch (PathNotFoundException e){
return false; return false;
} catch (RuntimeException e){ } 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) { static ConditionStatement createConditionStatement(String condition) {
Matcher matcher = PATTERN.matcher(condition); Matcher matcher = PATTERN.matcher(condition);
if (matcher.matches()) { 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("[?")) { if (pathFragment.startsWith("[?")) {
ArrayEvalFilter.ConditionStatement conditionStatement = ArrayEvalFilter.createConditionStatement(pathFragment); if(ArrayEvalFilter.isConditionStatement(pathFragment)){
if(conditionStatement != null){ return new ArrayEvalFilter(pathFragment);
return new ArrayEvalFilter(conditionStatement);
} else if (!pathFragment.contains("=") && !pathFragment.contains("<") && !pathFragment.contains(">")) { } else if (!pathFragment.contains("=") && !pathFragment.contains("<") && !pathFragment.contains(">")) {
//[?(@.isbn)] //[?(@.isbn)]
return new HasFieldFilter(pathFragment); 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")); 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 @Test
public void nulls_filter() { 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 * Date: 3/10/12
* Time: 8:12 AM * Time: 8:12 AM
*/ */
@Ignore //@Ignore
public class HttpProviderTest { public class HttpProviderTest {
private static final String EXPECTED = "{\n" + private static final String EXPECTED = "{\n" +
" \"results\" : [],\n" + " \"results\" : [],\n" +
" \"status\" : \"REQUEST_DENIED\"\n" + " \"status\" : \"ZERO_RESULTS\"\n" +
"}"; "}";
@Test @Test
public void http_get() throws Exception { 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; InputStream inputStream = null;
try { try {

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

@ -28,7 +28,6 @@ public class IssuesTest {
@Test @Test
public void issue_36() { public void issue_36() {
String json = "{\n" + String json = "{\n" +
"\n" + "\n" +
" \"arrayOfObjectsAndArrays\" : [ { \"k\" : [\"json\"] }, { \"k\":[\"path\"] }, { \"k\" : [\"is\"] }, { \"k\" : [\"cool\"] } ],\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\"]]", o1.toString());
assertEquals("[\"json\",\"path\",\"is\",\"cool\"]", o2.toString()); assertEquals("[\"json\",\"path\",\"is\",\"cool\"]", o2.toString());
} }
@Test(expected = PathNotFoundException.class) @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 org.junit.Test;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/** /**
* User: kalle * User: kalle
@ -11,33 +13,44 @@ import static org.junit.Assert.assertEquals;
*/ */
public class ArrayEvalFilterTest { 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 @Test
public void condition_statements_can_be_parsed() { public void condition_statements_can_be_parsed() {
//assertEquals(new ArrayEvalFilter.ConditionStatement("@.length", ">", "0"), ArrayEvalFilter.createConditionStatement("[?(@.length>0)]")); //assertEquals(new ArrayEvalFilter.ConditionStatement("@.length", ">", "0"), ArrayEvalFilter.createConditionStatement("[?(@.length>0)]"));
//int array //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 //String array
assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "one"), ArrayEvalFilter.createConditionStatement("[?(@=='one')]")); assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "one"), ArrayEvalFilter.createConditionStatement("@=='one'"));
assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "one monkey"), ArrayEvalFilter.createConditionStatement("[?(@ == 'one monkey')]")); assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "one monkey"), ArrayEvalFilter.createConditionStatement("@ == 'one monkey' "));
assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "two"), ArrayEvalFilter.createConditionStatement("[?(@ == 'two')]")); assertEquals(new ArrayEvalFilter.ConditionStatement("@", "==", "two"), ArrayEvalFilter.createConditionStatement("@ == 'two'"));
//Sub item dot notation //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 //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 //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