diff --git a/json-path-web-test/pom.xml b/json-path-web-test/pom.xml
index a072a03b..59ba2bf3 100644
--- a/json-path-web-test/pom.xml
+++ b/json-path-web-test/pom.xml
@@ -59,7 +59,7 @@
com.jayway.jsonpath
json-path
- 0.9.2-SNAPSHOT
+ ${project.version}
diff --git a/json-path/src/main/java/com/jayway/jsonpath/ReadContext.java b/json-path/src/main/java/com/jayway/jsonpath/ReadContext.java
index 01e54a71..9fb8c6a3 100644
--- a/json-path/src/main/java/com/jayway/jsonpath/ReadContext.java
+++ b/json-path/src/main/java/com/jayway/jsonpath/ReadContext.java
@@ -33,6 +33,17 @@ public interface ReadContext {
*/
T read(String path, Predicate... filters);
+ /**
+ * Reads the given path from this context
+ *
+ * @param path path to read
+ * @param type expected return type (will try to convert)
+ * @param filters filters
+ * @param
+ * @return result
+ */
+ T read(String path, Class type, Predicate... filters);
+
/**
* Reads the given path from this context
*
@@ -42,4 +53,16 @@ public interface ReadContext {
*/
T read(JsonPath path);
+ /**
+ * Reads the given path from this context
+ *
+ * @param path path to apply
+ * @param type expected return type (will try to convert)
+ * @param
+ * @return result
+ */
+ T read(JsonPath path, Class type);
+
+
+
}
diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/JsonReader.java b/json-path/src/main/java/com/jayway/jsonpath/internal/JsonReader.java
index db04142a..526e12c6 100644
--- a/json-path/src/main/java/com/jayway/jsonpath/internal/JsonReader.java
+++ b/json-path/src/main/java/com/jayway/jsonpath/internal/JsonReader.java
@@ -5,6 +5,7 @@ import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.ParseContext;
import com.jayway.jsonpath.Predicate;
import com.jayway.jsonpath.ReadContext;
+import com.jayway.jsonpath.spi.converter.ConverterFactory;
import com.jayway.jsonpath.spi.http.HttpProviderFactory;
import java.io.File;
@@ -92,10 +93,24 @@ public class JsonReader implements ParseContext, ReadContext {
return read(JsonPath.compile(path, filters));
}
+ @Override
+ public T read(String path, Class type, Predicate... filters) {
+ return convert(read(path, filters), type);
+ }
+
@Override
public T read(JsonPath path) {
notNull(path, "path can not be null");
return path.read(json, configuration);
}
+ @Override
+ public T read(JsonPath path, Class type) {
+ return convert(read(path), type);
+ }
+
+ private T convert(Object obj, Class type){
+ return ConverterFactory.createConverter(type).convert(obj, configuration);
+ }
+
}
diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/converter/Converter.java b/json-path/src/main/java/com/jayway/jsonpath/spi/converter/Converter.java
new file mode 100644
index 00000000..7271c913
--- /dev/null
+++ b/json-path/src/main/java/com/jayway/jsonpath/spi/converter/Converter.java
@@ -0,0 +1,7 @@
+package com.jayway.jsonpath.spi.converter;
+
+import com.jayway.jsonpath.Configuration;
+
+public interface Converter{
+ T convert(Object o, Configuration conf);
+}
\ No newline at end of file
diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/converter/ConverterFactory.java b/json-path/src/main/java/com/jayway/jsonpath/spi/converter/ConverterFactory.java
new file mode 100644
index 00000000..de7f87a1
--- /dev/null
+++ b/json-path/src/main/java/com/jayway/jsonpath/spi/converter/ConverterFactory.java
@@ -0,0 +1,174 @@
+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, Converter>> converters = new ConcurrentHashMap, 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 Converter createConverter(Class target){
+ Converter converter = (Converter) converters.get(target);
+ if(converter == null){
+ converter = new Converter() {
+ @Override
+ public T convert(Object o, Configuration conf) {
+ return (T)o;
+ }
+ };
+ }
+ return converter;
+ }
+
+ public static void registerConverter(Class target, Converter converter){
+ converters.put(target, converter);
+ }
+
+ public static void unRegisterConverter(Class target){
+ converters.remove(target);
+ }
+
+ private static class StringConverter implements Converter {
+ @Override
+ public String convert(Object o, Configuration conf) {
+ if(o == null){
+ return null;
+ } else {
+ return o.toString();
+ }
+ }
+ }
+
+ private static class DateConverter implements Converter {
+ @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 {
+ @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 {
+ @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 {
+ @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 {
+ @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());
+ }
+ }
+}
+
+
+
+
+
+
+
diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonProvider.java b/json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonProvider.java
index 599bbf06..726bbc50 100644
--- a/json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonProvider.java
+++ b/json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonProvider.java
@@ -32,14 +32,12 @@ public interface JsonProvider {
Object parse(InputStream jsonStream) throws InvalidJsonException;
-
String toJson(Object obj);
Object createMap();
Object createArray();
-
Object clone(Object model);
/**
diff --git a/json-path/src/test/java/com/jayway/jsonpath/BaseTest.java b/json-path/src/test/java/com/jayway/jsonpath/BaseTest.java
index a2c81b73..4aed81a4 100644
--- a/json-path/src/test/java/com/jayway/jsonpath/BaseTest.java
+++ b/json-path/src/test/java/com/jayway/jsonpath/BaseTest.java
@@ -4,10 +4,12 @@ public class BaseTest {
public static final String JSON_DOCUMENT = "{\n" +
" \"string-property\" : \"string-value\", \n" +
- " \"int-property\" : " + Integer.MAX_VALUE + ", \n" +
- " \"long-property\" : " + Long.MAX_VALUE + ", \n" +
+ " \"int-max-property\" : " + Integer.MAX_VALUE + ", \n" +
+ " \"long-max-property\" : " + Long.MAX_VALUE + ", \n" +
+ " \"long-max-property\" : " + Long.MAX_VALUE + ", \n" +
" \"boolean-property\" : true, \n" +
" \"null-property\" : null, \n" +
+ " \"int-small-property\" : 1, \n" +
" \"store\" : {\n" +
" \"book\" : [\n" +
" {\n" +
diff --git a/json-path/src/test/java/com/jayway/jsonpath/ConverterTest.java b/json-path/src/test/java/com/jayway/jsonpath/ConverterTest.java
new file mode 100644
index 00000000..95294aee
--- /dev/null
+++ b/json-path/src/test/java/com/jayway/jsonpath/ConverterTest.java
@@ -0,0 +1,45 @@
+package com.jayway.jsonpath;
+
+import org.junit.Test;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import static com.jayway.jsonpath.JsonPath.parse;
+import static java.util.Collections.singletonMap;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ConverterTest extends BaseTest {
+
+ @Test
+ public void an_Integer_can_be_converted_to_a_Long() {
+ assertThat(parse(singletonMap("val", 1)).read("val", Long.class)).isEqualTo(1L);
+ }
+
+ @Test
+ public void an_String_can_be_converted_to_a_Long() {
+ assertThat(parse(singletonMap("val", "1")).read("val", Long.class)).isEqualTo(1L);
+ }
+
+ @Test
+ public void an_Integer_can_be_converted_to_a_String() {
+ assertThat(parse(singletonMap("val", 1)).read("val", String.class)).isEqualTo("1");
+ }
+
+ @Test
+ public void an_Integer_can_be_converted_to_a_Double() {
+ assertThat(parse(singletonMap("val", 1)).read("val", Double.class)).isEqualTo(1D);
+ }
+
+ @Test
+ public void a_BigDecimal_can_be_converted_to_a_Long() {
+ assertThat(parse(singletonMap("val", new BigDecimal(1.5D))).read("val", Long.class)).isEqualTo(1L);
+ }
+
+ @Test
+ public void a_Long_can_be_converted_to_a_Date() {
+ Date now = new Date();
+ assertThat(parse(singletonMap("val", now.getTime())).read("val", Date.class)).isEqualTo(now);
+ }
+
+}
diff --git a/json-path/src/test/java/com/jayway/jsonpath/OptionsTest.java b/json-path/src/test/java/com/jayway/jsonpath/OptionsTest.java
new file mode 100644
index 00000000..672f33b6
--- /dev/null
+++ b/json-path/src/test/java/com/jayway/jsonpath/OptionsTest.java
@@ -0,0 +1,16 @@
+package com.jayway.jsonpath;
+
+import org.junit.Test;
+
+public class OptionsTest extends BaseTest {
+
+
+ @Test
+ public void leafs_can_be_defaulted_to_null() {
+
+ //assertThat(parse(singletonMap("foo", "bar"))).
+
+ }
+
+
+}
diff --git a/json-path/src/test/java/com/jayway/jsonpath/ReturnTypeTest.java b/json-path/src/test/java/com/jayway/jsonpath/ReturnTypeTest.java
index d54071b5..8a6bc601 100644
--- a/json-path/src/test/java/com/jayway/jsonpath/ReturnTypeTest.java
+++ b/json-path/src/test/java/com/jayway/jsonpath/ReturnTypeTest.java
@@ -3,52 +3,53 @@ package com.jayway.jsonpath;
import org.junit.Test;
import java.util.List;
+import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
@SuppressWarnings("ALL")
public class ReturnTypeTest extends BaseTest {
+ private static ReadContext reader = JsonPath.parse(JSON_DOCUMENT);
+
@Test
public void assert_strings_can_be_read() {
- assertThat(JsonPath.read(JSON_DOCUMENT, "$.string-property")).isEqualTo("string-value");
+ assertThat(reader.read("$.string-property")).isEqualTo("string-value");
}
@Test
public void assert_ints_can_be_read() {
- assertThat(JsonPath.read(JSON_DOCUMENT, "$.int-property")).isEqualTo(Integer.MAX_VALUE);
+ assertThat(reader.read("$.int-max-property")).isEqualTo(Integer.MAX_VALUE);
}
@Test
public void assert_longs_can_be_read() {
- assertThat(JsonPath.read(JSON_DOCUMENT, "$.long-property")).isEqualTo(Long.MAX_VALUE);
+ assertThat(reader.read("$.long-max-property")).isEqualTo(Long.MAX_VALUE);
}
@Test
public void assert_boolean_values_can_be_read() {
- assertThat(JsonPath.read(JSON_DOCUMENT, "$.boolean-property")).isEqualTo(true);
+ assertThat(reader.read("$.boolean-property")).isEqualTo(true);
}
@Test
public void assert_null_values_can_be_read() {
- assertThat(JsonPath.read(JSON_DOCUMENT, "$.null-property")).isNull();
+ assertThat(reader.read("$.null-property")).isNull();
}
@Test
- public void assert_arrays_can_be_read_2() {
- List