Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warning fixes #1656

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
87 changes: 52 additions & 35 deletions gson/src/main/java/com/google/gson/DefaultDateTypeAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,38 +41,68 @@
* @author Inderjeet Singh
* @author Joel Leitch
*/
final class DefaultDateTypeAdapter extends TypeAdapter<Date> {

final class DefaultDateTypeAdapter<T extends Date> extends TypeAdapter<T> {
private static final String SIMPLE_NAME = "DefaultDateTypeAdapter";

private final Class<? extends Date> dateType;
static abstract class DateType<T extends Date> {
private DateType() {
}

public static final DateType<Date> DATE = new DateType<Date>() {
@Override
protected Date deserialize(Date date) {
return date;
}
};
public static final DateType<java.sql.Date> SQL_DATE = new DateType<java.sql.Date>() {
@Override
protected java.sql.Date deserialize(Date date) {
return new java.sql.Date(date.getTime());
}
};
public static final DateType<Timestamp> SQL_TIMESTAMP = new DateType<Timestamp>() {
@Override
protected Timestamp deserialize(Date date) {
return new Timestamp(date.getTime());
}
};

protected abstract T deserialize(Date date);

public DefaultDateTypeAdapter<T> createAdapter(String datePattern) {
return new DefaultDateTypeAdapter<T>(this, datePattern);
}

public DefaultDateTypeAdapter<T> createAdapter(int style) {
return new DefaultDateTypeAdapter<T>(this, style);
}

public DefaultDateTypeAdapter<T> createAdapter(int dateStyle, int timeStyle) {
return new DefaultDateTypeAdapter<T>(this, dateStyle, timeStyle);
}

public DefaultDateTypeAdapter<T> createDefaultsAdapter() {
return new DefaultDateTypeAdapter<T>(this, DateFormat.DEFAULT, DateFormat.DEFAULT);
}
}

private final DateType<T> dateType;

/**
* List of 1 or more different date formats used for de-serialization attempts.
* The first of them is used for serialization as well.
*/
private final List<DateFormat> dateFormats = new ArrayList<DateFormat>();

DefaultDateTypeAdapter(Class<? extends Date> dateType) {
this.dateType = verifyDateType(dateType);
dateFormats.add(DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.US));
if (!Locale.getDefault().equals(Locale.US)) {
dateFormats.add(DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT));
}
if (JavaVersion.isJava9OrLater()) {
dateFormats.add(PreJava9DateFormatProvider.getUSDateTimeFormat(DateFormat.DEFAULT, DateFormat.DEFAULT));
}
}

