From ebf24fbda51cd8391791fb89499a6d732a36d835 Mon Sep 17 00:00:00 2001 From: Inderjeet Singh Date: Fri, 4 Dec 2009 01:21:13 +0000 Subject: [PATCH] Fixed issue 134 by adding support for java.sql Date and Timestamp classses. --- .../com/google/gson/DefaultTypeAdapters.java | 25 ++++++++ .../functional/DefaultTypeAdaptersTest.java | 62 ++++++++++++++++--- 2 files changed, 77 insertions(+), 10 deletions(-) diff --git a/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java b/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java index dd519062..6552815f 100644 --- a/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java +++ b/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java @@ -24,6 +24,7 @@ import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.sql.Timestamp; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -55,6 +56,10 @@ import java.util.UUID; final class DefaultTypeAdapters { private static final DefaultDateTypeAdapter DATE_TYPE_ADAPTER = new DefaultDateTypeAdapter(); + private static final DefaultJavaSqlDateDeserializer JAVA_SQL_DATE_DESERIALIZER = + new DefaultJavaSqlDateDeserializer(); + private static final DefaultTimestampDeserializer TIMESTAMP_DESERIALIZER = + new DefaultTimestampDeserializer(); @SuppressWarnings("unchecked") private static final EnumTypeAdapter ENUM_TYPE_ADAPTER = new EnumTypeAdapter(); @@ -106,6 +111,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(Timestamp.class, DATE_TYPE_ADAPTER); + map.register(java.sql.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); @@ -140,6 +147,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(java.sql.Date.class, wrapDeserializer(JAVA_SQL_DATE_DESERIALIZER)); + map.register(Timestamp.class, wrapDeserializer(TIMESTAMP_DESERIALIZER)); 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)); @@ -281,6 +290,22 @@ final class DefaultTypeAdapters { } } + static class DefaultJavaSqlDateDeserializer implements JsonDeserializer { + public java.sql.Date deserialize(JsonElement json, Type typeOfT, + JsonDeserializationContext context) throws JsonParseException { + Date date = context.deserialize(json, Date.class); + return new java.sql.Date(date.getTime()); + } + } + + static class DefaultTimestampDeserializer implements JsonDeserializer { + public Timestamp deserialize(JsonElement json, Type typeOfT, + JsonDeserializationContext context) throws JsonParseException { + Date date = context.deserialize(json, Date.class); + return new Timestamp(date.getTime()); + } + } + private static class GregorianCalendarTypeAdapter implements JsonSerializer, JsonDeserializer { diff --git a/gson/src/test/java/com/google/gson/functional/DefaultTypeAdaptersTest.java b/gson/src/test/java/com/google/gson/functional/DefaultTypeAdaptersTest.java index 1a6e825a..254854d1 100644 --- a/gson/src/test/java/com/google/gson/functional/DefaultTypeAdaptersTest.java +++ b/gson/src/test/java/com/google/gson/functional/DefaultTypeAdaptersTest.java @@ -15,10 +15,17 @@ */ package com.google.gson.functional; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; + +import junit.framework.TestCase; + import java.math.BigDecimal; import java.math.BigInteger; import java.net.URI; import java.net.URL; +import java.sql.Timestamp; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; @@ -30,12 +37,6 @@ import java.util.Properties; import java.util.Set; import java.util.UUID; -import junit.framework.TestCase; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonParseException; - /** * Functional test for Json serialization and deserialization for common classes for which default * support is provided in Gson. The tests for Map types are available in {@link MapTest}. @@ -197,11 +198,52 @@ public class DefaultTypeAdaptersTest extends TestCase { } public void testDefaultDateDeserialization() { - Date date = new Date(); - String json = gson.toJson(date); + String json = "'Dec 13, 2009 07:18:02 AM'"; Date extracted = gson.fromJson(json, Date.class); - // Using comparison of string forms since the extracted date has lost the millisecond portion. - assertEquals(date.toString(), extracted.toString()); + assertEquals(extracted, 2009, 11, 13, 7, 18, 02); + } + + // Date can not directly be compared with another instance since the deserialization loses the + // millisecond portion. + @SuppressWarnings("deprecation") + private void assertEquals(Date date, int year, int month, int day, int hours, int minutes, + int seconds) { + assertEquals(year-1900, date.getYear()); + assertEquals(month, date.getMonth()); + assertEquals(day, date.getDate()); + if (!(date instanceof java.sql.Date)) { + assertEquals(hours, date.getHours()); + assertEquals(minutes, date.getMinutes()); + assertEquals(seconds, date.getSeconds()); + } + } + + public void testDefaultJavaSqlDateSerialization() { + long currentTimeMillis = System.currentTimeMillis(); + java.sql.Date now = new java.sql.Date(currentTimeMillis); + String json = gson.toJson(now); + assertEquals("\"" + DateFormat.getDateTimeInstance().format(now) + "\"", json); + } + + @SuppressWarnings("deprecation") + public void testDefaultJavaSqlDateDeserialization() { + String json = "'Dec 3, 2009 1:18:02 PM'"; + java.sql.Date extracted = gson.fromJson(json, java.sql.Date.class); + assertEquals(extracted, 2009, 11, 3, 13, 18, 02); + } + + public void testDefaultJavaSqlTimestampSerialization() { + long currentTimeMillis = System.currentTimeMillis(); + Timestamp now = new java.sql.Timestamp(currentTimeMillis); + String json = gson.toJson(now); + assertEquals("\"" + DateFormat.getDateTimeInstance().format(now) + "\"", json); + } + + @SuppressWarnings("deprecation") + public void testDefaultJavaSqlTimestampDeserialization() { + String json = "'Dec 3, 2009 1:18:02 PM'"; + Timestamp extracted = gson.fromJson(json, Timestamp.class); + assertEquals(extracted, 2009, 11, 3, 13, 18, 02); } public void testDefaultDateSerializationUsingBuilder() throws Exception {