| package com.fasterxml.jackson.databind.introspect; |
| |
| import java.lang.reflect.Field; |
| import java.lang.reflect.Member; |
| import java.lang.reflect.Method; |
| |
| |
| import com.fasterxml.jackson.annotation.JsonAutoDetect; |
| import com.fasterxml.jackson.annotation.PropertyAccessor; |
| import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; |
| |
| /** |
| * Interface for object used for determine which property elements |
| * (methods, fields, constructors) can be auto-detected, with respect |
| * to their visibility modifiers. |
| *<p> |
| * Note on type declaration: funky recursive type is necessary to |
| * support builder/fluent pattern. |
| */ |
| public interface VisibilityChecker<T extends VisibilityChecker<T>> |
| { |
| // // Builder methods |
| |
| /** |
| * Builder method that will return an instance that has same |
| * settings as this instance has, except for values that |
| * given annotation overrides. |
| */ |
| public T with(JsonAutoDetect ann); |
| |
| /** |
| * Method that can be used for merging default values from `this` |
| * instance with specified overrides; and either return `this` |
| * if overrides had no effect (that is, result would be equal), |
| * or a new instance with merged visibility settings. |
| * |
| * @since 2.9 |
| */ |
| public T withOverrides(JsonAutoDetect.Value vis); |
| |
| /** |
| * Builder method that will create and return an instance that has specified |
| * {@link Visibility} value to use for all property elements. |
| * Typical usage would be something like: |
| *<pre> |
| * mapper.setVisibilityChecker( |
| * mapper.getVisibilityChecker().with(Visibility.NONE)); |
| *</pre> |
| * (which would basically disable all auto-detection) |
| */ |
| public T with(Visibility v); |
| |
| /** |
| * Builder method that will create and return an instance that has specified |
| * {@link Visibility} value to use for specified property. |
| * Typical usage would be: |
| *<pre> |
| * mapper.setVisibilityChecker( |
| * mapper.getVisibilityChecker().withVisibility(JsonMethod.FIELD, Visibility.ANY)); |
| *</pre> |
| * (which would basically enable auto-detection for all member fields) |
| */ |
| public T withVisibility(PropertyAccessor method, Visibility v); |
| |
| /** |
| * Builder method that will return a checker instance that has |
| * specified minimum visibility level for regular ("getXxx") getters. |
| */ |
| public T withGetterVisibility(Visibility v); |
| |
| /** |
| * Builder method that will return a checker instance that has |
| * specified minimum visibility level for "is-getters" ("isXxx"). |
| */ |
| public T withIsGetterVisibility(Visibility v); |
| |
| /** |
| * Builder method that will return a checker instance that has |
| * specified minimum visibility level for setters. |
| */ |
| public T withSetterVisibility(Visibility v); |
| |
| /** |
| * Builder method that will return a checker instance that has |
| * specified minimum visibility level for creator methods |
| * (constructors, factory methods) |
| */ |
| public T withCreatorVisibility(Visibility v); |
| |
| /** |
| * Builder method that will return a checker instance that has |
| * specified minimum visibility level for fields. |
| */ |
| public T withFieldVisibility(Visibility v); |
| |
| // // Accessors |
| |
| /** |
| * Method for checking whether given method is auto-detectable |
| * as regular getter, with respect to its visibility (not considering |
| * method signature or name, just visibility) |
| */ |
| public boolean isGetterVisible(Method m); |
| public boolean isGetterVisible(AnnotatedMethod m); |
| |
| /** |
| * Method for checking whether given method is auto-detectable |
| * as is-getter, with respect to its visibility (not considering |
| * method signature or name, just visibility) |
| */ |
| public boolean isIsGetterVisible(Method m); |
| public boolean isIsGetterVisible(AnnotatedMethod m); |
| |
| /** |
| * Method for checking whether given method is auto-detectable |
| * as setter, with respect to its visibility (not considering |
| * method signature or name, just visibility) |
| */ |
| public boolean isSetterVisible(Method m); |
| public boolean isSetterVisible(AnnotatedMethod m); |
| |
| /** |
| * Method for checking whether given method is auto-detectable |
| * as Creator, with respect to its visibility (not considering |
| * method signature or name, just visibility) |
| */ |
| public boolean isCreatorVisible(Member m); |
| public boolean isCreatorVisible(AnnotatedMember m); |
| |
| /** |
| * Method for checking whether given field is auto-detectable |
| * as property, with respect to its visibility (not considering |
| * method signature or name, just visibility) |
| */ |
| public boolean isFieldVisible(Field f); |
| public boolean isFieldVisible(AnnotatedField f); |
| |
| /* |
| /******************************************************** |
| /* Standard implementation suitable for basic use |
| /******************************************************** |
| */ |
| |
| /** |
| * Default standard implementation is purely based on visibility |
| * modifier of given class members, and its configured minimum |
| * levels. |
| * Implemented using "builder" (or "Fluent") pattern, whereas instances |
| * are immutable, and configuration is achieved by chainable factory |
| * methods. As a result, type is declared is funky recursive generic |
| * type, to allow for sub-classing of build methods with property type |
| * co-variance. |
| */ |
| public static class Std |
| implements VisibilityChecker<Std>, |
| java.io.Serializable |
| { |
| private static final long serialVersionUID = 1; |
| |
| /** |
| * This is the canonical base instance, configured with default |
| * visibility values |
| */ |
| protected final static Std DEFAULT = new Std( |
| Visibility.PUBLIC_ONLY, // getter |
| Visibility.PUBLIC_ONLY, // is-getter |
| Visibility.ANY, // setter |
| Visibility.ANY, // creator -- legacy, to support single-arg ctors |
| Visibility.PUBLIC_ONLY // field |
| ); |
| |
| protected final Visibility _getterMinLevel; |
| protected final Visibility _isGetterMinLevel; |
| protected final Visibility _setterMinLevel; |
| protected final Visibility _creatorMinLevel; |
| protected final Visibility _fieldMinLevel; |
| |
| public static Std defaultInstance() { return DEFAULT; } |
| |
| /** |
| * Constructor used for building instance that has minumum visibility |
| * levels as indicated by given annotation instance |
| * |
| * @param ann Annotations to use for determining minimum visibility levels |
| */ |
| public Std(JsonAutoDetect ann) |
| { |
| // let's combine checks for enabled/disabled, with minimum level checks: |
| _getterMinLevel = ann.getterVisibility(); |
| _isGetterMinLevel = ann.isGetterVisibility(); |
| _setterMinLevel = ann.setterVisibility(); |
| _creatorMinLevel = ann.creatorVisibility(); |
| _fieldMinLevel = ann.fieldVisibility(); |
| } |
| |
| /** |
| * Constructor that allows directly specifying minimum visibility levels to use |
| */ |
| public Std(Visibility getter, Visibility isGetter, Visibility setter, |
| Visibility creator, Visibility field) |
| { |
| _getterMinLevel = getter; |
| _isGetterMinLevel = isGetter; |
| _setterMinLevel = setter; |
| _creatorMinLevel = creator; |
| _fieldMinLevel = field; |
| } |
| |
| /** |
| * Constructor that will assign given visibility value for all |
| * properties. |
| * |
| * @param v level to use for all property types |
| */ |
| public Std(Visibility v) |
| { |
| // typically we shouldn't get this value; but let's handle it if we do: |
| if (v == Visibility.DEFAULT) { |
| _getterMinLevel = DEFAULT._getterMinLevel; |
| _isGetterMinLevel = DEFAULT._isGetterMinLevel; |
| _setterMinLevel = DEFAULT._setterMinLevel; |
| _creatorMinLevel = DEFAULT._creatorMinLevel; |
| _fieldMinLevel = DEFAULT._fieldMinLevel; |
| } else { |
| _getterMinLevel = v; |
| _isGetterMinLevel = v; |
| _setterMinLevel = v; |
| _creatorMinLevel = v; |
| _fieldMinLevel = v; |
| } |
| } |
| |
| /** |
| * @since 2.9 |
| */ |
| public static Std construct(JsonAutoDetect.Value vis) { |
| return DEFAULT.withOverrides(vis); |
| } |
| |
| /* |
| /******************************************************** |
| /* Builder/fluent methods for instantiating configured |
| /* instances |
| /******************************************************** |
| */ |
| |
| protected Std _with(Visibility g, Visibility isG, Visibility s, |
| Visibility cr, Visibility f) { |
| if ((g == _getterMinLevel) |
| && (isG == _isGetterMinLevel) |
| && (s == _setterMinLevel) |
| && (cr == _creatorMinLevel) |
| && (f == _fieldMinLevel) |
| ) { |
| return this; |
| } |
| return new Std(g, isG, s, cr, f); |
| } |
| |
| @Override |
| public Std with(JsonAutoDetect ann) |
| { |
| Std curr = this; |
| if (ann != null) { |
| return _with( |
| _defaultOrOverride(_getterMinLevel, ann.getterVisibility()), |
| _defaultOrOverride(_isGetterMinLevel, ann.isGetterVisibility()), |
| _defaultOrOverride(_setterMinLevel, ann.setterVisibility()), |
| _defaultOrOverride(_creatorMinLevel, ann.creatorVisibility()), |
| _defaultOrOverride(_fieldMinLevel, ann.fieldVisibility()) |
| ); |
| } |
| return curr; |
| } |
| |
| @Override // since 2.9 |
| public Std withOverrides(JsonAutoDetect.Value vis) |
| { |
| Std curr = this; |
| if (vis != null) { |
| return _with( |
| _defaultOrOverride(_getterMinLevel, vis.getGetterVisibility()), |
| _defaultOrOverride(_isGetterMinLevel, vis.getIsGetterVisibility()), |
| _defaultOrOverride(_setterMinLevel, vis.getSetterVisibility()), |
| _defaultOrOverride(_creatorMinLevel, vis.getCreatorVisibility()), |
| _defaultOrOverride(_fieldMinLevel, vis.getFieldVisibility()) |
| ); |
| } |
| return curr; |
| } |
| |
| private Visibility _defaultOrOverride(Visibility defaults, Visibility override) { |
| if (override == Visibility.DEFAULT) { |
| return defaults; |
| } |
| return override; |
| } |
| |
| @Override |
| public Std with(Visibility v) |
| { |
| if (v == Visibility.DEFAULT) { |
| return DEFAULT; |
| } |
| return new Std(v); |
| } |
| |
| @Override |
| public Std withVisibility(PropertyAccessor method, Visibility v) |
| { |
| switch (method) { |
| case GETTER: |
| return withGetterVisibility(v); |
| case SETTER: |
| return withSetterVisibility(v); |
| case CREATOR: |
| return withCreatorVisibility(v); |
| case FIELD: |
| return withFieldVisibility(v); |
| case IS_GETTER: |
| return withIsGetterVisibility(v); |
| case ALL: |
| return with(v); |
| //case NONE: |
| default: |
| // break; |
| return this; |
| } |
| } |
| |
| @Override |
| public Std withGetterVisibility(Visibility v) { |
| if (v == Visibility.DEFAULT) v = DEFAULT._getterMinLevel; |
| if (_getterMinLevel == v) return this; |
| return new Std(v, _isGetterMinLevel, _setterMinLevel, _creatorMinLevel, _fieldMinLevel); |
| } |
| |
| @Override |
| public Std withIsGetterVisibility(Visibility v) { |
| if (v == Visibility.DEFAULT) v = DEFAULT._isGetterMinLevel; |
| if (_isGetterMinLevel == v) return this; |
| return new Std(_getterMinLevel, v, _setterMinLevel, _creatorMinLevel, _fieldMinLevel); |
| } |
| |
| @Override |
| public Std withSetterVisibility(Visibility v) { |
| if (v == Visibility.DEFAULT) v = DEFAULT._setterMinLevel; |
| if (_setterMinLevel == v) return this; |
| return new Std(_getterMinLevel, _isGetterMinLevel, v, _creatorMinLevel, _fieldMinLevel); |
| } |
| |
| @Override |
| public Std withCreatorVisibility(Visibility v) { |
| if (v == Visibility.DEFAULT) v = DEFAULT._creatorMinLevel; |
| if (_creatorMinLevel == v) return this; |
| return new Std(_getterMinLevel, _isGetterMinLevel, _setterMinLevel, v, _fieldMinLevel); |
| } |
| |
| @Override |
| public Std withFieldVisibility(Visibility v) { |
| if (v == Visibility.DEFAULT) v = DEFAULT._fieldMinLevel; |
| if (_fieldMinLevel == v) return this; |
| return new Std(_getterMinLevel, _isGetterMinLevel, _setterMinLevel, _creatorMinLevel, v); |
| } |
| |
| /* |
| /******************************************************** |
| /* Public API impl |
| /******************************************************** |
| */ |
| |
| @Override |
| public boolean isCreatorVisible(Member m) { |
| return _creatorMinLevel.isVisible(m); |
| } |
| |
| @Override |
| public boolean isCreatorVisible(AnnotatedMember m) { |
| return isCreatorVisible(m.getMember()); |
| } |
| |
| @Override |
| public boolean isFieldVisible(Field f) { |
| return _fieldMinLevel.isVisible(f); |
| } |
| |
| @Override |
| public boolean isFieldVisible(AnnotatedField f) { |
| return isFieldVisible(f.getAnnotated()); |
| } |
| |
| @Override |
| public boolean isGetterVisible(Method m) { |
| return _getterMinLevel.isVisible(m); |
| } |
| |
| @Override |
| public boolean isGetterVisible(AnnotatedMethod m) { |
| return isGetterVisible(m.getAnnotated()); |
| } |
| |
| @Override |
| public boolean isIsGetterVisible(Method m) { |
| return _isGetterMinLevel.isVisible(m); |
| } |
| |
| @Override |
| public boolean isIsGetterVisible(AnnotatedMethod m) { |
| return isIsGetterVisible(m.getAnnotated()); |
| } |
| |
| @Override |
| public boolean isSetterVisible(Method m) { |
| return _setterMinLevel.isVisible(m); |
| } |
| |
| @Override |
| public boolean isSetterVisible(AnnotatedMethod m) { |
| return isSetterVisible(m.getAnnotated()); |
| } |
| |
| /* |
| /******************************************************** |
| /* Standard methods |
| /******************************************************** |
| */ |
| |
| @Override |
| public String toString() { |
| return String.format("[Visibility: getter=%s,isGetter=%s,setter=%s,creator=%s,field=%s]", |
| _getterMinLevel, _isGetterMinLevel, _setterMinLevel, _creatorMinLevel, _fieldMinLevel); |
| } |
| } |
| } |