com.convergencelabs.convergence.server.api.rest.JsonSupport.scala Maven / Gradle / Ivy
/*
* Copyright (c) 2019 - Convergence Labs, Inc.
*
* This file is part of the Convergence Server, which is released under
* the terms of the GNU General Public License version 3 (GPLv3). A copy
* of the GPLv3 should have been provided along with this file, typically
* located in the "LICENSE" file, which is part of this source code package.
* Alternatively, see for the
* full text of the GPLv3 license, if it was not provided.
*/
package com.convergencelabs.convergence.server.api.rest
import com.convergencelabs.convergence.server.api.rest.domain.DomainChatService.ChatEventData
import com.convergencelabs.convergence.server.api.rest.domain.DomainUserIdSerializer
import com.convergencelabs.convergence.server.model.domain.model.DataValue
import com.convergencelabs.convergence.server.model.domain.user.DomainUserType.DomainUserType
import com.convergencelabs.convergence.server.model.domain.user.{DomainUserId, DomainUserType}
import com.convergencelabs.convergence.server.util.DataValueToJValue
import de.heikoseeberger.akkahttpjson4s.Json4sSupport
import org.json4s.JsonAST.{JInt, JLong, JString}
import org.json4s.jackson.Serialization
import org.json4s.{CustomKeySerializer, CustomSerializer, DefaultFormats, FieldSerializer, Formats}
import java.time.{Duration, Instant}
/**
* A helper trait the supports JSON serialization in the REST API.
*/
trait JsonSupport extends Json4sSupport {
val instantSerializer = new CustomSerializer[Instant](_ => ( {
case JInt(num) =>
Instant.ofEpochMilli(num.longValue)
case JLong(num) =>
Instant.ofEpochMilli(num.longValue)
}, {
case x: Instant =>
JLong(x.toEpochMilli)
}))
val durationSerializer = new CustomSerializer[Duration](_ => ( {
case JInt(int) =>
val l = int.longValue
Duration.ofMillis(l)
case JLong(long) =>
Duration.ofMillis(long)
}, {
case x: Duration =>
JLong(x.toMillis)
}))
val dataValueSerializer = new CustomSerializer[DataValue](_ => ( {
case _: Any =>
???
}, {
case x: DataValue =>
DataValueToJValue.toJson(x)
}))
val domainUserTypeSerializer = new CustomSerializer[DomainUserType](_ => ( {
case JString(userType) =>
DomainUserType.withName(userType)
}, {
case domainUserType: DomainUserType =>
JString(domainUserType.toString)
}))
val domainUserIdSerializer = new CustomSerializer[DomainUserId](_ => ( {
case JString(userId) =>
DomainUserIdSerializer.decodeDomainUserId(userId) match {
case Left(error) =>
throw new UnsupportedOperationException("cannot deserialize domain userId: " + error)
case Right(id) =>
id
}
}, {
case userId: DomainUserId =>
JString(DomainUserIdSerializer.encodeDomainUserId(userId))
}))
val domainUserIdKeySerializer = new CustomKeySerializer[DomainUserId](_ => ( {
case userId =>
DomainUserIdSerializer.decodeDomainUserId(userId) match {
case Left(error) =>
throw new UnsupportedOperationException("cannot deserialize domain userId: " + error)
case Right(id) =>
id
}
}, {
case userId: DomainUserId =>
DomainUserIdSerializer.encodeDomainUserId(userId)
}))
implicit val serialization: Serialization.type = Serialization
implicit val formats: Formats = DefaultFormats +
instantSerializer +
durationSerializer +
dataValueSerializer +
domainUserTypeSerializer +
domainUserIdSerializer +
domainUserIdKeySerializer +
FieldSerializer[RestResponseEntity]() +
FieldSerializer[ChatEventData]()
}