blob: b08fb09d1dc5769eadc97422b8a76e9049175b8d [file] [log] [blame]
package com.fasterxml.jackson.databind.ser;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
/**
* Intermediate base class for serializers used for serializing
* types that contain element(s) of other types, such as arrays,
* {@link java.util.Collection}s (<code>Lists</code>, <code>Sets</code>
* etc) and {@link java.util.Map}s and iterable things
* ({@link java.util.Iterator}s).
*/
public abstract class ContainerSerializer<T>
extends StdSerializer<T>
{
/*
/**********************************************************
/* Construction, initialization
/**********************************************************
*/
protected ContainerSerializer(Class<T> t) {
super(t);
}
/**
* Alternate constructor that is (alas!) needed to work
* around kinks of generic type handling
*
* @param t
*/
protected ContainerSerializer(Class<?> t, boolean dummy) {
super(t, dummy);
}
protected ContainerSerializer(ContainerSerializer<?> src) {
super(src._handledType, false);
}
/**
* Factory(-like) method that can be used to construct a new container
* serializer that uses specified {@link TypeSerializer} for decorating
* contained values with additional type information.
*
* @param vts Type serializer to use for contained values; can be null,
* in which case 'this' serializer is returned as is
* @return Serializer instance that uses given type serializer for values if
* that is possible (or if not, just 'this' serializer)
*/
public ContainerSerializer<?> withValueTypeSerializer(TypeSerializer vts) {
if (vts == null) return this;
return _withValueTypeSerializer(vts);
}
/*
/**********************************************************
/* Extended API
/**********************************************************
*/
/**
* Accessor for finding declared (static) element type for
* type this serializer is used for.
*/
public abstract JavaType getContentType();
/**
* Accessor for serializer used for serializing contents
* (List and array elements, Map values etc) of the
* container for which this serializer is used, if it is
* known statically.
* Note that for dynamic types this may return null; if so,
* caller has to instead use {@link #getContentType()} and
* {@link com.fasterxml.jackson.databind.SerializerProvider#findValueSerializer}.
*/
public abstract JsonSerializer<?> getContentSerializer();
/*
/**********************************************************
/* Abstract methods for sub-classes to implement
/**********************************************************
*/
/* Overridden as abstract, to force re-implementation; necessary for all
* collection types.
*/
@Override
public abstract boolean isEmpty(T value);
/**
* Method called to determine if the given value (of type handled by
* this serializer) contains exactly one element.
*<p>
* Note: although it might seem sensible to instead define something
* like "getElementCount()" method, this would not work well for
* containers that do not keep track of size (like linked lists may
* not).
*/
public abstract boolean hasSingleElement(T value);
/**
* Method that needs to be implemented to allow construction of a new
* serializer object with given {@link TypeSerializer}, used when
* addition type information is to be embedded.
*/
protected abstract ContainerSerializer<?> _withValueTypeSerializer(TypeSerializer vts);
/*
/**********************************************************
/* Helper methods for sub-types
/**********************************************************
*/
/**
* Helper method used to encapsulate logic for determining whether there is
* a property annotation that overrides element type; if so, we can
* and need to statically find the serializer.
*
* @since 2.1
*/
protected boolean hasContentTypeAnnotation(SerializerProvider provider,
BeanProperty property)
{
if (property != null) {
AnnotationIntrospector intr = provider.getAnnotationIntrospector();
if (intr != null) {
if (intr.findSerializationContentType(property.getMember(), property.getType()) != null) {
return true;
}
}
}
return false;
}
}