Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance StdNodeBasedDeserializer to facilitate usage with ObjectMapper#readerForUpdating #3860

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,19 @@ public void resolve(DeserializationContext ctxt) throws JsonMappingException {

public abstract T convert(JsonNode root, DeserializationContext ctxt) throws IOException;

/**
* Facilitates usage with {@link ObjectMapper#readerForUpdating(Object)} and {@link #deserialize(JsonParser, DeserializationContext, Object)}
* by eliminating the need to manually convert the value to a {@link JsonNode}.
*
* If this method is not overridden, it falls back to the behavior of {@link #convert(JsonNode, DeserializationContext)}.
*
* @since 2.15
*/
public T convert(JsonNode root, DeserializationContext ctxt, T newValue) throws IOException {
ctxt.handleBadMerge(this);
return convert(root, ctxt);
}

/*
/**********************************************************
/* JsonDeserializer impl
Expand All @@ -73,6 +86,18 @@ public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOExcept
return convert(n, ctxt);
}

/**
*
* Added to support {@link #convert(JsonNode, DeserializationContext, Object)}
*
* @since 2.15
*/
@Override
public T deserialize(JsonParser jp, DeserializationContext ctxt, T newValue) throws IOException {
JsonNode n = (JsonNode) _treeDeserializer.deserialize(jp, ctxt);
return convert(n, ctxt, newValue);
}

@Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt,
TypeDeserializer td)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.deser.std.StdNodeBasedDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;

import static org.junit.Assert.assertArrayEquals;
Expand Down Expand Up @@ -115,6 +116,61 @@ public AnimalWrapper deserialize(JsonParser json, DeserializationContext context
}
}

@JsonDeserialize(using = Custom3814DeserializerA.class)
static class Bean3814A {
public int age;

public Bean3814A(int age) {
this.age = age;
}

public void updateTo(JsonNode root) {
age = root.get("age").asInt();
}
}

static class Custom3814DeserializerA extends StdNodeBasedDeserializer<Bean3814A> {
public Custom3814DeserializerA() {
super(Bean3814A.class);
}

@Override
public Bean3814A convert(JsonNode root, DeserializationContext ctxt) throws IOException {
return null;
}

@Override
public Bean3814A convert(JsonNode root, DeserializationContext ctxt, Bean3814A oldValue) throws IOException {
oldValue.updateTo(root);
return oldValue;
}
}

@JsonDeserialize(using = Custom3814DeserializerB.class)
static class Bean3814B {
public int age;

public Bean3814B(int age) {
this.age = age;
}

public void updateTo(JsonNode root) {
age = root.get("age").asInt();
}
}

static class Custom3814DeserializerB extends StdNodeBasedDeserializer<Bean3814B> {
public Custom3814DeserializerB() {
super(Bean3814B.class);
}

@Override
public Bean3814B convert(JsonNode root, DeserializationContext ctxt) throws IOException {
return null;
}

}

/*
/********************************************************
/* Test methods
Expand Down Expand Up @@ -233,7 +289,7 @@ public void testUpdatingWithViews() throws Exception
}

// [databind#744]
public void testIssue744() throws IOException
public void testIssue744() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
Expand Down Expand Up @@ -274,7 +330,7 @@ public void testIssue744() throws IOException
}

// [databind#1831]
public void test1831UsingNode() throws IOException {
public void test1831UsingNode() throws Exception {
String catJson = MAPPER.writeValueAsString(new Cat());
JsonNode jsonNode = MAPPER.readTree(catJson);
AnimalWrapper optionalCat = new AnimalWrapper();
Expand All @@ -283,10 +339,38 @@ public void test1831UsingNode() throws IOException {
assertSame(optionalCat, result);
}

public void test1831UsingString() throws IOException {
public void test1831UsingString() throws Exception {
String catJson = MAPPER.writeValueAsString(new Cat());
AnimalWrapper optionalCat = new AnimalWrapper();
AnimalWrapper result = MAPPER.readerForUpdating(optionalCat).readValue(catJson);
assertSame(optionalCat, result);
}

// [databind#3814]
public void testReaderForUpdating3814() throws Exception {
// Arrange
JsonNode root = MAPPER.readTree(a2q("{'age': 30 }"));
Bean3814A obj = new Bean3814A(25);

// Act
Bean3814A newObj = MAPPER.readerForUpdating(obj).readValue(root);

// Assert
assertSame(obj, newObj);
assertEquals(30, newObj.age);
}

// [databind#3814]
public void testReaderForUpdating3814DoesNotOverride() throws Exception {
// Arrange
JsonNode root = MAPPER.readTree(a2q("{'age': 30 }"));
Bean3814B obj = new Bean3814B(25);

// Act
Bean3814B newObj = MAPPER.readerForUpdating(obj).readValue(root);

// Assert
assertNotSame(obj, newObj);
assertNull(newObj);
}
}