Browse Source

Fixed JsonPath compliance issue.

see http://code.google.com/p/json-path/issues/detail?id=7
pull/6/head
Kalle Stenflo 13 years ago
parent
commit
c3d60b764d
  1. 11
      json-path/src/main/java/com/jayway/jsonpath/JsonPath.java
  2. 5
      json-path/src/main/java/com/jayway/jsonpath/reader/PathToken.java
  3. 5
      json-path/src/main/java/com/jayway/jsonpath/reader/filter/ArrayEvalFilter.java
  4. 5
      json-path/src/main/java/com/jayway/jsonpath/reader/filter/ArrayIndexFilter.java
  5. 38
      json-path/src/main/java/com/jayway/jsonpath/reader/filter/FieldFilter.java
  6. 8
      json-path/src/main/java/com/jayway/jsonpath/reader/filter/Filter.java
  7. 4
      json-path/src/main/java/com/jayway/jsonpath/reader/filter/FilterFactory.java
  8. 5
      json-path/src/main/java/com/jayway/jsonpath/reader/filter/HasFieldFilter.java
  9. 10
      json-path/src/main/java/com/jayway/jsonpath/reader/filter/PassThrewFilter.java
  10. 5
      json-path/src/main/java/com/jayway/jsonpath/reader/filter/ScanFilter.java
  11. 5
      json-path/src/main/java/com/jayway/jsonpath/reader/filter/WildcardFilter.java
  12. 27
      json-path/src/test/java/com/jayway/jsonpath/Issues.java
  13. 3
      json-path/src/test/java/com/jayway/jsonpath/JsonPathTest.java
  14. 170
      json-path/src/test/java/com/jayway/jsonpath/PathTokenizerTest.java

11
json-path/src/main/java/com/jayway/jsonpath/JsonPath.java

@ -3,6 +3,7 @@ package com.jayway.jsonpath;
import com.jayway.jsonpath.reader.PathToken;
import com.jayway.jsonpath.reader.PathTokenizer;
import com.jayway.jsonpath.reader.filter.Filter;
import com.jayway.jsonpath.spi.JsonProvider;
import java.util.List;
@ -149,8 +150,16 @@ public class JsonPath {
Object result = container;
boolean inArrayContext = false;
for (PathToken pathToken : tokenizer) {
result = pathToken.filter(result, jsonProvider);
Filter filter = pathToken.getFilter();
result = filter.filter(result, jsonProvider, inArrayContext);
if (!inArrayContext) {
inArrayContext = filter.isArrayFilter();
}
//result = pathToken.filter(result, jsonProvider);
}
return (T) result;
}

5
json-path/src/main/java/com/jayway/jsonpath/reader/PathToken.java

@ -1,5 +1,6 @@
package com.jayway.jsonpath.reader;
import com.jayway.jsonpath.reader.filter.Filter;
import com.jayway.jsonpath.reader.filter.FilterFactory;
import com.jayway.jsonpath.spi.JsonProvider;
@ -17,6 +18,10 @@ public class PathToken {
this.fragment = fragment;
}
public Filter getFilter(){
return FilterFactory.createFilter(fragment);
}
public Object filter(Object model, JsonProvider jsonProvider){
return FilterFactory.createFilter(fragment).filter(model, jsonProvider);
}

5
json-path/src/main/java/com/jayway/jsonpath/reader/filter/ArrayEvalFilter.java

@ -48,6 +48,11 @@ public class ArrayEvalFilter extends Filter {
return result;
}
@Override
public boolean isArrayFilter() {
return true;
}
private boolean isMatch(Object check, ConditionStatement conditionStatement, JsonProvider jsonProvider) {
if (!jsonProvider.isMap(check)) {
return false;

5
json-path/src/main/java/com/jayway/jsonpath/reader/filter/ArrayIndexFilter.java

@ -58,4 +58,9 @@ public class ArrayIndexFilter extends Filter {
}
}
}
@Override
public boolean isArrayFilter() {
return true;
}
}

38
json-path/src/main/java/com/jayway/jsonpath/reader/filter/FieldFilter.java

@ -17,8 +17,38 @@ public class FieldFilter extends Filter {
super(condition);
}
@Override
public Object filter(Object obj, JsonProvider jsonProvider, boolean inArrayContext) {
if (jsonProvider.isList(obj)) {
if (!inArrayContext) {
return null;
} else {
List<Object> result = jsonProvider.createList();
for (Object current : jsonProvider.toList(obj)) {
if (jsonProvider.isMap(current)) {
Map<String, Object> map = jsonProvider.toMap(current);
if (map.containsKey(condition)) {
Object o = map.get(condition);
if (jsonProvider.isList(o)) {
result.addAll(jsonProvider.toList(o));
} else {
result.add(map.get(condition));
}
}
}
}
return result;
}
} else {
return jsonProvider.getMapValue(obj, condition);
}
}
public Object filter(Object obj, JsonProvider jsonProvider) {
if (jsonProvider.isList(obj)) {
return obj;
/*
List<Object> result = jsonProvider.createList();
for (Object current : jsonProvider.toList(obj)) {
if (jsonProvider.isMap(current)) {
@ -34,8 +64,16 @@ public class FieldFilter extends Filter {
}
}
return result;
*/
} else {
return jsonProvider.getMapValue(obj, condition);
}
}
@Override
public boolean isArrayFilter() {
return false;
}
}

