package com.fasterxml.jackson.databind.introspect; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyName; /* Tests mostly for [JACKSON-754]: ability to create "annotation bundles" */ public class TestAnnotationBundles extends com.fasterxml.jackson.databind.BaseMapTest { @Retention(RetentionPolicy.RUNTIME) @JacksonAnnotationsInside @JsonIgnore private @interface MyIgnoral { } @Retention(RetentionPolicy.RUNTIME) @JacksonAnnotationsInside @JsonProperty("foobar") private @interface MyRename { } protected final static class Bean { @MyIgnoral public String getIgnored() { return "foo"; } @MyRename public int renamed = 13; } @Retention(RetentionPolicy.RUNTIME) @JsonAutoDetect(fieldVisibility=Visibility.NONE, getterVisibility=Visibility.NONE, isGetterVisibility=Visibility.NONE) @JacksonAnnotationsInside public @interface JsonAutoDetectOff {} @JsonAutoDetectOff public class NoAutoDetect { public int getA() { return 13; } @JsonProperty public int getB() { return 5; } } @Retention(RetentionPolicy.RUNTIME) @JacksonAnnotationsInside @JsonProperty("_id") public @interface Bundle92 {} public class Bean92 { @Bundle92 protected String id = "abc"; } @HolderB @JacksonAnnotationsInside @Retention(RetentionPolicy.RUNTIME) static @interface HolderA {} @HolderA @JacksonAnnotationsInside @Retention(RetentionPolicy.RUNTIME) static @interface HolderB {} static class RecursiveHolder { @HolderA public int unimportant = 42; } static class RecursiveHolder2 { @HolderA public int getValue() { return 28; } } static class RecursiveHolder3 { public int x; @JsonCreator @HolderA public RecursiveHolder3(int x) { this.x = x; } } @JsonProperty @JacksonAnnotationsInside @Retention(RetentionPolicy.RUNTIME) static @interface InformativeHolder { // doesn't really contribute to the test, but would be impossible without this feature boolean important() default true; } static class InformingHolder { @InformativeHolder public int unimportant = 42; } @SuppressWarnings("serial") static class BundleAnnotationIntrospector extends JacksonAnnotationIntrospector { @Override public PropertyName findNameForSerialization(Annotated a) { InformativeHolder informativeHolder = a.getAnnotation(InformativeHolder.class); if ((informativeHolder != null) && informativeHolder.important()) { return PropertyName.construct("important"); } return super.findNameForSerialization(a); } } /* /********************************************************** /* Test methods /********************************************************** */ private final ObjectMapper MAPPER = new ObjectMapper(); public void testKeepAnnotationBundle() throws Exception { MAPPER.setAnnotationIntrospector(new BundleAnnotationIntrospector()); assertEquals("{\"important\":42}", MAPPER.writeValueAsString(new InformingHolder())); } public void testRecursiveBundlesField() throws Exception { assertEquals("{\"unimportant\":42}", MAPPER.writeValueAsString(new RecursiveHolder())); } public void testRecursiveBundlesMethod() throws Exception { assertEquals("{\"value\":28}", MAPPER.writeValueAsString(new RecursiveHolder2())); } public void testRecursiveBundlesConstructor() throws Exception { RecursiveHolder3 result = MAPPER.readValue("17", RecursiveHolder3.class); assertNotNull(result); assertEquals(17, result.x); } public void testBundledIgnore() throws Exception { assertEquals("{\"foobar\":13}", MAPPER.writeValueAsString(new Bean())); } public void testVisibilityBundle() throws Exception { assertEquals("{\"b\":5}", MAPPER.writeValueAsString(new NoAutoDetect())); } public void testIssue92() throws Exception { assertEquals("{\"_id\":\"abc\"}", MAPPER.writeValueAsString(new Bean92())); } }