blob: 9b5a5ab7e9f1fffc32791bd83801108eec5b080c [file] [log] [blame]
package org.codehaus.jackson.map.ext;
import java.io.IOException;
import java.util.*;
import org.joda.time.*;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import org.codehaus.jackson.*;
import org.codehaus.jackson.map.*;
import org.codehaus.jackson.map.ser.std.SerializerBase;
import org.codehaus.jackson.map.ser.std.ToStringSerializer;
import org.codehaus.jackson.map.util.Provider;
/**
* Provider for serializers that handle some basic data types
* for <a href="http://joda-time.sourceforge.net/">Joda</a> date/time library.
*<p>
* Since version 1.5, more types are supported. These types use slightly
* different approach to serialization than core date types: "timestamp"
* notation is implemented using JSON arrays, for improved readability.
*
* @since 1.4
*/
public class JodaSerializers
implements Provider<Map.Entry<Class<?>,JsonSerializer<?>>>
{
final static HashMap<Class<?>,JsonSerializer<?>> _serializers = new HashMap<Class<?>,JsonSerializer<?>>();
static {
_serializers.put(DateTime.class, new DateTimeSerializer());
_serializers.put(LocalDateTime.class, new LocalDateTimeSerializer());
_serializers.put(LocalDate.class, new LocalDateSerializer());
_serializers.put(DateMidnight.class, new DateMidnightSerializer());
// [JACKSON-706]:
_serializers.put(Period.class, ToStringSerializer.instance);
}
public JodaSerializers() { }
@Override
public Collection<Map.Entry<Class<?>,JsonSerializer<?>>> provide() {
return _serializers.entrySet();
}
/*
/**********************************************************
/* Intermediate base classes
/**********************************************************
*/
protected abstract static class JodaSerializer<T> extends SerializerBase<T>
{
final static DateTimeFormatter _localDateTimeFormat = ISODateTimeFormat.dateTime();
final static DateTimeFormatter _localDateFormat = ISODateTimeFormat.date();
protected JodaSerializer(Class<T> cls) { super(cls); }
protected String printLocalDateTime(ReadablePartial dateValue)
throws IOException, JsonProcessingException
{
return _localDateTimeFormat.print(dateValue);
}
protected String printLocalDate(ReadablePartial dateValue)
throws IOException, JsonProcessingException
{
return _localDateFormat.print(dateValue);
}
protected String printLocalDate(ReadableInstant dateValue)
throws IOException, JsonProcessingException
{
return _localDateFormat.print(dateValue);
}
}
/*
/**********************************************************
/* Concrete serializers
/**********************************************************
*/
public final static class DateTimeSerializer
extends JodaSerializer<DateTime>
{
public DateTimeSerializer() { super(DateTime.class); }
@Override
public void serialize(DateTime value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonGenerationException
{
if (provider.isEnabled(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS)) {
jgen.writeNumber(value.getMillis());
} else {
jgen.writeString(value.toString());
}
}
@Override
public JsonNode getSchema(SerializerProvider provider, java.lang.reflect.Type typeHint)
{
return createSchemaNode(provider.isEnabled(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS)
? "number" : "string", true);
}
}
/**
*
* @since 1.5
*/
public final static class LocalDateTimeSerializer
extends JodaSerializer<LocalDateTime>
{
public LocalDateTimeSerializer() { super(LocalDateTime.class); }
@Override
public void serialize(LocalDateTime dt, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonGenerationException
{
if (provider.isEnabled(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS)) {
// Timestamp here actually means an array of values
jgen.writeStartArray();
jgen.writeNumber(dt.year().get());
jgen.writeNumber(dt.monthOfYear().get());
jgen.writeNumber(dt.dayOfMonth().get());
jgen.writeNumber(dt.hourOfDay().get());
jgen.writeNumber(dt.minuteOfHour().get());
jgen.writeNumber(dt.secondOfMinute().get());
jgen.writeNumber(dt.millisOfSecond().get());
jgen.writeEndArray();
} else {
jgen.writeString(printLocalDateTime(dt));
}
}
@Override
public JsonNode getSchema(SerializerProvider provider, java.lang.reflect.Type typeHint)
{
return createSchemaNode(provider.isEnabled(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS)
? "array" : "string", true);
}
}
public final static class LocalDateSerializer
extends JodaSerializer<LocalDate>
{
public LocalDateSerializer() { super(LocalDate.class); }
@Override
public void serialize(LocalDate dt, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonGenerationException
{
if (provider.isEnabled(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS)) {
// Timestamp here actually means an array of values
jgen.writeStartArray();
jgen.writeNumber(dt.year().get());
jgen.writeNumber(dt.monthOfYear().get());
jgen.writeNumber(dt.dayOfMonth().get());
jgen.writeEndArray();
} else {
jgen.writeString(printLocalDate(dt));
}
}
@Override
public JsonNode getSchema(SerializerProvider provider, java.lang.reflect.Type typeHint)
{
return createSchemaNode(provider.isEnabled(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS)
? "array" : "string", true);
}
}
public final static class DateMidnightSerializer
extends JodaSerializer<DateMidnight>
{
public DateMidnightSerializer() { super(DateMidnight.class); }
@Override
public void serialize(DateMidnight dt, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonGenerationException
{
if (provider.isEnabled(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS)) {
// same as with other date-only values
jgen.writeStartArray();
jgen.writeNumber(dt.year().get());
jgen.writeNumber(dt.monthOfYear().get());
jgen.writeNumber(dt.dayOfMonth().get());
jgen.writeEndArray();
} else {
jgen.writeString(printLocalDate(dt));
}
}
@Override
public JsonNode getSchema(SerializerProvider provider, java.lang.reflect.Type typeHint)
{
return createSchemaNode(provider.isEnabled(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS)
? "array" : "string", true);
}
}
}