package com.fasterxml.jackson.datatype.joda.ser;
import java.io.IOException;
import org.joda.time.ReadablePeriod;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonGenerator;
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.FormatConfig;
import com.fasterxml.jackson.datatype.joda.cfg.JacksonJodaPeriodFormat;
Serializes a ReadablePeriod
using Joda default formatting.
TODO: allow serialization as an array of numbers, for numeric ("timestamp")
notation?
/**
* Serializes a {@link ReadablePeriod} using Joda default formatting.
*<p>
* TODO: allow serialization as an array of numbers, for numeric ("timestamp")
* notation?
*/
public class PeriodSerializer // non final since 2.6.1
// alas, difficult to extend JodaDateSerializerBase
extends JodaSerializerBase<ReadablePeriod>
implements ContextualSerializer
{
private static final long serialVersionUID = 1L;
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 JsonSerializer<?> createContextual(SerializerProvider prov,
BeanProperty property) throws JsonMappingException
{
if (property != null) {
JsonFormat.Value ann = findFormatOverrides(prov, 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().trim());
format = format.withLocale(ann.getLocale());
if (format != _format) {
return new PeriodSerializer(format);
}
}
}
return this;
}
@Override
public void serialize(ReadablePeriod value, JsonGenerator gen, SerializerProvider provider) throws IOException
{
gen.writeString(_format.createFormatter(provider).print(value));
}
@Override
public JsonNode getSchema(SerializerProvider provider, java.lang.reflect.Type typeHint) {
return createSchemaNode("string", true);
}
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException
{
JsonStringFormatVisitor v2 = visitor.expectStringFormat(typeHint);
// Alas, nothing really matches Periods; should not call DATE or DATE_TIME
if (v2 != null) {
// v2.format(JsonValueFormat.DATE);
}
}
}