VisibilityChecker.java
package tools.jackson.databind.introspect;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.PropertyAccessor;
/**
* Interface for object used for determine which property elements
* (methods, fields, constructors) can be auto-detected, with respect
* to their visibility modifiers.
*/
public class VisibilityChecker
implements java.io.Serializable
{
private static final long serialVersionUID = 1;
/**
* This is the canonical base instance, configured with default
* visibility values
*/
protected final static VisibilityChecker DEFAULT = new VisibilityChecker(
Visibility.PUBLIC_ONLY, // field
Visibility.PUBLIC_ONLY, // getter
Visibility.PUBLIC_ONLY, // is-getter
Visibility.ANY, // setter
Visibility.PUBLIC_ONLY, // creator -- NOTE: was `ANY` for 2.x
Visibility.NON_PRIVATE // scalar-constructor (new in 3.x)
);
// Added in 2.13 to be used for JDK types
protected final static VisibilityChecker ALL_PUBLIC = new VisibilityChecker(
Visibility.PUBLIC_ONLY, // field
Visibility.PUBLIC_ONLY, // getter
Visibility.PUBLIC_ONLY, // is-getter
Visibility.PUBLIC_ONLY, // setter
Visibility.PUBLIC_ONLY, // creator -- NOTE: was `ANY` for 2.x
Visibility.PUBLIC_ONLY // scalar-constructor (new in 3.x)
);
/**
* Visibility settings needed to support auto-discovery of non-private
* Records.
*
* @since 3.0
*/
protected final static VisibilityChecker ALL_PUBLIC_EXCEPT_CREATORS = new VisibilityChecker(
Visibility.PUBLIC_ONLY, // field
Visibility.PUBLIC_ONLY, // getter
Visibility.PUBLIC_ONLY, // is-getter
Visibility.PUBLIC_ONLY, // setter
// 26-Oct-2023, tatu: For [databind#4175] change from NON_PRIVATE to ANY
Visibility.ANY, // creator
Visibility.ANY // scalar-constructor (1 arg)
);
protected final Visibility _fieldMinLevel;
protected final Visibility _getterMinLevel;
protected final Visibility _isGetterMinLevel;
protected final Visibility _setterMinLevel;
protected final Visibility _creatorMinLevel;
protected final Visibility _scalarConstructorMinLevel;
/**
* 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 VisibilityChecker(JsonAutoDetect ann)
{
// let's combine checks for enabled/disabled, with minimum level checks:
_fieldMinLevel = ann.fieldVisibility();
_getterMinLevel = ann.getterVisibility();
_isGetterMinLevel = ann.isGetterVisibility();
_setterMinLevel = ann.setterVisibility();
_creatorMinLevel = ann.creatorVisibility();
_scalarConstructorMinLevel = ann.scalarConstructorVisibility();
}
/**
* Constructor that allows directly specifying minimum visibility levels to use
*/
public VisibilityChecker(Visibility field,
Visibility getter, Visibility isGetter, Visibility setter,
Visibility creator, Visibility scalarConstructor)
{
_getterMinLevel = getter;
_isGetterMinLevel = isGetter;
_setterMinLevel = setter;
_creatorMinLevel = creator;
_fieldMinLevel = field;
_scalarConstructorMinLevel = scalarConstructor;
}
/**
* Constructor that will assign given visibility value for all
* properties.
*
* @param v level to use for all property types
*/
public VisibilityChecker(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;
_scalarConstructorMinLevel = DEFAULT._scalarConstructorMinLevel;
} else {
_getterMinLevel = v;
_isGetterMinLevel = v;
_setterMinLevel = v;
_creatorMinLevel = v;
_fieldMinLevel = v;
_scalarConstructorMinLevel = v;
}
}
public static VisibilityChecker construct(JsonAutoDetect.Value vis) {
return DEFAULT.withOverrides(vis);
}
public static VisibilityChecker defaultInstance() { return DEFAULT; }
public static VisibilityChecker allPublicInstance() { return ALL_PUBLIC; }
public static VisibilityChecker allPublicExceptCreatorsInstance() {
return ALL_PUBLIC_EXCEPT_CREATORS;
}
/*
/**********************************************************************
/* Mutant factories
/**********************************************************************
*/
public VisibilityChecker withOverrides(JsonAutoDetect.Value vis)
{
if (vis == null) {
return this;
}
return _with(
_defaultOrOverride(_fieldMinLevel, vis.getFieldVisibility()),
_defaultOrOverride(_getterMinLevel, vis.getGetterVisibility()),
_defaultOrOverride(_isGetterMinLevel, vis.getIsGetterVisibility()),
_defaultOrOverride(_setterMinLevel, vis.getSetterVisibility()),
_defaultOrOverride(_creatorMinLevel, vis.getCreatorVisibility()),
_defaultOrOverride(_scalarConstructorMinLevel, vis.getScalarConstructorVisibility())
);
}
private Visibility _defaultOrOverride(Visibility defaults, Visibility override) {
if (override == Visibility.DEFAULT) {
return defaults;
}
return override;
}
/**
* 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 VisibilityChecker with(Visibility v)
{
if (v == Visibility.DEFAULT) {
return DEFAULT;
}
return new VisibilityChecker(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 VisibilityChecker 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;
}
}
/**
* Builder method that will return a checker instance that has
* specified minimum visibility level for fields.
*/
public VisibilityChecker withFieldVisibility(Visibility v) {
if (v == Visibility.DEFAULT) v = DEFAULT._fieldMinLevel;
if (_fieldMinLevel == v) return this;
return new VisibilityChecker(v, _getterMinLevel, _isGetterMinLevel, _setterMinLevel,
_creatorMinLevel, _scalarConstructorMinLevel);
}
/**
* Builder method that will return a checker instance that has
* specified minimum visibility level for regular ("getXxx") getters.
*/
public VisibilityChecker withGetterVisibility(Visibility v) {
if (v == Visibility.DEFAULT) v = DEFAULT._getterMinLevel;
if (_getterMinLevel == v) return this;
return new VisibilityChecker(_fieldMinLevel, v, _isGetterMinLevel, _setterMinLevel,
_creatorMinLevel, _scalarConstructorMinLevel);
}
/**
* Builder method that will return a checker instance that has
* specified minimum visibility level for "is-getters" ("isXxx").
*/
public VisibilityChecker withIsGetterVisibility(Visibility v) {
if (v == Visibility.DEFAULT) v = DEFAULT._isGetterMinLevel;
if (_isGetterMinLevel == v) return this;
return new VisibilityChecker(_fieldMinLevel, _getterMinLevel, v, _setterMinLevel,
_creatorMinLevel, _scalarConstructorMinLevel);
}
/**
* Builder method that will return a checker instance that has
* specified minimum visibility level for setters.
*/
public VisibilityChecker withSetterVisibility(Visibility v) {
if (v == Visibility.DEFAULT) v = DEFAULT._setterMinLevel;
if (_setterMinLevel == v) return this;
return new VisibilityChecker(_fieldMinLevel, _getterMinLevel, _isGetterMinLevel, v,
_creatorMinLevel, _scalarConstructorMinLevel);
}
/**
* Builder method that will return a checker instance that has
* specified minimum visibility level for creator methods
* (constructors, factory methods)
*/
public VisibilityChecker withCreatorVisibility(Visibility v) {
if (v == Visibility.DEFAULT) v = DEFAULT._creatorMinLevel;
if (_creatorMinLevel == v) return this;
return new VisibilityChecker(_fieldMinLevel, _getterMinLevel, _isGetterMinLevel, _setterMinLevel,
v, _scalarConstructorMinLevel);
}
/**
* @since 3.0
*/
public VisibilityChecker withScalarConstructorVisibility(Visibility v) {
if (v == Visibility.DEFAULT) v = DEFAULT._scalarConstructorMinLevel;
if (_scalarConstructorMinLevel == v) return this;
return new VisibilityChecker(_fieldMinLevel, _getterMinLevel, _isGetterMinLevel, _setterMinLevel,
_creatorMinLevel, v);
}
/**
* 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.
*/
protected VisibilityChecker _with(Visibility f, Visibility g, Visibility isG, Visibility s,
Visibility cr, Visibility scalarCr) {
if ((f == _fieldMinLevel)
&& (g == _getterMinLevel)
&& (isG == _isGetterMinLevel)
&& (s == _setterMinLevel)
&& (cr == _creatorMinLevel)
&& (scalarCr == _scalarConstructorMinLevel)) {
return this;
}
return new VisibilityChecker(f, g, isG, s, cr, scalarCr);
}
/*
/**********************************************************************
/* Accessors
/**********************************************************************
*/
/**
* 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(AnnotatedField f) {
return _fieldMinLevel.isVisible(f.getAnnotated());
}
/**
* 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(AnnotatedMethod m) {
return _getterMinLevel.isVisible(m.getAnnotated());
}
/**
* 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(AnnotatedMethod m) {
return _isGetterMinLevel.isVisible(m.getAnnotated());
}
/**
* 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(AnnotatedMethod m) {
return _setterMinLevel.isVisible(m.getAnnotated());
}
/**
* Method for checking whether given creator (other than "scalar constructor",
* see {@link #isScalarConstructorVisible}) is auto-detectable
* as Creator, with respect to its visibility
* (not considering signature, just visibility)
*/
public boolean isCreatorVisible(AnnotatedMember m) {
return _creatorMinLevel.isVisible(m.getMember());
}
/**
* Method for checking whether given single-scalar-argument
* constructor is auto-detectable
* as delegating Creator, with respect to its visibility
* (not considering signature, just visibility)
*
* @since 3.0
*/
public boolean isScalarConstructorVisible(AnnotatedMember m) {
return _scalarConstructorMinLevel.isVisible(m.getMember());
}
/*
/********************************************************
/* Standard methods
/********************************************************
*/
@Override
public String toString() {
return String.format("[Visibility: field=%s,getter=%s,isGetter=%s,setter=%s,creator=%s,scalarConstructor=%s]",
_fieldMinLevel, _getterMinLevel, _isGetterMinLevel, _setterMinLevel,
_creatorMinLevel, _scalarConstructorMinLevel);
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (o instanceof VisibilityChecker other) {
return _fieldMinLevel == other._fieldMinLevel
&& _getterMinLevel == other._getterMinLevel
&& _isGetterMinLevel == other._isGetterMinLevel
&& _setterMinLevel == other._setterMinLevel
&& _creatorMinLevel== other._creatorMinLevel
&& _scalarConstructorMinLevel == other._scalarConstructorMinLevel
;
} else {
return false;
}
}
}