DefaultDateTypeAdapter(Class<? extends Date> dateType, String datePattern) {
private DefaultDateTypeAdapter(DateType<T> dateType, String datePattern) {
this.dateType = verifyDateType(dateType);
dateFormats.add(new SimpleDateFormat(datePattern, Locale.US));
if (!Locale.getDefault().equals(Locale.US)) {
dateFormats.add(new SimpleDateFormat(datePattern));
}
}

DefaultDateTypeAdapter(Class<? extends Date> dateType, int style) {
private DefaultDateTypeAdapter(DateType<T> dateType, int style) {
this.dateType = verifyDateType(dateType);
dateFormats.add(DateFormat.getDateInstance(style, Locale.US));
if (!Locale.getDefault().equals(Locale.US)) {
Expand All @@ -83,11 +113,7 @@ final class DefaultDateTypeAdapter extends TypeAdapter<Date> {
}
}

public DefaultDateTypeAdapter(int dateStyle, int timeStyle) {
this(Date.class, dateStyle, timeStyle);
}

public DefaultDateTypeAdapter(Class<? extends Date> dateType, int dateStyle, int timeStyle) {
private DefaultDateTypeAdapter(DateType<T> dateType, int dateStyle, int timeStyle) {
this.dateType = verifyDateType(dateType);
dateFormats.add(DateFormat.getDateTimeInstance(dateStyle, timeStyle, Locale.US));
if (!Locale.getDefault().equals(Locale.US)) {
Expand All @@ -98,9 +124,9 @@ public DefaultDateTypeAdapter(Class<? extends Date> dateType, int dateStyle, int
}
}

private static Class<? extends Date> verifyDateType(Class<? extends Date> dateType) {
if ( dateType != Date.class && dateType != java.sql.Date.class && dateType != Timestamp.class ) {
throw new IllegalArgumentException("Date type must be one of " + Date.class + ", " + Timestamp.class + ", or " + java.sql.Date.class + " but was " + dateType);
private static <T extends Date> DateType<T> verifyDateType(DateType<T> dateType) {
if (dateType == null) {
throw new NullPointerException("dateType == null");
}
return dateType;
}
Expand All @@ -120,22 +146,13 @@ public void write(JsonWriter out, Date value) throws IOException {
}

@Override
public Date read(JsonReader in) throws IOException {
public T read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
Date date = deserializeToDate(in.nextString());
if (dateType == Date.class) {
return date;
} else if (dateType == Timestamp.class) {
return new Timestamp(date.getTime());
} else if (dateType == java.sql.Date.class) {
return new java.sql.Date(date.getTime());
} else {
// This must never happen: dateType is guarded in the primary constructor
throw new AssertionError();
}
return dateType.deserialize(date);
}

private Date deserializeToDate(String s) {
Expand Down
15 changes: 7 additions & 8 deletions gson/src/main/java/com/google/gson/GsonBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -602,20 +602,19 @@ public Gson create() {
this.factories, this.hierarchyFactories, factories);
}

@SuppressWarnings("unchecked")
private void addTypeAdaptersForDate(String datePattern, int dateStyle, int timeStyle,
List<TypeAdapterFactory> factories) {
DefaultDateTypeAdapter dateTypeAdapter;
DefaultDateTypeAdapter<Date> dateTypeAdapter;
TypeAdapter<Timestamp> timestampTypeAdapter;
TypeAdapter<java.sql.Date> javaSqlDateTypeAdapter;
if (datePattern != null && !"".equals(datePattern.trim())) {
dateTypeAdapter = new DefaultDateTypeAdapter(Date.class, datePattern);
timestampTypeAdapter = (TypeAdapter) new DefaultDateTypeAdapter(Timestamp.class, datePattern);
javaSqlDateTypeAdapter = (TypeAdapter) new DefaultDateTypeAdapter(java.sql.Date.class, datePattern);
dateTypeAdapter = DefaultDateTypeAdapter.DateType.DATE.createAdapter(datePattern);
timestampTypeAdapter = DefaultDateTypeAdapter.DateType.SQL_TIMESTAMP.createAdapter(datePattern);
javaSqlDateTypeAdapter = DefaultDateTypeAdapter.DateType.SQL_DATE.createAdapter(datePattern);
} else if (dateStyle != DateFormat.DEFAULT && timeStyle != DateFormat.DEFAULT) {
dateTypeAdapter = new DefaultDateTypeAdapter(Date.class, dateStyle, timeStyle);
timestampTypeAdapter = (TypeAdapter) new DefaultDateTypeAdapter(Timestamp.class, dateStyle, timeStyle);
javaSqlDateTypeAdapter = (TypeAdapter) new DefaultDateTypeAdapter(java.sql.Date.class, dateStyle, timeStyle);
dateTypeAdapter = DefaultDateTypeAdapter.DateType.DATE.createAdapter(dateStyle, timeStyle);
timestampTypeAdapter = DefaultDateTypeAdapter.DateType.SQL_TIMESTAMP.createAdapter(dateStyle, timeStyle);
javaSqlDateTypeAdapter = DefaultDateTypeAdapter.DateType.SQL_DATE.createAdapter(dateStyle, timeStyle);
} else {
return;
}
Expand Down
4 changes: 2 additions & 2 deletions gson/src/main/java/com/google/gson/internal/$Gson$Types.java
Original file line number Diff line number Diff line change
Expand Up @@ -334,11 +334,11 @@ public static Type[] getMapKeyAndValueTypes(Type context, Class<?> contextRawTyp
}

public static Type resolve(Type context, Class<?> contextRawType, Type toResolve) {
return resolve(context, contextRawType, toResolve, new HashSet<TypeVariable>());
return resolve(context, contextRawType, toResolve, new HashSet<TypeVariable<?>>());
}

private static Type resolve(Type context, Class<?> contextRawType, Type toResolve,
Collection<TypeVariable> visitedTypeVariables) {
Collection<TypeVariable<?>> visitedTypeVariables) {
// this implementation is made a little more complicated in an attempt to avoid object-creation
while (true) {
if (toResolve instanceof TypeVariable) {
Expand Down
70 changes: 35 additions & 35 deletions gson/src/test/java/com/google/gson/DefaultDateTypeAdapterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.Locale;
import java.util.TimeZone;

import com.google.gson.DefaultDateTypeAdapter.DateType;
import com.google.gson.internal.JavaVersion;

import junit.framework.TestCase;
Expand Down Expand Up @@ -52,18 +53,18 @@ private void assertFormattingAlwaysEmitsUsLocale(Locale locale) {
String afterYearLongSep = JavaVersion.isJava9OrLater() ? " at " : " ";
String utcFull = JavaVersion.isJava9OrLater() ? "Coordinated Universal Time" : "UTC";
assertFormatted(String.format("Jan 1, 1970%s12:00:00 AM", afterYearSep),
new DefaultDateTypeAdapter(Date.class));
assertFormatted("1/1/70", new DefaultDateTypeAdapter(Date.class, DateFormat.SHORT));
assertFormatted("Jan 1, 1970", new DefaultDateTypeAdapter(Date.class, DateFormat.MEDIUM));
assertFormatted("January 1, 1970", new DefaultDateTypeAdapter(Date.class, DateFormat.LONG));
DateType.DATE.createDefaultsAdapter());
assertFormatted("1/1/70", DateType.DATE.createAdapter(DateFormat.SHORT));
assertFormatted("Jan 1, 1970", DateType.DATE.createAdapter(DateFormat.MEDIUM));
assertFormatted("January 1, 1970", DateType.DATE.createAdapter(DateFormat.LONG));
assertFormatted(String.format("1/1/70%s12:00 AM", afterYearSep),
new DefaultDateTypeAdapter(DateFormat.SHORT, DateFormat.SHORT));
DateType.DATE.createAdapter(DateFormat.SHORT, DateFormat.SHORT));
assertFormatted(String.format("Jan 1, 1970%s12:00:00 AM", afterYearSep),
new DefaultDateTypeAdapter(DateFormat.MEDIUM, DateFormat.MEDIUM));
DateType.DATE.createAdapter(DateFormat.MEDIUM, DateFormat.MEDIUM));
assertFormatted(String.format("January 1, 1970%s12:00:00 AM UTC", afterYearLongSep),
new DefaultDateTypeAdapter(DateFormat.LONG, DateFormat.LONG));
DateType.DATE.createAdapter(DateFormat.LONG, DateFormat.LONG));
assertFormatted(String.format("Thursday, January 1, 1970%s12:00:00 AM %s", afterYearLongSep, utcFull),
new DefaultDateTypeAdapter(DateFormat.FULL, DateFormat.FULL));
DateType.DATE.createAdapter(DateFormat.FULL, DateFormat.FULL));
} finally {
TimeZone.setDefault(defaultTimeZone);
Locale.setDefault(defaultLocale);
Expand All @@ -78,21 +79,21 @@ public void testParsingDatesFormattedWithSystemLocale() throws Exception {
try {
String afterYearSep = JavaVersion.isJava9OrLater() ? " à " : " ";
assertParsed(String.format("1 janv. 1970%s00:00:00", afterYearSep),
new DefaultDateTypeAdapter(Date.class));
assertParsed("01/01/70", new DefaultDateTypeAdapter(Date.class, DateFormat.SHORT));
assertParsed("1 janv. 1970", new DefaultDateTypeAdapter(Date.class, DateFormat.MEDIUM));
assertParsed("1 janvier 1970", new DefaultDateTypeAdapter(Date.class, DateFormat.LONG));
DateType.DATE.createDefaultsAdapter());
assertParsed("01/01/70", DateType.DATE.createAdapter(DateFormat.SHORT));
assertParsed("1 janv. 1970", DateType.DATE.createAdapter(DateFormat.MEDIUM));
assertParsed("1 janvier 1970", DateType.DATE.createAdapter(DateFormat.LONG));
assertParsed("01/01/70 00:00",
new DefaultDateTypeAdapter(DateFormat.SHORT, DateFormat.SHORT));
DateType.DATE.createAdapter(DateFormat.SHORT, DateFormat.SHORT));
assertParsed(String.format("1 janv. 1970%s00:00:00", afterYearSep),
new DefaultDateTypeAdapter(DateFormat.MEDIUM, DateFormat.MEDIUM));
DateType.DATE.createAdapter(DateFormat.MEDIUM, DateFormat.MEDIUM));
assertParsed(String.format("1 janvier 1970%s00:00:00 UTC", afterYearSep),
new DefaultDateTypeAdapter(DateFormat.LONG, DateFormat.LONG));
DateType.DATE.createAdapter(DateFormat.LONG, DateFormat.LONG));
assertParsed(JavaVersion.isJava9OrLater() ? (JavaVersion.getMajorJavaVersion() <11 ?
"jeudi 1 janvier 1970 à 00:00:00 Coordinated Universal Time" :
"jeudi 1 janvier 1970 à 00:00:00 Temps universel coordonné") :
"jeudi 1 janvier 1970 00 h 00 UTC",
new DefaultDateTypeAdapter(DateFormat.FULL, DateFormat.FULL));
DateType.DATE.createAdapter(DateFormat.FULL, DateFormat.FULL));
} finally {
TimeZone.setDefault(defaultTimeZone);
Locale.setDefault(defaultLocale);
Expand All @@ -105,18 +106,18 @@ public void testParsingDatesFormattedWithUsLocale() throws Exception {
Locale defaultLocale = Locale.getDefault();
Locale.setDefault(Locale.US);
try {
assertParsed("Jan 1, 1970 0:00:00 AM", new DefaultDateTypeAdapter(Date.class));
assertParsed("1/1/70", new DefaultDateTypeAdapter(Date.class, DateFormat.SHORT));
assertParsed("Jan 1, 1970", new DefaultDateTypeAdapter(Date.class, DateFormat.MEDIUM));
assertParsed("January 1, 1970", new DefaultDateTypeAdapter(Date.class, DateFormat.LONG));
assertParsed("Jan 1, 1970 0:00:00 AM", DateType.DATE.createDefaultsAdapter());
assertParsed("1/1/70", DateType.DATE.createAdapter(DateFormat.SHORT));
assertParsed("Jan 1, 1970", DateType.DATE.createAdapter(DateFormat.MEDIUM));
assertParsed("January 1, 1970", DateType.DATE.createAdapter(DateFormat.LONG));
assertParsed("1/1/70 0:00 AM",
new DefaultDateTypeAdapter(DateFormat.SHORT, DateFormat.SHORT));
DateType.DATE.createAdapter(DateFormat.SHORT, DateFormat.SHORT));
assertParsed("Jan 1, 1970 0:00:00 AM",
new DefaultDateTypeAdapter(DateFormat.MEDIUM, DateFormat.MEDIUM));
DateType.DATE.createAdapter(DateFormat.MEDIUM, DateFormat.MEDIUM));
assertParsed("January 1, 1970 0:00:00 AM UTC",
new DefaultDateTypeAdapter(DateFormat.LONG, DateFormat.LONG));
DateType.DATE.createAdapter(DateFormat.LONG, DateFormat.LONG));
assertParsed("Thursday, January 1, 1970 0:00:00 AM UTC",
new DefaultDateTypeAdapter(DateFormat.FULL, DateFormat.FULL));
DateType.DATE.createAdapter(DateFormat.FULL, DateFormat.FULL));
} finally {
TimeZone.setDefault(defaultTimeZone);
Locale.setDefault(defaultLocale);
Expand All @@ -131,16 +132,16 @@ public void testFormatUsesDefaultTimezone() throws Exception {
try {
String afterYearSep = JavaVersion.isJava9OrLater() ? ", " : " ";
assertFormatted(String.format("Dec 31, 1969%s4:00:00 PM", afterYearSep),
new DefaultDateTypeAdapter(Date.class));
assertParsed("Dec 31, 1969 4:00:00 PM", new DefaultDateTypeAdapter(Date.class));
DateType.DATE.createDefaultsAdapter());
assertParsed("Dec 31, 1969 4:00:00 PM", DateType.DATE.createDefaultsAdapter());
} finally {
TimeZone.setDefault(defaultTimeZone);
Locale.setDefault(defaultLocale);
}
}

public void testDateDeserializationISO8601() throws Exception {
DefaultDateTypeAdapter adapter = new DefaultDateTypeAdapter(Date.class);
DefaultDateTypeAdapter<Date> adapter = DateType.DATE.createDefaultsAdapter();
assertParsed("1970-01-01T00:00:00.000Z", adapter);
assertParsed("1970-01-01T00:00Z", adapter);
assertParsed("1970-01-01T00:00:00+00:00", adapter);
Expand All @@ -150,7 +151,7 @@ public void testDateDeserializationISO8601() throws Exception {

public void testDateSerialization() throws Exception {
int dateStyle = DateFormat.LONG;
DefaultDateTypeAdapter dateTypeAdapter = new DefaultDateTypeAdapter(Date.class, dateStyle);
DefaultDateTypeAdapter<Date> dateTypeAdapter = DateType.DATE.createAdapter(dateStyle);
DateFormat formatter = DateFormat.getDateInstance(dateStyle, Locale.US);
Date currentDate = new Date();

Expand All @@ -160,41 +161,40 @@ public void testDateSerialization() throws Exception {

public void testDatePattern() throws Exception {
String pattern = "yyyy-MM-dd";
DefaultDateTypeAdapter dateTypeAdapter = new DefaultDateTypeAdapter(Date.class, pattern);
DefaultDateTypeAdapter<Date> dateTypeAdapter = DateType.DATE.createAdapter(pattern);
DateFormat formatter = new SimpleDateFormat(pattern);
Date currentDate = new Date();

String dateString = dateTypeAdapter.toJson(currentDate);
assertEquals(toLiteral(formatter.format(currentDate)), dateString);
}

@SuppressWarnings("unused")
public void testInvalidDatePattern() throws Exception {
try {
new DefaultDateTypeAdapter(Date.class, "I am a bad Date pattern....");
DateType.DATE.createAdapter("I am a bad Date pattern....");
fail("Invalid date pattern should fail.");
} catch (IllegalArgumentException expected) { }
}

public void testNullValue() throws Exception {
DefaultDateTypeAdapter adapter = new DefaultDateTypeAdapter(Date.class);
DefaultDateTypeAdapter<Date> adapter = DateType.DATE.createDefaultsAdapter();
assertNull(adapter.fromJson("null"));
assertEquals("null", adapter.toJson(null));
}

public void testUnexpectedToken() throws Exception {
try {
DefaultDateTypeAdapter adapter = new DefaultDateTypeAdapter(Date.class);
DefaultDateTypeAdapter<Date> adapter = DateType.DATE.createDefaultsAdapter();
adapter.fromJson("{}");
fail("Unexpected token should fail.");
} catch (IllegalStateException expected) { }
}

private void assertFormatted(String formatted, DefaultDateTypeAdapter adapter) {
private void assertFormatted(String formatted, DefaultDateTypeAdapter<Date> adapter) {
assertEquals(toLiteral(formatted), adapter.toJson(new Date(0)));
}

private void assertParsed(String date, DefaultDateTypeAdapter adapter) throws IOException {
private void assertParsed(String date, DefaultDateTypeAdapter<Date> adapter) throws IOException {
assertEquals(date, new Date(0), adapter.fromJson(toLiteral(date)));
assertEquals("ISO 8601", new Date(0), adapter.fromJson(toLiteral("1970-01-01T00:00:00Z")));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.common.MoreAsserts;
import com.google.gson.common.TestTypes.BagOfPrimitives;
import com.google.gson.reflect.TypeToken;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ private static class HistoryCourse {
int numClasses;
}

@SafeVarargs
private static <T> List<T> createList(T ...items) {
return Arrays.asList(items);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ private String toString(Node<?, ?> root) {
}
}

@SafeVarargs
private <T> void assertIterationOrder(Iterable<T> actual, T... expected) {
ArrayList<T> actualList = new ArrayList<T>();
for (T t : actual) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ public void testEqualsAndHashCode() throws Exception {
MoreAsserts.assertEqualsAndHashCode(map1, map2);
}

@SafeVarargs
private <T> void assertIterationOrder(Iterable<T> actual, T... expected) {
ArrayList<T> actualList = new ArrayList<T>();
for (T t : actual) {
Expand Down