Browse Source

Improved support for Gson and Jackson Providers.

pull/60/head
Kalle Stenflo 10 years ago
parent
commit
c71e2c5e48
  1. 4
      json-path/src/main/java/com/jayway/jsonpath/Configuration.java
  2. 2
      json-path/src/main/java/com/jayway/jsonpath/JsonPath.java
  3. 14
      json-path/src/main/java/com/jayway/jsonpath/internal/EvaluationContext.java
  4. 4
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/json/AbstractJsonProvider.java
  5. 12
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/json/GsonJsonProvider.java
  6. 260
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/json/JacksonTreeJsonProvider.java
  7. 52
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/DateMapper.java
  8. 63
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/DefaultMappingProvider.java
  9. 6
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/Factory.java
  10. 138
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/GsonMapper.java
  11. 32
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/GsonMappingProvider.java
  12. 19
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/JacksonMappingProvider.java
  13. 210
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/JsonSmartMappingProvider.java
  14. 86
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/Mapper.java
  15. 53
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/MapperBase.java
  16. 144
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/NumberMapper.java
  17. 39
      json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/StringMapper.java
  18. 8
      json-path/src/main/java/com/jayway/jsonpath/internal/token/EvaluationContextImpl.java
  19. 12
      json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonProvider.java
  20. 8
      json-path/src/test/java/com/jayway/jsonpath/BaseTest.java
  21. 89
      json-path/src/test/java/com/jayway/jsonpath/GsonJsonProviderTest.java
  22. 56
      json-path/src/test/java/com/jayway/jsonpath/JacksonTreeJsonProviderTest.java
  23. 1
      json-path/src/test/java/com/jayway/jsonpath/MapperTest.java

4
json-path/src/main/java/com/jayway/jsonpath/Configuration.java

