Browse Source

HttpProvider SPI.

Removed commons-io dependency.
pull/8/merge
Kalle Stenflo 12 years ago
parent
commit
1216133e18
  1. 6
      json-path/pom.xml
  2. 3
      json-path/src/main/java/com/jayway/jsonpath/Filter.java
  3. 10
      json-path/src/main/java/com/jayway/jsonpath/InvalidModelException.java
  4. 111
      json-path/src/main/java/com/jayway/jsonpath/JsonModel.java
  5. 13
      json-path/src/main/java/com/jayway/jsonpath/JsonPath.java
  6. 13
      json-path/src/main/java/com/jayway/jsonpath/Transformer.java
  7. 10
      json-path/src/main/java/com/jayway/jsonpath/internal/Util.java
  8. 10
      json-path/src/main/java/com/jayway/jsonpath/spi/HttpProvider.java
  9. 10
      json-path/src/main/java/com/jayway/jsonpath/spi/HttpProviderFactory.java
  10. 10
      json-path/src/test/java/com/jayway/jsonpath/HttpProviderTest.java
  11. 34
      json-path/src/test/java/com/jayway/jsonpath/JsonModelMappingTest.java
  12. 71
      json-path/src/test/java/com/jayway/jsonpath/JsonModelOpsTest.java
  13. 10
      json-path/src/test/java/com/jayway/jsonpath/JsonModelTest.java
  14. 5
      pom.xml

6
json-path/pom.xml

@ -32,16 +32,12 @@
<groupId>net.minidev</groupId>
<artifactId>json-smart</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>

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

@ -120,8 +120,5 @@ public abstract class Filter<T> {
}
return true;
}
}
}

10
json-path/src/main/java/com/jayway/jsonpath/InvalidModelPathException.java → json-path/src/main/java/com/jayway/jsonpath/InvalidModelException.java

