From 291eabafda585ff95faeb647f146a3b803fb5af7 Mon Sep 17 00:00:00 2001 From: Benjamin Rogge Date: Sun, 12 Feb 2017 17:41:19 -0800 Subject: [PATCH] enable bigdecimal and -integer for GSONProvider --- .../jsonpath/spi/json/GsonJsonProvider.java | 48 +++++++++------ .../jayway/jsonpath/GsonJsonProviderTest.java | 61 +++++++++++++++++++ 2 files changed, 90 insertions(+), 19 deletions(-) diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/json/GsonJsonProvider.java b/json-path/src/main/java/com/jayway/jsonpath/spi/json/GsonJsonProvider.java index 7a2636a8..0828b295 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/spi/json/GsonJsonProvider.java +++ b/json-path/src/main/java/com/jayway/jsonpath/spi/json/GsonJsonProvider.java @@ -14,28 +14,25 @@ */ package com.jayway.jsonpath.spi.json; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; - -import java.math.BigDecimal; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; - import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; -import com.google.gson.internal.LazilyParsedNumber; - import com.jayway.jsonpath.InvalidJsonException; import com.jayway.jsonpath.JsonPathException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + public class GsonJsonProvider extends AbstractJsonProvider { private static final JsonParser PARSER = new JsonParser(); @@ -86,25 +83,38 @@ public class GsonJsonProvider extends AbstractJsonProvider { return o; } + private static boolean isPrimitiveNumber(final Number n) { + return n instanceof Integer || + n instanceof Double || + n instanceof Long || + n instanceof BigDecimal || + n instanceof BigInteger; + } + private static Number unwrapNumber(final Number n) { Number unwrapped; - if (n instanceof LazilyParsedNumber) { - LazilyParsedNumber lpn = (LazilyParsedNumber) n; - BigDecimal bigDecimal = new BigDecimal(lpn.toString()); + if (!isPrimitiveNumber(n)) { + BigDecimal bigDecimal = new BigDecimal(n.toString()); if (bigDecimal.scale() <= 0) { if (bigDecimal.compareTo(new BigDecimal(Integer.MAX_VALUE)) <= 0) { unwrapped = bigDecimal.intValue(); - } else { + } else if (bigDecimal.compareTo(new BigDecimal(Long.MAX_VALUE)) <= 0){ unwrapped = bigDecimal.longValue(); + } else { + unwrapped = bigDecimal; } } else { - unwrapped = bigDecimal.doubleValue(); + final double doubleValue = bigDecimal.doubleValue(); + if (BigDecimal.valueOf(doubleValue).compareTo(bigDecimal) != 0) { + unwrapped = bigDecimal; + } else { + unwrapped = doubleValue; + } } } else { unwrapped = n; } - return unwrapped; } diff --git a/json-path/src/test/java/com/jayway/jsonpath/GsonJsonProviderTest.java b/json-path/src/test/java/com/jayway/jsonpath/GsonJsonProviderTest.java index 8f3ec333..1fc85bd9 100644 --- a/json-path/src/test/java/com/jayway/jsonpath/GsonJsonProviderTest.java +++ b/json-path/src/test/java/com/jayway/jsonpath/GsonJsonProviderTest.java @@ -7,6 +7,8 @@ import com.jayway.jsonpath.spi.mapper.MappingException; import org.junit.Test; import java.io.IOException; +import java.math.BigDecimal; +import java.math.BigInteger; import java.util.List; import static com.jayway.jsonpath.JsonPath.using; @@ -69,6 +71,65 @@ public class GsonJsonProviderTest extends BaseTest { assertThat(val).isEqualTo(node.getAsLong()); } + @Test + public void doubles_are_unwrapped() { + final String json = "{double-property = 56.78}"; + + JsonElement node = using(GSON_CONFIGURATION).parse(json).read("$.double-property"); + Double val = using(GSON_CONFIGURATION).parse(json).read("$.double-property", Double.class); + + assertThat(val).isEqualTo(56.78); + assertThat(val).isEqualTo(node.getAsDouble()); + } + + @Test + public void bigdecimals_are_unwrapped() { + final BigDecimal bd = BigDecimal.valueOf(Long.MAX_VALUE).add(BigDecimal.valueOf(10.5)); + final String json = "{bd-property = " + bd.toString() + "}"; + + JsonElement node = using(GSON_CONFIGURATION).parse(json).read("$.bd-property"); + BigDecimal val = using(GSON_CONFIGURATION).parse(json).read("$.bd-property", BigDecimal.class); + + assertThat(val).isEqualTo(bd); + assertThat(val).isEqualTo(node.getAsBigDecimal()); + } + + @Test + public void small_bigdecimals_are_unwrapped() { + final BigDecimal bd = BigDecimal.valueOf(10.5); + final String json = "{bd-property = " + bd.toString() + "}"; + + JsonElement node = using(GSON_CONFIGURATION).parse(json).read("$.bd-property"); + BigDecimal val = using(GSON_CONFIGURATION).parse(json).read("$.bd-property", BigDecimal.class); + + assertThat(val).isEqualTo(bd); + assertThat(val).isEqualTo(node.getAsBigDecimal()); + } + + @Test + public void bigintegers_are_unwrapped() { + final BigInteger bi = BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.TEN); + final String json = "{bi-property = " + bi.toString() + "}"; + + JsonElement node = using(GSON_CONFIGURATION).parse(json).read("$.bi-property"); + BigInteger val = using(GSON_CONFIGURATION).parse(json).read("$.bi-property", BigInteger.class); + + assertThat(val).isEqualTo(bi); + assertThat(val).isEqualTo(node.getAsBigInteger()); + } + + @Test + public void small_bigintegers_are_unwrapped() { + final BigInteger bi = BigInteger.valueOf(Long.MAX_VALUE); + final String json = "{bi-property = " + bi.toString() + "}"; + + JsonElement node = using(GSON_CONFIGURATION).parse(json).read("$.bi-property"); + BigInteger val = using(GSON_CONFIGURATION).parse(json).read("$.bi-property", BigInteger.class); + + assertThat(val).isEqualTo(bi); + assertThat(val).isEqualTo(node.getAsBigInteger()); + } + @Test public void int_to_long_mapping() { assertThat(using(GSON_CONFIGURATION).parse("{\"val\": 1}").read("val", Long.class)).isEqualTo(1L);