com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of payment-retries-plugin Show documentation
Show all versions of payment-retries-plugin Show documentation
Kill Bill Payment Retries plugin
The newest version!
package com.fasterxml.jackson.databind.introspect;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.*;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.*;
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.jsontype.NamedType;
import com.fasterxml.jackson.databind.jsontype.TypeIdResolver;
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
import com.fasterxml.jackson.databind.jsontype.impl.StdTypeResolverBuilder;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.VirtualBeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.impl.AttributePropertyWriter;
import com.fasterxml.jackson.databind.ser.std.RawSerializer;
import com.fasterxml.jackson.databind.util.*;
/**
* {@link AnnotationIntrospector} implementation that handles standard
* Jackson annotations.
*/
public class JacksonAnnotationIntrospector
extends AnnotationIntrospector
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
public JacksonAnnotationIntrospector() { }
@Override
public Version version() {
return com.fasterxml.jackson.databind.cfg.PackageVersion.VERSION;
}
/*
/**********************************************************
/* General annotation properties
/**********************************************************
*/
/**
* Annotations with meta-annotation {@link JacksonAnnotationsInside}
* are considered bundles.
*/
@Override
public boolean isAnnotationBundle(Annotation ann) {
return ann.annotationType().getAnnotation(JacksonAnnotationsInside.class) != null;
}
/*
/**********************************************************
/* General annotations
/**********************************************************
*/
/**
* Since 2.6, we have supported use of {@link JsonProperty} for specifying
* explicit serialized name
*/
@Override
public String findEnumValue(Enum> value)
{
// 11-Jun-2015, tatu: As per [databind#677], need to allow explicit naming.
// Unfortunately can not quite use standard AnnotatedClass here (due to various
// reasons, including odd representation JVM uses); has to do for now
try {
// We know that values are actually static fields with matching name so:
Field f = value.getClass().getField(value.name());
if (f != null) {
JsonProperty prop = f.getAnnotation(JsonProperty.class);
if (prop != null) {
String n = prop.value();
if (n != null && !n.isEmpty()) {
return n;
}
}
}
} catch (SecurityException e) {
// 17-Sep-2015, tatu: Anything we could/should do here?
} catch (NoSuchFieldException e) {
// 17-Sep-2015, tatu: should not really happen. But... can we do anything?
}
return value.name();
}
/*
/**********************************************************
/* General class annotations
/**********************************************************
*/
@Override
public PropertyName findRootName(AnnotatedClass ac)
{
JsonRootName ann = _findAnnotation(ac, JsonRootName.class);
if (ann == null) {
return null;
}
String ns = ann.namespace();
if (ns != null && ns.length() == 0) {
ns = null;
}
return PropertyName.construct(ann.value(), ns);
}
@Override
@Deprecated // since 2.6, remove from 2.7 or later
public String[] findPropertiesToIgnore(Annotated ac) {
JsonIgnoreProperties ignore = _findAnnotation(ac, JsonIgnoreProperties.class);
return (ignore == null) ? null : ignore.value();
}
@Override // since 2.6
public String[] findPropertiesToIgnore(Annotated ac, boolean forSerialization) {
JsonIgnoreProperties ignore = _findAnnotation(ac, JsonIgnoreProperties.class);
if (ignore == null) {
return null;
}
// 13-May-2015, tatu: As per [databind#95], allow read-only/write-only props
if (forSerialization) {
if (ignore.allowGetters()) {
return null;
}
} else {
if (ignore.allowSetters()) {
return null;
}
}
return ignore.value();
}
@Override
public Boolean findIgnoreUnknownProperties(AnnotatedClass ac) {
JsonIgnoreProperties ignore = _findAnnotation(ac, JsonIgnoreProperties.class);
return (ignore == null) ? null : ignore.ignoreUnknown();
}
@Override
public Boolean isIgnorableType(AnnotatedClass ac) {
JsonIgnoreType ignore = _findAnnotation(ac, JsonIgnoreType.class);
return (ignore == null) ? null : ignore.value();
}
/**
* @deprecated (since 2.3) Use {@link #findFilterId(Annotated)} instead
*/
@Deprecated
@Override
public Object findFilterId(AnnotatedClass ac) {
return _findFilterId(ac);
}
@Override
public Object findFilterId(Annotated a) {
return _findFilterId(a);
}
protected final Object _findFilterId(Annotated a)
{
JsonFilter ann = _findAnnotation(a, JsonFilter.class);
if (ann != null) {
String id = ann.value();
// Empty String is same as not having annotation, to allow overrides
if (id.length() > 0) {
return id;
}
}
return null;
}
@Override
public Object findNamingStrategy(AnnotatedClass ac)
{
JsonNaming ann = _findAnnotation(ac, JsonNaming.class);
return (ann == null) ? null : ann.value();
}
/*
/**********************************************************
/* Property auto-detection
/**********************************************************
*/
@Override
public VisibilityChecker> findAutoDetectVisibility(AnnotatedClass ac,
VisibilityChecker> checker)
{
JsonAutoDetect ann = _findAnnotation(ac, JsonAutoDetect.class);
return (ann == null) ? checker : checker.with(ann);
}
/*
/**********************************************************
/* General member (field, method/constructor) annotations
/**********************************************************
*/
@Override
public String findImplicitPropertyName(AnnotatedMember param) {
// not known by default (until JDK8) for creators; default
//
return null;
}
@Override
public boolean hasIgnoreMarker(AnnotatedMember m) {
return _isIgnorable(m);
}
@Override
public Boolean hasRequiredMarker(AnnotatedMember m)
{
JsonProperty ann = _findAnnotation(m, JsonProperty.class);
if (ann != null) {
return ann.required();
}
return null;
}
@Override
public JsonProperty.Access findPropertyAccess(Annotated m) {
JsonProperty ann = _findAnnotation(m, JsonProperty.class);
if (ann != null) {
return ann.access();
}
return null;
}
@Override
public String findPropertyDescription(Annotated ann) {
JsonPropertyDescription desc = _findAnnotation(ann, JsonPropertyDescription.class);
return (desc == null) ? null : desc.value();
}
@Override
public Integer findPropertyIndex(Annotated ann) {
JsonProperty prop = _findAnnotation(ann, JsonProperty.class);
if (prop != null) {
int ix = prop.index();
if (ix != JsonProperty.INDEX_UNKNOWN) {
return Integer.valueOf(ix);
}
}
return null;
}
@Override
public String findPropertyDefaultValue(Annotated ann) {
JsonProperty prop = _findAnnotation(ann, JsonProperty.class);
if (prop == null) {
return null;
}
String str = prop.defaultValue();
// Since annotations do not allow nulls, need to assume empty means "none"
return str.isEmpty() ? null : str;
}
@Override
public JsonFormat.Value findFormat(Annotated ann) {
JsonFormat f = _findAnnotation(ann, JsonFormat.class);
return (f == null) ? null : new JsonFormat.Value(f);
}
@Override
public ReferenceProperty findReferenceType(AnnotatedMember member)
{
JsonManagedReference ref1 = _findAnnotation(member, JsonManagedReference.class);
if (ref1 != null) {
return AnnotationIntrospector.ReferenceProperty.managed(ref1.value());
}
JsonBackReference ref2 = _findAnnotation(member, JsonBackReference.class);
if (ref2 != null) {
return AnnotationIntrospector.ReferenceProperty.back(ref2.value());
}
return null;
}
@Override
public NameTransformer findUnwrappingNameTransformer(AnnotatedMember member)
{
JsonUnwrapped ann = _findAnnotation(member, JsonUnwrapped.class);
// if not enabled, just means annotation is not enabled; not necessarily
// that unwrapping should not be done (relevant when using chained introspectors)
if (ann == null || !ann.enabled()) {
return null;
}
String prefix = ann.prefix();
String suffix = ann.suffix();
return NameTransformer.simpleTransformer(prefix, suffix);
}
@Override
public Object findInjectableValueId(AnnotatedMember m)
{
JacksonInject ann = _findAnnotation(m, JacksonInject.class);
if (ann == null) {
return null;
}
/* Empty String means that we should use name of declared
* value class.
*/
String id = ann.value();
if (id.length() == 0) {
// slight complication; for setters, type
if (!(m instanceof AnnotatedMethod)) {
return m.getRawType().getName();
}
AnnotatedMethod am = (AnnotatedMethod) m;
if (am.getParameterCount() == 0) {
return m.getRawType().getName();
}
return am.getRawParameterType(0).getName();
}
return id;
}
@Override
public Class>[] findViews(Annotated a)
{
JsonView ann = _findAnnotation(a, JsonView.class);
return (ann == null) ? null : ann.value();
}
/*
/**********************************************************
/* Annotations for Polymorphic Type handling
/**********************************************************
*/
@Override
public TypeResolverBuilder> findTypeResolver(MapperConfig> config,
AnnotatedClass ac, JavaType baseType)
{
return _findTypeResolver(config, ac, baseType);
}
@Override
public TypeResolverBuilder> findPropertyTypeResolver(MapperConfig> config,
AnnotatedMember am, JavaType baseType)
{
/* As per definition of @JsonTypeInfo, should only apply to contents of container
* (collection, map) types, not container types themselves:
*/
if (baseType.isContainerType()) return null;
// No per-member type overrides (yet)
return _findTypeResolver(config, am, baseType);
}
@Override
public TypeResolverBuilder> findPropertyContentTypeResolver(MapperConfig> config,
AnnotatedMember am, JavaType containerType)
{
/* First: let's ensure property is a container type: caller should have
* verified but just to be sure
*/
if (!containerType.isContainerType()) {
throw new IllegalArgumentException("Must call method with a container type (got "+containerType+")");
}
return _findTypeResolver(config, am, containerType);
}
@Override
public List findSubtypes(Annotated a)
{
JsonSubTypes t = _findAnnotation(a, JsonSubTypes.class);
if (t == null) return null;
JsonSubTypes.Type[] types = t.value();
ArrayList result = new ArrayList(types.length);
for (JsonSubTypes.Type type : types) {
result.add(new NamedType(type.value(), type.name()));
}
return result;
}
@Override
public String findTypeName(AnnotatedClass ac)
{
JsonTypeName tn = _findAnnotation(ac, JsonTypeName.class);
return (tn == null) ? null : tn.value();
}
@Override
public Boolean isTypeId(AnnotatedMember member) {
return _hasAnnotation(member, JsonTypeId.class);
}
/*
/**********************************************************
/* Annotations for Object Id handling
/**********************************************************
*/
@Override
public ObjectIdInfo findObjectIdInfo(Annotated ann) {
JsonIdentityInfo info = _findAnnotation(ann, JsonIdentityInfo.class);
if (info == null || info.generator() == ObjectIdGenerators.None.class) {
return null;
}
// In future may need to allow passing namespace?
PropertyName name = PropertyName.construct(info.property());
return new ObjectIdInfo(name, info.scope(), info.generator(), info.resolver());
}
@Override
public ObjectIdInfo findObjectReferenceInfo(Annotated ann, ObjectIdInfo objectIdInfo) {
JsonIdentityReference ref = _findAnnotation(ann, JsonIdentityReference.class);
if (ref != null) {
objectIdInfo = objectIdInfo.withAlwaysAsId(ref.alwaysAsId());
}
return objectIdInfo;
}
/*
/**********************************************************
/* Serialization: general annotations
/**********************************************************
*/
@Override
public Object findSerializer(Annotated a)
{
JsonSerialize ann = _findAnnotation(a, JsonSerialize.class);
if (ann != null) {
@SuppressWarnings("rawtypes")
Class extends JsonSerializer> serClass = ann.using();
if (serClass != JsonSerializer.None.class) {
return serClass;
}
}
/* 18-Oct-2010, tatu: [JACKSON-351] @JsonRawValue handled just here, for now;
* if we need to get raw indicator from other sources need to add
* separate accessor within {@link AnnotationIntrospector} interface.
*/
JsonRawValue annRaw = _findAnnotation(a, JsonRawValue.class);
if ((annRaw != null) && annRaw.value()) {
// let's construct instance with nominal type:
Class> cls = a.getRawType();
return new RawSerializer