package org.edx.mobile.http.serialization;
import android.support.annotation.NonNull;
import java.io.IOException;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.Date;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.internal.bind.util.ISO8601Utils;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
/**
* Gson adapter for converting between ISO 8601 date and (@link Date).
*/
/* Unfortunately, the Gson library doesn't provide a built-in ISO
* 8601 date type adapter. The default date type adapters do fall
* back to parsing the ISO 8601 pattern, but serialization is done to
* a system-default or custom pattern using the local time zone (and
* without recording the UTC offset).
*/
public final class ISO8601DateTypeAdapter extends TypeAdapter<Date> {
public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
@SuppressWarnings("unchecked") // Type equality is ensured at runtime.
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
return typeToken.getRawType() != Date.class ? null :
(TypeAdapter<T>) new ISO8601DateTypeAdapter().nullSafe();
}
};
// Only allow the factory to instantiate this, to ensure that it's always wrapped
// in a null-safe wrapper, which enables the removal of the boilerplate code.
private ISO8601DateTypeAdapter() {}
@Override
public void write(@NonNull JsonWriter out, @NonNull Date date) throws IOException {
out.value(ISO8601Utils.format(date, true));
}
@Override
@NonNull
public Date read(final JsonReader in) throws IOException {
final String date = in.nextString();
final ParsePosition parsePosition = new ParsePosition(0);
try {
return ISO8601Utils.parse(date, parsePosition);
} catch (ParseException e) {
throw new JsonSyntaxException(date, e);
}
}
}