Browse Source

Added JsonOrgJsonProvider.

pull/183/merge
Kalle Stenflo 9 years ago
parent
commit
cb2795b38c
  1. 1
      build.gradle
  2. 1
      json-path-web-test/build.gradle
  3. 1
      json-path/build.gradle
  4. 220
      json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonOrgJsonProvider.java
  5. 56
      json-path/src/main/java/com/jayway/jsonpath/spi/mapper/JsonOrgMappingProvider.java
  6. 8
      json-path/src/test/java/com/jayway/jsonpath/BaseTest.java
  7. 9
      json-path/src/test/java/com/jayway/jsonpath/Configurations.java
  8. 71
      json-path/src/test/java/com/jayway/jsonpath/InlineFilterTest.java
  9. 43
      json-path/src/test/java/com/jayway/jsonpath/JsonOrgJsonProviderTest.java
  10. 16
      json-path/src/test/java/com/jayway/jsonpath/TestUtils.java

1
build.gradle

@ -15,6 +15,7 @@ ext {
jsonSmart: 'net.minidev:json-smart:2.2',
jacksonDatabind: 'com.fasterxml.jackson.core:jackson-databind:2.6.3',
gson: 'com.google.code.gson:gson:2.3.1',
jsonOrg: 'org.json:json:20150729',
hamcrestCore: 'org.hamcrest:hamcrest-core:1.3',
hamcrestLibrary: 'org.hamcrest:hamcrest-library:1.3',

1
json-path-web-test/build.gradle

@ -30,6 +30,7 @@ dependencies {
compile project(':json-path')
compile 'commons-io:commons-io:2.4'
compile libs.jacksonDatabind
compile libs.jsonSmart
compile 'io.fastjson:boon:0.33'
compile 'com.nebhale.jsonpath:jsonpath:1.2'
compile 'io.gatling:jsonpath_2.10:0.6.4'

1
json-path/build.gradle

@ -18,6 +18,7 @@ dependencies {
compile libs.slf4jApi
compile libs.jacksonDatabind, optional
compile libs.gson, optional
compile libs.jsonOrg, optional
testCompile libs.test
}

220
json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonOrgJsonProvider.java

@ -0,0 +1,220 @@
package com.jayway.jsonpath.spi.json;
import com.google.gson.JsonObject;
import com.jayway.jsonpath.InvalidJsonException;
import com.jayway.jsonpath.JsonPathException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class JsonOrgJsonProvider extends AbstractJsonProvider {
private static final Logger logger = LoggerFactory.getLogger(GsonJsonProvider.class);
@Override
public Object parse(String json) throws InvalidJsonException {
try {
return new JSONTokener(json).nextValue();
} catch (JSONException e) {
throw new InvalidJsonException(e);
}
}
@Override
public Object parse(InputStream jsonStream, String charset) throws InvalidJsonException {
try {
return new JSONTokener(new InputStreamReader(jsonStream, charset)).nextValue();
} catch (UnsupportedEncodingException e) {
throw new JsonPathException(e);
} catch (JSONException e) {
throw new InvalidJsonException(e);
}
}
@Override
public Object unwrap(Object obj) {
if(obj == JSONObject.NULL){
return null;
}
return obj;
}
@Override
public String toJson(Object obj) {
return obj.toString();
}
@Override
public Object createArray() {
return new JSONArray();
}
@Override
public Object createMap() {
return new JsonObject();
}
@Override
public boolean isArray(Object obj) {
return (obj instanceof JSONArray || obj instanceof List);
}
@Override
public Object getArrayIndex(Object obj, int idx) {
try {
return toJsonArray(obj).get(idx);
} catch (JSONException e) {
throw new JsonPathException(e);
}
}
@Override
public void setArrayIndex(Object array, int index, Object newValue) {
try {
if (!isArray(array)) {
throw new UnsupportedOperationException();
} else {
toJsonArray(array).put(index, createJsonElement(newValue));
}
} catch (JSONException e) {
throw new JsonPathException(e);
}
}
@Override
public Object getMapValue(Object obj, String key) {
try {
JSONObject jsonObject = toJsonObject(obj);
Object o = jsonObject.get(key);
if (!jsonObject.has(key)) {
return UNDEFINED;
} else {
return unwrap(o);
}
} catch (JSONException e) {
throw new JsonPathException(e);
}
}
@Override
public void setProperty(Object obj, Object key, Object value) {
try {
if (isMap(obj))
toJsonObject(obj).put(key.toString(), createJsonElement(value));
else {
JSONArray array = toJsonArray(obj);
int index;
if (key != null) {
index = key instanceof Integer ? (Integer) key : Integer.parseInt(key.toString());
} else {
index = array.length();
}
if (index == array.length()) {
array.put(createJsonElement(value));
} else {
array.put(index, createJsonElement(value));
}
}
} catch (JSONException e) {
throw new JsonPathException(e);
}
}
@SuppressWarnings("unchecked")
public void removeProperty(Object obj, Object key) {
if (isMap(obj))
toJsonObject(obj).remove(key.toString());
else {
JSONArray array = toJsonArray(obj);
int index = key instanceof Integer ? (Integer) key : Integer.parseInt(key.toString());
array.remove(index);
}
}
@Override
public boolean isMap(Object obj) {
return (obj instanceof JSONObject);
}
@Override
public Collection<String> getPropertyKeys(Object obj) {
JSONObject jsonObject = toJsonObject(obj);
List<String> keys = new ArrayList<String>();
try {
for (int i = 0; i < jsonObject.names().length(); i++) {
String key = (String) jsonObject.names().get(i);
keys.add(key);
}
return keys;
} catch (JSONException e) {
throw new JsonPathException(e);
}
}
@Override
public int length(Object obj) {
if (isArray(obj)) {
return toJsonArray(obj).length();
} else if (isMap(obj)) {
return toJsonObject(obj).length();
} else {
if (obj instanceof String) {
return ((String) obj).length();
}
}
throw new JsonPathException("length operation can not applied to " + obj != null ? obj.getClass().getName() : "null");
}
@Override
public Iterable<?> toIterable(Object obj) {
try {
if (isArray(obj)) {
JSONArray arr = toJsonArray(obj);
List<Object> values = new ArrayList<Object>(arr.length());
for (int i = 0; i < arr.length(); i++) {
values.add(unwrap(arr.get(i)));
}
return values;
} else {
JSONObject jsonObject = toJsonObject(obj);
List<Object> values = new ArrayList<Object>();
for (int i = 0; i < jsonObject.names().length(); i++) {
String key = (String) jsonObject.names().get(i);
Object val = jsonObject.get(key);
values.add(unwrap(val));
}
return values;
}
} catch (JSONException e) {
throw new JsonPathException(e);
}
}
private Object createJsonElement(Object o) {
return o;
}
private JSONArray toJsonArray(Object o) {
return (JSONArray) o;
}
private JSONObject toJsonObject(Object o) {
return (JSONObject) o;
}
}

56
json-path/src/main/java/com/jayway/jsonpath/spi/mapper/JsonOrgMappingProvider.java

@ -0,0 +1,56 @@
package com.jayway.jsonpath.spi.mapper;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.TypeRef;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JsonOrgMappingProvider implements MappingProvider {
@Override
public <T> T map(Object source, Class<T> targetType, Configuration configuration) {
if(source == null){
return null;
}
if(targetType.equals(Object.class) || targetType.equals(List.class) || targetType.equals(Map.class)){
return (T) mapToObject(source);
}
return (T)source;
}
@Override
public <T> T map(Object source, TypeRef<T> targetType, Configuration configuration) {
throw new UnsupportedOperationException("JsonOrg provider does not support TypeRef! Use a Jackson or Gson based provider");
}
private Object mapToObject(Object source){
if(source instanceof JSONArray){
List<Object> mapped = new ArrayList<Object>();
JSONArray array = (JSONArray) source;
for (Object o : array) {
mapped.add(mapToObject(o));
}
return mapped;
}
else if (source instanceof JSONObject){
Map<String, Object> mapped = new HashMap<String, Object>();
JSONObject obj = (JSONObject) source;
for (String key : obj.keySet()) {
mapped.put(key, mapToObject(obj.get(key)));
}
return mapped;
}
else if (source == JSONObject.NULL){
return null;
} else {
return source;
}
}
}

8
json-path/src/test/java/com/jayway/jsonpath/BaseTest.java

@ -5,15 +5,23 @@ import com.jayway.jsonpath.internal.token.PredicateContextImpl;
import com.jayway.jsonpath.spi.json.GsonJsonProvider;
import com.jayway.jsonpath.spi.json.JacksonJsonNodeJsonProvider;
import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
import com.jayway.jsonpath.spi.json.JsonOrgJsonProvider;
import com.jayway.jsonpath.spi.json.JsonSmartJsonProvider;
import com.jayway.jsonpath.spi.mapper.GsonMappingProvider;
import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
import com.jayway.jsonpath.spi.mapper.JsonOrgMappingProvider;
import com.jayway.jsonpath.spi.mapper.JsonSmartMappingProvider;
import java.util.HashMap;
public class BaseTest {
public static final Configuration JSON_ORG_CONFIGURATION = Configuration
.builder()
.mappingProvider(new JsonOrgMappingProvider())
.jsonProvider(new JsonOrgJsonProvider())
.build();
public static final Configuration GSON_CONFIGURATION = Configuration
.builder()
.mappingProvider(new GsonMappingProvider())

9
json-path/src/test/java/com/jayway/jsonpath/Configurations.java

@ -3,15 +3,23 @@ package com.jayway.jsonpath;
import com.jayway.jsonpath.spi.json.GsonJsonProvider;
import com.jayway.jsonpath.spi.json.JacksonJsonNodeJsonProvider;
import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
import com.jayway.jsonpath.spi.json.JsonOrgJsonProvider;
import com.jayway.jsonpath.spi.json.JsonSmartJsonProvider;
import com.jayway.jsonpath.spi.mapper.GsonMappingProvider;
import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
import com.jayway.jsonpath.spi.mapper.JsonOrgMappingProvider;
import com.jayway.jsonpath.spi.mapper.JsonSmartMappingProvider;
import java.util.Arrays;
public class Configurations {
public static final Configuration JSON_ORG_CONFIGURATION = Configuration
.builder()
.mappingProvider(new JsonOrgMappingProvider())
.jsonProvider(new JsonOrgJsonProvider())
.build();
public static final Configuration GSON_CONFIGURATION = Configuration
.builder()
.mappingProvider(new GsonMappingProvider())
@ -42,6 +50,7 @@ public class Configurations {
,GSON_CONFIGURATION
,JACKSON_CONFIGURATION
,JACKSON_JSON_NODE_CONFIGURATION
,JSON_ORG_CONFIGURATION
);
}

71
json-path/src/test/java/com/jayway/jsonpath/InlineFilterTest.java

@ -1,23 +1,38 @@
package com.jayway.jsonpath;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.ArrayList;
import java.util.List;
import static com.jayway.jsonpath.JsonPath.using;
import static com.jayway.jsonpath.TestUtils.assertHasNoResults;
import static com.jayway.jsonpath.TestUtils.assertHasOneResult;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(Parameterized.class)
public class InlineFilterTest extends BaseTest {
private static ReadContext reader = JsonPath.parse(JSON_DOCUMENT);
private static int bookCount = 4;
private Configuration conf = Configurations.GSON_CONFIGURATION;
public InlineFilterTest(Configuration conf) {
this.conf = conf;
}
@Parameterized.Parameters
public static Iterable<Configuration> configurations() {
return Configurations.configurations();
}
@Test
public void root_context_can_be_referred_in_predicate() {
List<Double> prices = reader.read("store.book[?(@.display-price <= $.max-price)].display-price", List.class);
List<Double> prices = using(conf).parse(JSON_DOCUMENT).read("store.book[?(@.display-price <= $.max-price)].display-price", List.class);
assertThat(prices).containsAll(asList(8.95D, 8.99D));
}
@ -25,19 +40,19 @@ public class InlineFilterTest extends BaseTest {
@Test
public void multiple_context_object_can_be_refered() {
List all = reader.read("store.book[ ?(@.category == @.category) ]", List.class);
List all = using(conf).parse(JSON_DOCUMENT).read("store.book[ ?(@.category == @.category) ]", List.class);
assertThat(all.size()).isEqualTo(bookCount);
List all2 = reader.read("store.book[ ?(@.category == @['category']) ]", List.class);
List all2 = using(conf).parse(JSON_DOCUMENT).read("store.book[ ?(@.category == @['category']) ]", List.class);
assertThat(all2.size()).isEqualTo(bookCount);
List all3 = reader.read("store.book[ ?(@ == @) ]", List.class);
List all3 = using(conf).parse(JSON_DOCUMENT).read("store.book[ ?(@ == @) ]", List.class);
assertThat(all3.size()).isEqualTo(bookCount);
List none = reader.read("store.book[ ?(@.category != @.category) ]", List.class);
List none = using(conf).parse(JSON_DOCUMENT).read("store.book[ ?(@.category != @.category) ]", List.class);
assertThat(none.size()).isEqualTo(0);
List none2 = reader.read("store.book[ ?(@.category != @) ]", List.class);
List none2 = using(conf).parse(JSON_DOCUMENT).read("store.book[ ?(@.category != @) ]", List.class);
assertThat(none2.size()).isEqualTo(4);
}
@ -45,16 +60,16 @@ public class InlineFilterTest extends BaseTest {
@Test
public void simple_inline_or_statement_evaluates() {
List a = reader.read("store.book[ ?(@.author == 'Nigel Rees' || @.author == 'Evelyn Waugh') ].author", List.class);
List a = using(conf).parse(JSON_DOCUMENT).read("store.book[ ?(@.author == 'Nigel Rees' || @.author == 'Evelyn Waugh') ].author", List.class);
assertThat(a).containsExactly("Nigel Rees", "Evelyn Waugh");
List b = reader.read("store.book[ ?((@.author == 'Nigel Rees' || @.author == 'Evelyn Waugh') && @.display-price < 15) ].author", List.class);
List b = using(conf).parse(JSON_DOCUMENT).read("store.book[ ?((@.author == 'Nigel Rees' || @.author == 'Evelyn Waugh') && @.display-price < 15) ].author", List.class);
assertThat(b).containsExactly("Nigel Rees", "Evelyn Waugh");
List c = reader.read("store.book[ ?((@.author == 'Nigel Rees' || @.author == 'Evelyn Waugh') && @.category == 'reference') ].author", List.class);
List c = using(conf).parse(JSON_DOCUMENT).read("store.book[ ?((@.author == 'Nigel Rees' || @.author == 'Evelyn Waugh') && @.category == 'reference') ].author", List.class);
assertThat(c).containsExactly("Nigel Rees");
List d = reader.read("store.book[ ?((@.author == 'Nigel Rees') || (@.author == 'Evelyn Waugh' && @.category != 'fiction')) ].author", List.class);
List d = using(conf).parse(JSON_DOCUMENT).read("store.book[ ?((@.author == 'Nigel Rees') || (@.author == 'Evelyn Waugh' && @.category != 'fiction')) ].author", List.class);
assertThat(d).containsExactly("Nigel Rees");
}
@ -143,34 +158,34 @@ public class InlineFilterTest extends BaseTest {
@Test
public void equality_check_does_not_break_evaluation() {
assertHasOneResult("[{\"value\":\"5\"}]", "$[?(@.value=='5')]");
assertHasOneResult("[{\"value\":5}]", "$[?(@.value==5)]");
assertHasOneResult("[{\"value\":\"5\"}]", "$[?(@.value=='5')]", conf);
assertHasOneResult("[{\"value\":5}]", "$[?(@.value==5)]", conf);
assertHasOneResult("[{\"value\":\"5.1.26\"}]", "$[?(@.value=='5.1.26')]");
assertHasOneResult("[{\"value\":\"5.1.26\"}]", "$[?(@.value=='5.1.26')]", conf);
assertHasNoResults("[{\"value\":\"5\"}]", "$[?(@.value=='5.1.26')]");
assertHasNoResults("[{\"value\":5}]", "$[?(@.value=='5.1.26')]");
assertHasNoResults("[{\"value\":5.1}]", "$[?(@.value=='5.1.26')]");
assertHasNoResults("[{\"value\":\"5\"}]", "$[?(@.value=='5.1.26')]", conf);
assertHasNoResults("[{\"value\":5}]", "$[?(@.value=='5.1.26')]", conf);
assertHasNoResults("[{\"value\":5.1}]", "$[?(@.value=='5.1.26')]", conf);
assertHasNoResults("[{\"value\":\"5.1.26\"}]", "$[?(@.value=='5')]");
assertHasNoResults("[{\"value\":\"5.1.26\"}]", "$[?(@.value==5)]");
assertHasNoResults("[{\"value\":\"5.1.26\"}]", "$[?(@.value==5.1)]");
assertHasNoResults("[{\"value\":\"5.1.26\"}]", "$[?(@.value=='5')]", conf);
assertHasNoResults("[{\"value\":\"5.1.26\"}]", "$[?(@.value==5)]", conf);
assertHasNoResults("[{\"value\":\"5.1.26\"}]", "$[?(@.value==5.1)]", conf);
}
@Test
public void lt_check_does_not_break_evaluation() {
assertHasOneResult("[{\"value\":\"5\"}]", "$[?(@.value<'7')]");
assertHasOneResult("[{\"value\":\"5\"}]", "$[?(@.value<'7')]", conf);
assertHasNoResults("[{\"value\":\"7\"}]", "$[?(@.value<'5')]");
assertHasNoResults("[{\"value\":\"7\"}]", "$[?(@.value<'5')]", conf);
assertHasOneResult("[{\"value\":5}]", "$[?(@.value<7)]");
assertHasNoResults("[{\"value\":7}]", "$[?(@.value<5)]");
assertHasOneResult("[{\"value\":5}]", "$[?(@.value<7)]", conf);
assertHasNoResults("[{\"value\":7}]", "$[?(@.value<5)]", conf);
assertHasOneResult("[{\"value\":5}]", "$[?(@.value<7.1)]");
assertHasNoResults("[{\"value\":7}]", "$[?(@.value<5.1)]");
assertHasOneResult("[{\"value\":5}]", "$[?(@.value<7.1)]", conf);
assertHasNoResults("[{\"value\":7}]", "$[?(@.value<5.1)]", conf);
assertHasOneResult("[{\"value\":5.1}]", "$[?(@.value<7)]");
assertHasNoResults("[{\"value\":7.1}]", "$[?(@.value<5)]");
assertHasOneResult("[{\"value\":5.1}]", "$[?(@.value<7)]", conf);
assertHasNoResults("[{\"value\":7.1}]", "$[?(@.value<5)]", conf);
}
}

43
json-path/src/test/java/com/jayway/jsonpath/JsonOrgJsonProviderTest.java

@ -0,0 +1,43 @@
package com.jayway.jsonpath;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.Test;
import static com.jayway.jsonpath.JsonPath.using;
public class JsonOrgJsonProviderTest extends BaseTest {
@Test
public void an_object_can_be_read() {
JSONObject book = using(JSON_ORG_CONFIGURATION).parse(JSON_DOCUMENT).read("$.store.book[0]");
System.out.println(book);
}
@Test
public void a_property_can_be_read() {
String category = using(JSON_ORG_CONFIGURATION).parse(JSON_DOCUMENT).read("$.store.book[0].category");
System.out.println(category);
}
@Test
public void a_filter_can_be_applied() {
JSONArray fictionBooks = using(JSON_ORG_CONFIGURATION).parse(JSON_DOCUMENT).read("$.store.book[?(@.category == 'fiction')]");
System.out.println(fictionBooks);
}
@Test
public void result_can_be_mapped_to_object() {
Object result = using(JSON_ORG_CONFIGURATION).parse(JSON_DOCUMENT).read("$.store.book", Object.class);
System.out.println(result);
}
}

16
json-path/src/test/java/com/jayway/jsonpath/TestUtils.java

@ -1,7 +1,5 @@
package com.jayway.jsonpath;
import java.util.List;
import static com.jayway.jsonpath.JsonPath.using;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
@ -38,8 +36,8 @@ public final class TestUtils {
* @param json json to be parsed
* @param path path to be evaluated
*/
public static void assertHasNoResults(final String json, final String path) {
assertHasResults(json, path, 0);
public static void assertHasNoResults(final String json, final String path, Configuration conf) {
assertHasResults(json, path, 0, conf);
}
/**
@ -47,8 +45,8 @@ public final class TestUtils {
* @param json json to be parsed
* @param path path to be evaluated
*/
public static void assertHasOneResult(final String json, final String path) {
assertHasResults(json, path, 1);
public static void assertHasOneResult(final String json, final String path, Configuration conf) {
assertHasResults(json, path, 1, conf);
}
/**
@ -57,8 +55,8 @@ public final class TestUtils {
* @param path path to be evaluated
* @param expectedResultCount expected number of nodes to be found
*/
public static void assertHasResults(final String json, final String path, final int expectedResultCount) {
final List<Object> result = JsonPath.parse(json).read(path);
assertThat(result).hasSize(expectedResultCount);
public static void assertHasResults(final String json, final String path, final int expectedResultCount, Configuration conf) {
Object result = JsonPath.using(conf).parse(json).read(path);
assertThat(conf.jsonProvider().length(result)).isEqualTo(expectedResultCount);
}
}

Loading…
Cancel
Save