8
json-path/src/main/java/com/jayway/jsonpath/reader/filter/Filter.java

@ -29,6 +29,14 @@ public abstract class Filter {
return res;
}
public Object filter(Object obj, JsonProvider jsonProvider, boolean inArrayContext){
return filter(obj, jsonProvider);
}
public abstract Object filter(Object obj, JsonProvider jsonProvider);
public abstract boolean isArrayFilter();
}

4
json-path/src/main/java/com/jayway/jsonpath/reader/filter/FilterFactory.java

@ -8,8 +8,8 @@ package com.jayway.jsonpath.reader.filter;
*/
public class FilterFactory {
private final static Filter DOCUMENT_FILTER = new PassThrewFilter("$");
private final static Filter ALL_ARRAY_ITEMS_FILTER = new PassThrewFilter("[*]");
private final static Filter DOCUMENT_FILTER = new PassThrewFilter("$", false);
private final static Filter ALL_ARRAY_ITEMS_FILTER = new PassThrewFilter("[*]", true);
private final static Filter WILDCARD_FILTER = new WildcardFilter("*");
private final static Filter SCAN_FILTER = new ScanFilter("..");

5
json-path/src/main/java/com/jayway/jsonpath/reader/filter/HasFieldFilter.java

@ -43,4 +43,9 @@ public class HasFieldFilter extends Filter {
}
return result;
}
@Override
public boolean isArrayFilter() {
return true;
}
}

10
json-path/src/main/java/com/jayway/jsonpath/reader/filter/PassThrewFilter.java

@ -10,11 +10,19 @@ import com.jayway.jsonpath.spi.JsonProvider;
*/
public class PassThrewFilter extends Filter {
public PassThrewFilter(String condition) {
private boolean isArrayFilter;
public PassThrewFilter(String condition, boolean isArrayFilter) {
super(condition);
this.isArrayFilter = isArrayFilter;
}
public Object filter(Object obj, JsonProvider jsonProvider) {
return obj;
}
@Override
public boolean isArrayFilter() {
return isArrayFilter;
}
}

5
json-path/src/main/java/com/jayway/jsonpath/reader/filter/ScanFilter.java

@ -25,6 +25,11 @@ public class ScanFilter extends Filter {
return result;
}
@Override
public boolean isArrayFilter() {
return true;
}
private void scan(Object container, List<Object> result, JsonProvider jsonProvider) {

5
json-path/src/main/java/com/jayway/jsonpath/reader/filter/WildcardFilter.java

@ -33,4 +33,9 @@ public class WildcardFilter extends Filter {
}
return result;
}
@Override
public boolean isArrayFilter() {
return true;
}
}

27
json-path/src/test/java/com/jayway/jsonpath/Issues.java

@ -0,0 +1,27 @@
package com.jayway.jsonpath;
import org.junit.Test;
import static junit.framework.Assert.assertNull;
/**
* Created by IntelliJ IDEA.
* User: kallestenflo
* Date: 2/29/12
* Time: 8:42 AM
*/
public class Issues {
@Test
public void issue_7() throws Exception {
String json = "{ \"foo\" : [\n" +
" { \"id\": 1 }, \n" +
" { \"id\": 2 }, \n" +
" { \"id\": 3 }\n" +
" ] }";
assertNull(JsonPath.read(json, "$.foo.id"));
}
}

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

