• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind.ser;
2 
3 import java.util.*;
4 
5 import com.fasterxml.jackson.annotation.JsonInclude;
6 import com.fasterxml.jackson.core.JsonGenerator;
7 import com.fasterxml.jackson.databind.*;
8 import com.fasterxml.jackson.databind.annotation.JsonAppend;
9 import com.fasterxml.jackson.databind.cfg.MapperConfig;
10 import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
11 import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
12 import com.fasterxml.jackson.databind.util.Annotations;
13 
14 /**
15  * Tests for verifying that one can append virtual properties after regular ones.
16  *
17  * @since 2.5
18  */
19 public class TestVirtualProperties extends BaseMapTest
20 {
21     @JsonAppend(attrs={ @JsonAppend.Attr("id"),
22         @JsonAppend.Attr(value="internal", propName="extra", required=true)
23     })
24     static class SimpleBean
25     {
26         public int value = 13;
27     }
28 
29     @JsonAppend(prepend=true, attrs={ @JsonAppend.Attr("id"),
30             @JsonAppend.Attr(value="internal", propName="extra")
31         })
32     static class SimpleBeanPrepend
33     {
34         public int value = 13;
35     }
36 
37     enum ABC {
38         A, B, C;
39     }
40 
41     @JsonAppend(attrs=@JsonAppend.Attr(value="desc", include=JsonInclude.Include.NON_EMPTY))
42     static class OptionalsBean
43     {
44         public int value = 28;
45     }
46 
47     @SuppressWarnings("serial")
48     static class CustomVProperty
49         extends VirtualBeanPropertyWriter
50     {
CustomVProperty()51         private CustomVProperty() { super(); }
52 
CustomVProperty(BeanPropertyDefinition propDef, Annotations ctxtAnn, JavaType type)53         private CustomVProperty(BeanPropertyDefinition propDef,
54                 Annotations ctxtAnn, JavaType type) {
55             super(propDef, ctxtAnn, type);
56         }
57 
58         @Override
value(Object bean, JsonGenerator jgen, SerializerProvider prov)59         protected Object value(Object bean, JsonGenerator jgen, SerializerProvider prov) {
60             if (_name.toString().equals("id")) {
61                 return "abc123";
62             }
63             if (_name.toString().equals("extra")) {
64                 return new int[] { 42 };
65             }
66             return "???";
67         }
68 
69         @Override
withConfig(MapperConfig<?> config, AnnotatedClass declaringClass, BeanPropertyDefinition propDef, JavaType type)70         public VirtualBeanPropertyWriter withConfig(MapperConfig<?> config,
71                 AnnotatedClass declaringClass, BeanPropertyDefinition propDef,
72                 JavaType type)
73         {
74             return new CustomVProperty(propDef, declaringClass.getAnnotations(), type);
75         }
76     }
77 
78     @JsonAppend(prepend=true, props={ @JsonAppend.Prop(value=CustomVProperty.class, name="id"),
79             @JsonAppend.Prop(value=CustomVProperty.class, name="extra")
80         })
81     static class CustomVBean
82     {
83         public int value = 72;
84     }
85 
86     /*
87     /**********************************************************
88     /* Test methods
89     /**********************************************************
90      */
91 
92     private final ObjectWriter WRITER = objectWriter();
93 
testAttributeProperties()94     public void testAttributeProperties() throws Exception
95     {
96         Map<String,Object> stuff = new LinkedHashMap<String,Object>();
97         stuff.put("x", 3);
98         stuff.put("y", ABC.B);
99 
100         String json = WRITER.withAttribute("id", "abc123")
101                 .withAttribute("internal", stuff)
102                 .writeValueAsString(new SimpleBean());
103         assertEquals(aposToQuotes("{'value':13,'id':'abc123','extra':{'x':3,'y':'B'}}"), json);
104 
105         json = WRITER.withAttribute("id", "abc123")
106                 .withAttribute("internal", stuff)
107                 .writeValueAsString(new SimpleBeanPrepend());
108         assertEquals(aposToQuotes("{'id':'abc123','extra':{'x':3,'y':'B'},'value':13}"), json);
109     }
110 
testAttributePropInclusion()111     public void testAttributePropInclusion() throws Exception
112     {
113         // first, with desc
114         String json = WRITER.withAttribute("desc", "nice")
115                 .writeValueAsString(new OptionalsBean());
116         assertEquals(aposToQuotes("{'value':28,'desc':'nice'}"), json);
117 
118         // then with null (not defined)
119         json = WRITER.writeValueAsString(new OptionalsBean());
120         assertEquals(aposToQuotes("{'value':28}"), json);
121 
122         // and finally "empty"
123         json = WRITER.withAttribute("desc", "")
124                 .writeValueAsString(new OptionalsBean());
125         assertEquals(aposToQuotes("{'value':28}"), json);
126     }
127 
testCustomProperties()128     public void testCustomProperties() throws Exception
129     {
130         String json = WRITER.withAttribute("desc", "nice")
131                 .writeValueAsString(new CustomVBean());
132         assertEquals(aposToQuotes("{'id':'abc123','extra':[42],'value':72}"), json);
133     }
134 }
135