Advertisement
Guest User

Untitled

a guest
Aug 24th, 2019
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.58 KB | None | 0 0
  1. import com.fasterxml.jackson.core.{JsonGenerator, JsonParser}
  2. import com.fasterxml.jackson.databind.deser.Deserializers
  3. import com.fasterxml.jackson.databind.ser.Serializers
  4. import com.fasterxml.jackson.databind.{BeanDescription, DeserializationConfig, DeserializationContext, JavaType, JsonDeserializer, JsonSerializer, SerializationConfig, SerializerProvider}
  5. import com.fasterxml.jackson.module.scala.JacksonModule
  6.  
  7. import scala.reflect.runtime.universe._
  8.  
  9. class JsonEnum extends scala.annotation.StaticAnnotation
  10. class JsonEnumItem(value: String) extends scala.annotation.StaticAnnotation
  11.  
  12. object EnumHelpers {
  13. def getJsonEnumItemValue(annotation: Annotation) = {
  14. annotation.tree.children(1).asInstanceOf[Literal].value.value.toString
  15. }
  16.  
  17. def getEnumBaseTrait(symbol: Symbol): Option[ClassSymbol] = {
  18. if (symbol.isClass) {
  19. val classSymbol = symbol.asClass
  20. if (classSymbol.isTrait && classSymbol.isSealed && classSymbol.annotations.exists(_.tree.tpe =:= typeOf[JsonEnum]))
  21. Some(classSymbol)
  22. else
  23. None
  24. } else {
  25. None
  26. }
  27. }
  28.  
  29. def getEnumTrait(javaType: JavaType): Option[ClassSymbol] = {
  30. val classSymbol = runtimeMirror(getClass.getClassLoader).classSymbol(javaType.getRawClass)
  31. val traitClasses = classSymbol.baseClasses.map(getEnumBaseTrait).flatten
  32. traitClasses.headOption
  33. }
  34.  
  35. def getEnumItemString(symbol: ClassSymbol): String = {
  36. symbol.
  37. annotations.find(_.tree.tpe =:= typeOf[JsonEnumItem]).
  38. map(getJsonEnumItemValue).getOrElse(symbol.name.toString)
  39. }
  40.  
  41. def getEnumItemInstance(symbol: ClassSymbol) = {
  42. val mirror = runtimeMirror(getClass.getClassLoader)
  43. val module = mirror.staticModule(symbol.fullName)
  44. val objekt = mirror.reflectModule(module).instance
  45. objekt
  46. }
  47.  
  48. def getEnumItemsToStr(traitSymbol: ClassSymbol) = {
  49. traitSymbol.
  50. knownDirectSubclasses.toList.map(_.asClass).
  51. map(s => getEnumItemInstance(s) -> getEnumItemString(s)).toMap
  52. }
  53.  
  54. def getEnumItemsFromStr(traitSymbol: ClassSymbol) = {
  55. for ((k,v) <- getEnumItemsToStr(traitSymbol)) yield (v, k)
  56. }
  57. }
  58.  
  59. private class EnumSealedSerializer(val enumItems: Map[Any, String]) extends JsonSerializer[Any] {
  60. override def serialize(value: Any, jgen: JsonGenerator, provider: SerializerProvider) = {
  61. val strValue = enumItems(value)
  62. jgen.writeString(strValue)
  63. }
  64. }
  65.  
  66. private object EnumSealedSerializerResolver extends Serializers.Base {
  67. import EnumHelpers._
  68.  
  69. override def findSerializer(
  70. config: SerializationConfig,
  71. javaType: JavaType,
  72. beanDescription: BeanDescription
  73. ): JsonSerializer[_] = {
  74. getEnumTrait(javaType).map(symbol => new EnumSealedSerializer(getEnumItemsToStr(symbol))).getOrElse(null)
  75. }
  76. }
  77.  
  78. trait EnumSealedSerializerModule extends JacksonModule {
  79. this += EnumSealedSerializerResolver
  80. }
  81.  
  82. private class EnumSealedDeserializer(val enumItems: Map[String, Any]) extends JsonDeserializer[Any] {
  83. override def deserialize(p: JsonParser, ctxt: DeserializationContext): Any = {
  84. val strValue = p.readValueAs(classOf[String])
  85. enumItems(strValue)
  86. }
  87. }
  88.  
  89. private object EnumSealedDeserializerResolver extends Deserializers.Base {
  90. import EnumHelpers._
  91.  
  92. override def findBeanDeserializer(
  93. javaType: JavaType,
  94. config: DeserializationConfig,
  95. beanDesc: BeanDescription
  96. ): JsonDeserializer[_] = {
  97. getEnumTrait(javaType).map(symbol => new EnumSealedDeserializer(getEnumItemsFromStr(symbol))).getOrElse(null)
  98. }
  99. }
  100.  
  101. trait EnumSealedDeserializerModule extends JacksonModule {
  102. this += EnumSealedDeserializerResolver
  103. }
  104.  
  105. object EnumSealedModule extends EnumSealedSerializerModule with EnumSealedDeserializerModule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement