Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import com.fasterxml.jackson.core.{JsonGenerator, JsonParser}
- import com.fasterxml.jackson.databind.deser.Deserializers
- import com.fasterxml.jackson.databind.ser.Serializers
- import com.fasterxml.jackson.databind.{BeanDescription, DeserializationConfig, DeserializationContext, JavaType, JsonDeserializer, JsonSerializer, SerializationConfig, SerializerProvider}
- import com.fasterxml.jackson.module.scala.JacksonModule
- import scala.reflect.runtime.universe._
- class JsonEnum extends scala.annotation.StaticAnnotation
- class JsonEnumItem(value: String) extends scala.annotation.StaticAnnotation
- object EnumHelpers {
- def getJsonEnumItemValue(annotation: Annotation) = {
- annotation.tree.children(1).asInstanceOf[Literal].value.value.toString
- }
- def getEnumBaseTrait(symbol: Symbol): Option[ClassSymbol] = {
- if (symbol.isClass) {
- val classSymbol = symbol.asClass
- if (classSymbol.isTrait && classSymbol.isSealed && classSymbol.annotations.exists(_.tree.tpe =:= typeOf[JsonEnum]))
- Some(classSymbol)
- else
- None
- } else {
- None
- }
- }
- def getEnumTrait(javaType: JavaType): Option[ClassSymbol] = {
- val classSymbol = runtimeMirror(getClass.getClassLoader).classSymbol(javaType.getRawClass)
- val traitClasses = classSymbol.baseClasses.map(getEnumBaseTrait).flatten
- traitClasses.headOption
- }
- def getEnumItemString(symbol: ClassSymbol): String = {
- symbol.
- annotations.find(_.tree.tpe =:= typeOf[JsonEnumItem]).
- map(getJsonEnumItemValue).getOrElse(symbol.name.toString)
- }
- def getEnumItemInstance(symbol: ClassSymbol) = {
- val mirror = runtimeMirror(getClass.getClassLoader)
- val module = mirror.staticModule(symbol.fullName)
- val objekt = mirror.reflectModule(module).instance
- objekt
- }
- def getEnumItemsToStr(traitSymbol: ClassSymbol) = {
- traitSymbol.
- knownDirectSubclasses.toList.map(_.asClass).
- map(s => getEnumItemInstance(s) -> getEnumItemString(s)).toMap
- }
- def getEnumItemsFromStr(traitSymbol: ClassSymbol) = {
- for ((k,v) <- getEnumItemsToStr(traitSymbol)) yield (v, k)
- }
- }
- private class EnumSealedSerializer(val enumItems: Map[Any, String]) extends JsonSerializer[Any] {
- override def serialize(value: Any, jgen: JsonGenerator, provider: SerializerProvider) = {
- val strValue = enumItems(value)
- jgen.writeString(strValue)
- }
- }
- private object EnumSealedSerializerResolver extends Serializers.Base {
- import EnumHelpers._
- override def findSerializer(
- config: SerializationConfig,
- javaType: JavaType,
- beanDescription: BeanDescription
- ): JsonSerializer[_] = {
- getEnumTrait(javaType).map(symbol => new EnumSealedSerializer(getEnumItemsToStr(symbol))).getOrElse(null)
- }
- }
- trait EnumSealedSerializerModule extends JacksonModule {
- this += EnumSealedSerializerResolver
- }
- private class EnumSealedDeserializer(val enumItems: Map[String, Any]) extends JsonDeserializer[Any] {
- override def deserialize(p: JsonParser, ctxt: DeserializationContext): Any = {
- val strValue = p.readValueAs(classOf[String])
- enumItems(strValue)
- }
- }
- private object EnumSealedDeserializerResolver extends Deserializers.Base {
- import EnumHelpers._
- override def findBeanDeserializer(
- javaType: JavaType,
- config: DeserializationConfig,
- beanDesc: BeanDescription
- ): JsonDeserializer[_] = {
- getEnumTrait(javaType).map(symbol => new EnumSealedDeserializer(getEnumItemsFromStr(symbol))).getOrElse(null)
- }
- }
- trait EnumSealedDeserializerModule extends JacksonModule {
- this += EnumSealedDeserializerResolver
- }
- object EnumSealedModule extends EnumSealedSerializerModule with EnumSealedDeserializerModule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement