diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonNodeJsonProvider.java b/json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonNodeJsonProvider.java index c47c65c8..f755c07e 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonNodeJsonProvider.java +++ b/json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonNodeJsonProvider.java @@ -12,6 +12,7 @@ import com.jayway.jsonpath.JsonPathException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; @@ -151,12 +152,13 @@ public class JacksonJsonNodeJsonProvider extends AbstractJsonProvider { } } - @Override - public void setProperty(Object obj, Object key, Object value) { - if (isMap(obj)) - toJsonObject(obj).put(key.toString(), createJsonElement(value)); - else { - ArrayNode array = toJsonArray(obj); + @Override + public void setProperty(Object obj, Object key, Object value) { + // jlolling: Bug: #211 avoid create cloned nodes + if (isMap(obj)) { + setValueInObjectNode((ObjectNode) obj, key, value); + } else { + ArrayNode array = (ArrayNode) obj; int index; if (key != null) { index = key instanceof Integer ? (Integer) key : Integer.parseInt(key.toString()); @@ -169,11 +171,8 @@ public class JacksonJsonNodeJsonProvider extends AbstractJsonProvider { array.set(index, createJsonElement(value)); } } - } - - + } - @SuppressWarnings("unchecked") public void removeProperty(Object obj, Object key) { if (isMap(obj)) toJsonObject(obj).remove(key.toString()); @@ -226,7 +225,16 @@ public class JacksonJsonNodeJsonProvider extends AbstractJsonProvider { } private JsonNode createJsonElement(Object o) { - return objectMapper.valueToTree(o); + if (o != null) { + // jlolling: avoid creating a cloned node: bug #211 + if (o instanceof JsonNode) { + return (JsonNode) o; + } else { + return objectMapper.valueToTree(o); + } + } else { + return null; + } } private ArrayNode toJsonArray(Object o) { @@ -237,5 +245,33 @@ public class JacksonJsonNodeJsonProvider extends AbstractJsonProvider { return (ObjectNode) o; } + private void setValueInObjectNode(ObjectNode objectNode, Object key, Object value) { + // jlolling: necessary to avoid deprecated methods and to avoid creating a cloned node. Bug: #211 + if (value instanceof JsonNode) { + objectNode.set(key.toString(), (JsonNode) value); + } else if (value instanceof String) { + objectNode.put(key.toString(), (String) value); + } else if (value instanceof Integer) { + objectNode.put(key.toString(), (Integer) value); + } else if (value instanceof Long) { + objectNode.put(key.toString(), (Long) value); + } else if (value instanceof Short) { + objectNode.put(key.toString(), (Short) value); + } else if (value instanceof Double) { + objectNode.put(key.toString(), (Double) value); + } else if (value instanceof Float) { + objectNode.put(key.toString(), (Float) value); + } else if (value instanceof BigDecimal) { + objectNode.put(key.toString(), (BigDecimal) value); + } else if (value instanceof Boolean) { + objectNode.put(key.toString(), (Boolean) value); + } else if (value instanceof byte[]) { + objectNode.put(key.toString(), (byte[]) value); + } else if (value == null) { + objectNode.remove(key.toString()); + } else { + throw new IllegalArgumentException("Cannot handle object type: " + value.getClass().getName()); + } + } } diff --git a/json-path/src/test/java/com/jayway/jsonpath/JacksonJsonNodeJsonProviderTest.java b/json-path/src/test/java/com/jayway/jsonpath/JacksonJsonNodeJsonProviderTest.java index 595fb14e..09401682 100644 --- a/json-path/src/test/java/com/jayway/jsonpath/JacksonJsonNodeJsonProviderTest.java +++ b/json-path/src/test/java/com/jayway/jsonpath/JacksonJsonNodeJsonProviderTest.java @@ -2,6 +2,7 @@ package com.jayway.jsonpath; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; import com.jayway.jsonpath.spi.mapper.MappingException; import org.junit.Test; @@ -42,6 +43,20 @@ public class JacksonJsonNodeJsonProviderTest extends BaseTest { assertThat(node.get("string-property").asText()).isEqualTo("string-value"); } + @Test + public void always_return_same_object() { // Test because of Bug #211 + DocumentContext context = using(JACKSON_JSON_NODE_CONFIGURATION).parse(JSON_DOCUMENT); + ObjectNode node1 = context.read("$"); + ObjectNode child1 = new ObjectNode(JsonNodeFactory.instance); + child1.put("name", "test"); + context.put("$", "child", child1); + ObjectNode node2 = context.read("$"); + ObjectNode child2 = context.read("$.child"); + + assertThat(node1).isSameAs(node2); + assertThat(child1).isSameAs(child2); + } + @Test public void strings_are_unwrapped() { JsonNode node = using(JACKSON_JSON_NODE_CONFIGURATION).parse(JSON_DOCUMENT).read("$.string-property");