@ -77,7 +77,8 @@ public class JsonPathTest {
@Test
public void array_start_expands() throws Exception {
assertThat(JsonPath.<List<String>>read(ARRAY_EXPAND, "$[?(@.parent = 'ONE')].child.name"), hasItems("NAME_ONE"));
//assertThat(JsonPath.<List<String>>read(ARRAY_EXPAND, "$[?(@.parent = 'ONE')].child.name"), hasItems("NAME_ONE"));
assertThat(JsonPath.<List<String>>read(ARRAY_EXPAND, "$[?(@['parent'] = 'ONE')].child.name"), hasItems("NAME_ONE"));
}
@Test

170
json-path/src/test/java/com/jayway/jsonpath/PathTokenizerTest.java

@ -1,170 +0,0 @@
package com.jayway.jsonpath;
import com.jayway.jsonpath.reader.PathToken;
import com.jayway.jsonpath.reader.PathTokenizer;
import com.jayway.jsonpath.spi.JsonProvider;
import org.junit.Test;
import java.util.List;
import static junit.framework.Assert.assertEquals;
import static org.hamcrest.Matchers.hasItems;
import static org.junit.Assert.assertThat;
/**
* Created by IntelliJ IDEA.
* User: kallestenflo
* Date: 11/4/11
* Time: 10:44 PM
*/
public class PathTokenizerTest {
private JsonProvider jsonProvider = JsonProvider.getInstance();
public final static String DOCUMENT =
"{ \"store\": {\n" +
" \"book\": [ \n" +
" { \"category\": \"reference\",\n" +
" \"author\": \"Nigel Rees\",\n" +
" \"title\": \"Sayings of the Century\",\n" +
" \"price\": 8.95\n" +
" },\n" +
" { \"category\": \"fiction\",\n" +
" \"author\": \"Evelyn Waugh\",\n" +
" \"title\": \"Sword of Honour\",\n" +
" \"price\": 12.99\n" +
" },\n" +
" { \"category\": \"fiction\",\n" +
" \"author\": \"Herman Melville\",\n" +
" \"title\": \"Moby Dick\",\n" +
" \"isbn\": \"0-553-21311-3\",\n" +
" \"price\": 8.99\n" +
" },\n" +
" { \"category\": \"fiction\",\n" +
" \"author\": \"J. R. R. Tolkien\",\n" +
" \"title\": \"The Lord of the Rings\",\n" +
" \"custom\": \"onely this\",\n" +
" \"isbn\": \"0-395-19395-8\",\n" +
" \"price\": 22.99\n" +
" }\n" +
" ],\n" +
" \"bicycle\": {\n" +
" \"color\": \"red\",\n" +
" \"price\": 19.95,\n" +
" \"foo:bar\": \"fooBar\",\n" +
" \"dot.notation\": \"new\"\n" +
" }\n" +
" }\n" +
"}";
@Test
public void path_tokens_can_be_read() throws Exception {
Object result = jsonProvider.parse(DOCUMENT);
for (PathToken pathToken : new PathTokenizer("$.store.bicycle.color", jsonProvider)) {
result = pathToken.filter(result, jsonProvider);
}
assertEquals("red", result);
}
@Test
public void read_an_array_without_filters() throws Exception {
Object result = jsonProvider.parse(DOCUMENT);
for (PathToken pathToken : new PathTokenizer("$.store.book", jsonProvider)) {
result = pathToken.filter(result, jsonProvider);
}
assertEquals(4, toList(result).size());
}
@Test
public void read_a_literal_property_from_object_in_array() throws Exception {
Object result = jsonProvider.parse(DOCUMENT);
for (PathToken pathToken : new PathTokenizer("$.store.book[*].title", jsonProvider)) {
result = pathToken.filter(result, jsonProvider);
}
assertEquals(4, toList(result).size());
}
@Test
public void read_a_literal_property_from_position_in_array() throws Exception {
Object result = jsonProvider.parse(DOCUMENT);
for (PathToken pathToken : new PathTokenizer("$.store.book[0].title", jsonProvider)) {
result = pathToken.filter(result, jsonProvider);
}
assertEquals("Sayings of the Century", result);
}
@Test
public void read_a_literal_property_from_two_positions_in_array() throws Exception {
Object result = jsonProvider.parse(DOCUMENT);
for (PathToken pathToken : new PathTokenizer("$.store.book[0, 1].author", jsonProvider)) {
result = pathToken.filter(result, jsonProvider);
}
assertThat(this.<String>toList(result), hasItems("Nigel Rees", "Evelyn Waugh"));
}
@Test
public void read_a_literal_property_from_head_in_array() throws Exception {
Object result = jsonProvider.parse(DOCUMENT);
for (PathToken pathToken : new PathTokenizer("$.store.book[:2].author", jsonProvider)) {
result = pathToken.filter(result, jsonProvider);
}
assertThat(this.<String>toList(result), hasItems("Nigel Rees", "Evelyn Waugh"));
}
@Test
public void read_a_literal_property_from_tail_in_array() throws Exception {
Object result = jsonProvider.parse(DOCUMENT);
for (PathToken pathToken : new PathTokenizer("$.store.book[-1:].author", jsonProvider)) {
result = pathToken.filter(result, jsonProvider);
}
assertEquals("J. R. R. Tolkien", result);
}
@Test
public void field_defined_in_array_object() throws Exception {
Object result = jsonProvider.parse(DOCUMENT);
for (PathToken pathToken : new PathTokenizer("$.store.book[?(@.custom)].author", jsonProvider)) {
result = pathToken.filter(result, jsonProvider);
}
assertThat(this.<String>toList(result), hasItems("J. R. R. Tolkien"));
}
@Test
public void property_value_in_array_object() throws Exception {
Object result = jsonProvider.parse(DOCUMENT);
for (PathToken pathToken : new PathTokenizer("$.store.book[?(@.custom = 'onely this')].author", jsonProvider)) {
result = pathToken.filter(result, jsonProvider);
}
assertThat(this.<String>toList(result), hasItems("J. R. R. Tolkien"));
}
@Test
public void deep_scan() throws Exception {
Object result = jsonProvider.parse(DOCUMENT);
for (PathToken pathToken : new PathTokenizer("$..author", jsonProvider)) {
result = pathToken.filter(result, jsonProvider);
}
assertThat(this.<String>toList(result), hasItems("Nigel Rees","Evelyn Waugh", "J. R. R. Tolkien"));
}
private <T> List<T> toList(Object obj) {
return (List<T>) obj;
}
}
Loading…
Cancel
Save