Skip to content

Commit

Permalink
Add failing test for #2049
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed May 25, 2018
1 parent 0e06d15 commit 93e82dd
Showing 1 changed file with 181 additions and 0 deletions.
181 changes: 181 additions & 0 deletions src/test/java/com/fasterxml/jackson/failing/NodeContext2049Test.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
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;

public void setParent(Parent p) { parent = p; }
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());
}
}
}

0 comments on commit 93e82dd

Please sign in to comment.