Skip to content

Instantly share code, notes, and snippets.

@galcyurio
Last active May 16, 2019 07:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save galcyurio/7900ce61a4a7535d8c5e55d367860017 to your computer and use it in GitHub Desktop.
Save galcyurio/7900ce61a4a7535d8c5e55d367860017 to your computer and use it in GitHub Desktop.
import com.google.gson.Gson
import com.google.gson.JsonElement
import com.google.gson.TypeAdapter
import com.google.gson.TypeAdapterFactory
import com.google.gson.reflect.TypeToken
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonWriter
/**
* custom 직렬화, 역직렬화와 default 직렬화, 역직렬화를 섞어서 쓰기 위한 [TypeAdapterFactory]이다.
* 원하는 필드들만 조작하고 나머지 필드들은 기존 규칙을 따르도록 할 수 있다.
*
* [StackOverflow 답변 참고](https://stackoverflow.com/a/11272452/6686126)
* @author Jesse Wilson
* */
abstract class CustomizedTypeAdapterFactory<C>(
private val customizedClass: Class<C>
) : TypeAdapterFactory {
@Suppress("UNCHECKED_CAST") // we use a runtime check to guarantee that 'C' and 'T' are equal
override fun <T> create(
gson: Gson,
type: TypeToken<T>
): TypeAdapter<T>? {
return if (type.rawType == customizedClass)
customizeMyClassAdapter(gson, type as TypeToken<C>) as TypeAdapter<T>
else
null
}
private fun customizeMyClassAdapter(
gson: Gson,
type: TypeToken<C>
): TypeAdapter<C> {
val delegate = gson.getDelegateAdapter(this, type)
val elementAdapter = gson.getAdapter(JsonElement::class.java)
return object : TypeAdapter<C>() {
override fun write(out: JsonWriter, value: C) {
val tree = delegate.toJsonTree(value)
beforeWrite(value, tree)
elementAdapter.write(out, tree)
}
override fun read(`in`: JsonReader): C {
val tree = elementAdapter.read(`in`)
afterRead(tree)
return delegate.fromJsonTree(tree)
}
}
}
/**
* Override this to muck with `toSerialize` before it is written to
* the outgoing JSON stream.
*/
protected open fun beforeWrite(source: C, toSerialize: JsonElement) {}
/**
* Override this to muck with `deserialized` before it parsed into
* the application type.
*/
protected open fun afterRead(deserialized: JsonElement) {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment