Skip to content

Commit

Permalink
Enhance StdNodeBasedDeserializer to facilitate usage with `ObjectMa…
Browse files Browse the repository at this point in the history
…pper#readerForUpdating` (#3860)
  • Loading branch information
JooHyukKim authored Apr 6, 2023
1 parent 158a68b commit aeffef7
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 3 deletions.
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);
}
}

0 comments on commit aeffef7

Please sign in to comment.