PeriodSerializer.java
package tools.jackson.datatype.joda.ser;
import com.fasterxml.jackson.annotation.JsonFormat;
import tools.jackson.core.JacksonException;
import tools.jackson.core.JsonGenerator;
import tools.jackson.databind.*;
import tools.jackson.databind.jsonFormatVisitors.*;
import tools.jackson.datatype.joda.cfg.FormatConfig;
import tools.jackson.datatype.joda.cfg.JacksonJodaPeriodFormat;
import org.joda.time.ReadablePeriod;
/**
* Serializes a {@link ReadablePeriod} using Joda default formatting.
*<p>
* TODO: allow serialization as an array of numbers, for numeric ("timestamp")
* notation?
*/
public class PeriodSerializer
// alas, difficult to extend JodaDateSerializerBase
extends JodaSerializerBase<ReadablePeriod>
{
protected final JacksonJodaPeriodFormat _format;
public PeriodSerializer() {
this(FormatConfig.DEFAULT_PERIOD_FORMAT);
}
protected PeriodSerializer(JacksonJodaPeriodFormat format) {
super(ReadablePeriod.class);
_format = format;
}
// anything naturally "empty" to check?
/*
@Override
public boolean isEmpty(ReadablePeriod value) {
return (value.getMillis() == 0L);
}
*/
// Lots of work, although realistically, won't have much or any effect...
@Override
public ValueSerializer<?> createContextual(SerializationContext ctxt,
BeanProperty property)
{
if (property != null) {
JsonFormat.Value ann = findFormatOverrides(ctxt, property, handledType());
if (ann != null) {
JacksonJodaPeriodFormat format = _format;
Boolean useTimestamp;
// Simple case first: serialize as numeric timestamp?
if (ann.getShape().isNumeric()) {
useTimestamp = Boolean.TRUE;
} else if (ann.getShape() == JsonFormat.Shape.STRING) {
useTimestamp = Boolean.FALSE;
} else if (ann.getShape() == JsonFormat.Shape.ARRAY) {
// 17-Nov-2014, tatu: also, arrays typically contain non-string representation
useTimestamp = Boolean.TRUE;
} else {
useTimestamp = null;
}
// must not call if flag defined, to rely on defaults:
if (useTimestamp != null) {
format = format.withUseTimestamp(useTimestamp);
}
// for others, safe to call, null/empty just ignored
format = format.withFormat(ann.getPattern());
format = format.withLocale(ann.getLocale());
if (format != _format) {
return new PeriodSerializer(format);
}
}
}
return this;
}
@Override
public void serialize(ReadablePeriod value, JsonGenerator g, SerializationContext ctxt)
throws JacksonException
{
g.writeString(_format.createFormatter(ctxt).print(value));
}
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
{
JsonStringFormatVisitor v2 = visitor.expectStringFormat(typeHint);
// Alas, nothing really matches Periods; should not call DATE or DATE_TIME
if (v2 != null) {
// v2.format(JsonValueFormat.DATE);
}
}
}