• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind.struct;
2 
3 import java.io.IOException;
4 import java.util.Map;
5 import java.util.TreeMap;
6 
7 import com.fasterxml.jackson.annotation.*;
8 
9 import com.fasterxml.jackson.databind.*;
10 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
11 
12 // Unit test for [JACKSON-890]
13 public class TestBackRefsWithPolymorphic extends BaseMapTest
14 {
15     @JsonPropertyOrder(alphabetic=true)
16     interface Entity
17     {
getEntityType()18         @JsonIgnore String getEntityType();
getId()19         Long getId();
setId(Long id)20         void setId(Long id);
setPersistable()21         @JsonIgnore void setPersistable();
22     }
23 
24     @JsonDeserialize(as = NestedPropertySheetImpl.class)
25     interface NestedPropertySheet
26         extends Property<PropertySheet>
27     {
getValue()28         @Override PropertySheet getValue();
setValue(PropertySheet propertySheet)29         void setValue(PropertySheet propertySheet);
30     }
31 
32     @JsonDeserialize(as = AbstractProperty.class)
33     @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS,
34         include  = JsonTypeInfo.As.PROPERTY,
35         property = "@class")
36     interface Property<T> extends Entity
37     {
getName()38         String getName();
getParentSheet()39         PropertySheet getParentSheet();
getValue()40         T getValue();
setName(String name)41         void setName(String name);
setParentSheet(PropertySheet parentSheet)42         void setParentSheet(PropertySheet parentSheet);
43     }
44 
45     @JsonDeserialize(as = PropertySheetImpl.class)
46     @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS,
47         include  = JsonTypeInfo.As.PROPERTY,
48         property = "@class")
49     @SuppressWarnings("rawtypes")
50     interface PropertySheet extends Entity
51     {
addProperty(Property property)52         void addProperty(Property property);
getProperties()53         Map<String, Property> getProperties();
setProperties(Map<String, Property> properties)54         void setProperties(Map<String, Property> properties);
55     }
56 
57     @JsonDeserialize(as = StringPropertyImpl.class)
58     interface StringProperty
59         extends Property<String>
60     {
getValue()61         @Override String getValue();
setValue(String value)62         void setValue(String value);
63     }
64 
65     static class AbstractEntity implements Entity
66     {
67         private long id;
68 
getEntityType()69         @Override public String getEntityType() {
70             return "";
71         }
72 
getId()73         @Override public Long getId() {
74             return id;
75         }
76 
setId(Long id)77         @Override public void setId(Long id)
78         {
79             this.id = id;
80         }
81 
setPersistable()82         @Override public void setPersistable() { }
83     }
84 
85     abstract static class AbstractProperty<T>
86         extends AbstractEntity
87         implements Property<T>
88     {
89         private String        m_name;
90         private PropertySheet m_parentSheet;
91 
AbstractProperty()92         protected AbstractProperty() { }
93 
AbstractProperty(String name)94         protected AbstractProperty(String name) {
95             m_name = name;
96         }
97 
getName()98         @Override public String getName() {
99             return m_name;
100         }
101 
102         @JsonBackReference("propertySheet-properties")
getParentSheet()103         @Override public PropertySheet getParentSheet() {
104             return m_parentSheet;
105         }
106 
setName(String name)107         @Override public void setName(String name) {
108             m_name = name;
109         }
110 
setParentSheet(PropertySheet parentSheet)111         @Override public void setParentSheet(PropertySheet parentSheet) {
112             m_parentSheet = parentSheet;
113         }
114     }
115 
116     @JsonPropertyOrder(alphabetic=true)
117     static class NestedPropertySheetImpl
118         extends AbstractProperty<PropertySheet>
119         implements NestedPropertySheet
120     {
121         private PropertySheet m_propertySheet;
122 
NestedPropertySheetImpl(String name, PropertySheet propertySheet)123         protected NestedPropertySheetImpl(String name,
124                 PropertySheet propertySheet)
125         {
126             super(name);
127             m_propertySheet = propertySheet;
128         }
129 
NestedPropertySheetImpl()130         NestedPropertySheetImpl() { }
131 
getValue()132         @Override public PropertySheet getValue() {
133             return m_propertySheet;
134         }
135 
setValue(PropertySheet propertySheet)136         @Override public void setValue(PropertySheet propertySheet) {
137             m_propertySheet = propertySheet;
138         }
139     }
140 
141     @SuppressWarnings("rawtypes")
142     static class PropertySheetImpl
143         extends AbstractEntity
144         implements PropertySheet
145     {
146         private Map<String, Property> m_properties;
147 
addProperty(Property property)148         @Override public void addProperty(Property property)
149         {
150             if (m_properties == null) {
151                 m_properties = new TreeMap<String, Property>();
152             }
153             property.setParentSheet(this);
154             m_properties.put(property.getName(), property);
155         }
156 
157         @JsonDeserialize(as = TreeMap.class,
158             keyAs     = String.class,
159             contentAs = Property.class)
160         @JsonManagedReference("propertySheet-properties")
getProperties()161         @Override public Map<String, Property> getProperties() {
162             return m_properties;
163         }
164 
setProperties(Map<String, Property> properties)165         @Override public void setProperties(Map<String, Property> properties) {
166             m_properties = properties;
167         }
168     }
169 
170     static class StringPropertyImpl
171         extends AbstractProperty<String>
172         implements StringProperty
173     {
174         private String m_value;
175 
StringPropertyImpl(String name, String value)176         public StringPropertyImpl(String name, String value) {
177             super(name);
178             m_value = value;
179         }
180 
StringPropertyImpl()181         StringPropertyImpl() { }
182 
getValue()183         @Override public String getValue() {
184             return m_value;
185         }
186 
setValue(String value)187         @Override public void setValue(String value) {
188             m_value = value;
189         }
190     }
191 
192     static class YetAnotherClass extends StringPropertyImpl { }
193 
194     /*
195     /**********************************************************
196     /* Test methods
197     /**********************************************************
198      */
199 
200     private final String CLASS_NAME = getClass().getName();
201     // NOTE: order is arbitrary, test is fragile... has to work for now
202     private final String JSON =
203         "{\"@class\":\""+CLASS_NAME+"$PropertySheetImpl\",\"id\":0,\"properties\":{\"p1name\":{\"@class\":"
204             +"\"" +CLASS_NAME+ "$StringPropertyImpl\",\"id\":0,\"name\":\"p1name\",\"value\":\"p1value\"},"
205             +"\"p2name\":{\"@class\":\""+CLASS_NAME+"$StringPropertyImpl\",\"id\":0,"
206             +"\"name\":\"p2name\",\"value\":\"p2value\"}}}";
207 
208     private final ObjectMapper MAPPER = new ObjectMapper();
209 
testDeserialize()210     public void testDeserialize() throws IOException
211     {
212         PropertySheet input = MAPPER.readValue(JSON, PropertySheet.class);
213         assertEquals(JSON, MAPPER.writeValueAsString(input));
214     }
215 
testSerialize()216     public void testSerialize() throws IOException
217     {
218         PropertySheet sheet = new PropertySheetImpl();
219 
220         sheet.addProperty(new StringPropertyImpl("p1name", "p1value"));
221         sheet.addProperty(new StringPropertyImpl("p2name", "p2value"));
222         String actual = MAPPER.writeValueAsString(sheet);
223         assertEquals(JSON, actual);
224     }
225 }
226