com.fasterxml.jackson.xml.util.XmlRootNameLookup Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jackson-xml-databind Show documentation
Show all versions of jackson-xml-databind Show documentation
Extension for Jackson (http://jackson.codehaus.org) to offer
alternative support for serializing POJOs as XML and deserializing XML as pojos.
Support implemented on top of Stax API (javax.xml.stream), by implementing core Jackson Streaming API types like JsonGenerator, JsonParser and JsonFactory.
Some data-binding types overridden as well (ObjectMapper sub-classed as XmlMapper).
package com.fasterxml.jackson.xml.util;
import javax.xml.namespace.QName;
import org.codehaus.jackson.map.AnnotationIntrospector;
import org.codehaus.jackson.map.MapperConfig;
import org.codehaus.jackson.map.introspect.AnnotatedClass;
import org.codehaus.jackson.map.introspect.BasicBeanDescription;
import org.codehaus.jackson.map.type.ClassKey;
import org.codehaus.jackson.map.util.LRUMap;
import org.codehaus.jackson.type.JavaType;
import com.fasterxml.jackson.xml.XmlAnnotationIntrospector;
/**
* Helper class used for efficiently finding root element name used with
* XML serializations.
*
* @since 1.7
*/
public class XmlRootNameLookup
{
/**
* For efficient operation, let's try to minimize number of times we
* need to introspect root element name to use.
*/
protected final LRUMap _rootNames = new LRUMap(40, 200);
public XmlRootNameLookup() { }
public QName findRootName(JavaType rootType, MapperConfig> config)
{
return findRootName(rootType.getRawClass(), config);
}
public QName findRootName(Class> rootType, MapperConfig> config)
{
ClassKey key = new ClassKey(rootType);
QName name;
synchronized (_rootNames) {
name = _rootNames.get(key);
if (name == null) {
BasicBeanDescription beanDesc = (BasicBeanDescription) config.introspectClassAnnotations(rootType);
AnnotationIntrospector intr = config.getAnnotationIntrospector();
AnnotatedClass ac = beanDesc.getClassInfo();
String localName = null;
String ns = null;
QName root = findRootElement(intr, ac);
if (root != null) {
localName = root.getLocalPart();
ns = root.getNamespaceURI();
}
if (localName == null || localName.length() == 0) {
localName = intr.findRootName(ac);
}
// No answer so far? Let's just default to using simple class name
if (localName == null || localName.length() == 0) {
// Should we strip out enclosing class tho? For now, nope:
localName = rootType.getSimpleName();
name = new QName("", localName);
} else {
// Otherwise let's see if there's namespace, too (if we are missing it)
if (ns == null || ns.length() == 0) {
ns = findNamespace(intr, ac);
}
}
if (ns == null) { // some QName impls barf on nulls...
ns = "";
}
name = new QName(ns, localName);
_rootNames.put(key, name);
}
}
return name;
}
private String findNamespace(AnnotationIntrospector ai, AnnotatedClass ann)
{
for (AnnotationIntrospector intr : ai.allIntrospectors()) {
if (intr instanceof XmlAnnotationIntrospector) {
String ns = ((XmlAnnotationIntrospector) intr).findNamespace(ann);
if (ns != null) {
return ns;
}
}
}
return null;
}
private QName findRootElement(AnnotationIntrospector ai, AnnotatedClass ann)
{
for (AnnotationIntrospector intr : ai.allIntrospectors()) {
if (intr instanceof XmlAnnotationIntrospector) {
QName elem = ((XmlAnnotationIntrospector) intr).findRootElement(ann);
if (elem != null) {
return elem;
}
}
}
return null;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy