blob: ab198d4928bda8cc4548e2ce0a754979772bbb2f [file] [log] [blame]
package com.fasterxml.jackson.failing;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.*;
import com.fasterxml.jackson.databind.deser.std.CollectionDeserializer;
import com.fasterxml.jackson.databind.deser.std.DelegatingDeserializer;
import com.fasterxml.jackson.databind.type.CollectionLikeType;
public class NodeContext2049Test extends BaseMapTest
{
public interface HasParent {
void setParent(Parent parent);
Parent getParent();
}
static class Child implements HasParent {
public Parent parent;
public String property;
@Override
public void setParent(Parent p) { parent = p; }
@Override
public Parent getParent() { return parent; }
}
static class Parent {
public List<Child> children;
public Child singleChild;
}
static class ListValueInstantiator extends ValueInstantiator {
@Override
public String getValueTypeDesc() {
return List.class.getName();
}
@Override
public Object createUsingDefault(DeserializationContext ctxt) throws IOException {
return new ArrayList<>();
}
}
static class ParentSettingDeserializerModifier extends BeanDeserializerModifier {
@Override
public BeanDeserializerBuilder updateBuilder(DeserializationConfig config, BeanDescription beanDesc,
BeanDeserializerBuilder builder) {
for (Iterator<SettableBeanProperty> propertyIt = builder.getProperties(); propertyIt.hasNext(); ) {
SettableBeanProperty property = propertyIt.next();
builder.addOrReplaceProperty(property.withValueDeserializer(new ParentSettingDeserializerContextual()), false);
}
return builder;
}
}
@SuppressWarnings("serial")
static class ParentSettingDeserializer extends DelegatingDeserializer {
public ParentSettingDeserializer(JsonDeserializer<?> delegatee) {
super(delegatee);
}
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
Object retValue = super.deserialize(jp, ctxt);
if (retValue instanceof HasParent) {
HasParent obj = (HasParent) retValue;
Parent parent = null;
JsonStreamContext parsingContext = jp.getParsingContext();
while (parent == null && parsingContext != null) {
Object currentValue = parsingContext.getCurrentValue();
if (currentValue != null && currentValue instanceof Parent) {
parent = (Parent) currentValue;
}
parsingContext = parsingContext.getParent();
}
if (parent != null) {
obj.setParent(parent);
}
}
return retValue;
}
@Override
protected JsonDeserializer<?> newDelegatingInstance(JsonDeserializer<?> newDelegatee) {
return new ParentSettingDeserializer(newDelegatee);
}
}
static class ParentSettingDeserializerContextual extends JsonDeserializer<Object> implements ContextualDeserializer {
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property)
throws JsonMappingException {
JavaType propertyType = property.getType();
JavaType contentType = propertyType;
if (propertyType.isCollectionLikeType()) {
contentType = propertyType.getContentType();
}
JsonDeserializer<Object> delegatee = ctxt.findNonContextualValueDeserializer(contentType);
JsonDeserializer<Object> objectDeserializer = new ParentSettingDeserializer(delegatee);
JsonDeserializer<?> retValue;
if (propertyType.isCollectionLikeType()) {
CollectionLikeType collectionType = ctxt.getTypeFactory().constructCollectionLikeType(propertyType.getRawClass(),
contentType);
ValueInstantiator instantiator = new ListValueInstantiator();
retValue = new CollectionDeserializer(collectionType, objectDeserializer, null, instantiator);
} else {
retValue = objectDeserializer;
}
return retValue;
}
@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
// TODO Auto-generated method stub
return null;
}
}
/*
/**********************************************************************
/* Test methods
/**********************************************************************
*/
private ObjectMapper objectMapper;
{
objectMapper = new ObjectMapper();
objectMapper.registerModule(new Module() {
@Override
public String getModuleName() {
return "parentSetting";
}
@Override
public Version version() {
return Version.unknownVersion();
}
@Override
public void setupModule(SetupContext context) {
context.addBeanDeserializerModifier(new ParentSettingDeserializerModifier());
}
});
}
final static String JSON = "{\n" +
" \"children\": [\n" +
" {\n" +
" \"property\": \"value1\"\n" +
" },\n" +
" {\n" +
" \"property\": \"value2\"\n" +
" }\n" +
" ],\n" +
" \"singleChild\": {\n" +
" \"property\": \"value3\"\n" +
" }\n" +
"}";
public void testReadNoBuffering() throws IOException {
Parent obj = objectMapper.readerFor(Parent.class).readValue(JSON);
assertSame(obj, obj.singleChild.getParent());
for (Child child : obj.children) {
assertSame(obj, child.getParent());
}
}
public void testReadFromTree() throws IOException {
JsonNode tree = objectMapper.readTree(JSON);
Parent obj = objectMapper.reader().forType(Parent.class).readValue(tree);
assertSame(obj, obj.singleChild.getParent());
for (Child child : obj.children) {
assertSame(obj, child.getParent());
}
}
}