Jochen Berger
10 years ago
36 changed files with 1134 additions and 328 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