diff --git a/gson/src/main/java/com/google/gson/Gson.java b/gson/src/main/java/com/google/gson/Gson.java
index 27f3ee92..a7938c84 100644
--- a/gson/src/main/java/com/google/gson/Gson.java
+++ b/gson/src/main/java/com/google/gson/Gson.java
@@ -49,9 +49,8 @@ import com.google.gson.internal.bind.JsonTreeWriter;
import com.google.gson.internal.bind.MapTypeAdapterFactory;
import com.google.gson.internal.bind.ObjectTypeAdapter;
import com.google.gson.internal.bind.ReflectiveTypeAdapterFactory;
-import com.google.gson.internal.bind.SqlDateTypeAdapter;
-import com.google.gson.internal.bind.TimeTypeAdapter;
import com.google.gson.internal.bind.TypeAdapters;
+import com.google.gson.internal.sql.SqlTypesSupport;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
@@ -262,9 +261,13 @@ public final class Gson {
factories.add(TypeAdapters.BIT_SET_FACTORY);
factories.add(DateTypeAdapter.FACTORY);
factories.add(TypeAdapters.CALENDAR_FACTORY);
- factories.add(TimeTypeAdapter.FACTORY);
- factories.add(SqlDateTypeAdapter.FACTORY);
- factories.add(TypeAdapters.TIMESTAMP_FACTORY);
+
+ if (SqlTypesSupport.SUPPORTS_SQL_TYPES) {
+ factories.add(SqlTypesSupport.TIME_FACTORY);
+ factories.add(SqlTypesSupport.DATE_FACTORY);
+ factories.add(SqlTypesSupport.TIMESTAMP_FACTORY);
+ }
+
factories.add(ArrayTypeAdapter.FACTORY);
factories.add(TypeAdapters.CLASS_FACTORY);
diff --git a/gson/src/main/java/com/google/gson/GsonBuilder.java b/gson/src/main/java/com/google/gson/GsonBuilder.java
index 2c8dbe03..b2fd74ed 100644
--- a/gson/src/main/java/com/google/gson/GsonBuilder.java
+++ b/gson/src/main/java/com/google/gson/GsonBuilder.java
@@ -17,7 +17,6 @@
package com.google.gson;
import java.lang.reflect.Type;
-import java.sql.Timestamp;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collections;
@@ -28,8 +27,10 @@ import java.util.Map;
import com.google.gson.internal.$Gson$Preconditions;
import com.google.gson.internal.Excluder;
+import com.google.gson.internal.bind.DefaultDateTypeAdapter;
import com.google.gson.internal.bind.TreeTypeAdapter;
import com.google.gson.internal.bind.TypeAdapters;
+import com.google.gson.internal.sql.SqlTypesSupport;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
@@ -417,8 +418,8 @@ public final class GsonBuilder {
* call this method or {@link #setDateFormat(int)} multiple times, but only the last invocation
* will be used to decide the serialization format.
*
- *
The date format will be used to serialize and deserialize {@link java.util.Date}, {@link
- * java.sql.Timestamp} and {@link java.sql.Date}.
+ *
The date format will be used to serialize and deserialize {@link java.util.Date} and in case
+ * the {@code java.sql} module is present, also {@link java.sql.Timestamp} and {@link java.sql.Date}.
*
*
Note that this pattern must abide by the convention provided by {@code SimpleDateFormat}
* class. See the documentation in {@link java.text.SimpleDateFormat} for more information on
@@ -604,23 +605,33 @@ public final class GsonBuilder {
private void addTypeAdaptersForDate(String datePattern, int dateStyle, int timeStyle,
List factories) {
- DefaultDateTypeAdapter dateTypeAdapter;
- TypeAdapter timestampTypeAdapter;
- TypeAdapter javaSqlDateTypeAdapter;
- if (datePattern != null && !"".equals(datePattern.trim())) {
- dateTypeAdapter = DefaultDateTypeAdapter.DateType.DATE.createAdapter(datePattern);
- timestampTypeAdapter = DefaultDateTypeAdapter.DateType.SQL_TIMESTAMP.createAdapter(datePattern);
- javaSqlDateTypeAdapter = DefaultDateTypeAdapter.DateType.SQL_DATE.createAdapter(datePattern);
+ TypeAdapterFactory dateAdapterFactory;
+ boolean sqlTypesSupported = SqlTypesSupport.SUPPORTS_SQL_TYPES;
+ TypeAdapterFactory sqlTimestampAdapterFactory = null;
+ TypeAdapterFactory sqlDateAdapterFactory = null;
+
+ if (datePattern != null && !datePattern.trim().isEmpty()) {
+ dateAdapterFactory = DefaultDateTypeAdapter.DateType.DATE.createAdapterFactory(datePattern);
+
+ if (sqlTypesSupported) {
+ sqlTimestampAdapterFactory = SqlTypesSupport.TIMESTAMP_DATE_TYPE.createAdapterFactory(datePattern);
+ sqlDateAdapterFactory = SqlTypesSupport.DATE_DATE_TYPE.createAdapterFactory(datePattern);
+ }
} else if (dateStyle != DateFormat.DEFAULT && timeStyle != DateFormat.DEFAULT) {
- dateTypeAdapter = DefaultDateTypeAdapter.DateType.DATE.createAdapter(dateStyle, timeStyle);
- timestampTypeAdapter = DefaultDateTypeAdapter.DateType.SQL_TIMESTAMP.createAdapter(dateStyle, timeStyle);
- javaSqlDateTypeAdapter = DefaultDateTypeAdapter.DateType.SQL_DATE.createAdapter(dateStyle, timeStyle);
+ dateAdapterFactory = DefaultDateTypeAdapter.DateType.DATE.createAdapterFactory(dateStyle, timeStyle);
+
+ if (sqlTypesSupported) {
+ sqlTimestampAdapterFactory = SqlTypesSupport.TIMESTAMP_DATE_TYPE.createAdapterFactory(dateStyle, timeStyle);
+ sqlDateAdapterFactory = SqlTypesSupport.DATE_DATE_TYPE.createAdapterFactory(dateStyle, timeStyle);
+ }
} else {
return;
}
- factories.add(TypeAdapters.newFactory(Date.class, dateTypeAdapter));
- factories.add(TypeAdapters.newFactory(Timestamp.class, timestampTypeAdapter));
- factories.add(TypeAdapters.newFactory(java.sql.Date.class, javaSqlDateTypeAdapter));
+ factories.add(dateAdapterFactory);
+ if (sqlTypesSupported) {
+ factories.add(sqlTimestampAdapterFactory);
+ factories.add(sqlDateAdapterFactory);
+ }
}
}
diff --git a/gson/src/main/java/com/google/gson/DefaultDateTypeAdapter.java b/gson/src/main/java/com/google/gson/internal/bind/DefaultDateTypeAdapter.java
similarity index 73%
rename from gson/src/main/java/com/google/gson/DefaultDateTypeAdapter.java
rename to gson/src/main/java/com/google/gson/internal/bind/DefaultDateTypeAdapter.java
index 81b809be..9ac948f7 100644
--- a/gson/src/main/java/com/google/gson/DefaultDateTypeAdapter.java
+++ b/gson/src/main/java/com/google/gson/internal/bind/DefaultDateTypeAdapter.java
@@ -14,10 +14,9 @@
* limitations under the License.
*/
-package com.google.gson;
+package com.google.gson.internal.bind;
import java.io.IOException;
-import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
@@ -27,6 +26,9 @@ import java.util.Date;
import java.util.List;
import java.util.Locale;
+import com.google.gson.JsonSyntaxException;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
import com.google.gson.internal.JavaVersion;
import com.google.gson.internal.PreJava9DateFormatProvider;
import com.google.gson.internal.bind.util.ISO8601Utils;
@@ -35,54 +37,49 @@ import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
/**
- * This type adapter supports three subclasses of date: Date, Timestamp, and
- * java.sql.Date.
+ * This type adapter supports subclasses of date by defining a
+ * {@link DefaultDateTypeAdapter.DateType} and then using its {@code createAdapterFactory}
+ * methods.
*
* @author Inderjeet Singh
* @author Joel Leitch
*/
-final class DefaultDateTypeAdapter extends TypeAdapter {
+public final class DefaultDateTypeAdapter extends TypeAdapter {
private static final String SIMPLE_NAME = "DefaultDateTypeAdapter";
- static abstract class DateType {
- private DateType() {
- }
-
- public static final DateType DATE = new DateType() {
- @Override
- protected Date deserialize(Date date) {
+ public static abstract class DateType {
+ public static final DateType DATE = new DateType(Date.class) {
+ @Override protected Date deserialize(Date date) {
return date;
}
};
- public static final DateType SQL_DATE = new DateType() {
- @Override
- protected java.sql.Date deserialize(Date date) {
- return new java.sql.Date(date.getTime());
- }
- };
- public static final DateType SQL_TIMESTAMP = new DateType() {
- @Override
- protected Timestamp deserialize(Date date) {
- return new Timestamp(date.getTime());
- }
- };
+
+ private final Class dateClass;
+
+ protected DateType(Class dateClass) {
+ this.dateClass = dateClass;
+ }
protected abstract T deserialize(Date date);
- public DefaultDateTypeAdapter createAdapter(String datePattern) {
- return new DefaultDateTypeAdapter(this, datePattern);
+ private final TypeAdapterFactory createFactory(DefaultDateTypeAdapter adapter) {
+ return TypeAdapters.newFactory(dateClass, adapter);
}
- public DefaultDateTypeAdapter createAdapter(int style) {
- return new DefaultDateTypeAdapter(this, style);
+ public final TypeAdapterFactory createAdapterFactory(String datePattern) {
+ return createFactory(new DefaultDateTypeAdapter(this, datePattern));
}
- public DefaultDateTypeAdapter createAdapter(int dateStyle, int timeStyle) {
- return new DefaultDateTypeAdapter(this, dateStyle, timeStyle);
+ public final TypeAdapterFactory createAdapterFactory(int style) {
+ return createFactory(new DefaultDateTypeAdapter(this, style));
}
- public DefaultDateTypeAdapter createDefaultsAdapter() {
- return new DefaultDateTypeAdapter(this, DateFormat.DEFAULT, DateFormat.DEFAULT);
+ public final TypeAdapterFactory createAdapterFactory(int dateStyle, int timeStyle) {
+ return createFactory(new DefaultDateTypeAdapter(this, dateStyle, timeStyle));
+ }
+
+ public final TypeAdapterFactory createDefaultsAdapterFactory() {
+ return createFactory(new DefaultDateTypeAdapter(this, DateFormat.DEFAULT, DateFormat.DEFAULT));
}
}
@@ -162,11 +159,12 @@ final class DefaultDateTypeAdapter extends TypeAdapter {
return dateFormat.parse(s);
} catch (ParseException ignored) {}
}
- try {
- return ISO8601Utils.parse(s, new ParsePosition(0));
- } catch (ParseException e) {
- throw new JsonSyntaxException(s, e);
- }
+ }
+
+ try {
+ return ISO8601Utils.parse(s, new ParsePosition(0));
+ } catch (ParseException e) {
+ throw new JsonSyntaxException(s, e);
}
}
diff --git a/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java b/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java
index 354ce5a1..af790e2c 100644
--- a/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java
+++ b/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java
@@ -23,12 +23,10 @@ import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
-import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Currency;
-import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
@@ -406,7 +404,7 @@ public final class TypeAdapters {
out.value(value);
}
};
-
+
public static final TypeAdapter BIG_DECIMAL = new TypeAdapter() {
@Override public BigDecimal read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
@@ -424,7 +422,7 @@ public final class TypeAdapters {
out.value(value);
}
};
-
+
public static final TypeAdapter BIG_INTEGER = new TypeAdapter() {
@Override public BigInteger read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
@@ -569,27 +567,6 @@ public final class TypeAdapters {
}.nullSafe();
public static final TypeAdapterFactory CURRENCY_FACTORY = newFactory(Currency.class, CURRENCY);
- public static final TypeAdapterFactory TIMESTAMP_FACTORY = new TypeAdapterFactory() {
- @SuppressWarnings("unchecked") // we use a runtime check to make sure the 'T's equal
- @Override public TypeAdapter create(Gson gson, TypeToken typeToken) {
- if (typeToken.getRawType() != Timestamp.class) {
- return null;
- }
-
- final TypeAdapter dateTypeAdapter = gson.getAdapter(Date.class);
- return (TypeAdapter) new TypeAdapter() {
- @Override public Timestamp read(JsonReader in) throws IOException {
- Date date = dateTypeAdapter.read(in);
- return date != null ? new Timestamp(date.getTime()) : null;
- }
-
- @Override public void write(JsonWriter out, Timestamp value) throws IOException {
- dateTypeAdapter.write(out, value);
- }
- };
- }
- };
-
public static final TypeAdapter CALENDAR = new TypeAdapter() {
private static final String YEAR = "year";
private static final String MONTH = "month";
diff --git a/gson/src/main/java/com/google/gson/internal/bind/SqlDateTypeAdapter.java b/gson/src/main/java/com/google/gson/internal/sql/SqlDateTypeAdapter.java
similarity index 91%
rename from gson/src/main/java/com/google/gson/internal/bind/SqlDateTypeAdapter.java
rename to gson/src/main/java/com/google/gson/internal/sql/SqlDateTypeAdapter.java
index 5ec244f2..b3da1fef 100644
--- a/gson/src/main/java/com/google/gson/internal/bind/SqlDateTypeAdapter.java
+++ b/gson/src/main/java/com/google/gson/internal/sql/SqlDateTypeAdapter.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.google.gson.internal.bind;
+package com.google.gson.internal.sql;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
@@ -35,8 +35,8 @@ import java.text.SimpleDateFormat;
* this class state. DateFormat isn't thread safe either, so this class has
* to synchronize its read and write methods.
*/
-public final class SqlDateTypeAdapter extends TypeAdapter {
- public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
+final class SqlDateTypeAdapter extends TypeAdapter {
+ static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
@SuppressWarnings("unchecked") // we use a runtime check to make sure the 'T's equal
@Override public TypeAdapter create(Gson gson, TypeToken typeToken) {
return typeToken.getRawType() == java.sql.Date.class
@@ -46,6 +46,9 @@ public final class SqlDateTypeAdapter extends TypeAdapter {
private final DateFormat format = new SimpleDateFormat("MMM d, yyyy");
+ private SqlDateTypeAdapter() {
+ }
+
@Override
public synchronized java.sql.Date read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
diff --git a/gson/src/main/java/com/google/gson/internal/bind/TimeTypeAdapter.java b/gson/src/main/java/com/google/gson/internal/sql/SqlTimeTypeAdapter.java
similarity index 86%
rename from gson/src/main/java/com/google/gson/internal/bind/TimeTypeAdapter.java
rename to gson/src/main/java/com/google/gson/internal/sql/SqlTimeTypeAdapter.java
index 55d4b2f6..ee65726b 100644
--- a/gson/src/main/java/com/google/gson/internal/bind/TimeTypeAdapter.java
+++ b/gson/src/main/java/com/google/gson/internal/sql/SqlTimeTypeAdapter.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.google.gson.internal.bind;
+package com.google.gson.internal.sql;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
@@ -32,21 +32,24 @@ import java.text.SimpleDateFormat;
import java.util.Date;
/**
- * Adapter for Time. Although this class appears stateless, it is not.
+ * Adapter for java.sql.Time. Although this class appears stateless, it is not.
* DateFormat captures its time zone and locale when it is created, which gives
* this class state. DateFormat isn't thread safe either, so this class has
* to synchronize its read and write methods.
*/
-public final class TimeTypeAdapter extends TypeAdapter