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