blob: 8f5ac679f9bb1fe2f376f8948d49f0215e4600e5 [file] [log] [blame]
package org.codehaus.jackson.map.introspect;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonMethod;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
/**
* 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.
*<p>
* Note on compatibility: 1.9 introduced overloaded "with" method
* (which takes {@link Visibility} as value to assign); which could
* be potential issue, but assumption here is that all custom implementations
* are based on "Std" base class
*
* @author tatu
* @since 1.5
*/
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);
/**
* 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)
*
* @since 1.9
*/
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)
*
* @since 1.9
*/
public T withVisibility(JsonMethod 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" (aka "Fluid") 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.
*<p>
* Note on <code>JsonAutoDetect</code> annotation: it is used to
* access default minimum visibility access definitions.
*/
@JsonAutoDetect(
getterVisibility = Visibility.PUBLIC_ONLY,
isGetterVisibility = Visibility.PUBLIC_ONLY,
setterVisibility = Visibility.ANY,
/**
* By default, all matching single-arg constructed are found,
* regardless of visibility. Does not apply to factory methods,
* they can not be auto-detected; ditto for multiple-argument
* constructors.
*/
creatorVisibility = Visibility.ANY,
fieldVisibility = Visibility.PUBLIC_ONLY
)
public static class Std
implements VisibilityChecker<Std>
{
/**
* This is the canonical base instance, configured with default
* visibility values
*/
protected final static Std DEFAULT = new Std(Std.class.getAnnotation(JsonAutoDetect.class));
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)
{
JsonMethod[] incl = ann.value();
// let's combine checks for enabled/disabled, with minimimum level checks:
_getterMinLevel = hasMethod(incl, JsonMethod.GETTER) ? ann.getterVisibility() : Visibility.NONE;
_isGetterMinLevel = hasMethod(incl, JsonMethod.IS_GETTER) ? ann.isGetterVisibility() : Visibility.NONE;
_setterMinLevel = hasMethod(incl, JsonMethod.SETTER) ? ann.setterVisibility() : Visibility.NONE;
_creatorMinLevel = hasMethod(incl, JsonMethod.CREATOR) ? ann.creatorVisibility() : Visibility.NONE;
_fieldMinLevel = hasMethod(incl, JsonMethod.FIELD) ? ann.fieldVisibility() : Visibility.NONE;
}
/**
* 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;
}
/**
* Costructor that will assign given visibility value for all
* properties.
*
* @param v level to use for all property types
*
* @since 1.9
*/
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;
}
}
/*
/********************************************************
/* Builder/fluent methods for instantiating configured
/* instances
/********************************************************
*/
@Override
public Std with(JsonAutoDetect ann)
{
if (ann == null) return this;
Std curr = this;
JsonMethod[] incl = ann.value();
Visibility v;
v = hasMethod(incl, JsonMethod.GETTER) ? ann.getterVisibility() : Visibility.NONE;
curr = curr.withGetterVisibility(v);
v = hasMethod(incl, JsonMethod.IS_GETTER) ? ann.isGetterVisibility() : Visibility.NONE;
curr = curr.withIsGetterVisibility(v);
v = hasMethod(incl, JsonMethod.SETTER) ? ann.setterVisibility() : Visibility.NONE;
curr = curr.withSetterVisibility(v);
v = hasMethod(incl, JsonMethod.CREATOR) ? ann.creatorVisibility() : Visibility.NONE;
curr = curr.withCreatorVisibility(v);
v = hasMethod(incl, JsonMethod.FIELD) ? ann.fieldVisibility() : Visibility.NONE;
curr = curr.withFieldVisibility(v);
return curr;
}
@Override
public Std with(Visibility v)
{
if (v == Visibility.DEFAULT) {
return DEFAULT;
}
return new Std(v);
}
@Override
public Std withVisibility(JsonMethod 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:
// 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());
}
/*
/********************************************************
/* Helper methods
/********************************************************
*/
private static boolean hasMethod(JsonMethod[] methods, JsonMethod method)
{
for (JsonMethod curr : methods) {
if (curr == method || curr == JsonMethod.ALL) return true;
}
return false;
}
/*
/********************************************************
/* Standard methods
/********************************************************
*/
@Override
public String toString() {
return new StringBuilder("[Visibility:")
.append(" getter: ").append(_getterMinLevel)
.append(", isGetter: ").append(_isGetterMinLevel)
.append(", setter: ").append(_setterMinLevel)
.append(", creator: ").append(_creatorMinLevel)
.append(", field: ").append(_fieldMinLevel)
.append("]").toString();
}
}
}