org.codehaus.jackson.map.ext.OptionalHandlerFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ehcache Show documentation
Show all versions of ehcache Show documentation
Ehcache is an open source, standards-based cache used to boost performance,
offload the database and simplify scalability. Ehcache is robust, proven and full-featured and
this has made it the most widely-used Java-based cache.
package org.codehaus.jackson.map.ext;
import java.util.Collection;
import java.util.Map;
import org.codehaus.jackson.map.*;
import org.codehaus.jackson.map.deser.std.StdDeserializer;
import org.codehaus.jackson.map.util.Provider;
import org.codehaus.jackson.type.JavaType;
/**
* Helper class used for isolating details of handling optional+external types (Joda datetime,
* javax.xml classes) from standard factories that offer them.
*
* @author tatu
*
* @since 1.6.1
*/
public class OptionalHandlerFactory
{
/* 1.6.1+ To make 2 main "optional" handler groups (javax.xml.stream, Joda date/time)
* more dynamic, we better only figure out handlers completely dynamically, if and
* when they are needed. To do this we need to assume package prefixes.
*/
private final static String PACKAGE_PREFIX_JODA_DATETIME = "org.joda.time.";
private final static String PACKAGE_PREFIX_JAVAX_XML = "javax.xml.";
private final static String SERIALIZERS_FOR_JODA_DATETIME = "org.codehaus.jackson.map.ext.JodaSerializers";
private final static String SERIALIZERS_FOR_JAVAX_XML = "org.codehaus.jackson.map.ext.CoreXMLSerializers";
private final static String DESERIALIZERS_FOR_JODA_DATETIME = "org.codehaus.jackson.map.ext.JodaDeserializers";
private final static String DESERIALIZERS_FOR_JAVAX_XML = "org.codehaus.jackson.map.ext.CoreXMLDeserializers";
// Plus we also have a single serializer for DOM Node:
private final static String CLASS_NAME_DOM_NODE = "org.w3c.dom.Node";
private final static String CLASS_NAME_DOM_DOCUMENT = "org.w3c.dom.Node";
private final static String SERIALIZER_FOR_DOM_NODE = "org.codehaus.jackson.map.ext.DOMSerializer";
private final static String DESERIALIZER_FOR_DOM_DOCUMENT = "org.codehaus.jackson.map.ext.DOMDeserializer$DocumentDeserializer";
private final static String DESERIALIZER_FOR_DOM_NODE = "org.codehaus.jackson.map.ext.DOMDeserializer$NodeDeserializer";
public final static OptionalHandlerFactory instance = new OptionalHandlerFactory();
protected OptionalHandlerFactory() { }
/*
/**********************************************************
/* Public API
/**********************************************************
*/
public JsonSerializer> findSerializer(SerializationConfig config, JavaType type)
// BasicBeanDescription beanInfo, BeanProperty property)
{
Class> rawType = type.getRawClass();
String className = rawType.getName();
String factoryName;
if (className.startsWith(PACKAGE_PREFIX_JODA_DATETIME)) {
factoryName = SERIALIZERS_FOR_JODA_DATETIME;
} else if (className.startsWith(PACKAGE_PREFIX_JAVAX_XML)
|| hasSupertypeStartingWith(rawType, PACKAGE_PREFIX_JAVAX_XML)) {
factoryName = SERIALIZERS_FOR_JAVAX_XML;
} else if (doesImplement(rawType, CLASS_NAME_DOM_NODE)) {
return (JsonSerializer>) instantiate(SERIALIZER_FOR_DOM_NODE);
} else {
return null;
}
Object ob = instantiate(factoryName);
if (ob == null) { // could warn, if we had logging system (j.u.l?)
return null;
}
@SuppressWarnings("unchecked")
Provider,JsonSerializer>>> prov = (Provider,JsonSerializer>>>) ob;
Collection,JsonSerializer>>> entries = prov.provide();
// first, check for exact match (concrete)
for (Map.Entry,JsonSerializer>> entry : entries) {
if (rawType == entry.getKey()) {
return entry.getValue();
}
}
// if no match, check super-type match
for (Map.Entry,JsonSerializer>> entry : entries) {
if (entry.getKey().isAssignableFrom(rawType)) {
return entry.getValue();
}
}
// but maybe there's just no match to be found?
return null;
}
public JsonDeserializer> findDeserializer(JavaType type, DeserializationConfig config, DeserializerProvider p)
{
Class> rawType = type.getRawClass();
String className = rawType.getName();
String factoryName;
if (className.startsWith(PACKAGE_PREFIX_JODA_DATETIME)) {
factoryName = DESERIALIZERS_FOR_JODA_DATETIME;
} else if (className.startsWith(PACKAGE_PREFIX_JAVAX_XML)
|| hasSupertypeStartingWith(rawType, PACKAGE_PREFIX_JAVAX_XML)) {
factoryName = DESERIALIZERS_FOR_JAVAX_XML;
} else if (doesImplement(rawType, CLASS_NAME_DOM_DOCUMENT)) {
return (JsonDeserializer>) instantiate(DESERIALIZER_FOR_DOM_DOCUMENT);
} else if (doesImplement(rawType, CLASS_NAME_DOM_NODE)) {
return (JsonDeserializer>) instantiate(DESERIALIZER_FOR_DOM_NODE);
} else {
return null;
}
Object ob = instantiate(factoryName);
if (ob == null) { // could warn, if we had logging system (j.u.l?)
return null;
}
@SuppressWarnings("unchecked")
Provider> prov = (Provider>) ob;
Collection> entries = prov.provide();
// first, check for exact match (concrete)
for (StdDeserializer> deser : entries) {
if (rawType == deser.getValueClass()) {
return deser;
}
}
// if no match, check super-type match
for (StdDeserializer> deser : entries) {
if (deser.getValueClass().isAssignableFrom(rawType)) {
return deser;
}
}
// but maybe there's just no match to be found?
return null;
}
/*
/**********************************************************
/* Internal helper methods
/**********************************************************
*/
private Object instantiate(String className)
{
try {
return Class.forName(className).newInstance();
}
catch (LinkageError e) { }
// too many different kinds to enumerate here:
catch (Exception e) { }
return null;
}
private boolean doesImplement(Class> actualType, String classNameToImplement)
{
for (Class> type = actualType; type != null; type = type.getSuperclass()) {
if (type.getName().equals(classNameToImplement)) {
return true;
}
// or maybe one of super-interfaces
if (hasInterface(type, classNameToImplement)) {
return true;
}
}
return false;
}
private boolean hasInterface(Class> type, String interfaceToImplement)
{
Class>[] interfaces = type.getInterfaces();
for (Class> iface : interfaces) {
if (iface.getName().equals(interfaceToImplement)) {
return true;
}
}
// maybe super-interface?
for (Class> iface : interfaces) {
if (hasInterface(iface, interfaceToImplement)) {
return true;
}
}
return false;
}
private boolean hasSupertypeStartingWith(Class> rawType, String prefix)
{
// first, superclasses
for (Class> supertype = rawType.getSuperclass(); supertype != null; supertype = supertype.getSuperclass()) {
if (supertype.getName().startsWith(prefix)) {
return true;
}
}
// then interfaces
for (Class> cls = rawType; cls != null; cls = cls.getSuperclass()) {
if (hasInterfaceStartingWith(cls, prefix)) {
return true;
}
}
return false;
}
private boolean hasInterfaceStartingWith(Class> type, String prefix)
{
Class>[] interfaces = type.getInterfaces();
for (Class> iface : interfaces) {
if (iface.getName().startsWith(prefix)) {
return true;
}
}
// maybe super-interface?
for (Class> iface : interfaces) {
if (hasInterfaceStartingWith(iface, prefix)) {
return true;
}
}
return false;
}
}