Skip to content

Commit

Permalink
Start work on #2336
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Aug 21, 2019
1 parent 5e4488a commit 152e3fa
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 9 deletions.
21 changes: 16 additions & 5 deletions src/main/java/com/fasterxml/jackson/databind/JsonDeserializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,8 @@ public abstract T deserialize(JsonParser p, DeserializationContext ctxt)
public T deserialize(JsonParser p, DeserializationContext ctxt, T intoValue)
throws IOException
{
if (ctxt.isEnabled(MapperFeature.IGNORE_MERGE_FOR_UNMERGEABLE)) {
return deserialize(p, ctxt);
}
throw new UnsupportedOperationException("Cannot update object of type "
+intoValue.getClass().getName()+" (by deserializer of type "+getClass().getName()+")");
ctxt.reportBadMerge(this);
return deserialize(p, ctxt);
}

/**
Expand All @@ -154,6 +151,20 @@ public Object deserializeWithType(JsonParser p, DeserializationContext ctxt,
return typeDeserializer.deserializeTypedFromAny(p, ctxt);
}

/**
* Method similar to {@link #deserializeWithType(JsonParser,DeserializationContext,TypeDeserializer)}
* but called when merging value.
*
* @since 2.10
*/
public Object deserializeWithType(JsonParser p, DeserializationContext ctxt,
TypeDeserializer typeDeserializer, T intoValue)
throws IOException
{
ctxt.reportBadMerge(this);
return typeDeserializer.deserializeTypedFromAny(p, ctxt);
}

/*
/**********************************************************
/* Fluent factory methods for constructing decorated versions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ public SettableBeanProperty findBackReference(String logicalName) {
/* Deserializer implementation
/**********************************************************
*/

@Override
public Object deserializeWithType(JsonParser p, DeserializationContext ctxt,
TypeDeserializer typeDeserializer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,11 @@ protected final void _readAndUpdate(JsonParser p, DeserializationContext ctxt,
Object old = result.get(key);
Object value;
if (old != null) {
value = valueDes.deserialize(p, ctxt, old);
if (typeDeser == null) {
value = valueDes.deserialize(p, ctxt, old);
} else {
value = valueDes.deserializeWithType(p, ctxt, typeDeser, old);
}
} else if (typeDeser == null) {
value = valueDes.deserialize(p, ctxt);
} else {
Expand All @@ -685,7 +689,7 @@ protected final void _readAndUpdate(JsonParser p, DeserializationContext ctxt,

/**
* Optimized method used when keys can be deserialized as plain old
* {@link java.lang.String}s, and there is no custom deserialized
* {@link java.lang.String}s, and there is no custom deserializer
* specified.
*
* @since 2.9
Expand Down Expand Up @@ -731,7 +735,11 @@ protected final void _readAndUpdateStringKeyMap(JsonParser p, DeserializationCon
Object old = result.get(key);
Object value;
if (old != null) {
value = valueDes.deserialize(p, ctxt, old);
if (typeDeser == null) {
value = valueDes.deserialize(p, ctxt, old);
} else {
value = valueDes.deserializeWithType(p, ctxt, typeDeser, old);
}
} else if (typeDeser == null) {
value = valueDes.deserialize(p, ctxt);
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package com.fasterxml.jackson.failing;

import java.util.LinkedHashMap;
import java.util.Map;

import com.fasterxml.jackson.annotation.*;

import com.fasterxml.jackson.databind.*;

public class MapPolymorphicMerge2336Test extends BaseMapTest
{
private final ObjectMapper MAPPER = sharedMapper();

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "discriminator"
//, visible = true
)
@JsonSubTypes({@JsonSubTypes.Type(value = SomeClassA.class, name = "FirstConcreteImpl")})
@JsonInclude(JsonInclude.Include.NON_NULL)
public static abstract class SomeBaseClass {
private String name;

@JsonCreator
public SomeBaseClass(@JsonProperty("name") String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

@JsonTypeName("FirstConcreteImpl")
public static class SomeClassA extends SomeBaseClass {
private Integer a;
private Integer b;

@JsonCreator
public SomeClassA(@JsonProperty("name") String name, @JsonProperty("a") Integer a, @JsonProperty("b") Integer b) {
super(name);
this.a = a;
this.b = b;
}

public Integer getA() {
return a;
}

public void setA(Integer a) {
this.a = a;
}

public Integer getB() {
return b;
}

public void setB(Integer b) {
this.b = b;
}
}

public static class SomeOtherClass {
String someprop;

@JsonCreator
public SomeOtherClass(@JsonProperty("someprop") String someprop) {
this.someprop = someprop;
}

@JsonMerge
private Map<String, SomeBaseClass> data = new LinkedHashMap<>();

public void addValue(String key, SomeBaseClass value) {
data.put(key, value);
}

public Map<String, SomeBaseClass> getData() {
return data;
}

public void setData(
Map<String, SomeBaseClass> data) {
this.data = data;
}
}

public void testPolymorphicMapMerge() throws Exception
{
// first let's just get some valid JSON
SomeOtherClass test = new SomeOtherClass("house");
test.addValue("SOMEKEY", new SomeClassA("fred", 1, null));
// String serializedValue = MAPPER.writeValueAsString(test);

//System.out.println("Serialized value: " + serializedValue);

// now create a reader specifically for merging
ObjectReader reader = MAPPER.readerForUpdating(test);

SomeOtherClass toBeMerged = new SomeOtherClass("house");
toBeMerged.addValue("SOMEKEY", new SomeClassA("jim", null, 2));
String jsonForMerging = MAPPER.writeValueAsString(toBeMerged);
System.out.println("JSON to be merged: " + jsonForMerging);
// now try to do the merge and it blows up
SomeOtherClass mergedResult = reader.readValue(jsonForMerging);
System.out.println("Serialized value: " + MAPPER.writeValueAsString(mergedResult));
}
}

0 comments on commit 152e3fa

Please sign in to comment.