• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind.introspect;
2 
3 import java.lang.annotation.Retention;
4 import java.lang.annotation.RetentionPolicy;
5 
6 import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
7 import com.fasterxml.jackson.annotation.JsonAutoDetect;
8 import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
9 import com.fasterxml.jackson.annotation.JsonCreator;
10 import com.fasterxml.jackson.annotation.JsonIgnore;
11 import com.fasterxml.jackson.annotation.JsonProperty;
12 import com.fasterxml.jackson.databind.ObjectMapper;
13 import com.fasterxml.jackson.databind.PropertyName;
14 
15 /* Tests mostly for [JACKSON-754]: ability to create "annotation bundles"
16  */
17 public class TestAnnotationBundles extends com.fasterxml.jackson.databind.BaseMapTest
18 {
19     @Retention(RetentionPolicy.RUNTIME)
20     @JacksonAnnotationsInside
21     @JsonIgnore
22     private @interface MyIgnoral { }
23 
24     @Retention(RetentionPolicy.RUNTIME)
25     @JacksonAnnotationsInside
26     @JsonProperty("foobar")
27     private @interface MyRename { }
28 
29     protected final static class Bean {
30         @MyIgnoral
getIgnored()31         public String getIgnored() { return "foo"; }
32 
33         @MyRename
34         public int renamed = 13;
35     }
36 
37     @Retention(RetentionPolicy.RUNTIME)
38     @JsonAutoDetect(fieldVisibility=Visibility.NONE,
39             getterVisibility=Visibility.NONE, isGetterVisibility=Visibility.NONE)
40     @JacksonAnnotationsInside
41     public @interface JsonAutoDetectOff {}
42 
43     @JsonAutoDetectOff
44     public class NoAutoDetect {
getA()45       public int getA() { return 13; }
46 
47       @JsonProperty
getB()48       public int getB() { return 5; }
49     }
50 
51     @Retention(RetentionPolicy.RUNTIME)
52     @JacksonAnnotationsInside
53     @JsonProperty("_id")
54     public @interface Bundle92 {}
55 
56     public class Bean92 {
57         @Bundle92
58         protected String id = "abc";
59     }
60 
61     @HolderB
62     @JacksonAnnotationsInside
63     @Retention(RetentionPolicy.RUNTIME)
64     static @interface HolderA {}
65 
66     @HolderA
67     @JacksonAnnotationsInside
68     @Retention(RetentionPolicy.RUNTIME)
69     static @interface HolderB {}
70 
71     static class RecursiveHolder {
72         @HolderA public int unimportant = 42;
73     }
74 
75     static class RecursiveHolder2 {
getValue()76         @HolderA public int getValue() { return 28; }
77     }
78 
79     static class RecursiveHolder3 {
80         public int x;
81 
82         @JsonCreator
83         @HolderA
RecursiveHolder3(int x)84         public RecursiveHolder3(int x) { this.x = x; }
85     }
86 
87     @JsonProperty
88     @JacksonAnnotationsInside
89     @Retention(RetentionPolicy.RUNTIME)
90     static @interface InformativeHolder {
91         // doesn't really contribute to the test, but would be impossible without this feature
important()92         boolean important() default true;
93     }
94 
95     static class InformingHolder {
96         @InformativeHolder public int unimportant = 42;
97     }
98 
99     @SuppressWarnings("serial")
100     static class BundleAnnotationIntrospector extends JacksonAnnotationIntrospector {
101         @Override
findNameForSerialization(Annotated a)102         public PropertyName findNameForSerialization(Annotated a)
103         {
104             InformativeHolder informativeHolder = a.getAnnotation(InformativeHolder.class);
105             if ((informativeHolder != null) && informativeHolder.important()) {
106                 return PropertyName.construct("important");
107             }
108             return super.findNameForSerialization(a);
109         }
110     }
111 
112     /*
113     /**********************************************************
114     /* Test methods
115     /**********************************************************
116      */
117 
118     private final ObjectMapper MAPPER = new ObjectMapper();
119 
testKeepAnnotationBundle()120     public void testKeepAnnotationBundle() throws Exception
121     {
122         MAPPER.setAnnotationIntrospector(new BundleAnnotationIntrospector());
123         assertEquals("{\"important\":42}", MAPPER.writeValueAsString(new InformingHolder()));
124     }
125 
testRecursiveBundlesField()126     public void testRecursiveBundlesField() throws Exception {
127         assertEquals("{\"unimportant\":42}", MAPPER.writeValueAsString(new RecursiveHolder()));
128     }
129 
testRecursiveBundlesMethod()130     public void testRecursiveBundlesMethod() throws Exception {
131         assertEquals("{\"value\":28}", MAPPER.writeValueAsString(new RecursiveHolder2()));
132     }
133 
testRecursiveBundlesConstructor()134     public void testRecursiveBundlesConstructor() throws Exception {
135         RecursiveHolder3 result = MAPPER.readValue("17", RecursiveHolder3.class);
136         assertNotNull(result);
137         assertEquals(17, result.x);
138     }
139 
testBundledIgnore()140     public void testBundledIgnore() throws Exception
141     {
142         assertEquals("{\"foobar\":13}", MAPPER.writeValueAsString(new Bean()));
143     }
144 
testVisibilityBundle()145     public void testVisibilityBundle() throws Exception
146     {
147         assertEquals("{\"b\":5}", MAPPER.writeValueAsString(new NoAutoDetect()));
148     }
149 
testIssue92()150     public void testIssue92() throws Exception
151     {
152         assertEquals("{\"_id\":\"abc\"}", MAPPER.writeValueAsString(new Bean92()));
153     }
154 }
155