26 changed files with 750 additions and 327 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,52 @@ |
|||||||
|
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 java.util.HashMap; |
||||||
|
|
||||||
|
public class DefaultConversionProvider implements ConversionProvider { |
||||||
|
|
||||||
|
private HashMap<Class<?>, HashMap<Class<?>, Converter>> converters = new HashMap<Class<?>, HashMap<Class<?>, Converter>>(); |
||||||
|
|
||||||
|
public DefaultConversionProvider(){ |
||||||
|
addConverters(new NumberConverter()); |
||||||
|
addConverters(new StringConverter()); |
||||||
|
addConverters(new DateConverter()); |
||||||
|
} |
||||||
|
|
||||||
|
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,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,26 @@ |
|||||||
|
package com.jayway.jsonpath.internal.spi.converter; |
||||||
|
|
||||||
|
import com.jayway.jsonpath.Configuration; |
||||||
|
import com.jayway.jsonpath.spi.converter.Converter; |
||||||
|
|
||||||
|
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,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