package com.fasterxml.jackson.datatype.joda.ser;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonParser;

import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.jsonFormatVisitors.*;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.datatype.joda.cfg.JacksonJodaDateFormat;

public abstract class JodaDateSerializerBase<T> extends JodaSerializerBase<T>
// need contextualization to read per-property annotations
    implements ContextualSerializer
{
    private static final long serialVersionUID = 1L;

    // // Since 2.9

    protected final static int FORMAT_STRING = 1;
    protected final static int FORMAT_TIMESTAMP = 2;
    protected final static int FORMAT_ARRAY = 3;

    protected final JacksonJodaDateFormat _format;

    protected final SerializationFeature _featureForNumeric;

    
Shape to use for generic "use numeric" feature (instead of more specific JsonFormat.shape).
Since:2.9
/** * Shape to use for generic "use numeric" feature (instead of more specific * JsonFormat.shape). * * @since 2.9 */
protected final int _defaultNumericShape;
Marker set to non-0 if (and only if) property or type override exists.
Since:2.9
/** * Marker set to non-0 if (and only if) property or type override exists. * * @since 2.9 */
protected final int _shapeOverride; protected JodaDateSerializerBase(Class<T> type, JacksonJodaDateFormat format, SerializationFeature numericFeature, int defaultNumericShape, int shapeOverride) { super(type); _format = format; _featureForNumeric = numericFeature; _defaultNumericShape = defaultNumericShape; _shapeOverride = shapeOverride; }
Since:2.9
/** * @since 2.9 */
public abstract JodaDateSerializerBase<T> withFormat(JacksonJodaDateFormat format, int shapeOverride); @Override public boolean isEmpty(SerializerProvider prov, T value) { return value == null; } @Override public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { JsonFormat.Value ann = findFormatOverrides(prov, property, handledType()); if (ann != null) { int shapeOverride = 0; JacksonJodaDateFormat format = _format; Boolean useTimestamp; // Simple case first: serialize as numeric timestamp? final JsonFormat.Shape shape = ann.getShape(); if (shape.isNumeric()) { useTimestamp = Boolean.TRUE; shapeOverride = FORMAT_TIMESTAMP; } else if (shape == JsonFormat.Shape.STRING) { useTimestamp = Boolean.FALSE; shapeOverride = FORMAT_STRING; } else if (shape == JsonFormat.Shape.ARRAY) { // 17-Nov-2014, tatu: also, arrays typically contain non-string representation useTimestamp = Boolean.TRUE; shapeOverride = FORMAT_ARRAY; } else { useTimestamp = null; shapeOverride = 0; } // must not call if flag defined, to rely on defaults: if (useTimestamp != null) { format = format.withUseTimestamp(useTimestamp); } format = format.with(ann); if ((format != _format) || (shapeOverride != _shapeOverride)) { return withFormat(format, shapeOverride); } } return this; } @Override public JsonNode getSchema(SerializerProvider provider, java.lang.reflect.Type typeHint) { switch (_serializationShape(provider)) { case FORMAT_TIMESTAMP: return createSchemaNode("array", true); case FORMAT_ARRAY: return createSchemaNode("number", true); case FORMAT_STRING: default: return createSchemaNode("string", true); } } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { switch (_serializationShape(visitor.getProvider())) { case FORMAT_TIMESTAMP: { JsonIntegerFormatVisitor v2 = visitor.expectIntegerFormat(typeHint); if (v2 != null) { v2.numberType(JsonParser.NumberType.LONG); v2.format(JsonValueFormat.UTC_MILLISEC); } } break; case FORMAT_ARRAY: { JsonArrayFormatVisitor v2 = visitor.expectArrayFormat(typeHint); if (v2 != null) { v2.itemsFormat(JsonFormatTypes.INTEGER); } } break; case FORMAT_STRING: default: { JsonStringFormatVisitor v2 = visitor.expectStringFormat(typeHint); if (v2 != null) { v2.format(JsonValueFormat.DATE_TIME); } } } } /* /********************************************************** /* Helper methods /********************************************************** */
Since:2.8
/** * @since 2.8 */
protected boolean writeWithZoneId(SerializerProvider provider) { return _format.shouldWriteWithZoneId(provider); }
Since:2.9
/** * @since 2.9 */
protected int _serializationShape(SerializerProvider provider) { int shape = _shapeOverride; if (shape == 0) { if (_format.useTimestamp(provider, _featureForNumeric)) { shape = _defaultNumericShape; } else { shape = FORMAT_STRING; } } return shape; } }