Jochen Berger
10 years ago
36 changed files with 1119 additions and 318 deletions
@ -0,0 +1,4 @@
|
||||
package com.jayway.jsonpath; |
||||
|
||||
public class ValueCompareException extends RuntimeException { |
||||
} |
@ -0,0 +1,40 @@
|
||||
package com.jayway.jsonpath.internal.spi.converter; |
||||
|
||||
import com.jayway.jsonpath.spi.converter.ConversionException; |
||||
import com.jayway.jsonpath.spi.converter.Converter; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.HashSet; |
||||
import java.util.Set; |
||||
|
||||
public abstract class ConverterBase implements Converter{ |
||||
|
||||
private final Set<Converter.ConvertiblePair> convertiblePairs = new HashSet<Converter.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 ConversionException("Source: " + src.getClass() + " is not assignable from: " + srcType.getName()); |
||||
} |
||||
if(!canConvert(srcType, targetType)){ |
||||
throw new ConversionException("Can not convert: " + srcType.getName() + " to: " + targetType.getName()); |
||||
} |
||||
} |
||||
|
||||
boolean canConvert(Class<?> srcType, Class<?> targetType){ |
||||
return convertiblePairs.contains(new Converter.ConvertiblePair(srcType, targetType)); |
||||
} |
||||
} |
@ -0,0 +1,38 @@
|
||||
package com.jayway.jsonpath.internal.spi.converter; |
||||
|
||||
import com.jayway.jsonpath.Configuration; |
||||
import com.jayway.jsonpath.spi.converter.ConversionException; |
||||
|
||||
import java.text.DateFormat; |
||||
import java.text.ParseException; |
||||
import java.util.Date; |
||||
|
||||
public class DateConverter extends ConverterBase { |
||||
|
||||
public DateConverter() { |
||||
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 ConversionException(e); |
||||
} |
||||
} |
||||
|
||||
throw new ConversionException("Can not convert: " + srcType.getName() + " to: " + targetType.getName()); |
||||
} |
||||
} |
@ -0,0 +1,66 @@
|
||||
package com.jayway.jsonpath.internal.spi.converter; |
||||
|
||||
import com.jayway.jsonpath.Configuration; |
||||
import com.jayway.jsonpath.spi.converter.ConversionProvider; |
||||
import com.jayway.jsonpath.spi.converter.Converter; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
import java.util.HashMap; |
||||
|
||||
public class DefaultConversionProvider implements ConversionProvider { |
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DefaultConversionProvider.class); |
||||
|
||||
private HashMap<Class<?>, HashMap<Class<?>, Converter>> converters = new HashMap<Class<?>, HashMap<Class<?>, Converter>>(); |
||||
|
||||
public DefaultConversionProvider(){ |
||||
addConverters(new NumberConverter()); |
||||
addConverters(new StringConverter()); |
||||
addConverters(new DateConverter()); |
||||
|
||||
try { |
||||
Class.forName("com.google.gson.Gson"); |
||||
addConverters(new GsonConverter()); |
||||
} catch (ClassNotFoundException e) { |
||||
logger.debug("Gson not found on class path. No converters configured."); |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
public void addConverters(ConverterBase converter) { |
||||
for (Converter.ConvertiblePair convertible : converter.getConvertibleTypes()) { |
||||
if(!converters.containsKey(convertible.getTargetType())){ |
||||
converters.put(convertible.getTargetType(), new HashMap<Class<?>, Converter>()); |
||||
} |
||||
converters.get(convertible.getTargetType()).put(convertible.getSourceType(), converter); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public boolean canConvert(Class<?> sourceType, Class<?> targetType) { |
||||
HashMap<Class<?>, Converter> targetConverters = converters.get(targetType); |
||||
return targetConverters != null && targetConverters.containsKey(sourceType); |
||||
} |
||||
|
||||
@Override |
||||
public <T> T convert(Object source, Class<T> targetType, Configuration configuration) { |
||||
if(source == null){ |
||||
return null; |
||||
} |
||||
HashMap<Class<?>, Converter> targetConverters = converters.get(targetType); |
||||
if(targetConverters != null){ |
||||
Converter converter = targetConverters.get(source.getClass()); |
||||
if(converter != null){ |
||||
return (T)converter.convert(source, source.getClass(), targetType, configuration); |
||||
} |
||||
converter = targetConverters.get(Object.class); |
||||
if(converter != null){ |
||||
return (T)converter.convert(source, source.getClass(), targetType, configuration); |
||||
} |
||||
} |
||||
return (T)source; |
||||
} |
||||
} |
@ -0,0 +1,90 @@
|
||||
package com.jayway.jsonpath.internal.spi.converter; |
||||
|
||||
import com.google.gson.JsonArray; |
||||
import com.google.gson.JsonNull; |
||||
import com.google.gson.JsonObject; |
||||
import com.google.gson.JsonPrimitive; |
||||
import com.jayway.jsonpath.Configuration; |
||||
import com.jayway.jsonpath.spi.converter.ConversionException; |
||||
|
||||
import java.math.BigDecimal; |
||||
import java.math.BigInteger; |
||||
import java.text.DateFormat; |
||||
import java.text.ParseException; |
||||
import java.util.Date; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
public class GsonConverter extends ConverterBase { |
||||
|
||||
public GsonConverter() { |
||||
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(JsonArray.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 ConversionException(e); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
} else if (JsonObject.class.isAssignableFrom(srcType)) { |
||||
|
||||
} else if (JsonArray.class.isAssignableFrom(srcType)) { |
||||
|
||||
} |
||||
|
||||
return null; |
||||
} |
||||
} |
@ -0,0 +1,130 @@
|
||||
package com.jayway.jsonpath.internal.spi.converter; |
||||
|
||||
import com.jayway.jsonpath.Configuration; |
||||
import com.jayway.jsonpath.spi.converter.ConversionException; |
||||
|
||||
import java.math.BigDecimal; |
||||
|
||||
public class NumberConverter extends ConverterBase { |
||||
|
||||
public NumberConverter() { |
||||
//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 ConversionException("Can not convert: " + srcType.getName() + " to: " + targetType.getName()); |
||||
} |
||||
} |
@ -0,0 +1,25 @@
|
||||
package com.jayway.jsonpath.internal.spi.converter; |
||||
|
||||
import com.jayway.jsonpath.Configuration; |
||||
|
||||
public class StringConverter extends ConverterBase { |
||||
|
||||
public StringConverter() { |
||||
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; |
||||
} |
||||
} |
@ -0,0 +1,358 @@
|
||||
package com.jayway.jsonpath.internal.spi.json; |
||||
|
||||
import com.google.gson.Gson; |
||||
import com.google.gson.GsonBuilder; |
||||
import com.google.gson.InstanceCreator; |
||||
import com.google.gson.JsonArray; |
||||
import com.google.gson.JsonDeserializationContext; |
||||
import com.google.gson.JsonDeserializer; |
||||
import com.google.gson.JsonElement; |
||||
import com.google.gson.JsonNull; |
||||
import com.google.gson.JsonObject; |
||||
import com.google.gson.JsonParseException; |
||||
import com.google.gson.JsonParser; |
||||
import com.google.gson.JsonPrimitive; |
||||
import com.google.gson.JsonSerializationContext; |
||||
import com.google.gson.JsonSerializer; |
||||
import com.google.gson.internal.LazilyParsedNumber; |
||||
import com.jayway.jsonpath.InvalidJsonException; |
||||
import com.jayway.jsonpath.ValueCompareException; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
import java.io.InputStream; |
||||
import java.io.InputStreamReader; |
||||
import java.io.Reader; |
||||
import java.lang.reflect.Type; |
||||
import java.math.BigDecimal; |
||||
import java.util.ArrayList; |
||||
import java.util.Collection; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
public class GsonProvider extends AbstractJsonProvider { |
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(GsonProvider.class); |
||||
|
||||
private static final JsonParser parser = new JsonParser(); |
||||
private static final Gson gson = new GsonBuilder().registerTypeAdapter(Number.class, new NumberTypeAdapter()).create(); |
||||
|
||||
static { |
||||
|
||||
//ConverterFactory.registerConverter();
|
||||
|
||||
} |
||||
|
||||
public int compare(Object expected, Object providerParsed) throws ValueCompareException { |
||||
|
||||
JsonElement element = (JsonElement) providerParsed; |
||||
|
||||
boolean nullish = isNullish(expected); |
||||
|
||||
if (nullish && !element.isJsonNull()) { |
||||
return -1; |
||||
} else if (!nullish && element.isJsonNull()) { |
||||
return 1; |
||||
} else if (nullish && element.isJsonNull()) { |
||||
return 0; |
||||
} |
||||
if(element.isJsonPrimitive()){ |
||||
JsonPrimitive primitive = element.getAsJsonPrimitive(); |
||||
|
||||
if (expected instanceof String && primitive.isString()) { |
||||
return ((String) expected).compareTo(primitive.getAsString()); |
||||
} else if (expected instanceof Number && primitive.isNumber()) { |
||||
return new BigDecimal(expected.toString()).compareTo(new BigDecimal(primitive.toString())); |
||||
} else if (expected instanceof String && primitive.isNumber()) { |
||||
return new BigDecimal(expected.toString()).compareTo(new BigDecimal(primitive.toString())); |
||||
} else if (expected instanceof String && primitive.isBoolean()) { |
||||
Boolean e = Boolean.valueOf((String)expected); |
||||
Boolean a = primitive.getAsBoolean(); |
||||
return e.compareTo(a); |
||||
} else if (expected instanceof Boolean && primitive.isBoolean()) { |
||||
Boolean e = (Boolean) expected; |
||||
Boolean a = primitive.getAsBoolean(); |
||||
return e.compareTo(a); |
||||
} |
||||
} |
||||
logger.debug("Can not compare a {} with a {}", expected.getClass().getName(), providerParsed.getClass().getName()); |
||||
throw new ValueCompareException(); |
||||
} |
||||
|
||||
private static boolean isNullish(Object o){ |
||||
return (o == null || ((o instanceof String) && ("null".equals(o)))); |
||||
} |
||||
|
||||
|
||||
public Object unwrap(Object o) { |
||||
return o; |
||||
/* |
||||
if (o == null) { |
||||
return null; |
||||
} |
||||
if (!(o instanceof JsonElement)) { |
||||
return o; |
||||
} |
||||
|
||||
Object unwrapped = null; |
||||
|
||||
JsonElement e = (JsonElement) o; |
||||
|
||||
if (e.isJsonNull()) { |
||||
unwrapped = null; |
||||
} else if (e.isJsonPrimitive()) { |
||||
|
||||
JsonPrimitive p = e.getAsJsonPrimitive(); |
||||
if (p.isString()) { |
||||
unwrapped = p.getAsString(); |
||||
} else if (p.isBoolean()) { |
||||
unwrapped = p.getAsBoolean(); |
||||
} else if (p.isNumber()) { |
||||
unwrapped = unwrapNumber(p.getAsNumber()); |
||||
} |
||||
} else { |
||||
//unwrapped = o;
|
||||
if (e.isJsonArray()) { |
||||
JsonArray res = new JsonArray(); |
||||
for (JsonElement jsonElement : e.getAsJsonArray()) { |
||||
if(jsonElement.isJsonPrimitive()){ |
||||
JsonPrimitive primitive = jsonElement.getAsJsonPrimitive(); |
||||
if(primitive.isNumber()){ |
||||
res.add(new JsonPrimitive(unwrapNumber(primitive.getAsNumber()))); |
||||
} |
||||
} |
||||
} |
||||
unwrapped = res; |
||||
//unwrapped = gson.fromJson(e, List.class);
|
||||
} else { |
||||
unwrapped = gson.fromJson(e, Map.class); |
||||
} |
||||
|
||||
} |
||||
return unwrapped; |
||||
*/ |
||||
} |
||||
|
||||
private Number unwrapNumber(Number n){ |
||||
Number unwrapped; |
||||
|
||||
if (n instanceof LazilyParsedNumber) { |
||||
LazilyParsedNumber lpn = (LazilyParsedNumber) n; |
||||
BigDecimal bigDecimal = new BigDecimal(lpn.toString()); |
||||
if (bigDecimal.scale() <= 0) { |
||||
if (bigDecimal.compareTo(new BigDecimal(Integer.MAX_VALUE)) <= 0) { |
||||
unwrapped = bigDecimal.intValue(); |
||||
} else { |
||||
unwrapped = bigDecimal.longValue(); |
||||
} |
||||
} else { |
||||
if (bigDecimal.compareTo(new BigDecimal(Float.MAX_VALUE)) <= 0) { |
||||
unwrapped = bigDecimal.floatValue(); |
||||
} else { |
||||
unwrapped = bigDecimal.doubleValue(); |
||||
} |
||||
} |
||||
} else { |
||||
unwrapped = n; |
||||
} |
||||
return unwrapped; |
||||
} |
||||
|
||||
@Override |
||||
public Object parse(String json) throws InvalidJsonException { |
||||
return parser.parse(json); |
||||
} |
||||
|
||||
@Override |
||||
public Object parse(Reader jsonReader) throws InvalidJsonException { |
||||
return parser.parse(jsonReader); |
||||
} |
||||
|
||||
@Override |
||||
public Object parse(InputStream jsonStream) throws InvalidJsonException { |
||||
return parser.parse(new InputStreamReader(jsonStream)); |
||||
} |
||||
|
||||
@Override |
||||
public String toJson(Object obj) { |
||||
return obj.toString(); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public Object createNull(){ |
||||
return JsonNull.INSTANCE; |
||||
} |
||||
|
||||
@Override |
||||
public Object createMap() { |
||||
return new JsonObject(); |
||||
} |
||||
|
||||
@Override |
||||
public Object createArray() { |
||||
return new JsonArray(); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isArray(Object obj) { |
||||
return (obj instanceof JsonArray); |
||||
} |
||||
|
||||
public boolean isString(Object obj){ |
||||
if(obj == null) { |
||||
return false; |
||||
} |
||||
JsonElement element = toJsonElement(obj); |
||||
if(element.isJsonPrimitive()){ |
||||
return element.getAsJsonPrimitive().isString(); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public Object getArrayIndex(Object obj, int idx) { |
||||
return toJsonArray(obj).get(idx); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public Object getMapValue(Object obj, String key) { |
||||
Object o = toJsonObject(obj).get(key); |
||||
if (o == null) { |
||||
return UNDEFINED; |
||||
} else { |
||||
return o; |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void setProperty(Object obj, Object key, Object value) { |
||||
if (isMap(obj)) |
||||
toJsonObject(obj).add(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.size(); |
||||
} |
||||
if (index == array.size()) { |
||||
array.add(createJsonElement(value)); |
||||
} else { |
||||
array.set(index, createJsonElement(value)); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public boolean isMap(Object obj) { |
||||
return (obj instanceof JsonObject) ; |
||||
} |
||||
|
||||
@Override |
||||
public Collection<String> getPropertyKeys(Object obj) { |
||||
List<String> keys = new ArrayList<String>(); |
||||
for (Map.Entry<String, JsonElement> entry : toJsonObject(obj).entrySet()) { |
||||
keys.add(entry.getKey()); |
||||
} |
||||
return keys; |
||||
} |
||||
|
||||
@Override |
||||
public int length(Object obj) { |
||||
if (isArray(obj)) { |
||||
return toJsonArray(obj).size(); |
||||
} else if(isMap(obj)){ |
||||
return toJsonObject(obj).entrySet().size(); |
||||
} else { |
||||
if(obj instanceof JsonElement){ |
||||
JsonElement element = toJsonElement(obj); |
||||
if(element.isJsonPrimitive()){ |
||||
return element.toString().length(); |
||||
} |
||||
} |
||||
} |
||||
throw new RuntimeException("length operation can not applied to " + obj!=null?obj.getClass().getName():"null"); |
||||
} |
||||
|
||||
@Override |
||||
public Iterable<?> toIterable(Object obj) { |
||||
if (isArray(obj)) { |
||||
return toJsonArray(obj); |
||||
} else { |
||||
List<JsonElement> values = new ArrayList<JsonElement>(); |
||||
JsonObject jsonObject = toJsonObject(obj); |
||||
for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) { |
||||
values.add(entry.getValue()); |
||||
} |
||||
return values; |
||||
} |
||||
} |
||||
|
||||
private JsonElement createJsonElement(Object o) { |
||||
return gson.toJsonTree(o); |
||||
} |
||||
|
||||
private JsonArray toJsonArray(Object o) { |
||||
return (JsonArray) o; |
||||
} |
||||
|
||||
private JsonObject toJsonObject(Object o) { |
||||
return (JsonObject) o; |
||||
} |
||||
|
||||
private JsonElement toJsonElement(Object o) { |
||||
return (JsonElement) o; |
||||
} |
||||
|
||||
|
||||
public static class NumberTypeAdapter |
||||
implements JsonSerializer<Number>, JsonDeserializer<Number>, |
||||
InstanceCreator<Number> { |
||||
|
||||
public JsonElement serialize(Number src, Type typeOfSrc, JsonSerializationContext |
||||
context) { |
||||
return new JsonPrimitive(src); |
||||
} |
||||
|
||||
public Number deserialize(JsonElement json, Type typeOfT, |
||||
JsonDeserializationContext context) |
||||
throws JsonParseException { |
||||
|
||||
Number res = null; |
||||
JsonPrimitive jsonPrimitive = json.getAsJsonPrimitive(); |
||||
if (jsonPrimitive.isNumber()) { |
||||
Number n = jsonPrimitive.getAsNumber(); |
||||
if (n instanceof LazilyParsedNumber) { |
||||
LazilyParsedNumber lpn = (LazilyParsedNumber) n; |
||||
BigDecimal bigDecimal = new BigDecimal(lpn.toString()); |
||||
if (bigDecimal.scale() <= 0) { |
||||
if (bigDecimal.compareTo(new BigDecimal(Integer.MAX_VALUE)) <= 0) { |
||||
res = bigDecimal.intValue(); |
||||
} else { |
||||
res = bigDecimal.longValue(); |
||||
} |
||||
} else { |
||||
if (bigDecimal.compareTo(new BigDecimal(Float.MAX_VALUE)) <= 0) { |
||||
res = bigDecimal.floatValue(); |
||||
} else { |
||||
res = bigDecimal.doubleValue(); |
||||
} |
||||
} |
||||
} |
||||
} else { |
||||
throw new IllegalStateException("Expected a number field, but was " + json); |
||||
} |
||||
return res; |
||||
} |
||||
|
||||
|
||||
|
||||
public Number createInstance(Type type) { |
||||
return 1L; |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,21 @@
|
||||
package com.jayway.jsonpath.spi.converter; |
||||
|
||||
public class ConversionException extends RuntimeException { |
||||
|
||||
|
||||
public ConversionException(String message, Throwable cause) { |
||||
super(message, cause); |
||||
} |
||||
|
||||
public ConversionException(Throwable cause) { |
||||
super(cause); |
||||
} |
||||
|
||||
public ConversionException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { |
||||
super(message, cause, enableSuppression, writableStackTrace); |
||||
} |
||||
|
||||
public ConversionException(String message) { |
||||
super(message); |
||||
} |
||||
} |
@ -0,0 +1,10 @@
|
||||
package com.jayway.jsonpath.spi.converter; |
||||
|
||||
import com.jayway.jsonpath.Configuration; |
||||
|
||||
public interface ConversionProvider { |
||||
|
||||
boolean canConvert(Class<?> sourceType, Class<?> targetType); |
||||
|
||||
<T> T convert(Object source, Class<T> targetType, Configuration configuration); |
||||
} |
@ -1,174 +0,0 @@
|
||||
package com.jayway.jsonpath.spi.converter; |
||||
|
||||
import com.jayway.jsonpath.Configuration; |
||||
|
||||
import java.math.BigDecimal; |
||||
import java.text.DateFormat; |
||||
import java.text.ParseException; |
||||
import java.util.Date; |
||||
import java.util.Map; |
||||
import java.util.concurrent.ConcurrentHashMap; |
||||
|
||||
public class ConverterFactory { |
||||
|
||||
private static Map<Class<?>, Converter<?>> converters = new ConcurrentHashMap<Class<?>, Converter<?>>(); |
||||
|
||||
static { |
||||
registerConverter(Long.class, new LongConverter()); |
||||
registerConverter(Integer.class, new IntegerConverter()); |
||||
registerConverter(BigDecimal.class, new BigDecimalConverter()); |
||||
registerConverter(Double.class, new DoubleConverter()); |
||||
registerConverter(Date.class, new DateConverter()); |
||||
registerConverter(String.class, new StringConverter()); |
||||
} |
||||
|
||||
public static <T> Converter<T> createConverter(Class<T> target){ |
||||
Converter<T> converter = (Converter<T>) converters.get(target); |
||||
if(converter == null){ |
||||
converter = new Converter<T>() { |
||||
@Override |
||||
public T convert(Object o, Configuration conf) { |
||||
return (T)o; |
||||
} |
||||
}; |
||||
} |
||||
return converter; |
||||
} |
||||
|
||||
public static <T> void registerConverter(Class<T> target, Converter<T> converter){ |
||||
converters.put(target, converter); |
||||
} |
||||
|
||||
public static <T> void unRegisterConverter(Class<T> target){ |
||||
converters.remove(target); |
||||
} |
||||
|
||||
private static class StringConverter implements Converter<String> { |
||||
@Override |
||||
public String convert(Object o, Configuration conf) { |
||||
if(o == null){ |
||||
return null; |
||||
} else { |
||||
return o.toString(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private static class DateConverter implements Converter<Date> { |
||||
@Override |
||||
public Date convert(Object o, Configuration conf) { |
||||
|
||||
if(o == null){ |
||||
return null; |
||||
} else if(o instanceof Date){ |
||||
return (Date)o; |
||||
} else if(o instanceof Long){ |
||||
return new Date(((Long)o).longValue()); |
||||
} else if(o instanceof String){ |
||||
try { |
||||
return DateFormat.getInstance().parse(o.toString()); |
||||
} catch (ParseException e) { |
||||
throw new IllegalArgumentException("Can not convert: " + o.getClass().getName() + " to: " + Integer.class.getName(), e); |
||||
} |
||||
} |
||||
throw new IllegalArgumentException("Can not convert: " + o.getClass().getName() + " to: " + Integer.class.getName()); |
||||
} |
||||
} |
||||
|
||||
private static class IntegerConverter implements Converter<Integer> { |
||||
@Override |
||||
public Integer convert(Object o, Configuration conf) { |
||||
|
||||
if(o == null){ |
||||
return null; |
||||
} else if(o instanceof Integer){ |
||||
return (Integer)o; |
||||
} else if(o instanceof Long){ |
||||
return ((Long)o).intValue(); |
||||
} else if(o instanceof Double){ |
||||
return ((Double)o).intValue(); |
||||
} else if(o instanceof BigDecimal){ |
||||
return ((BigDecimal)o).intValue(); |
||||
} else if(o instanceof Float){ |
||||
return ((Float)o).intValue(); |
||||
} else if(o instanceof String){ |
||||
return Integer.parseInt(o.toString()); |
||||
} |
||||
throw new IllegalArgumentException("Can not convert: " + o.getClass().getName() + " to: " + Integer.class.getName()); |
||||
} |
||||
} |
||||
|
||||
private static class LongConverter implements Converter<Long> { |
||||
@Override |
||||
public Long convert(Object o, Configuration conf) { |
||||
|
||||
if(o == null){ |
||||
return null; |
||||
} else if(o instanceof Long){ |
||||
return (Long)o; |
||||
} else if(o instanceof Integer){ |
||||
return ((Integer)o).longValue(); |
||||
} else if(o instanceof Double){ |
||||
return ((Double)o).longValue(); |
||||
} else if(o instanceof BigDecimal){ |
||||
return ((BigDecimal)o).longValue(); |
||||
} else if(o instanceof Float){ |
||||
return ((Float)o).longValue(); |
||||
} else if(o instanceof String){ |
||||
return Long.parseLong(o.toString()); |
||||
} |
||||
throw new IllegalArgumentException("Can not convert: " + o.getClass().getName() + " to: " + Long.class.getName()); |
||||
} |
||||
} |
||||
|
||||
private static class DoubleConverter implements Converter<Double> { |
||||
@Override |
||||
public Double convert(Object o, Configuration conf) { |
||||
|
||||
if(o == null){ |
||||
return null; |
||||
} else if(o instanceof Double){ |
||||
return (Double)o; |
||||
} else if(o instanceof Integer){ |
||||
return Double.valueOf(o.toString()); |
||||
} else if(o instanceof Long){ |
||||
return Double.valueOf(o.toString()); |
||||
} else if(o instanceof BigDecimal){ |
||||
return ((BigDecimal)o).doubleValue(); |
||||
} else if(o instanceof Float){ |
||||
return ((Float)o).doubleValue(); |
||||
} else if(o instanceof String){ |
||||
return Double.parseDouble(o.toString()); |
||||
} |
||||
throw new IllegalArgumentException("Can not convert: " + o.getClass().getName() + " to: " + Double.class.getName()); |
||||
} |
||||
} |
||||
|
||||
private static class BigDecimalConverter implements Converter<BigDecimal> { |
||||
@Override |
||||
public BigDecimal convert(Object o, Configuration conf) { |
||||
|
||||
if(o == null){ |
||||
return null; |
||||
} else if(o instanceof BigDecimal){ |
||||
return (BigDecimal)o; |
||||
} else if(o instanceof Integer){ |
||||
return new BigDecimal(o.toString()); |
||||
} else if(o instanceof Long){ |
||||
return new BigDecimal(o.toString()); |
||||
} else if(o instanceof Float){ |
||||
return BigDecimal.valueOf(((Float)o).doubleValue()); |
||||
} else if(o instanceof String){ |
||||
return new BigDecimal(o.toString()); |
||||
} |
||||
throw new IllegalArgumentException("Can not convert: " + o.getClass().getName() + " to: " + BigDecimal.class.getName()); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in new issue