@ -18,21 +18,21 @@ package com.jayway.jsonpath;
* @author Kalle Stenflo
*/
@SuppressWarnings("serial")
public class InvalidModelPathException extends RuntimeException {
public class InvalidModelException extends RuntimeException {
public InvalidModelPathException() {
public InvalidModelException() {
super();
}
public InvalidModelPathException(String message) {
public InvalidModelException(String message) {
super(message);
}
public InvalidModelPathException(String message, Throwable cause) {
public InvalidModelException(String message, Throwable cause) {
super(message, cause);
}
public InvalidModelPathException(Throwable cause) {
public InvalidModelException(Throwable cause) {
super(cause);
}
}

111
json-path/src/main/java/com/jayway/jsonpath/JsonModel.java

@ -15,10 +15,10 @@
package com.jayway.jsonpath;
import com.jayway.jsonpath.internal.PathToken;
import com.jayway.jsonpath.internal.Util;
import com.jayway.jsonpath.spi.JsonProvider;
import com.jayway.jsonpath.spi.JsonProviderFactory;
import com.jayway.jsonpath.spi.MappingProviderFactory;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.io.InputStream;
@ -57,13 +57,13 @@ public class JsonModel {
* Creates a new JsonModel based on a json document.
* Note that the jsonObject must either a {@link List} or a {@link Map}
*
* @param jsonObject the json object
* @param jsonObject the json object
* @param jsonProvider
*/
private JsonModel(Object jsonObject, JsonProvider jsonProvider) {
notNull(jsonObject, "json can not be null");
if (!(jsonObject instanceof Map) && !(jsonObject instanceof List)) {
if (!jsonProvider.isContainer(jsonObject)) {
throw new IllegalArgumentException("Invalid container object");
}
this.jsonProvider = jsonProvider;
@ -85,7 +85,7 @@ public class JsonModel {
/**
* Creates a new JsonModel by fetching the content from the provided URL
*
* @param jsonURL the URL to read
* @param jsonURL the URL to read
* @param jsonProvider
* @throws IOException failed to load URL
*/
@ -98,10 +98,18 @@ public class JsonModel {
this.jsonObject = jsonProvider.parse(jsonInputStream);
this.jsonProvider = jsonProvider;
} finally {
IOUtils.closeQuietly(jsonInputStream);
Util.closeQuietly(jsonInputStream);
}
}
public boolean isList(){
return jsonProvider.isList(jsonObject);
}
public boolean isMap(){
return jsonProvider.isMap(jsonObject);
}
// --------------------------------------------------------
//
// Getters
@ -138,14 +146,22 @@ public class JsonModel {
return opsForArray(JsonPath.compile(jsonPath));
}
public ArrayOps opsForArray() {
return new DefaultArrayOps(this.jsonObject);
}
public ArrayOps opsForArray(JsonPath jsonPath) {
notNull(jsonPath, "jsonPath can not be null");
List<Object> opsTarget = getTargetObject(jsonPath, List.class);
Object opsTarget = getTargetObject(jsonPath, List.class);
return new DefaultArrayOps(opsTarget);
}
public ObjectOps opsForObject() {
return new DefaultObjectOps(this.jsonObject);
}
public ObjectOps opsForObject(String jsonPath) {
return opsForObject(JsonPath.compile(jsonPath));
}
@ -153,7 +169,7 @@ public class JsonModel {
public ObjectOps opsForObject(JsonPath jsonPath) {
notNull(jsonPath, "jsonPath can not be null");
Map<String, Object> opsTarget = getTargetObject(jsonPath, Map.class);
Object opsTarget = getTargetObject(jsonPath, Map.class);
return new DefaultObjectOps(opsTarget);
}
@ -192,8 +208,8 @@ public class JsonModel {
Object subModel = jsonPath.read(jsonObject);
if (!(subModel instanceof Map) && !(subModel instanceof List)) {
throw new InvalidModelPathException("The path " + jsonPath.getPath() + " returned an invalid model " + (subModel != null ? subModel.getClass() : "null"));
if(!jsonProvider.isContainer(subModel)){
throw new InvalidModelException("The path " + jsonPath.getPath() + " returned an invalid model " + (subModel != null ? subModel.getClass() : "null"));
}
return new JsonModel(subModel, this.jsonProvider);
@ -204,8 +220,12 @@ public class JsonModel {
// Mapping model readers
//
// --------------------------------------------------------
public MappingModelReader map(String jsonPath) {
return map(JsonPath.compile(jsonPath));
public MappingModelReader map() {
return new DefaultMappingModelReader(this.jsonObject);
}
public MappingModelReader map(String jsonPath, Filter... filters) {
return map(JsonPath.compile(jsonPath, filters));
}
public MappingModelReader map(JsonPath jsonPath) {
@ -219,25 +239,25 @@ public class JsonModel {
// Static factory methods
//
// --------------------------------------------------------
public static JsonModel create(String json) {
public static JsonModel model(String json) {
notEmpty(json, "json can not be null or empty");
return new JsonModel(json, JsonProviderFactory.createProvider());
}
public static JsonModel create(Object jsonObject) {
public static JsonModel model(Object jsonObject) {
notNull(jsonObject, "jsonObject can not be null");
return new JsonModel(jsonObject, JsonProviderFactory.createProvider());
}
public static JsonModel create(URL url) throws IOException {
public static JsonModel model(URL url) throws IOException {
notNull(url, "url can not be null");
return new JsonModel(url, JsonProviderFactory.createProvider());
}
public static JsonModel create(InputStream jsonInputStream) throws IOException {
public static JsonModel model(InputStream jsonInputStream) throws IOException {
notNull(jsonInputStream, "jsonInputStream can not be null");
return new JsonModel(jsonInputStream, JsonProviderFactory.createProvider());
@ -269,7 +289,7 @@ public class JsonModel {
} while (!tokens.isEmpty());
if (modelRef.getClass().isAssignableFrom(clazz)) {
throw new InvalidModelPathException(jsonPath + " does nor refer to a Map but " + currentToken.getClass().getName());
throw new InvalidModelException(jsonPath + " does nor refer to a Map but " + currentToken.getClass().getName());
}
return clazz.cast(modelRef);
}
@ -307,10 +327,16 @@ public class JsonModel {
ObjectOps put(String key, Object value);
ObjectOps putIfAbsent(String key, Object value);
Object get(String key);
ObjectOps putAll(Map<String, Object> map);
ObjectOps remove(String key);
ObjectOps transform(Transformer<JsonModel> transformer);
<T> T to(Class<T> targetClass);
}
@ -325,6 +351,8 @@ public class JsonModel {
ListMappingModelReader toList();
ArrayOps transform(Transformer<Object> transformer);
<T> List<T> toListOf(Class<T> targetClass);
<T> Set<T> toSetOf(Class<T> targetClass);
@ -334,9 +362,8 @@ public class JsonModel {
private Map<String, Object> opsTarget;
private DefaultObjectOps(Map<String, Object> opsTarget) {
this.opsTarget = opsTarget;
private DefaultObjectOps(Object opsTarget) {
this.opsTarget = (Map<String, Object>) opsTarget;
}
@Override
@ -355,6 +382,19 @@ public class JsonModel {
return this;
}
@Override
public ObjectOps putIfAbsent(String key, Object value) {
if (!opsTarget.containsKey(key)) {
opsTarget.put(key, value);
}
return this;
}
@Override
public Object get(String key) {
return opsTarget.get(key);
}
@Override
public ObjectOps putAll(Map<String, Object> map) {
opsTarget.putAll(map);
@ -367,6 +407,12 @@ public class JsonModel {
return this;
}
@Override
public ObjectOps transform(Transformer<JsonModel> transformer) {
transformer.transform(-1, JsonModel.model(opsTarget));
return this;
}
@Override
public <T> T to(Class<T> targetClass) {
return new DefaultMappingModelReader(opsTarget).to(targetClass);
@ -377,8 +423,8 @@ public class JsonModel {
private List<Object> opsTarget;
private DefaultArrayOps(List<Object> opsTarget) {
this.opsTarget = opsTarget;
private DefaultArrayOps(Object opsTarget) {
this.opsTarget = (List<Object>) opsTarget;
}
@Override
@ -409,6 +455,15 @@ public class JsonModel {
return new DefaultMappingModelReader(opsTarget);
}
@Override
public ArrayOps transform(Transformer<Object> transformer) {
for (int i = 0; i < opsTarget.size(); i++) {
Object current = opsTarget.get(i);
opsTarget.set(i, transformer.transform(i, current));
}
return this;
}
@Override
public <T> List<T> toListOf(Class<T> targetClass) {
return new DefaultMappingModelReader(opsTarget).toListOf(targetClass);
@ -439,20 +494,22 @@ public class JsonModel {
@Override
public <T> List<T> toListOf(Class<T> targetClass) {
if (!(model instanceof List)) {
model = asList(model);
Object modelRef = model;
if (!(modelRef instanceof List)) {
modelRef = asList(modelRef);
}
return MappingProviderFactory.createProvider().convertValue(model, List.class, targetClass);
return MappingProviderFactory.createProvider().convertValue(modelRef, List.class, targetClass);
}
@Override
public <T> Set<T> toSetOf(Class<T> targetClass) {
if (!(model instanceof List)) {
Object modelRef = model;
if (!(modelRef instanceof List)) {
Set setModel = new HashSet();
setModel.add(model);
model = setModel;
modelRef = setModel;
}
return MappingProviderFactory.createProvider().convertValue(model, Set.class, targetClass);
return MappingProviderFactory.createProvider().convertValue(modelRef, Set.class, targetClass);
}
@Override

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

@ -17,10 +17,11 @@ package com.jayway.jsonpath;
import com.jayway.jsonpath.internal.PathToken;
import com.jayway.jsonpath.internal.PathTokenizer;
import com.jayway.jsonpath.internal.Util;
import com.jayway.jsonpath.internal.filter.PathTokenFilter;
import com.jayway.jsonpath.spi.HttpProviderFactory;
import com.jayway.jsonpath.spi.JsonProvider;
import com.jayway.jsonpath.spi.JsonProviderFactory;
import org.apache.commons.io.IOUtils;
import java.io.*;
import java.net.URL;
@ -214,12 +215,12 @@ public class JsonPath {
public <T> T read(URL jsonURL) throws IOException {
notNull(jsonURL, "json URL can not be null");
BufferedReader in = null;
InputStream in = null;
try {
in = new BufferedReader(new InputStreamReader(jsonURL.openStream()));
in = HttpProviderFactory.getProvider().get(jsonURL);
return (T) read(JsonProviderFactory.createProvider().parse(in));
} finally {
IOUtils.closeQuietly(in);
Util.closeQuietly(in);
}
}
@ -241,7 +242,7 @@ public class JsonPath {
fis = new FileInputStream(jsonFile);
return (T) read(JsonProviderFactory.createProvider().parse(fis));
} finally {
IOUtils.closeQuietly(fis);
Util.closeQuietly(fis);
}
}
@ -260,7 +261,7 @@ public class JsonPath {
try {
return (T) read(JsonProviderFactory.createProvider().parse(jsonInputStream));
} finally {
IOUtils.closeQuietly(jsonInputStream);
Util.closeQuietly(jsonInputStream);
}
}

13
json-path/src/main/java/com/jayway/jsonpath/Transformer.java

@ -0,0 +1,13 @@
package com.jayway.jsonpath;
/**
* Created by IntelliJ IDEA.
* User: kallestenflo
* Date: 3/9/12
* Time: 3:20 PM
*/
public interface Transformer {
public JsonModel transform(JsonModel model);
}

10
json-path/src/main/java/com/jayway/jsonpath/internal/Util.java

@ -0,0 +1,10 @@
package com.jayway.jsonpath.internal;
/**
* Created by IntelliJ IDEA.
* User: kallestenflo
* Date: 3/10/12
* Time: 7:25 AM
*/
public class Util {
}

10
json-path/src/main/java/com/jayway/jsonpath/spi/HttpProvider.java

@ -0,0 +1,10 @@
package com.jayway.jsonpath.spi;
/**
* Created by IntelliJ IDEA.
* User: kallestenflo
* Date: 3/10/12
* Time: 7:38 AM
*/
public interface HttpProvider {
}

10
json-path/src/main/java/com/jayway/jsonpath/spi/HttpProviderFactory.java

@ -0,0 +1,10 @@
package com.jayway.jsonpath.spi;
/**
* Created by IntelliJ IDEA.
* User: kallestenflo
* Date: 3/10/12
* Time: 7:39 AM
*/
public class HttpProviderFactory {
}

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

@ -0,0 +1,10 @@
package com.jayway.jsonpath;
/**
* Created by IntelliJ IDEA.
* User: kallestenflo
* Date: 3/10/12
* Time: 8:12 AM
*/
public class HttpProviderTest {
}

34
json-path/src/test/java/com/jayway/jsonpath/JsonModelMappingTest.java

@ -5,6 +5,9 @@ import org.junit.Test;
import java.util.List;
import java.util.Set;
import static com.jayway.jsonpath.Criteria.where;
import static com.jayway.jsonpath.Filter.filter;
import static com.jayway.jsonpath.JsonModel.model;
import static junit.framework.Assert.assertEquals;
/**
@ -49,11 +52,36 @@ public class JsonModelMappingTest {
" }\n" +
" }\n" +
"}";
@Test
public void map_and_filter_can_be_combined() throws Exception {
JsonModel model = JsonModel.model(DOCUMENT);
Filter filter = Filter.filter(Criteria.where("category").is("fiction").and("price").gt(10D));
List<Book> books = model.map("$.store.book[?]", filter).toList().of(Book.class);
JsonPath jsonPath = JsonPath.compile("$.store.book[?]", filter(where("category").is("fiction").and("price").gt(10D)));
Object read = jsonPath.read(DOCUMENT);
List<Book> books1 = JsonModel.model(DOCUMENT).map("$.store.book[?]", filter).toListOf(Book.class);
model(DOCUMENT);
System.out.println("");
}
@Test
public void map_a_json_model_to_an_Class() throws Exception {
JsonModel model = JsonModel.create(DOCUMENT);
JsonModel model = JsonModel.model(DOCUMENT);
Book book = model.map("$.store.book[1]").to(Book.class);
@ -65,7 +93,7 @@ public class JsonModelMappingTest {
@Test
public void map_a_json_model_to_a_List() throws Exception {
JsonModel model = JsonModel.create(DOCUMENT);
JsonModel model = JsonModel.model(DOCUMENT);
List<Book> booksList = model.map("$.store.book[0,1]").toListOf(Book.class);
@ -92,7 +120,7 @@ public class JsonModelMappingTest {
@Test
public void map_a_json_model_to_a_Set() throws Exception {
JsonModel model = JsonModel.create(DOCUMENT);
JsonModel model = JsonModel.model(DOCUMENT);
Set<Book> bookSet = model.map("$.store.book[1]").toSetOf(Book.class);

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

@ -55,7 +55,7 @@ public class JsonModelOpsTest {
@Test
public void object_ops_can_update() throws Exception {
JsonModel model = JsonModel.create(DOCUMENT);
JsonModel model = JsonModel.model(DOCUMENT);
model.opsForObject("store.book[0]")
.put("author", "Kalle")
@ -68,7 +68,7 @@ public class JsonModelOpsTest {
@Test
public void array_ops_can_add_element() throws Exception {
JsonModel model = JsonModel.create(DOCUMENT);
JsonModel model = JsonModel.model(DOCUMENT);
Map<String, Object> newBook = new HashMap<String, Object>();
newBook.put("category", "reference");
@ -90,7 +90,7 @@ public class JsonModelOpsTest {
@Test
public void arrays_can_be_mapped() throws Exception {
JsonModel model = JsonModel.create(DOCUMENT);
JsonModel model = JsonModel.model(DOCUMENT);
List<Book> books1 = model.opsForArray("store.book").toList().of(Book.class);
List<Book> books2 = model.opsForArray("store.book").toListOf(Book.class);
@ -103,7 +103,7 @@ public class JsonModelOpsTest {
@Test
public void objects_can_be_mapped() throws Exception {
JsonModel model = JsonModel.create(DOCUMENT);
JsonModel model = JsonModel.model(DOCUMENT);
Book book = model.opsForObject("store.book[1]").to(Book.class);
@ -114,6 +114,69 @@ public class JsonModelOpsTest {
}
@Test
public void object_can_be_transformed() throws Exception {
Transformer transformer = new Transformer<JsonModel>() {
@Override
public JsonModel transform(int index, JsonModel model) {
model.opsForObject().put("newProp", "newProp");
return model;
}
};
JsonModel model = JsonModel.model(DOCUMENT);
model.opsForObject("store.book[1]").transform(transformer);
assertEquals("newProp", model.get("store.book[1].newProp"));
}
@Test
public void arrays_can_be_transformed() throws Exception {
Transformer transformer = new Transformer<Object>() {
@Override
public Object transform(int index, Object model) {
Map<String, Object> map = (Map<String, Object>) model;
map.put("newProp", "newProp");
return model;
}
};
JsonModel model = JsonModel.model(DOCUMENT);
model.opsForArray("store.book").transform(transformer);
assertEquals("newProp", model.get("store.book[1].newProp"));
}
@Test
public void array_can_be_transformed_to_primitives() throws Exception {
Transformer positionTransformer = new Transformer<Object>() {
private int i = 0;
@Override
public Object transform(int index, Object model) {
return i++;
}
};
Transformer multiplyingTransformer = new Transformer<Object>() {
@Override
public Object transform(int index, Object model) {
int in = (Integer)model;
return in * 2;
}
};
JsonModel model = JsonModel.model(DOCUMENT);
model.opsForArray("store.book").transform(positionTransformer).transform(multiplyingTransformer);
assertEquals(2, model.get("store.book[1]"));
}
public static class Book {
public String category;
public String author;

10
json-path/src/test/java/com/jayway/jsonpath/JsonModelTest.java

@ -57,18 +57,18 @@ public class JsonModelTest {
@Test
public void a_json_document_can_be_fetched_with_a_URL() throws Exception {
URL url = new URL("http://maps.googleapis.com/maps/api/geocode/json");
assertEquals("REQUEST_DENIED", JsonModel.create(url).get("status"));
assertEquals("REQUEST_DENIED", JsonModel.model(url).get("status"));
}
@Test
public void a_json_document_can_be_fetched_with_a_InputStream() throws Exception {
ByteArrayInputStream bis = new ByteArrayInputStream(DOCUMENT.getBytes());
assertEquals("Nigel Rees", JsonModel.create(bis).get("store.book[0].author"));
assertEquals("Nigel Rees", JsonModel.model(bis).get("store.book[0].author"));
}
@Test
public void test_a_sub_model_can_be_fetched_and_read() throws Exception {
JsonModel model = JsonModel.create(DOCUMENT);
JsonModel model = JsonModel.model(DOCUMENT);
assertEquals("Nigel Rees", model.getModel("$store.book[0]").get("author"));
assertEquals("Nigel Rees", model.getModel(JsonPath.compile("$store.book[0]")).get("author"));
}
@ -79,7 +79,7 @@ public class JsonModelTest {
doc.put("items", asList(0, 1, 2));
doc.put("child", Collections.singletonMap("key", "value"));
JsonModel model = JsonModel.create(doc);
JsonModel model = JsonModel.model(doc);
assertEquals("value", model.get("$child.key"));
assertEquals(1, model.get("$items[1]"));
@ -89,7 +89,7 @@ public class JsonModelTest {
@Test(expected = InvalidPathException.class)
public void invalid_path_throws() throws Exception {
JsonModel.create(DOCUMENT).get("store.invalid");
JsonModel.model(DOCUMENT).get("store.invalid");
}

5
pom.xml

@ -239,11 +239,6 @@
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>

Loading…
Cancel
Save