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