Fixed bug 106 by adding custom serialization support for Gregorian Calendar.

This commit is contained in:
Inderjeet Singh 2009-03-11 21:46:58 +00:00
parent 16be7167ec
commit 809e3b5e21
2 changed files with 91 additions and 0 deletions

View File

@ -27,8 +27,10 @@ import java.net.URL;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
@ -78,6 +80,8 @@ final class DefaultTypeAdapters {
private static final PropertiesCreator PROPERTIES_CREATOR = new PropertiesCreator();
private static final TreeSetCreator TREE_SET_CREATOR = new TreeSetCreator();
private static final GregorianCalendarTypeAdapter GREGORIAN_CALENDAR_TYPE_ADAPTER =
new GregorianCalendarTypeAdapter();
// The constants DEFAULT_SERIALIZERS, DEFAULT_DESERIALIZERS, and DEFAULT_INSTANCE_CREATORS
// must be defined after the constants for the type adapters. Otherwise, the type adapter
@ -101,6 +105,8 @@ final class DefaultTypeAdapters {
map.register(Collection.class, COLLECTION_TYPE_ADAPTER);
map.register(Map.class, MAP_TYPE_ADAPTER);
map.register(Date.class, DATE_TYPE_ADAPTER);
map.register(Calendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER);
map.register(GregorianCalendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER);
map.register(BigDecimal.class, BIG_DECIMAL_TYPE_ADAPTER);
map.register(BigInteger.class, BIG_INTEGER_TYPE_ADAPTER);
@ -133,6 +139,8 @@ final class DefaultTypeAdapters {
map.register(Collection.class, wrapDeserializer(COLLECTION_TYPE_ADAPTER));
map.register(Map.class, wrapDeserializer(MAP_TYPE_ADAPTER));
map.register(Date.class, wrapDeserializer(DATE_TYPE_ADAPTER));
map.register(Calendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER);
map.register(GregorianCalendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER);
map.register(BigDecimal.class, wrapDeserializer(BIG_DECIMAL_TYPE_ADAPTER));
map.register(BigInteger.class, wrapDeserializer(BIG_INTEGER_TYPE_ADAPTER));
@ -267,6 +275,40 @@ final class DefaultTypeAdapters {
}
}
private static class GregorianCalendarTypeAdapter implements JsonSerializer<GregorianCalendar>,
JsonDeserializer<GregorianCalendar> {
private static final String YEAR = "year";
private static final String MONTH = "month";
private static final String DAY_OF_MONTH = "dayOfMonth";
private static final String HOUR_OF_DAY = "hourOfDay";
private static final String MINUTE = "minute";
private static final String SECOND = "second";
public JsonElement serialize(GregorianCalendar src, Type typeOfSrc,
JsonSerializationContext context) {
JsonObject obj = new JsonObject();
obj.addProperty(YEAR, src.get(Calendar.YEAR));
obj.addProperty(MONTH, src.get(Calendar.MONTH));
obj.addProperty(DAY_OF_MONTH, src.get(Calendar.DAY_OF_MONTH));
obj.addProperty(HOUR_OF_DAY, src.get(Calendar.HOUR_OF_DAY));
obj.addProperty(MINUTE, src.get(Calendar.MINUTE));
obj.addProperty(SECOND, src.get(Calendar.SECOND));
return obj;
}
public GregorianCalendar deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
JsonObject obj = json.getAsJsonObject();
int year = obj.get(YEAR).getAsInt();
int month = obj.get(MONTH).getAsInt();
int dayOfMonth = obj.get(DAY_OF_MONTH).getAsInt();
int hourOfDay = obj.get(HOUR_OF_DAY).getAsInt();
int minute = obj.get(MINUTE).getAsInt();
int second = obj.get(SECOND).getAsInt();
return new GregorianCalendar(year, month, dayOfMonth, hourOfDay, minute, second);
}
}
@SuppressWarnings("unchecked")
private static class EnumTypeAdapter<T extends Enum<T>>
implements JsonSerializer<T>, JsonDeserializer<T> {

View File

@ -21,7 +21,9 @@ import java.net.URI;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Locale;
import java.util.Properties;
@ -217,6 +219,53 @@ public class DefaultTypeAdaptersTest extends TestCase {
assertEquals(now.toString(), extracted.toString());
}
public void testDefaultCalendarSerialization() throws Exception {
Gson gson = new GsonBuilder().create();
String json = gson.toJson(Calendar.getInstance());
assertTrue(json.contains("year"));
assertTrue(json.contains("month"));
assertTrue(json.contains("dayOfMonth"));
assertTrue(json.contains("hourOfDay"));
assertTrue(json.contains("minute"));
assertTrue(json.contains("second"));
}
public void testDefaultCalendarDeserialization() throws Exception {
Gson gson = new GsonBuilder().create();
String json = "{year:2009,month:2,dayOfMonth:11,hourOfDay:14,minute:29,second:23}";
Calendar cal = gson.fromJson(json, Calendar.class);
assertEquals(2009, cal.get(Calendar.YEAR));
assertEquals(2, cal.get(Calendar.MONTH));
assertEquals(11, cal.get(Calendar.DAY_OF_MONTH));
assertEquals(14, cal.get(Calendar.HOUR_OF_DAY));
assertEquals(29, cal.get(Calendar.MINUTE));
assertEquals(23, cal.get(Calendar.SECOND));
}
public void testDefaultGregorianCalendarSerialization() throws Exception {
Gson gson = new GsonBuilder().create();
GregorianCalendar cal = new GregorianCalendar();
String json = gson.toJson(cal);
assertTrue(json.contains("year"));
assertTrue(json.contains("month"));
assertTrue(json.contains("dayOfMonth"));
assertTrue(json.contains("hourOfDay"));
assertTrue(json.contains("minute"));
assertTrue(json.contains("second"));
}
public void testDefaultGregorianCalendarDeserialization() throws Exception {
Gson gson = new GsonBuilder().create();
String json = "{year:2009,month:2,dayOfMonth:11,hourOfDay:14,minute:29,second:23}";
GregorianCalendar cal = gson.fromJson(json, GregorianCalendar.class);
assertEquals(2009, cal.get(Calendar.YEAR));
assertEquals(2, cal.get(Calendar.MONTH));
assertEquals(11, cal.get(Calendar.DAY_OF_MONTH));
assertEquals(14, cal.get(Calendar.HOUR_OF_DAY));
assertEquals(29, cal.get(Calendar.MINUTE));
assertEquals(23, cal.get(Calendar.SECOND));
}
public void testDateSerializationWithPattern() throws Exception {
String pattern = "yyyy-MM-dd";
DateFormat formatter = new SimpleDateFormat(pattern);