MonthSerializer.java
package tools.jackson.databind.ext.javatime.ser;
import java.time.Month;
import java.time.format.DateTimeFormatter;
import java.util.LinkedHashSet;
import java.util.Set;
import com.fasterxml.jackson.annotation.JsonFormat;
import tools.jackson.core.*;
import tools.jackson.core.type.WritableTypeId;
import tools.jackson.databind.JavaType;
import tools.jackson.databind.SerializationContext;
import tools.jackson.databind.cfg.DateTimeFeature;
import tools.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import tools.jackson.databind.jsonFormatVisitors.JsonStringFormatVisitor;
import tools.jackson.databind.jsontype.TypeSerializer;
/**
* Serializer for Java 8 temporal {@link java.time.Month}s.
*<p>
* By default values are serialized as JSON Numbers: one- or zero-based
* index depending on {@link DateTimeFeature#ONE_BASED_MONTHS}.
* With {@code @JsonFormat(pattern = ...)} values are serialized as
* JSON Strings formatted using the pattern (and locale, if any); and with
* {@code @JsonFormat(shape = JsonFormat.Shape.STRING)} (without pattern)
* as JSON Strings containing Enum name (like {@code "JANUARY"}).
*/
public class MonthSerializer
extends JSR310FormattedSerializerBase<Month>
{
public static final MonthSerializer INSTANCE = new MonthSerializer();
protected MonthSerializer() { this(null); }
public MonthSerializer(DateTimeFormatter formatter) {
super(Month.class, formatter);
}
private MonthSerializer(MonthSerializer base, DateTimeFormatter dtf, Boolean useTimestamp,
JsonFormat.Shape shape) {
super(base, dtf, useTimestamp, null, shape);
}
@Override
protected MonthSerializer withFormat(DateTimeFormatter dtf,
Boolean useTimestamp, JsonFormat.Shape shape) {
return new MonthSerializer(this, dtf, useTimestamp, shape);
}
@Override
public void serialize(Month value, JsonGenerator g, SerializationContext ctxt)
throws JacksonException
{
if (_useTimestampExplicitOnly(ctxt)) {
g.writeStartArray();
_serialize(g, value, ctxt);
g.writeEndArray();
} else {
_serialize(g, value, ctxt);
}
}
@Override
public void serializeWithType(Month value, JsonGenerator g,
SerializationContext ctxt, TypeSerializer typeSer)
throws JacksonException
{
WritableTypeId typeIdDef = typeSer.writeTypePrefix(g, ctxt,
typeSer.typeId(value, serializationShape(ctxt)));
_serialize(g, value, ctxt);
typeSer.writeTypeSuffix(g, ctxt, typeIdDef);
}
@Override
protected JsonToken serializationShape(SerializationContext ctxt) {
return _useTimestampExplicitOnly(ctxt) ? JsonToken.START_ARRAY : JsonToken.VALUE_STRING;
}
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
// [databind#6233]: must match what `_serialize()` writes
if (_useTimestampExplicitOnly(visitor.getContext())) {
_acceptTimestampVisitor(visitor, typeHint);
} else if (_formatter != null) {
visitStringFormat(visitor, typeHint);
} else if (Boolean.FALSE.equals(_useTimestamp)) {
JsonStringFormatVisitor v2 = visitor.expectStringFormat(typeHint);
if (v2 != null) {
Set<String> names = new LinkedHashSet<>();
for (Month m : Month.values()) {
names.add(m.name());
}
v2.enumTypes(names);
}
} else {
visitIntFormat(visitor, typeHint, JsonParser.NumberType.INT);
}
}
private void _serialize(JsonGenerator g, Month value, SerializationContext ctxt)
throws JacksonException
{
if (_formatter != null) {
g.writeString(_formatter.format(value));
return;
}
// [databind#6233]: explicit `Shape.STRING` (without pattern) means Enum name,
// which is locale-independent and readable by `MonthDeserializer`
if (Boolean.FALSE.equals(_useTimestamp)) {
g.writeString(value.name());
return;
}
if (ctxt.isEnabled(DateTimeFeature.ONE_BASED_MONTHS)) {
g.writeNumber(value.getValue());
} else {
g.writeNumber(value.getValue() - 1);
}
}
}