package xyz.driver.pdsuidomain.formats.json.sprayformats import spray.json._ import xyz.driver.pdsuicommon.domain.{FuzzyValue, LongId, TextJson} import xyz.driver.pdsuidomain.entities._ import xyz.driver.pdsuidomain.services.ExtractedDataService.RichExtractedData object extracteddata { import DefaultJsonProtocol._ import common._ import ExtractedData._ implicit val metaKeywordFormat: RootJsonFormat[Meta.Keyword] = jsonFormat4(Meta.Keyword) implicit val metaTextLayerPositionFormat: RootJsonFormat[Meta.TextLayerPosition] = jsonFormat3( Meta.TextLayerPosition) implicit val metaEvidenceFormat: RootJsonFormat[Meta.Evidence] = jsonFormat3(Meta.Evidence) implicit val extractedDataMetaFormat: RootJsonFormat[Meta] = jsonFormat2(Meta.apply) implicit val fullExtractedDataMetaFormat = new RootJsonFormat[TextJson[Meta]] { override def write(obj: TextJson[Meta]): JsValue = obj.content.toJson override def read(json: JsValue): TextJson[Meta] = TextJson(extractedDataMetaFormat.read(json)) } implicit val extractedDataLabelFormat: RootJsonFormat[ExtractedDataLabel] = new RootJsonFormat[ExtractedDataLabel] { override def write(label: ExtractedDataLabel): JsObject = { JsObject( "id" -> label.labelId.toJson, "categoryId" -> label.categoryId.toJson, "value" -> label.value.toJson ) } override def read(json: JsValue): ExtractedDataLabel = json match { case JsObject(fields) => val labelId = fields .get("id") .map(_.convertTo[LongId[Label]]) val categoryId = fields .get("categoryId") .map(_.convertTo[LongId[Category]]) val value = fields .get("value") .map(_.convertTo[FuzzyValue]) ExtractedDataLabel( id = LongId(0), dataId = LongId(0), labelId = labelId, categoryId = categoryId, value = value ) case _ => deserializationError(s"Expected Json Object as ExtractedDataLabel, but got $json") } } def applyUpdateToExtractedData(json: JsValue, orig: RichExtractedData): RichExtractedData = json match { case JsObject(fields) => val keywordId = if (fields.contains("keywordId")) { fields .get("keywordId") .map(_.convertTo[LongId[Keyword]]) } else orig.extractedData.keywordId val evidence = if (fields.contains("evidence")) { fields .get("evidence") .map(_.convertTo[String]) } else orig.extractedData.evidenceText val meta = if (fields.contains("meta")) { fields .get("meta") .map(_.convertTo[TextJson[Meta]]) } else orig.extractedData.meta val labels = if (fields.contains("labels")) { fields .get("labels") .map(_.convertTo[List[ExtractedDataLabel]]) .getOrElse(List.empty[ExtractedDataLabel]) } else orig.labels val extractedData = orig.extractedData.copy( keywordId = keywordId, evidenceText = evidence, meta = meta ) orig.copy( extractedData = extractedData, labels = labels ) case _ => deserializationError(s"Expected Json Object as partial ExtractedData, but got $json") } implicit val extractedDataFormat: RootJsonFormat[RichExtractedData] = new RootJsonFormat[RichExtractedData] { override def write(richData: RichExtractedData): JsValue = JsObject( "id" -> richData.extractedData.id.id.toJson, "documentId" -> richData.extractedData.documentId.toJson, "keywordId" -> richData.extractedData.keywordId.toJson, "evidence" -> richData.extractedData.evidenceText.toJson, "meta" -> richData.extractedData.meta.toJson, "labels" -> richData.labels.toJson ) override def read(json: JsValue): RichExtractedData = json match { case JsObject(fields) => val documentId = fields .get("documentId") .map(_.convertTo[LongId[Document]]) .getOrElse( deserializationError(s"ExtractedData create json object does not contain `documentId` field: $json")) val keywordId = fields .get("keywordId") .map(_.convertTo[LongId[Keyword]]) val evidence = fields .get("evidence") .map(_.convertTo[String]) val meta = fields .get("meta") .map(_.convertTo[TextJson[Meta]]) val labels = fields .get("labels") .map(_.convertTo[List[ExtractedDataLabel]]) .getOrElse(List.empty[ExtractedDataLabel]) val extractedData = ExtractedData( documentId = documentId, keywordId = keywordId, evidenceText = evidence, meta = meta ) RichExtractedData(extractedData, labels) case _ => deserializationError(s"Expected Json Object as ExtractedData, but got $json") } } }