ImmutablePrimitiveArraySerializerBase.java
package tools.jackson.datatype.guava.ser.primitives;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonFormat;
import tools.jackson.core.JsonGenerator;
import tools.jackson.databind.BeanProperty;
import tools.jackson.databind.JavaType;
import tools.jackson.databind.SerializationContext;
import tools.jackson.databind.ValueSerializer;
import tools.jackson.databind.jsontype.TypeSerializer;
import tools.jackson.databind.ser.std.ArraySerializerBase;
import tools.jackson.databind.ser.std.StdContainerSerializer;
import tools.jackson.databind.type.TypeFactory;
/**
* Shared base for serializers of Guava immutable primitive arrays
* ({@code ImmutableIntArray}, {@code ImmutableLongArray}, {@code ImmutableDoubleArray}).
* Extends {@link ArraySerializerBase} to get per-property handling of
* {@code @JsonFormat} single-element unwrapping.
*<p>
* Note: content inclusion ({@code @JsonInclude(content = ...)}) is NOT supported,
* to avoid boxing of element values.
*
* @since 3.3
*/
public abstract class ImmutablePrimitiveArraySerializerBase<T>
extends ArraySerializerBase<T>
{
protected final JavaType _elementType;
protected ImmutablePrimitiveArraySerializerBase(Class<T> cls, Class<?> primitiveType) {
super(cls);
_elementType = TypeFactory.unsafeSimpleType(primitiveType);
}
protected ImmutablePrimitiveArraySerializerBase(ImmutablePrimitiveArraySerializerBase<T> src,
BeanProperty prop, Boolean unwrapSingle) {
super(src, prop, unwrapSingle, null, false);
_elementType = src._elementType;
}
/*
/**********************************************************************
/* Abstract methods for sub-classes
/**********************************************************************
*/
protected abstract int _length(T value);
protected abstract void _writeElement(JsonGenerator g, T value, int index);
/*
/**********************************************************************
/* Contextualization
/**********************************************************************
*/
// Overridden to only resolve single-element unwrapping, not content inclusion
@Override
public ValueSerializer<?> createContextual(SerializationContext ctxt,
BeanProperty property)
{
Boolean unwrapSingle = null;
// Note: property may be null (root values), but per-type config overrides apply
JsonFormat.Value format = findFormatOverrides(ctxt, property, handledType());
if (format != null) {
unwrapSingle = format.getFeature(JsonFormat.Feature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED);
}
if (!Objects.equals(unwrapSingle, _unwrapSingle)) {
return _withResolved(property, unwrapSingle);
}
return this;
}
protected abstract ImmutablePrimitiveArraySerializerBase<T> _withResolved(BeanProperty prop,
Boolean unwrapSingle);
@Override
protected final ArraySerializerBase<T> _withResolved(BeanProperty prop,
Boolean unwrapSingle, Object suppressableValue, boolean suppressNulls) {
return _withResolved(prop, unwrapSingle);
}
/*
/**********************************************************************
/* StdContainerSerializer implementation
/**********************************************************************
*/
// Primitive elements never have type ids
@Override
protected StdContainerSerializer<?> _withValueTypeSerializer(TypeSerializer vts) {
return this;
}
@Override
public JavaType getContentType() {
return _elementType;
}
@Override
public ValueSerializer<?> getContentSerializer() {
return null;
}
@Override
public boolean isEmpty(SerializationContext ctxt, T value) {
return _length(value) == 0;
}
@Override
public boolean hasSingleElement(T value) {
return _length(value) == 1;
}
/*
/**********************************************************************
/* Serialization
/**********************************************************************
*/
@Override
public final void serialize(T value, JsonGenerator g, SerializationContext ctxt)
{
if (_shouldUnwrapSingle(ctxt) && hasSingleElement(value)) {
serializeContents(value, g, ctxt);
return;
}
g.writeStartArray(value, _length(value));
serializeContents(value, g, ctxt);
g.writeEndArray();
}
// NOTE: `serializeWithType()` inherited from `ArraySerializerBase`
@Override
protected void serializeContents(T value, JsonGenerator g, SerializationContext ctxt)
{
for (int i = 0, len = _length(value); i < len; ++i) {
_writeElement(g, value, i);
}
}
}