// Copyright 2012 Google Inc. All Rights Reserved.
package com.google.collide.server.documents;
import static com.google.collide.dto.DocOpComponent.Type.DELETE;
import static com.google.collide.dto.DocOpComponent.Type.INSERT;
import static com.google.collide.dto.DocOpComponent.Type.RETAIN;
import static com.google.collide.dto.DocOpComponent.Type.RETAIN_LINE;
import com.google.collide.dto.DocOpComponent;
import com.google.collide.dto.DocOpComponent.Delete;
import com.google.collide.dto.DocOpComponent.Insert;
import com.google.collide.dto.DocOpComponent.Retain;
import com.google.collide.dto.DocOpComponent.RetainLine;
import com.google.collide.dto.server.DtoServerImpls.DocOpComponentImpl;
import com.google.collide.dto.server.ServerDocOpFactory;
import com.google.gson.Gson;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import java.lang.reflect.Type;
/*
* TODO(jasonparekh): consider creating custom deserializers for subclasses as a
* feature in our DTO generator, or at minimum constants for the JSON property
* keys.
*/
/**
* Custom {@link Gson} deserializer for {@link DocOpComponent} subclasses.
*
* @author jasonparekh@google.com (Jason Parekh)
*/
public class DocOpComponentDeserializer
implements
JsonDeserializer<DocOpComponentImpl>,
JsonSerializer<DocOpComponentImpl> {
@Override
public DocOpComponentImpl deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
JsonObject componentJo = json.getAsJsonObject();
switch (componentJo.get("type").getAsInt()) {
case DELETE:
return (DocOpComponentImpl) ServerDocOpFactory.INSTANCE.createDelete(componentJo
.get("text")
.getAsString());
case INSERT:
return (DocOpComponentImpl) ServerDocOpFactory.INSTANCE.createInsert(componentJo
.get("text")
.getAsString());
case RETAIN:
return (DocOpComponentImpl) ServerDocOpFactory.INSTANCE.createRetain(
componentJo.get("count").getAsInt(),
componentJo.get("hasTrailingNewline").getAsBoolean());
case RETAIN_LINE:
return (DocOpComponentImpl) ServerDocOpFactory.INSTANCE.createRetainLine(componentJo.get(
"lineCount").getAsInt());
default:
throw new IllegalArgumentException("Could not deserialize DocOpComponent: "
+ componentJo);
}
}
@Override
public JsonElement serialize(DocOpComponentImpl component, Type typeOfSrc,
JsonSerializationContext context) {
JsonObject componentJo = new JsonObject();
componentJo.addProperty("type", component.getType());
switch (component.getType()) {
case DELETE:
componentJo.addProperty("text", ((Delete) component).getText());
break;
case INSERT:
componentJo.addProperty("text", ((Insert) component).getText());
break;
case RETAIN:
componentJo.addProperty("count", ((Retain) component).getCount());
componentJo.addProperty("hasTrailingNewline", ((Retain) component).hasTrailingNewline());
break;
case RETAIN_LINE:
componentJo.addProperty("lineCount", ((RetainLine) component).getLineCount());
break;
default:
throw new IllegalArgumentException("Could not serialize DocOpComponent: " + component);
}
return componentJo;
}
}