diff --git a/src/main/java/com/fasterxml/jackson/databind/annotation/JsonIgnoreIf.java b/src/main/java/com/fasterxml/jackson/databind/annotation/JsonIgnoreIf.java new file mode 100644 index 0000000000..539918e0c1 --- /dev/null +++ b/src/main/java/com/fasterxml/jackson/databind/annotation/JsonIgnoreIf.java @@ -0,0 +1,32 @@ +package com.fasterxml.jackson.databind.annotation; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.deser.JsonIgnoreValidator; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marker annotation that indicates that the logical property that + * the accessor (field, getter/setter method or Creator parameter + * [of {@link JsonCreator}-annotated constructor or factory method]) + * is to be ignored by introspection-based + * serialization and deserialization functionality in case the customized + * check of {@link JsonIgnoreValidator} + * returned false. + */ +@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.TYPE, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +@com.fasterxml.jackson.annotation.JacksonAnnotation +public @interface JsonIgnoreIf +{ + + /** + * Required Argument that defines the class exstending the {@link JsonIgnoreValidator} + * which is used to check if the property can be ignored. + */ + public Class value(); + +} \ No newline at end of file diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/JsonIgnoreValidator.java b/src/main/java/com/fasterxml/jackson/databind/deser/JsonIgnoreValidator.java new file mode 100644 index 0000000000..cb52050953 --- /dev/null +++ b/src/main/java/com/fasterxml/jackson/databind/deser/JsonIgnoreValidator.java @@ -0,0 +1,21 @@ +package com.fasterxml.jackson.databind.deser; + +import com.fasterxml.jackson.databind.annotation.JsonIgnoreIf; + +/** + * Abstract class which .class reference will be used to + * validate if a property annoated with {@link JsonIgnoreIf} + * should be ignored or not. + */ +public abstract class JsonIgnoreValidator { + + /** + * When instantiating this class this abstract method should be defined. + * The logic will be executed and checked if property should be ignored + * or not. + * + * @return When returning true the property will not be parsed. When returning false not. + */ + public abstract boolean ignore(); + +} \ No newline at end of file diff --git a/src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java b/src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java index c8bebb5199..33b44d2d96 100644 --- a/src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java +++ b/src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java @@ -10,6 +10,7 @@ import com.fasterxml.jackson.databind.annotation.*; import com.fasterxml.jackson.databind.cfg.HandlerInstantiator; import com.fasterxml.jackson.databind.cfg.MapperConfig; +import com.fasterxml.jackson.databind.deser.JsonIgnoreValidator; import com.fasterxml.jackson.databind.ext.Java7Support; import com.fasterxml.jackson.databind.jsontype.NamedType; import com.fasterxml.jackson.databind.jsontype.TypeIdResolver; @@ -1430,6 +1431,15 @@ protected boolean _isIgnorable(Annotated a) if (ann != null) { return ann.value(); } + JsonIgnoreIf jsonIgnoreIfAnn = _findAnnotation(a, JsonIgnoreIf.class); + if(jsonIgnoreIfAnn != null) { + try { + JsonIgnoreValidator jsonIgnoreValidator = jsonIgnoreIfAnn.value().newInstance(); + return jsonIgnoreValidator.ignore(); + } catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + } + } if (_java7Helper != null) { Boolean b = _java7Helper.findTransient(a); if (b != null) { diff --git a/src/test/java/com/fasterxml/jackson/databind/ser/filter/TestSimpleSerializationIgnoreIf.java b/src/test/java/com/fasterxml/jackson/databind/ser/filter/TestSimpleSerializationIgnoreIf.java new file mode 100644 index 0000000000..76d79738cd --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/databind/ser/filter/TestSimpleSerializationIgnoreIf.java @@ -0,0 +1,57 @@ +package com.fasterxml.jackson.databind.ser.filter; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.annotation.JsonIgnoreIf; +import com.fasterxml.jackson.databind.BaseMapTest; +import com.fasterxml.jackson.databind.deser.JsonIgnoreValidator; + +import java.util.Map; + +/** + * This unit test suite tests use of {@link JsonIgnoreIf} annotations + * with bean serialization. + */ +public class TestSimpleSerializationIgnoreIf + extends BaseMapTest +{ + + // Class representing simple JsonIgnoreValidator + public static class JsonIgnoreTrue extends JsonIgnoreValidator { + @Override + public boolean ignore() { + return true; + } + } + + // Class representing simple JsonIgnoreValidator + public static class JsonIgnoreFalse extends JsonIgnoreValidator { + @Override + public boolean ignore() { + return false; + } + } + + // Class for testing enabled {@link JsonIgnoreIf} annotation + final static class SizeClassEnabledIgnore + { + // should be seen + @JsonIgnoreIf(JsonIgnoreFalse.class) + public int x = 4; + + // should not be seen + @JsonIgnoreIf(JsonIgnoreTrue.class) + public int y = 2; + } + + private final ObjectMapper MAPPER = new ObjectMapper(); + + public void testSimpleIgnoreIf() throws Exception + { + // Should see "x", not "y" + Map result = writeAndMap(MAPPER, new TestSimpleSerializationIgnoreIf.SizeClassEnabledIgnore()); + assertEquals(1, result.size()); + assertEquals(Integer.valueOf(4), result.get("x")); + assertNull(result.get("y")); + } + +} \ No newline at end of file