Browse Source

Bug fixed: #211 setProperty and setArrayIndex set/add cloned nodes

pull/212/head
Jan Lolling 8 years ago
parent
commit
a1605a167b
  1. 58
      json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonNodeJsonProvider.java
  2. 15
      json-path/src/test/java/com/jayway/jsonpath/JacksonJsonNodeJsonProviderTest.java

58
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());
}
}
}

15
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");

Loading…
Cancel
Save