Created
November 14, 2021 03:47
-
-
Save dyno/42c3837495f314007f4113a4c6a5e629 to your computer and use it in GitHub Desktop.
Gson Adapter for Scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.google.gson._ | |
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl | |
import java.lang.reflect.{ParameterizedType, Type} | |
import java.util.{ArrayList => JArrayList, LinkedHashMap => JListMap, List => JList} | |
import scala.collection.JavaConverters._ | |
import scala.collection.immutable.ListMap | |
object GsonAdapter { | |
lazy val gson = (new GsonBuilder() | |
.setPrettyPrinting() | |
.disableHtmlEscaping() | |
.registerTypeAdapter(classOf[ListMap[_, _]], ListMapAdapter) | |
.registerTypeAdapter(classOf[Option[_]], OptionAdapter) | |
.registerTypeAdapter(classOf[Seq[_]], SeqAdapter) | |
.create()) | |
def getInnerTypes(outerType: Type): Array[Type] = | |
outerType match { | |
case pt: ParameterizedType => pt.getActualTypeArguments() | |
case _ => throw new UnsupportedOperationException(outerType.toString) | |
} | |
object ListMapAdapter extends JsonSerializer[ListMap[_, _]] with JsonDeserializer[ListMap[_, _]] { | |
override def serialize(obj: ListMap[_, _], typeOfT: Type, context: JsonSerializationContext): JsonElement = { | |
val innerTypes = getInnerTypes(typeOfT) | |
val pt = ParameterizedTypeImpl.make(classOf[JListMap[_, _]], innerTypes, null) | |
val jListMap = new JListMap[Any, Any]() | |
obj.foreach { case (k, v) => jListMap.put(k, v) } | |
context.serialize(jListMap, pt) | |
} | |
override def deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): ListMap[_, _] = { | |
val innerTypes = getInnerTypes(typeOfT) | |
val pt = ParameterizedTypeImpl.make(classOf[JListMap[_, _]], innerTypes, null) | |
val jListMap: JListMap[_, _] = context.deserialize(json, pt) | |
ListMap(jListMap.asScala.toSeq: _*) | |
} | |
} | |
object OptionAdapter extends JsonSerializer[Option[_]] with JsonDeserializer[Option[_]] { | |
override def serialize(obj: Option[_], typeOfT: Type, context: JsonSerializationContext): JsonElement = { | |
val jList = new JArrayList[Any]() | |
obj.foreach(jList.add) | |
val innerTypes = getInnerTypes(typeOfT) | |
val pt = ParameterizedTypeImpl.make(classOf[JList[_]], innerTypes, null) | |
context.serialize(jList, pt) | |
} | |
override def deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Option[_] = { | |
val innerTypes = getInnerTypes(typeOfT) | |
val pt = ParameterizedTypeImpl.make(classOf[JList[_]], innerTypes, null) | |
val jList: JList[_] = context.deserialize(json, pt) | |
jList.asScala.headOption | |
} | |
} | |
object SeqAdapter extends JsonSerializer[Seq[_]] with JsonDeserializer[Seq[_]] { | |
override def serialize(obj: Seq[_], typeOfT: Type, context: JsonSerializationContext): JsonElement = { | |
val jList = new JArrayList[Any]() | |
jList.addAll(obj.asJava) | |
val innerTypes = getInnerTypes(typeOfT) | |
val pt = ParameterizedTypeImpl.make(classOf[JList[_]], innerTypes, null) | |
context.serialize(jList, pt) | |
} | |
override def deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Seq[_] = { | |
val innerTypes = getInnerTypes(typeOfT) | |
val pt = ParameterizedTypeImpl.make(classOf[JList[_]], innerTypes, null) | |
val jList: JList[_] = context.deserialize(json, pt) | |
jList.asScala.toSeq | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment