in src/main/java/com/uber/cadence/converter/JsonDataConverter.java [172:235]
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
// Special handling of fields of DataConverter type.
// Needed to serialize exceptions like ActivityTimeoutException.
if (DataConverter.class.isAssignableFrom(typeToken.getRawType())) {
return new TypeAdapter<T>() {
@Override
public void write(JsonWriter out, T value) throws IOException {
out.beginObject();
out.name(TYPE_FIELD_NAME).value(JSON_CONVERTER_TYPE);
out.endObject();
}
@Override
@SuppressWarnings("unchecked")
public T read(JsonReader in) throws IOException {
in.beginObject();
if (!in.nextName().equals(TYPE_FIELD_NAME)) {
throw new IOException("Cannot deserialize DataConverter. Missing type field");
}
String value = in.nextString();
if (!"JSON".equals(value)) {
throw new IOException(
"Cannot deserialize DataConverter. Expected type is JSON. " + "Found " + value);
}
in.endObject();
return (T) JsonDataConverter.getInstance();
}
};
}
if (Class.class.isAssignableFrom(typeToken.getRawType())) {
return new TypeAdapter<T>() {
@Override
public void write(JsonWriter out, T value) throws IOException {
out.beginObject();
String className = ((Class) value).getName();
out.name(CLASS_NAME_FIELD_NAME).value(className);
out.endObject();
}
@Override
public T read(JsonReader in) throws IOException {
in.beginObject();
if (!in.nextName().equals(CLASS_NAME_FIELD_NAME)) {
throw new IOException(
"Cannot deserialize class. Missing " + CLASS_NAME_FIELD_NAME + " field");
}
String className = in.nextString();
try {
@SuppressWarnings("unchecked")
T result = (T) Class.forName(className);
in.endObject();
return result;
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
};
}
if (!Throwable.class.isAssignableFrom(typeToken.getRawType())) {
return null; // this class only serializes 'Throwable' and its subtypes
}
return new CustomThrowableTypeAdapter(gson, this).nullSafe();
}