package water.api;
import com.google.gson.*;
import water.api.schemas3.FrameV3;
import water.api.schemas3.KeyV3;
import java.lang.reflect.Type;
/**
* Custom Gson serialization for our REST API, which does things like turn a String of a Key into
* a Key object automagically.
*/
public class H2oRestGsonHelper {
/**
* Create a Gson JSON serializer / deserializer that has custom handling for certain H2O classes for
* which our REST API does automagic type conversions.
* <p>
* TODO: this method is copy-pasted from H2oApi.java in a more limited form; refactor.
* See the comments there.
*/
public static Gson createH2oCompatibleGson() {
return new GsonBuilder()
// .registerTypeAdapterFactory(new ModelV3TypeAdapter())
.registerTypeAdapter(KeyV3.class, new KeySerializer())
.registerTypeAdapter(FrameV3.ColSpecifierV3.class, new ColSerializer())
// .registerTypeAdapter(ModelBuilderSchema.class, new ModelDeserializer())
// .registerTypeAdapter(ModelSchemaBaseV3.class, new ModelSchemaDeserializer())
.create();
}
/**
* Keys get sent as Strings and returned as objects also containing the type and URL,
* so they need a custom GSON serializer.
*/
private static class KeySerializer implements JsonSerializer<KeyV3>, JsonDeserializer<KeyV3> {
@Override
public JsonElement serialize(KeyV3 key, Type typeOfKey, JsonSerializationContext context) {
return new JsonPrimitive(key.name);
}
@Override
public KeyV3 deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) {
if (json.isJsonNull()) return null;
JsonObject jobj = json.getAsJsonObject();
String type = jobj.get("type").getAsString();
switch (type) {
// TODO: dynamically generate all possible cases
case "Key<Model>": return context.deserialize(jobj, KeyV3.ModelKeyV3.class);
case "Key<Job>": return context.deserialize(jobj, KeyV3.JobKeyV3.class);
case "Key<Grid>": return context.deserialize(jobj, KeyV3.GridKeyV3.class);
case "Key<Frame>": return context.deserialize(jobj, KeyV3.FrameKeyV3.class);
default: throw new JsonParseException("Unable to deserialize key of type " + type);
}
}
}
private static class ColSerializer implements JsonSerializer<FrameV3.ColSpecifierV3>, JsonDeserializer<FrameV3.ColSpecifierV3> {
@Override
public JsonElement serialize(FrameV3.ColSpecifierV3 col, Type typeOfCol, JsonSerializationContext context) {
return new JsonPrimitive(col.column_name); // UGH: external-facing, generated POJO uses camelCase. . .
}
@Override
public FrameV3.ColSpecifierV3 deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) {
if (json.isJsonNull()) return null;
return new FrameV3.ColSpecifierV3(json.getAsString());
}
}
}