• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind.node;
2 
3 import java.io.IOException;
4 import java.util.ArrayList;
5 import java.util.Iterator;
6 import java.util.List;
7 
8 import com.fasterxml.jackson.core.*;
9 
10 import com.fasterxml.jackson.databind.*;
11 import com.fasterxml.jackson.databind.deser.*;
12 import com.fasterxml.jackson.databind.deser.std.CollectionDeserializer;
13 import com.fasterxml.jackson.databind.deser.std.DelegatingDeserializer;
14 import com.fasterxml.jackson.databind.type.CollectionLikeType;
15 
16 public class NodeContext2049Test extends BaseMapTest
17 {
18     public interface HasParent {
setParent(Parent parent)19         void setParent(Parent parent);
getParent()20         Parent getParent();
21     }
22 
23     static class Child implements HasParent {
24         public Parent parent;
25         public String property;
26 
27         @Override
setParent(Parent p)28         public void setParent(Parent p) { parent = p; }
29         @Override
getParent()30         public Parent getParent() { return parent; }
31     }
32 
33     static class Parent {
34         public List<Child> children;
35         public Child singleChild;
36     }
37 
38     static class ListValueInstantiator extends ValueInstantiator {
39         @Override
getValueTypeDesc()40         public String getValueTypeDesc() {
41              return List.class.getName();
42         }
43 
44         @Override
createUsingDefault(DeserializationContext ctxt)45         public Object createUsingDefault(DeserializationContext ctxt) throws IOException {
46              return new ArrayList<>();
47         }
48     }
49 
50     static class ParentSettingDeserializerModifier extends BeanDeserializerModifier {
51         @Override
updateBuilder(DeserializationConfig config, BeanDescription beanDesc, BeanDeserializerBuilder builder)52         public BeanDeserializerBuilder updateBuilder(DeserializationConfig config, BeanDescription beanDesc,
53                   BeanDeserializerBuilder builder) {
54              for (Iterator<SettableBeanProperty> propertyIt = builder.getProperties(); propertyIt.hasNext(); ) {
55                   SettableBeanProperty property = propertyIt.next();
56                   builder.addOrReplaceProperty(property.withValueDeserializer(new ParentSettingDeserializerContextual()), false);
57              }
58              return builder;
59         }
60     }
61 
62     @SuppressWarnings("serial")
63     static class ParentSettingDeserializer extends DelegatingDeserializer {
ParentSettingDeserializer(JsonDeserializer<?> delegatee)64         public ParentSettingDeserializer(JsonDeserializer<?> delegatee) {
65              super(delegatee);
66         }
67 
68         @Override
deserialize(JsonParser jp, DeserializationContext ctxt)69         public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
70              Object retValue = super.deserialize(jp, ctxt);
71              if (retValue instanceof HasParent) {
72                   HasParent obj = (HasParent) retValue;
73                   Parent parent = null;
74                   JsonStreamContext parsingContext = jp.getParsingContext();
75                   while (parent == null && parsingContext != null) {
76                        Object currentValue = parsingContext.getCurrentValue();
77                        if (currentValue != null && currentValue instanceof Parent) {
78                             parent = (Parent) currentValue;
79                        }
80                        parsingContext = parsingContext.getParent();
81                   }
82                   if (parent != null) {
83                        obj.setParent(parent);
84                   }
85              }
86              return retValue;
87         }
88 
89         @Override
newDelegatingInstance(JsonDeserializer<?> newDelegatee)90         protected JsonDeserializer<?> newDelegatingInstance(JsonDeserializer<?> newDelegatee) {
91              return new ParentSettingDeserializer(newDelegatee);
92         }
93 
94    }
95 
96     static class ParentSettingDeserializerContextual extends JsonDeserializer<Object> implements ContextualDeserializer {
97 
98         @Override
createContextual(DeserializationContext ctxt, BeanProperty property)99         public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property)
100                   throws JsonMappingException {
101              JavaType propertyType = property.getType();
102              JavaType contentType = propertyType;
103              if (propertyType.isCollectionLikeType()) {
104                   contentType = propertyType.getContentType();
105              }
106              JsonDeserializer<Object> delegatee = ctxt.findNonContextualValueDeserializer(contentType);
107              JsonDeserializer<Object> objectDeserializer = new ParentSettingDeserializer(delegatee);
108              JsonDeserializer<?> retValue;
109              if (propertyType.isCollectionLikeType()) {
110                   CollectionLikeType collectionType = ctxt.getTypeFactory().constructCollectionLikeType(propertyType.getRawClass(),
111                             contentType);
112                   ValueInstantiator instantiator = new ListValueInstantiator();
113                   retValue = new CollectionDeserializer(collectionType, objectDeserializer, null, instantiator);
114              } else {
115                   retValue = objectDeserializer;
116              }
117              return retValue;
118         }
119 
120         @Override
deserialize(JsonParser p, DeserializationContext ctxt)121         public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
122              // TODO Auto-generated method stub
123              return null;
124         }
125 
126    }
127 
128     /*
129     /**********************************************************************
130     /* Test methods
131     /**********************************************************************
132      */
133 
134     private ObjectMapper objectMapper;
135     {
136         objectMapper = new ObjectMapper();
objectMapper.registerModule(new com.fasterxml.jackson.databind.Module() { @Override public String getModuleName() { return "parentSetting"; } @Override public Version version() { return Version.unknownVersion(); } @Override public void setupModule(SetupContext context) { context.addBeanDeserializerModifier(new ParentSettingDeserializerModifier()); } })137         objectMapper.registerModule(new com.fasterxml.jackson.databind.Module() {
138               @Override
139               public String getModuleName() {
140                    return "parentSetting";
141               }
142               @Override
143               public Version version() {
144                    return Version.unknownVersion();
145               }
146               @Override
147               public void setupModule(SetupContext context) {
148                    context.addBeanDeserializerModifier(new ParentSettingDeserializerModifier());
149               }
150          });
151     }
152 
153     final static String JSON = "{\n" +
154             "     \"children\": [\n" +
155             "          {\n" +
156             "               \"property\": \"value1\"\n" +
157             "          },\n" +
158             "          {\n" +
159             "               \"property\": \"value2\"\n" +
160             "          }\n" +
161             "     ],\n" +
162             "     \"singleChild\": {\n" +
163             "          \"property\": \"value3\"\n" +
164             "     }\n" +
165             "}";
166 
testReadNoBuffering()167     public void testReadNoBuffering() throws IOException {
168         Parent obj = objectMapper.readerFor(Parent.class).readValue(JSON);
169         assertSame(obj, obj.singleChild.getParent());
170         for (Child child : obj.children) {
171             assertSame(obj, child.getParent());
172         }
173     }
174 
testReadFromTree()175     public void testReadFromTree() throws IOException {
176         JsonNode tree = objectMapper.readTree(JSON);
177         Parent obj = objectMapper.reader().forType(Parent.class).readValue(tree);
178         assertSame(obj, obj.singleChild.getParent());
179         for (Child child : obj.children) {
180             assertSame(obj, child.getParent());
181         }
182     }
183 }
184