package com.fasterxml.jackson.dataformat.xml;
import com.fasterxml.jackson.databind.PropertyName;
import com.fasterxml.jackson.databind.introspect.*;
import com.fasterxml.jackson.databind.jsontype.impl.StdTypeResolverBuilder;
import com.fasterxml.jackson.dataformat.xml.annotation.*;
Extension of JacksonAnnotationIntrospector
that is needed to support additional xml-specific annotation that Jackson provides. Note, however, that there is no JAXB annotation support here; that is provided with separate introspector (see JaxbAnnotationIntrospector
). /**
* Extension of {@link JacksonAnnotationIntrospector} that is needed to support
* additional xml-specific annotation that Jackson provides. Note, however, that
* there is no JAXB annotation support here; that is provided with
* separate introspector (see
* {@link com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector}).
*/
public class JacksonXmlAnnotationIntrospector
extends JacksonAnnotationIntrospector
implements XmlAnnotationIntrospector
{
private static final long serialVersionUID = 1L;
For backwards compatibility with 2.0, the default behavior is
to assume use of List wrapper if no annotations are used.
/**
* For backwards compatibility with 2.0, the default behavior is
* to assume use of List wrapper if no annotations are used.
*/
public final static boolean DEFAULT_USE_WRAPPER = true;
// non-final from 2.7 on, to allow mapper to change
protected boolean _cfgDefaultUseWrapper;
public JacksonXmlAnnotationIntrospector() {
this(DEFAULT_USE_WRAPPER);
}
public JacksonXmlAnnotationIntrospector(boolean defaultUseWrapper) {
_cfgDefaultUseWrapper = defaultUseWrapper;
}
/*
/**********************************************************************
/* Overrides of JacksonAnnotationIntrospector impls
/**********************************************************************
*/
@Override
public PropertyName findWrapperName(Annotated ann)
{
JacksonXmlElementWrapper w = ann.getAnnotation(JacksonXmlElementWrapper.class);
if (w != null) {
// Special case: wrapping explicitly blocked?
if (!w.useWrapping()) {
return PropertyName.NO_NAME;
}
// also: need to ensure we use marker:
String localName = w.localName();
if (localName == null || localName.length() == 0) {
return PropertyName.USE_DEFAULT;
}
return PropertyName.construct(w.localName(), w.namespace());
}
/* 09-Sep-2012, tatu: In absence of configurating we need to use our
* default settings...
*/
if (_cfgDefaultUseWrapper) {
return PropertyName.USE_DEFAULT;
}
return null;
}
@Override
public PropertyName findRootName(AnnotatedClass ac)
{
JacksonXmlRootElement root = ac.getAnnotation(JacksonXmlRootElement.class);
if (root != null) {
String local = root.localName();
String ns = root.namespace();
if (local.length() == 0 && ns.length() == 0) {
return PropertyName.USE_DEFAULT;
}
return new PropertyName(local, ns);
}
return super.findRootName(ac);
}
/*
/**********************************************************************
/* XmlAnnotationIntrospector, findXxx
/**********************************************************************
*/
@Override
public String findNamespace(Annotated ann)
{
JacksonXmlProperty prop = ann.getAnnotation(JacksonXmlProperty.class);
if (prop != null) {
return prop.namespace();
}
return null;
}
/*
/**********************************************************************
/* XmlAnnotationIntrospector, isXxx methods
/**********************************************************************
*/
@Override
public Boolean isOutputAsAttribute(Annotated ann)
{
JacksonXmlProperty prop = ann.getAnnotation(JacksonXmlProperty.class);
if (prop != null) {
return prop.isAttribute() ? Boolean.TRUE : Boolean.FALSE;
}
return null;
}
@Override
public Boolean isOutputAsText(Annotated ann)
{
JacksonXmlText prop = ann.getAnnotation(JacksonXmlText.class);
if (prop != null) {
return prop.value() ? Boolean.TRUE : Boolean.FALSE;
}
return null;
}
@Override
public Boolean isOutputAsCData(Annotated ann) {
JacksonXmlCData prop = ann.getAnnotation(JacksonXmlCData.class);
if (prop != null) {
return prop.value() ? Boolean.TRUE : Boolean.FALSE;
}
return null;
}
@Override
public void setDefaultUseWrapper(boolean b) {
_cfgDefaultUseWrapper = b;
}
/*
/**********************************************************************
/* Overrides for name, property detection
/**********************************************************************
*/
@Override
public PropertyName findNameForSerialization(Annotated a)
{
PropertyName name = _findXmlName(a);
if (name == null) {
name = super.findNameForSerialization(a);
if (name == null) {
if (a.hasAnnotation(JacksonXmlText.class)) {
return PropertyName.USE_DEFAULT;
}
}
}
return name;
}
@Override
public PropertyName findNameForDeserialization(Annotated a)
{
PropertyName name = _findXmlName(a);
if (name == null) {
name = super.findNameForDeserialization(a);
if (name == null) {
if (a.hasAnnotation(JacksonXmlText.class)) {
return PropertyName.USE_DEFAULT;
}
}
}
return name;
}
/*
/**********************************************************************
/* Overrides for non-public helper methods
/**********************************************************************
*/
We will override this method so that we can return instance
that cleans up type id property name to be a valid xml name.
/**
* We will override this method so that we can return instance
* that cleans up type id property name to be a valid xml name.
*/
@Override
protected StdTypeResolverBuilder _constructStdTypeResolverBuilder() {
return new XmlTypeResolverBuilder();
}
/*
/**********************************************************************
/* Internal methods
/**********************************************************************
*/
protected PropertyName _findXmlName(Annotated a)
{
JacksonXmlProperty pann = a.getAnnotation(JacksonXmlProperty.class);
if (pann != null) {
return PropertyName.construct(pann.localName(), pann.namespace());
}
return null;
}
}