org.codehaus.jackson.map.module.SimpleSerializers Maven / Gradle / Ivy
package org.codehaus.jackson.map.module;
import java.util.*;
import org.codehaus.jackson.map.*;
import org.codehaus.jackson.map.type.ArrayType;
import org.codehaus.jackson.map.type.ClassKey;
import org.codehaus.jackson.map.type.CollectionLikeType;
import org.codehaus.jackson.map.type.CollectionType;
import org.codehaus.jackson.map.type.MapLikeType;
import org.codehaus.jackson.map.type.MapType;
import org.codehaus.jackson.type.JavaType;
/**
* Simple implementation {@link Serializers} which allows registration of
* serializers based on raw (type erased class).
* It can work well for basic bean and scalar type serializers, but is not
* a good fit for handling generic types (like {@link Map}s and {@link Collection}s).
*
* Type registrations are assumed to be general; meaning that registration of serializer
* for a super type will also be used for handling subtypes, unless an exact match
* is found first. As an example, handler for {@link CharSequence} would also be used
* serializing {@link StringBuilder} instances, unless a direct mapping was found.
*
* @since 1.7
*/
public class SimpleSerializers extends Serializers.Base
{
/**
* Class-based mappings that are used both for exact and
* sub-class matches.
*/
protected HashMap> _classMappings = null;
/**
* Interface-based matches.
*/
protected HashMap> _interfaceMappings = null;
/*
/**********************************************************
/* Life-cycle, construction and configuring
/**********************************************************
*/
public SimpleSerializers() { }
/**
* Method for adding given serializer for type that {@link JsonSerializer#handledType}
* specifies (which MUST return a non-null class; and can NOT be {@link Object}, as a
* sanity check).
* For serializers that do not declare handled type, use the variant that takes
* two arguments.
*
* @param ser
*/
public void addSerializer(JsonSerializer> ser)
{
// Interface to match?
Class> cls = ser.handledType();
if (cls == null || cls == Object.class) {
throw new IllegalArgumentException("JsonSerializer of type "+ser.getClass().getName()
+" does not define valid handledType() -- must either register with method that takes type argument "
+" or make serializer extend 'org.codehaus.jackson.map.ser.std.SerializerBase'");
}
_addSerializer(cls, ser);
}
public void addSerializer(Class extends T> type, JsonSerializer ser)
{
_addSerializer(type, ser);
}
private void _addSerializer(Class> cls, JsonSerializer> ser)
{
ClassKey key = new ClassKey(cls);
// Interface or class type?
if (cls.isInterface()) {
if (_interfaceMappings == null) {
_interfaceMappings = new HashMap>();
}
_interfaceMappings.put(key, ser);
} else { // nope, class:
if (_classMappings == null) {
_classMappings = new HashMap>();
}
_classMappings.put(key, ser);
}
}
/*
/**********************************************************
/* Serializers implementation
/**********************************************************
*/
@Override
public JsonSerializer> findSerializer(SerializationConfig config, JavaType type,
BeanDescription beanDesc, BeanProperty property)
{
Class> cls = type.getRawClass();
ClassKey key = new ClassKey(cls);
JsonSerializer> ser = null;
// First: direct match?
if (cls.isInterface()) {
if (_interfaceMappings != null) {
ser = _interfaceMappings.get(key);
if (ser != null) {
return ser;
}
}
} else {
if (_classMappings != null) {
ser = _classMappings.get(key);
if (ser != null) {
return ser;
}
// If not direct match, maybe super-class match?
for (Class> curr = cls; (curr != null); curr = curr.getSuperclass()) {
key.reset(curr);
ser = _classMappings.get(key);
if (ser != null) {
return ser;
}
}
}
}
// No direct match? How about super-interfaces?
if (_interfaceMappings != null) {
ser = _findInterfaceMapping(cls, key);
if (ser != null) {
return ser;
}
// still no matches? Maybe interfaces of super classes
if (!cls.isInterface()) {
while ((cls = cls.getSuperclass()) != null) {
ser = _findInterfaceMapping(cls, key);
if (ser != null) {
return ser;
}
}
}
}
return null;
}
@Override
public JsonSerializer> findArraySerializer(SerializationConfig config,
ArrayType type, BeanDescription beanDesc, BeanProperty property,
TypeSerializer elementTypeSerializer, JsonSerializer