Skip to content

Commit

Permalink
Fix #1829: change JsonNode.deepCopy() return type to safer (#4832)
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder authored Dec 5, 2024
1 parent 6701b43 commit 12f5afc
Show file tree
Hide file tree
Showing 15 changed files with 29 additions and 14 deletions.
2 changes: 2 additions & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ Versions: 3.x (for earlier see VERSION-2.x)
(reported by timo-schmid@github)
#1789: Add `createGenerator` methods in `ObjectMapper`, `ObjectWriter`
#1790: Add `createParser` methods in `ObjectMapper`, `ObjectReader`
#1829: `JsonNode.deepCopy() `ClassCastException`s
(reported by @D3v01dZA)
#1883: Add "abstract type mapping" for deserialization from `Map<ENUMTYPE,V>`
into `EnumMap` (and `Set<ENUMTYPE>` to `EnumSet<EnumType>`)
#1888: Merge `ResolvableSerializer` into `JsonSerializer`, `ResolvableDeserializer`
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/tools/jackson/databind/JsonNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ protected JsonNode() { }
* @return Node that is either a copy of this node (and all non-leaf
* children); or, for immutable leaf nodes, node itself.
*/
public abstract <T extends JsonNode> T deepCopy();
public abstract JsonNode deepCopy();

/*
/**********************************************************************
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ protected int _firstHyphenOrUnderscore(String str)
return -1;
}

@SuppressWarnings("deprecation") // Locale constructors deprecated in JDK 19
private Locale _deserializeLocale(String fullValue, DeserializationContext ctxt)
throws JacksonException
{
Expand Down
1 change: 0 additions & 1 deletion src/main/java/tools/jackson/databind/node/ArrayNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ protected JsonNode _at(JsonPointer ptr) {
}

// note: co-variant to allow caller-side type safety
@SuppressWarnings("unchecked")
@Override
public ArrayNode deepCopy()
{
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/tools/jackson/databind/node/BooleanNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ public JsonNodeType getNodeType() {
return _value ? JsonToken.VALUE_TRUE : JsonToken.VALUE_FALSE;
}

@Override
public BooleanNode deepCopy() { return this; }

@Override
public boolean booleanValue() {
return _value;
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/tools/jackson/databind/node/MissingNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,8 @@ protected Object readResolve() {
}

// Immutable: no need to copy
@SuppressWarnings("unchecked")
@Override
public <T extends JsonNode> T deepCopy() { return (T) this; }
public MissingNode deepCopy() { return this; }

public static MissingNode getInstance() { return instance; }

Expand Down
3 changes: 3 additions & 0 deletions src/main/java/tools/jackson/databind/node/NullNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ public JsonNodeType getNodeType() {

@Override public JsonToken asToken() { return JsonToken.VALUE_NULL; }

@Override
public NullNode deepCopy() { return this; }

@Override
public String asText(String defaultValue) { return defaultValue; }

Expand Down
4 changes: 4 additions & 0 deletions src/main/java/tools/jackson/databind/node/NumericNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ public final JsonNodeType getNodeType()
return JsonNodeType.NUMBER;
}

// Overridden for type co-variance
@Override
public NumericNode deepCopy() { return this; }

// // // Let's re-abstract so sub-classes handle them

@Override
Expand Down
1 change: 0 additions & 1 deletion src/main/java/tools/jackson/databind/node/ObjectNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ protected JsonNode _at(JsonPointer ptr) {
* have to, as long as sub-types override the method but...
*/
// note: co-variant for type safety
@SuppressWarnings("unchecked")
@Override
public ObjectNode deepCopy()
{
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/tools/jackson/databind/node/TextNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ public JsonNodeType getNodeType() {

@Override public JsonToken asToken() { return JsonToken.VALUE_STRING; }

@Override
public TextNode deepCopy() { return this; }

@Override
public String textValue() {
return _value;
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/tools/jackson/databind/node/ValueNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,8 @@ protected JsonNode _at(JsonPointer ptr) {
* All current value nodes are immutable, so we can just return
* them as is.
*/
@SuppressWarnings("unchecked")
@Override
public <T extends JsonNode> T deepCopy() { return (T) this; }
public ValueNode deepCopy() { return this; }

@Override public abstract JsonToken asToken();

Expand Down
10 changes: 4 additions & 6 deletions src/test/java/tools/jackson/databind/ObjectReaderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -554,9 +554,8 @@ public void serializeWithType(JsonGenerator g, SerializationContext ctxt, TypeSe
}

@Override
@SuppressWarnings("unchecked")
public <T extends JsonNode> T deepCopy() {
return (T) new CustomObjectNode(_delegate);
public CustomObjectNode deepCopy() {
return new CustomObjectNode(_delegate);
}

@Override
Expand Down Expand Up @@ -675,9 +674,8 @@ public void serializeWithType(JsonGenerator g, SerializationContext ctxt, TypeSe
}

@Override
@SuppressWarnings("unchecked")
public <T extends JsonNode> T deepCopy() {
return (T) new DelegatingArrayNode(_delegate);
public DelegatingArrayNode deepCopy() {
return new DelegatingArrayNode(_delegate);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
import static tools.jackson.databind.testutil.DatabindTestUtil.newJsonMapper;
import static tools.jackson.databind.testutil.DatabindTestUtil.q;

// Tests for `java.util.Locale`
// Tests for `java.util.Locale`.
// NOTE: warnings are due to JDK 19 deprecating Locale constructors
@SuppressWarnings("deprecation")
public class LocaleDeserTest
{
private final Locale[] LOCALES = new Locale[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ static class Id953 {
public int someId;
}

@SuppressWarnings("deprecation") // Locale constructors deprecated in JDK 19
private final Locale LOCALE_EN = new Locale("en", "US");

private final ObjectMapper INSENSITIVE_MAPPER_EN = jsonMapperBuilder()
.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
.defaultLocale(LOCALE_EN)
.build();

@SuppressWarnings("deprecation") // Locale constructors deprecated in JDK 19
private final Locale LOCALE_TR = new Locale("tr", "TR");

private final ObjectMapper INSENSITIVE_MAPPER_TR = jsonMapperBuilder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ public void testCurrency() throws IOException
assertEquals(q("USD"), MAPPER.writeValueAsString(usd));
}

@SuppressWarnings("deprecation")
@Test
public void testLocale() throws IOException
{
Expand Down

0 comments on commit 12f5afc

Please sign in to comment.