@ -15,7 +15,7 @@
package com.jayway.jsonpath; package com.jayway.jsonpath;
import com.jayway.jsonpath.internal.spi.json.JsonSmartJsonProvider; import com.jayway.jsonpath.internal.spi.json.JsonSmartJsonProvider;
import com.jayway.jsonpath.internal.spi.mapper.DefaultMappingProvider; import com.jayway.jsonpath.internal.spi.mapper.JsonSmartMappingProvider;
import com.jayway.jsonpath.spi.json.JsonProvider; import com.jayway.jsonpath.spi.json.JsonProvider;
import com.jayway.jsonpath.spi.mapper.MappingProvider; import com.jayway.jsonpath.spi.mapper.MappingProvider;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -40,7 +40,7 @@ public class Configuration {
private static Defaults DEFAULTS = new Defaults() { private static Defaults DEFAULTS = new Defaults() {
private final MappingProvider mappingProvider = new DefaultMappingProvider(); private final MappingProvider mappingProvider = new JsonSmartMappingProvider();
public JsonProvider jsonProvider() { public JsonProvider jsonProvider() {
return new JsonSmartJsonProvider(); return new JsonSmartJsonProvider();

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

@ -176,7 +176,7 @@ public class JsonPath {
if(optAsPathList){ if(optAsPathList){
return (T)path.evaluate(jsonObject, jsonObject, configuration).getPath(); return (T)path.evaluate(jsonObject, jsonObject, configuration).getPath();
} else { } else {
Object res = path.evaluate(jsonObject, jsonObject, configuration).getValue(); Object res = path.evaluate(jsonObject, jsonObject, configuration).getValue(false);
if(optAlwaysReturnList && path.isDefinite()){ if(optAlwaysReturnList && path.isDefinite()){
Object array = configuration.jsonProvider().createArray(); Object array = configuration.jsonProvider().createArray();
configuration.jsonProvider().setProperty(array, 0, res); configuration.jsonProvider().setProperty(array, 0, res);

14
json-path/src/main/java/com/jayway/jsonpath/internal/EvaluationContext.java

@ -43,7 +43,21 @@ public interface EvaluationContext {
*/ */
<T> T getValue(); <T> T getValue();
/**
* See {@link com.jayway.jsonpath.internal.EvaluationContext#getValue()}
*
* @param unwrap tells th underlying json provider if primitives should be unwrapped
* @param <T> expected return type
* @return evaluation result
*/
<T> T getValue(boolean unwrap);
/**
* Returns the list of formalized paths that represent the result of the evaluation
* @param <T>
* @return list of paths
*/
<T> T getPath(); <T> T getPath();

4
json-path/src/main/java/com/jayway/jsonpath/internal/spi/json/AbstractJsonProvider.java

@ -46,6 +46,10 @@ public abstract class AbstractJsonProvider implements JsonProvider {
* @return the entry at the given index * @return the entry at the given index
*/ */
public Object getArrayIndex(Object obj, int idx) { public Object getArrayIndex(Object obj, int idx) {
return getArrayIndex(obj, idx, true);
}
public Object getArrayIndex(Object obj, int idx, boolean unwrap){
return ((List) obj).get(idx); return ((List) obj).get(idx);
} }

12
json-path/src/main/java/com/jayway/jsonpath/internal/spi/json/GsonJsonProvider.java

@ -129,7 +129,17 @@ public class GsonJsonProvider extends AbstractJsonProvider {
@Override @Override
public Object getArrayIndex(Object obj, int idx) { public Object getArrayIndex(Object obj, int idx) {
return unwrap(toJsonArray(obj).get(idx)); return getArrayIndex(obj, idx, true);
}
@Override
public Object getArrayIndex(Object obj, int idx, boolean unwrap){
if(unwrap){
return unwrap(toJsonArray(obj).get(idx));
}
else {
return toJsonArray(obj).get(idx);
}
} }
@Override @Override

260
json-path/src/main/java/com/jayway/jsonpath/internal/spi/json/JacksonTreeJsonProvider.java

@ -0,0 +1,260 @@
package com.jayway.jsonpath.internal.spi.json;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
import com.jayway.jsonpath.InvalidJsonException;
import com.jayway.jsonpath.JsonPathException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
public class JacksonTreeJsonProvider extends AbstractJsonProvider {
private static final Logger logger = LoggerFactory.getLogger(JacksonJsonProvider.class);
private static final ObjectMapper defaultObjectMapper = new ObjectMapper();
protected ObjectMapper objectMapper;
public ObjectMapper getObjectMapper() {
return objectMapper;
}
/**
* Initialize the JacksonTreeJsonProvider with the default ObjectMapper and ObjectReader
*/
public JacksonTreeJsonProvider() {
this(defaultObjectMapper);
}
/**
* Initialize the JacksonTreeJsonProvider with a custom ObjectMapper and ObjectReader.
*
* @param objectMapper the ObjectMapper to use
*/
public JacksonTreeJsonProvider(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
@Override
public Object parse(String json) throws InvalidJsonException {
try {
return objectMapper.readTree(json);
} catch (IOException e) {
logger.debug("Invalid JSON: \n" + json);
throw new InvalidJsonException(e);
}
}
@Override
public Object parse(InputStream jsonStream, String charset) throws InvalidJsonException {
try {
return objectMapper.readTree(new InputStreamReader(jsonStream, charset));
} catch (IOException e) {
throw new InvalidJsonException(e);
}
}
@Override
public String toJson(Object obj) {
if (!(obj instanceof JsonNode)) {
throw new JsonPathException("Not a JSON Node");
}
return toString();
}
@Override
public Object createArray() {
return JsonNodeFactory.instance.arrayNode();
}
@Override
public Object createMap() {
return JsonNodeFactory.instance.objectNode();
}
public static Object unwrap(Object o) {
if (o == null) {
return null;
}
if (!(o instanceof JsonNode)) {
return o;
}
JsonNode e = (JsonNode) o;
if (e.isValueNode()) {
if (e.isTextual()) {
return e.asText();
} else if (e.isBoolean()) {
return e.asBoolean();
} else if (e.isInt()) {
return e.asInt();
} else if (e.isLong()) {
return e.asLong();
} else if (e.isBigDecimal()) {
return e.decimalValue();
} else if (e.isDouble()) {
return e.doubleValue();
} else if (e.isFloat()) {
return e.floatValue();
} else if (e.isBigDecimal()) {
return e.decimalValue();
} else if (e.isNull()) {
return null;
}
}
return o;
}
@Override
public boolean isArray(Object obj) {
return (obj instanceof ArrayNode || obj instanceof List);
}
@Override
public Object getArrayIndex(Object obj, int idx) {
return getArrayIndex(obj, idx, true);
}
@Override
public Object getArrayIndex(Object obj, int idx, boolean unwrap){
if(unwrap){
return unwrap(toJsonArray(obj).get(idx));
}
else {
return toJsonArray(obj).get(idx);
}
}
@Override
public void setArrayIndex(Object array, int index, Object newValue) {
if (!isArray(array)) {
throw new UnsupportedOperationException();
} else {
toJsonArray(array).insert( index, createJsonElement(newValue));
}
}
@Override
public Object getMapValue(Object obj, String key) {
ObjectNode jsonObject = toJsonObject(obj);
Object o = jsonObject.get(key);
if (!jsonObject.has(key)) {
return UNDEFINED;
} else {
return unwrap(o);
}
}
@Override
public void setProperty(Object obj, Object key, Object value) {
if (isMap(obj))
toJsonObject(obj).put(key.toString(), createJsonElement(value));
else {
ArrayNode array = toJsonArray(obj);
int index;
if (key != null) {
index = key instanceof Integer ? (Integer) key : Integer.parseInt(key.toString());
} else {
index = array.size();
}
if (index == array.size()) {
array.add(createJsonElement(value));
} else {
array.set(index, createJsonElement(value));
}
}
}
@SuppressWarnings("unchecked")
public void removeProperty(Object obj, Object key) {
if (isMap(obj))
toJsonObject(obj).remove(key.toString());
else {
ArrayNode 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 ObjectNode);
}
@Override
public Collection<String> getPropertyKeys(Object obj) {
List<String> keys = new ArrayList<String>();
Iterator<String> iter = toJsonObject(obj).fieldNames();
while (iter.hasNext()){
keys.add(iter.next());
}
return keys;
}
@Override
public int length(Object obj) {
if (isArray(obj)) {
return toJsonArray(obj).size();
} else if (isMap(obj)) {
return toJsonObject(obj).size();
} else {
if (obj instanceof TextNode) {
TextNode element = (TextNode) obj;
return element.size();
}
}
throw new JsonPathException("length operation can not applied to " + obj != null ? obj.getClass().getName() : "null");
}
@Override
public Iterable<?> toIterable(Object obj) {
if (isArray(obj)) {
ArrayNode arr = toJsonArray(obj);
List<Object> values = new ArrayList<Object>(arr.size());
for (Object o : arr) {
values.add(unwrap(o));
}
return values;
} else {
List<Object> values = new ArrayList<Object>();
Iterator<JsonNode> iter = toJsonObject(obj).elements();
while (iter.hasNext()){
values.add(unwrap(iter.next()));
}
return values;
}
}
private JsonNode createJsonElement(Object o) {
return objectMapper.valueToTree(o);
}
private ArrayNode toJsonArray(Object o) {
return (ArrayNode) o;
}
private ObjectNode toJsonObject(Object o) {
return (ObjectNode) o;
}
}

52
json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/DateMapper.java

@ -1,52 +0,0 @@
/*
* Copyright 2011 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jayway.jsonpath.internal.spi.mapper;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.spi.mapper.MappingException;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
public class DateMapper extends MapperBase {
public DateMapper() {
register(Long.class, Date.class);
register(String.class, Date.class);
}
@Override
public Object convert(Object src, Class<?> srcType, Class<?> targetType, Configuration conf) {
assertValidConversion(src, srcType, targetType);
if(src == null){
return null;
}
if(Long.class.isAssignableFrom(srcType)){
return new Date((Long) src);
}
else if(String.class.isAssignableFrom(srcType)){
try {
return DateFormat.getInstance().parse(src.toString());
} catch (ParseException e) {
throw new MappingException(e);
}
}
throw new MappingException("Can not map: " + srcType.getName() + " to: " + targetType.getName());
}
}

63
json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/DefaultMappingProvider.java

@ -1,63 +0,0 @@
/*
* Copyright 2011 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jayway.jsonpath.internal.spi.mapper;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.spi.mapper.MappingProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
public class DefaultMappingProvider implements MappingProvider {
private static final Logger logger = LoggerFactory.getLogger(DefaultMappingProvider.class);
private HashMap<Class<?>, HashMap<Class<?>, Mapper>> converters = new HashMap<Class<?>, HashMap<Class<?>, Mapper>>();
public DefaultMappingProvider(){
addMapper(new NumberMapper());
addMapper(new StringMapper());
addMapper(new DateMapper());
}
protected void addMapper(Mapper converter) {
for (Mapper.ConvertiblePair convertible : converter.getConvertibleTypes()) {
if(!converters.containsKey(convertible.getTargetType())){
converters.put(convertible.getTargetType(), new HashMap<Class<?>, Mapper>());
}
converters.get(convertible.getTargetType()).put(convertible.getSourceType(), converter);
}
}
@Override
public <T> T map(Object source, Class<T> targetType, Configuration configuration) {
if(source == null){
return null;
}
HashMap<Class<?>, Mapper> targetConverters = converters.get(targetType);
if(targetConverters != null){
Mapper mapper = targetConverters.get(source.getClass());
if(mapper != null){
return (T) mapper.convert(source, source.getClass(), targetType, configuration);
}
mapper = targetConverters.get(Object.class);
if(mapper != null){
return (T) mapper.convert(source, source.getClass(), targetType, configuration);
}
}
return (T)source;
}
}

6
json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/Factory.java

@ -0,0 +1,6 @@
package com.jayway.jsonpath.internal.spi.mapper;
public interface Factory<T> {
T createInstance();
}

138
json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/GsonMapper.java

@ -1,138 +0,0 @@
/*
* Copyright 2011 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jayway.jsonpath.internal.spi.mapper;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.internal.spi.json.GsonJsonProvider;
import com.jayway.jsonpath.spi.mapper.MappingException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class GsonMapper extends MapperBase {
public GsonMapper() {
register(JsonPrimitive.class, Integer.class);
register(JsonPrimitive.class, Long.class);
register(JsonPrimitive.class, Float.class);
register(JsonPrimitive.class, Double.class);
register(JsonPrimitive.class, BigDecimal.class);
register(JsonPrimitive.class, BigInteger.class);
register(JsonPrimitive.class, Date.class);
register(JsonPrimitive.class, String.class);
register(JsonPrimitive.class, Boolean.class);
register(JsonArray.class, List.class);
register(JsonObject.class, Map.class);
}
@Override
public Object convert(Object src, Class<?> srcType, Class<?> targetType, Configuration conf) {
assertValidConversion(src, srcType, targetType);
if (src == null || src.getClass().equals(JsonNull.class)) {
return null;
}
if (JsonPrimitive.class.isAssignableFrom(srcType)) {
JsonPrimitive primitive = (JsonPrimitive) src;
if (targetType.equals(Long.class)) {
return primitive.getAsLong();
} else if (targetType.equals(Integer.class)) {
return primitive.getAsInt();
} else if (targetType.equals(BigInteger.class)) {
return primitive.getAsBigInteger();
} else if (targetType.equals(Byte.class)) {
return primitive.getAsByte();
} else if (targetType.equals(BigDecimal.class)) {
return primitive.getAsBigDecimal();
} else if (targetType.equals(Double.class)) {
return primitive.getAsDouble();
} else if (targetType.equals(Float.class)) {
return primitive.getAsFloat();
} else if (targetType.equals(String.class)) {
return primitive.getAsString();
} else if (targetType.equals(Boolean.class)) {
return primitive.getAsBoolean();
} else if (targetType.equals(Date.class)) {
if(primitive.isNumber()){
return new Date(primitive.getAsLong());
} else if(primitive.isString()){
try {
return DateFormat.getInstance().parse(primitive.getAsString());
} catch (ParseException e) {
throw new MappingException(e);
}
}
}
} else if (JsonObject.class.isAssignableFrom(srcType)) {
JsonObject srcObject = (JsonObject) src;
if(targetType.equals(Map.class)){
Map<String, Object> targetMap = new LinkedHashMap<String, Object>();
for (Map.Entry<String,JsonElement> entry : srcObject.entrySet()) {
Object val = null;
JsonElement element = entry.getValue();
if(element.isJsonPrimitive()) {
val = GsonJsonProvider.unwrap(element);
} else if(element.isJsonArray()){
val = convert(element, element.getClass(), List.class, conf);
} else if(element.isJsonObject()){
val = convert(element, element.getClass(), Map.class, conf);
} else if(element.isJsonNull()){
val = null;
}
targetMap.put(entry.getKey(), val);
}
return targetMap;
}
} else if (JsonArray.class.isAssignableFrom(srcType)) {
JsonArray srcArray = (JsonArray) src;
if(targetType.equals(List.class)){
List<Object> targetList = new ArrayList<Object>();
for (JsonElement element : srcArray) {
if(element.isJsonPrimitive()) {
targetList.add(GsonJsonProvider.unwrap(element));
} else if(element.isJsonArray()){
targetList.add(convert(element, element.getClass(), List.class, conf));
} else if(element.isJsonObject()){
targetList.add(convert(element, element.getClass(), Map.class, conf));
} else if(element.isJsonNull()){
targetList.add(null);
}
}
return targetList;
}
}
throw new MappingException("Can not map: " + srcType.getName() + " to: " + targetType.getName());
}
}

32
json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/GsonMappingProvider.java

@ -14,23 +14,51 @@
*/ */
package com.jayway.jsonpath.internal.spi.mapper; package com.jayway.jsonpath.internal.spi.mapper;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPathException; import com.jayway.jsonpath.JsonPathException;
import com.jayway.jsonpath.spi.mapper.MappingProvider; import com.jayway.jsonpath.spi.mapper.MappingProvider;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class GsonMappingProvider extends DefaultMappingProvider implements MappingProvider { public class GsonMappingProvider implements MappingProvider {
private static final Logger logger = LoggerFactory.getLogger(GsonMappingProvider.class); private static final Logger logger = LoggerFactory.getLogger(GsonMappingProvider.class);
private final Factory<Gson> factory;
public GsonMappingProvider(final Gson gson) {
this(new Factory<Gson>() {
@Override
public Gson createInstance() {
return gson;
}
});
}
public GsonMappingProvider(Factory<Gson> factory) {
this.factory = factory;
}
public GsonMappingProvider() { public GsonMappingProvider() {
super(); super();
try { try {
Class.forName("com.google.gson.Gson"); Class.forName("com.google.gson.Gson");
addMapper(new GsonMapper()); this.factory = new Factory<Gson>() {
@Override
public Gson createInstance() {
return new Gson();
}
};
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
logger.error("Gson not found on class path. No converters configured."); logger.error("Gson not found on class path. No converters configured.");
throw new JsonPathException("Gson not found on path", e); throw new JsonPathException("Gson not found on path", e);
} }
} }
@Override
public <T> T map(Object source, Class<T> targetType, Configuration configuration) {
return factory.createInstance().getAdapter(targetType).fromJsonTree((JsonElement) source);
}
} }

19
json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/JacksonMappingProvider.java

@ -18,13 +18,10 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.jayway.jsonpath.Configuration; import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.spi.mapper.MappingProvider; import com.jayway.jsonpath.spi.mapper.MappingProvider;
import java.util.HashMap;
public class JacksonMappingProvider implements MappingProvider { public class JacksonMappingProvider implements MappingProvider {
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
private HashMap<Class<?>, HashMap<Class<?>, Mapper>> converters = new HashMap<Class<?>, HashMap<Class<?>, Mapper>>();
public JacksonMappingProvider() { public JacksonMappingProvider() {
this(new ObjectMapper()); this(new ObjectMapper());
@ -33,14 +30,7 @@ public class JacksonMappingProvider implements MappingProvider {
public JacksonMappingProvider(ObjectMapper objectMapper) { public JacksonMappingProvider(ObjectMapper objectMapper) {
this.objectMapper = objectMapper; this.objectMapper = objectMapper;
} }
public void addMapper(Mapper converter) {
for (Mapper.ConvertiblePair convertible : converter.getConvertibleTypes()) {
if(!converters.containsKey(convertible.getTargetType())){
converters.put(convertible.getTargetType(), new HashMap<Class<?>, Mapper>());
}
converters.get(convertible.getTargetType()).put(convertible.getSourceType(), converter);
}
}
@Override @Override
@ -48,13 +38,6 @@ public class JacksonMappingProvider implements MappingProvider {
if(source == null){ if(source == null){
return null; return null;
} }
HashMap<Class<?>, Mapper> targetConverters = converters.get(targetType);
if(targetConverters != null){
Mapper mapper = targetConverters.get(source.getClass());
if(mapper != null){
return (T) mapper.convert(source, source.getClass(), targetType, configuration);
}
}
return objectMapper.convertValue(source, targetType); return objectMapper.convertValue(source, targetType);
} }
} }

210
json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/JsonSmartMappingProvider.java

@ -0,0 +1,210 @@
/*
* Copyright 2011 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jayway.jsonpath.internal.spi.mapper;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.spi.mapper.MappingException;
import com.jayway.jsonpath.spi.mapper.MappingProvider;
import net.minidev.json.writer.JsonReader;
import net.minidev.json.writer.JsonReaderI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
public class JsonSmartMappingProvider implements MappingProvider {
private static final Logger logger = LoggerFactory.getLogger(JsonSmartMappingProvider.class);
private static JsonReader DEFAULT = new JsonReader();
static {
DEFAULT.registerReader(Long.class, new LongReader());
DEFAULT.registerReader(Integer.class, new IntegerReader());
DEFAULT.registerReader(Double.class, new DoubleReader());
DEFAULT.registerReader(Float.class, new FloatReader());
DEFAULT.registerReader(BigDecimal.class, new BigDecimalReader());
DEFAULT.registerReader(String.class, new StringReader());
DEFAULT.registerReader(Date.class, new DateReader());
}
private final Factory<JsonReader> factory;
public JsonSmartMappingProvider(final JsonReader jsonReader) {
this(new Factory<JsonReader>() {
@Override
public JsonReader createInstance() {
return jsonReader;
}
});
}
public JsonSmartMappingProvider(Factory<JsonReader> factory) {
this.factory = factory;
}
public JsonSmartMappingProvider() {
this(DEFAULT);
}
@Override
public <T> T map(Object source, Class<T> targetType, Configuration configuration) {
if(source == null){
return null;
}
if (targetType.isAssignableFrom(source.getClass())) {
return (T) source;
}
return factory.createInstance().getMapper(targetType).convert(source);
}
private static class StringReader extends JsonReaderI<String> {
public StringReader() {
super(null);
}
public String convert(Object src) {
if(src == null){
return null;
}
return src.toString();
}
}
private static class IntegerReader extends JsonReaderI<Integer> {
public IntegerReader() {
super(null);
}
public Integer convert(Object src) {
if(src == null){
return null;
}
if (Long.class.isAssignableFrom(src.getClass())) {
return ((Integer) src).intValue();
} else if (Double.class.isAssignableFrom(src.getClass())) {
return ((Double) src).intValue();
} else if (BigDecimal.class.isAssignableFrom(src.getClass())) {
return ((BigDecimal) src).intValue();
} else if (Float.class.isAssignableFrom(src.getClass())) {
return ((Float) src).intValue();
} else if (String.class.isAssignableFrom(src.getClass())) {
return Integer.valueOf(src.toString());
}
throw new MappingException("can not map a " + src.getClass() + " to " + Integer.class.getName());
}
}
private static class LongReader extends JsonReaderI<Long> {
public LongReader() {
super(null);
}
public Long convert(Object src) {
if(src == null){
return null;
}
if (Integer.class.isAssignableFrom(src.getClass())) {
return ((Integer) src).longValue();
} else if (Double.class.isAssignableFrom(src.getClass())) {
return ((Double) src).longValue();
} else if (BigDecimal.class.isAssignableFrom(src.getClass())) {
return ((BigDecimal) src).longValue();
} else if (Float.class.isAssignableFrom(src.getClass())) {
return ((Float) src).longValue();
} else if (String.class.isAssignableFrom(src.getClass())) {
return Long.valueOf(src.toString());
}
throw new MappingException("can not map a " + src.getClass() + " to " + Long.class.getName());
}
}
private static class DoubleReader extends JsonReaderI<Double> {
public DoubleReader() {
super(null);
}
public Double convert(Object src) {
if(src == null){
return null;
}
if (Integer.class.isAssignableFrom(src.getClass())) {
return ((Integer) src).doubleValue();
} else if (Long.class.isAssignableFrom(src.getClass())) {
return ((Long) src).doubleValue();
} else if (BigDecimal.class.isAssignableFrom(src.getClass())) {
return ((BigDecimal) src).doubleValue();
} else if (Float.class.isAssignableFrom(src.getClass())) {
return ((Float) src).doubleValue();
} else if (String.class.isAssignableFrom(src.getClass())) {
return Double.valueOf(src.toString());
}
throw new MappingException("can not map a " + src.getClass() + " to " + Double.class.getName());
}
}
private static class FloatReader extends JsonReaderI<Float> {
public FloatReader() {
super(null);
}
public Float convert(Object src) {
if(src == null){
return null;
}
if (Integer.class.isAssignableFrom(src.getClass())) {
return ((Integer) src).floatValue();
} else if (Long.class.isAssignableFrom(src.getClass())) {
return ((Long) src).floatValue();
} else if (BigDecimal.class.isAssignableFrom(src.getClass())) {
return ((BigDecimal) src).floatValue();
} else if (Double.class.isAssignableFrom(src.getClass())) {
return ((Double) src).floatValue();
} else if (String.class.isAssignableFrom(src.getClass())) {
return Float.valueOf(src.toString());
}
throw new MappingException("can not map a " + src.getClass() + " to " + Float.class.getName());
}
}
private static class BigDecimalReader extends JsonReaderI<BigDecimal> {
public BigDecimalReader() {
super(null);
}
public BigDecimal convert(Object src) {
if(src == null){
return null;
}
return new BigDecimal(src.toString());
}
}
private static class DateReader extends JsonReaderI<Date> {
public DateReader() {
super(null);
}
public Date convert(Object src) {
if(src == null){
return null;
}
if(Long.class.isAssignableFrom(src.getClass())){
return new Date((Long) src);
}
else if(String.class.isAssignableFrom(src.getClass())){
try {
return DateFormat.getInstance().parse(src.toString());
} catch (ParseException e) {
throw new MappingException(e);
}
}
throw new MappingException("can not map a " + src.getClass() + " to " + Date.class.getName());
}
}
}

86
json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/Mapper.java

@ -1,86 +0,0 @@
/*
* Copyright 2011 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jayway.jsonpath.internal.spi.mapper;
import com.jayway.jsonpath.Configuration;
import java.util.Set;
import static com.jayway.jsonpath.internal.Utils.notNull;
public interface Mapper {
Set<ConvertiblePair> getConvertibleTypes();
Object convert(Object src, Class<?> srcType, Class<?> targetType, Configuration conf);
/**
* Holder for a source-to-target class pair.
*/
public static final class ConvertiblePair {
private final Class<?> sourceType;
private final Class<?> targetType;
/**
* Create a new source-to-target pair.
*
* @param sourceType the source type
* @param targetType the target type
*/
public ConvertiblePair(Class<?> sourceType, Class<?> targetType) {
notNull(sourceType, "Source type must not be null");
notNull(targetType, "Target type must not be null");
this.sourceType = sourceType;
this.targetType = targetType;
}
public Class<?> getSourceType() {
return this.sourceType;
}
public Class<?> getTargetType() {
return this.targetType;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ConvertiblePair)) return false;
ConvertiblePair that = (ConvertiblePair) o;
if (!sourceType.equals(that.sourceType)) return false;
if (!targetType.equals(that.targetType)) return false;
return true;
}
@Override
public int hashCode() {
int result = sourceType.hashCode();
result = 31 * result + targetType.hashCode();
return result;
}
@Override
public String toString() {
return this.sourceType.getName() + " -> " + this.targetType.getName();
}
}
}

53
json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/MapperBase.java

@ -1,53 +0,0 @@
/*
* Copyright 2011 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jayway.jsonpath.internal.spi.mapper;
import com.jayway.jsonpath.spi.mapper.MappingException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public abstract class MapperBase implements Mapper {
private final Set<Mapper.ConvertiblePair> convertiblePairs = new HashSet<Mapper.ConvertiblePair>();
protected void register(Class<?> srcType, Class<?> targetType){
convertiblePairs.add(new ConvertiblePair(srcType, targetType));
}
@Override
public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.unmodifiableSet(convertiblePairs);
}
void assertValidConversion(Object src, Class<?> srcType, Class<?> targetType) {
if (src == null) {
return;
}
if (!srcType.isAssignableFrom(src.getClass())) {
throw new MappingException("Source: " + src.getClass() + " is not assignable from: " + srcType.getName());
}
if(!canConvert(srcType, targetType)){
throw new MappingException("Can not map: " + srcType.getName() + " to: " + targetType.getName());
}
}
boolean canConvert(Class<?> srcType, Class<?> targetType){
return convertiblePairs.contains(new Mapper.ConvertiblePair(srcType, targetType));
}
}

144
json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/NumberMapper.java

@ -1,144 +0,0 @@
/*
* Copyright 2011 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jayway.jsonpath.internal.spi.mapper;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.spi.mapper.MappingException;
import java.math.BigDecimal;
public class NumberMapper extends MapperBase {
public NumberMapper() {
//to long
register(Integer.class, Long.class);
register(Double.class, Long.class);
register(Float.class, Long.class);
register(BigDecimal.class, Long.class);
register(String.class, Long.class);
//to int
register(Long.class, Integer.class);
register(Double.class, Integer.class);
register(Float.class, Integer.class);
register(BigDecimal.class, Integer.class);
register(String.class, Integer.class);
//to double
register(Long.class, Double.class);
register(Integer.class, Double.class);
register(Float.class, Double.class);
register(BigDecimal.class, Double.class);
register(String.class, Double.class);
//to float
register(Long.class, Float.class);
register(Integer.class, Float.class);
register(Double.class, Float.class);
register(BigDecimal.class, Float.class);
register(String.class, Float.class);
//to BigDecimal
register(Long.class, BigDecimal.class);
register(Integer.class, BigDecimal.class);
register(Double.class, BigDecimal.class);
register(Float.class, BigDecimal.class);
register(String.class, BigDecimal.class);
}
@Override
public Object convert(Object src, Class<?> srcType, Class<?> targetType, Configuration conf) {
assertValidConversion(src, srcType, targetType);
if (src == null) {
return null;
}
//to long
if(targetType.equals(Long.class)) {
if (Integer.class.isAssignableFrom(srcType)) {
return ((Integer) src).longValue();
} else if (Double.class.isAssignableFrom(srcType)) {
return ((Double) src).longValue();
} else if (BigDecimal.class.isAssignableFrom(srcType)) {
return ((BigDecimal) src).longValue();
} else if (Float.class.isAssignableFrom(srcType)) {
return ((Float) src).longValue();
} else if (String.class.isAssignableFrom(srcType)) {
return Long.parseLong(src.toString());
}
}
else if(targetType.equals(Integer.class)) {
//to int
if (Long.class.isAssignableFrom(srcType)) {
return ((Long) src).intValue();
} else if (Double.class.isAssignableFrom(srcType)) {
return ((Double) src).intValue();
} else if (BigDecimal.class.isAssignableFrom(srcType)) {
return ((BigDecimal) src).intValue();
} else if (Float.class.isAssignableFrom(srcType)) {
return ((Float) src).intValue();
} else if (String.class.isAssignableFrom(srcType)) {
return Integer.parseInt(src.toString());
}
}
else if(targetType.equals(Double.class)) {
//to double
if (Long.class.isAssignableFrom(srcType)) {
return ((Long) src).doubleValue();
} else if (Integer.class.isAssignableFrom(srcType)) {
return ((Integer) src).doubleValue();
} else if (BigDecimal.class.isAssignableFrom(srcType)) {
return ((BigDecimal) src).doubleValue();
} else if (Float.class.isAssignableFrom(srcType)) {
return ((Float) src).doubleValue();
} else if (String.class.isAssignableFrom(srcType)) {
return Double.parseDouble(src.toString());
}
}
else if(targetType.equals(Float.class)) {
//to float
if (Long.class.isAssignableFrom(srcType) && targetType.equals(Float.class)) {
return ((Long) src).floatValue();
} else if (Integer.class.isAssignableFrom(srcType) && targetType.equals(Float.class)) {
return ((Integer) src).floatValue();
} else if (BigDecimal.class.isAssignableFrom(srcType) && targetType.equals(Float.class)) {
return ((BigDecimal) src).floatValue();
} else if (Double.class.isAssignableFrom(srcType) && targetType.equals(Float.class)) {
return ((Double) src).floatValue();
} else if (String.class.isAssignableFrom(srcType) && targetType.equals(Float.class)) {
return Float.parseFloat(src.toString());
}
}
else if(targetType.equals(BigDecimal.class)) {
//to BigDecimal
if (Long.class.isAssignableFrom(srcType) && targetType.equals(BigDecimal.class)) {
return new BigDecimal(src.toString());
} else if (Integer.class.isAssignableFrom(srcType) && targetType.equals(BigDecimal.class)) {
return new BigDecimal(src.toString());
} else if (Float.class.isAssignableFrom(srcType) && targetType.equals(BigDecimal.class)) {
return new BigDecimal(src.toString());
} else if (Double.class.isAssignableFrom(srcType) && targetType.equals(BigDecimal.class)) {
return new BigDecimal(src.toString());
} else if (String.class.isAssignableFrom(srcType) && targetType.equals(BigDecimal.class)) {
return new BigDecimal(src.toString());
}
}
throw new MappingException("Can not map: " + srcType.getName() + " to: " + targetType.getName());
}
}

39
json-path/src/main/java/com/jayway/jsonpath/internal/spi/mapper/StringMapper.java

@ -1,39 +0,0 @@
/*
* Copyright 2011 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jayway.jsonpath.internal.spi.mapper;
import com.jayway.jsonpath.Configuration;
public class StringMapper extends MapperBase {
public StringMapper() {
register(Object.class, String.class);
}
@Override
public Object convert(Object src, Class<?> srcType, Class<?> targetType, Configuration conf) {
assertValidConversion(src, srcType, targetType);
if (src == null) {
return null;
}
return src.toString();
}
@Override
boolean canConvert(Class<?> srcType, Class<?> targetType){
return true;
}
}

8
json-path/src/main/java/com/jayway/jsonpath/internal/token/EvaluationContextImpl.java

@ -124,11 +124,17 @@ public class EvaluationContextImpl implements EvaluationContext {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public <T> T getValue() { public <T> T getValue() {
return getValue(true);
}
@SuppressWarnings("unchecked")
@Override
public <T> T getValue(boolean unwrap) {
if (path.isDefinite()) { if (path.isDefinite()) {
if(resultIndex == 0){ if(resultIndex == 0){
throw new PathNotFoundException("No results for path: " + path.toString()); throw new PathNotFoundException("No results for path: " + path.toString());
} }
return (T) jsonProvider().getArrayIndex(valueResult, 0); return (T) jsonProvider().getArrayIndex(valueResult, 0, unwrap);
} }
return (T)valueResult; return (T)valueResult;
} }

12
json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonProvider.java

@ -93,7 +93,7 @@ public interface JsonProvider {
Collection<String> getPropertyKeys(Object obj); Collection<String> getPropertyKeys(Object obj);
/** /**
* Extracts a value from an array * Extracts a value from an array anw unwraps provider specific data type
* *
* @param obj an array * @param obj an array
* @param idx index * @param idx index
@ -101,6 +101,16 @@ public interface JsonProvider {
*/ */
Object getArrayIndex(Object obj, int idx); Object getArrayIndex(Object obj, int idx);
/**
* Extracts a value from an array
*
* @param obj an array
* @param idx index
* @param unwrap should provider specific data type be unwrapped
* @return the entry at the given index
*/
Object getArrayIndex(Object obj, int idx, boolean unwrap);
/** /**
* Sets a value in an array * Sets a value in an array
* *

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

@ -3,6 +3,7 @@ package com.jayway.jsonpath;
import com.jayway.jsonpath.internal.Path; import com.jayway.jsonpath.internal.Path;
import com.jayway.jsonpath.internal.spi.json.GsonJsonProvider; import com.jayway.jsonpath.internal.spi.json.GsonJsonProvider;
import com.jayway.jsonpath.internal.spi.json.JacksonJsonProvider; import com.jayway.jsonpath.internal.spi.json.JacksonJsonProvider;
import com.jayway.jsonpath.internal.spi.json.JacksonTreeJsonProvider;
import com.jayway.jsonpath.internal.spi.mapper.GsonMappingProvider; import com.jayway.jsonpath.internal.spi.mapper.GsonMappingProvider;
import com.jayway.jsonpath.internal.spi.mapper.JacksonMappingProvider; import com.jayway.jsonpath.internal.spi.mapper.JacksonMappingProvider;
import com.jayway.jsonpath.internal.token.PredicateContextImpl; import com.jayway.jsonpath.internal.token.PredicateContextImpl;
@ -23,13 +24,18 @@ public class BaseTest {
.jsonProvider(new JacksonJsonProvider()) .jsonProvider(new JacksonJsonProvider())
.build(); .build();
public static final Configuration JACKSON_TREE_CONFIGURATION = Configuration
.builder()
.mappingProvider(new JacksonMappingProvider())
.jsonProvider(new JacksonTreeJsonProvider())
.build();
public static final Configuration JSON_SMART_CONFIGURATION = Configuration.defaultConfiguration(); public static final Configuration JSON_SMART_CONFIGURATION = Configuration.defaultConfiguration();
public static final String JSON_DOCUMENT = "{\n" + public static final String JSON_DOCUMENT = "{\n" +
" \"string-property\" : \"string-value\", \n" + " \"string-property\" : \"string-value\", \n" +
" \"int-max-property\" : " + Integer.MAX_VALUE + ", \n" + " \"int-max-property\" : " + Integer.MAX_VALUE + ", \n" +
" \"long-max-property\" : " + Long.MAX_VALUE + ", \n" + " \"long-max-property\" : " + Long.MAX_VALUE + ", \n" +
" \"long-max-property\" : " + Long.MAX_VALUE + ", \n" +
" \"boolean-property\" : true, \n" + " \"boolean-property\" : true, \n" +
" \"null-property\" : null, \n" + " \"null-property\" : null, \n" +
" \"int-small-property\" : 1, \n" + " \"int-small-property\" : 1, \n" +

89
json-path/src/test/java/com/jayway/jsonpath/GsonJsonProviderTest.java

@ -0,0 +1,89 @@
package com.jayway.jsonpath;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.junit.Test;
import static com.jayway.jsonpath.JsonPath.using;
import static org.assertj.core.api.Assertions.assertThat;
public class GsonJsonProviderTest extends BaseTest {
@Test
public void json_can_be_parsed() {
JsonObject node = using(GSON_CONFIGURATION).parse(JSON_DOCUMENT).read("$");
assertThat(node.get("string-property").getAsString()).isEqualTo("string-value");
}
@Test
public void strings_are_unwrapped() {
JsonElement node = using(GSON_CONFIGURATION).parse(JSON_DOCUMENT).read("$.string-property");
String unwrapped = using(GSON_CONFIGURATION).parse(JSON_DOCUMENT).read("$.string-property", String.class);
assertThat(unwrapped).isEqualTo("string-value");
assertThat(unwrapped).isEqualTo(node.getAsString());
}
@Test
public void ints_are_unwrapped() {
JsonElement node = using(GSON_CONFIGURATION).parse(JSON_DOCUMENT).read("$.int-max-property");
int unwrapped = using(GSON_CONFIGURATION).parse(JSON_DOCUMENT).read("$.int-max-property", Integer.class);
assertThat(unwrapped).isEqualTo(Integer.MAX_VALUE);
assertThat(unwrapped).isEqualTo(node.getAsInt());
}
@Test
public void longs_are_unwrapped() {
JsonElement node = using(GSON_CONFIGURATION).parse(JSON_DOCUMENT).read("$.long-max-property");
long val = using(GSON_CONFIGURATION).parse(JSON_DOCUMENT).read("$.long-max-property", Long.class);
assertThat(val).isEqualTo(Long.MAX_VALUE);
assertThat(val).isEqualTo(node.getAsLong());
}
@Test
public void int_to_long_mapping() {
assertThat(using(GSON_CONFIGURATION).parse("{\"val\": 1}").read("val", Long.class)).isEqualTo(1L);
}
@Test
public void an_Integer_can_be_converted_to_a_Double() {
assertThat(using(GSON_CONFIGURATION).parse("{\"val\": 1}").read("val", Double.class)).isEqualTo(1D);
}
@Test
public void list_of_numbers() {
JsonArray objs = using(GSON_CONFIGURATION).parse(JSON_DOCUMENT).read("$.store.book[*].display-price");
assertThat(objs.iterator()).extracting("asDouble").containsExactly(8.95D, 12.99D, 8.99D, 22.99D);
}
@Test
public void an_object_can_be_mapped_to_pojo() {
String json = "{\n" +
" \"foo\" : \"foo\",\n" +
" \"bar\" : 10,\n" +
" \"baz\" : true\n" +
"}";
FooBarBaz fooBarBaz = JsonPath.using(GSON_CONFIGURATION).parse(json).read("$", FooBarBaz.class);
assertThat(fooBarBaz.foo).isEqualTo("foo");
assertThat(fooBarBaz.bar).isEqualTo(10L);
assertThat(fooBarBaz.baz).isEqualTo(true);
}
public static class FooBarBaz {
public String foo;
public Long bar;
public boolean baz;
}
}

56
json-path/src/test/java/com/jayway/jsonpath/JacksonTreeJsonProviderTest.java

@ -0,0 +1,56 @@
package com.jayway.jsonpath;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.Test;
import static com.jayway.jsonpath.JsonPath.using;
import static org.assertj.core.api.Assertions.assertThat;
public class JacksonTreeJsonProviderTest extends BaseTest {
@Test
public void json_can_be_parsed() {
ObjectNode node = using(JACKSON_TREE_CONFIGURATION).parse(JSON_DOCUMENT).read("$");
assertThat(node.get("string-property").asText()).isEqualTo("string-value");
}
@Test
public void strings_are_unwrapped() {
JsonNode node = using(JACKSON_TREE_CONFIGURATION).parse(JSON_DOCUMENT).read("$.string-property");
String unwrapped = using(JACKSON_TREE_CONFIGURATION).parse(JSON_DOCUMENT).read("$.string-property", String.class);
assertThat(unwrapped).isEqualTo("string-value");
assertThat(unwrapped).isEqualTo(node.asText());
}
@Test
public void ints_are_unwrapped() {
JsonNode node = using(JACKSON_TREE_CONFIGURATION).parse(JSON_DOCUMENT).read("$.int-max-property");
int unwrapped = using(JACKSON_TREE_CONFIGURATION).parse(JSON_DOCUMENT).read("$.int-max-property", int.class);
assertThat(unwrapped).isEqualTo(Integer.MAX_VALUE);
assertThat(unwrapped).isEqualTo(node.asInt());
}
@Test
public void longs_are_unwrapped() {
JsonNode node = using(JACKSON_TREE_CONFIGURATION).parse(JSON_DOCUMENT).read("$.long-max-property");
long unwrapped = using(JACKSON_TREE_CONFIGURATION).parse(JSON_DOCUMENT).read("$.long-max-property", long.class);
assertThat(unwrapped).isEqualTo(Long.MAX_VALUE);
assertThat(unwrapped).isEqualTo(node.asLong());
}
@Test
public void list_of_numbers() {
ArrayNode objs = using(JACKSON_TREE_CONFIGURATION).parse(JSON_DOCUMENT).read("$.store.book[*].display-price");
System.out.println(objs.toString());
}
}

1
json-path/src/test/java/com/jayway/jsonpath/MapperTest.java

@ -42,5 +42,4 @@ public class MapperTest extends BaseTest {
} }
} }

Loading…
Cancel
Save