blob: 34ca38746d408f05c32bab92172b6eaeacae9777 [file] [log] [blame]
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.jmap.json
import org.apache.james.jmap.api.model.Preview
import org.apache.james.jmap.mail.{Address, BlobId, Charset, Disposition, EmailAddress, EmailBody, EmailBodyMetadata, EmailBodyPart, EmailBodyValue, EmailFastView, EmailFullView, EmailGetRequest, EmailGetResponse, EmailHeader, EmailHeaderName, EmailHeaderValue, EmailHeaderView, EmailHeaders, EmailIds, EmailMetadata, EmailMetadataView, EmailNotFound, EmailView, EmailerName, FetchAllBodyValues, FetchHTMLBodyValues, FetchTextBodyValues, HasAttachment, HeaderMessageId, IsEncodingProblem, IsTruncated, Language, Location, MailboxIds, Name, PartId, RawHeaderValue, Subject, TextHeaderValue, ThreadId, Type}
import org.apache.james.jmap.model._
import org.apache.james.mailbox.model.{Cid, MailboxId, MessageId}
import play.api.libs.functional.syntax._
import play.api.libs.json._
import scala.language.implicitConversions
object EmailGetSerializer {
private implicit val mailboxIdWrites: Writes[MailboxId] = mailboxId => JsString(mailboxId.serialize)
private implicit val fetchTextBodyValuesReads: Reads[FetchTextBodyValues] = Json.valueReads[FetchTextBodyValues]
private implicit val fetchHTMLBodyValuesReads: Reads[FetchHTMLBodyValues] = Json.valueReads[FetchHTMLBodyValues]
private implicit val fetchAllBodyValuesReads: Reads[FetchAllBodyValues] = Json.valueReads[FetchAllBodyValues]
private implicit val blobIdWrites: Writes[BlobId] = Json.valueWrites[BlobId]
private implicit val cidWrites: Writes[Cid] = cid => JsString(cid.getValue)
private implicit val nameWrites: Writes[Name] = Json.valueWrites[Name]
private implicit val threadIdWrites: Writes[ThreadId] = Json.valueWrites[ThreadId]
private implicit val mailboxIdsWrites: Writes[MailboxIds] = ids => JsObject(ids.value.map(id => (id.serialize(), JsBoolean(true))))
private implicit val typeWrites: Writes[Type] = Json.valueWrites[Type]
private implicit val charsetWrites: Writes[Charset] = Json.valueWrites[Charset]
private implicit val dispositionWrites: Writes[Disposition] = Json.valueWrites[Disposition]
private implicit val languageWrites: Writes[Language] = Json.valueWrites[Language]
private implicit val locationWrites: Writes[Location] = Json.valueWrites[Location]
private implicit val emailerNameWrites: Writes[EmailerName] = Json.valueWrites[EmailerName]
private implicit val addressWrites: Writes[Address] = Json.valueWrites[Address]
private implicit val emailAddressWrites: Writes[EmailAddress] = Json.writes[EmailAddress]
private implicit val headerMessageIdWrites: Writes[HeaderMessageId] = Json.valueWrites[HeaderMessageId]
private implicit val isEncodingProblemWrites: Writes[IsEncodingProblem] = Json.valueWrites[IsEncodingProblem]
private implicit val isTruncatedWrites: Writes[IsTruncated] = Json.valueWrites[IsTruncated]
private implicit val partIdWrites: Writes[PartId] = partId => JsString(partId.serialize)
private implicit val previewWrites: Writes[Preview] = preview => JsString(preview.getValue)
private implicit val hasAttachmentWrites: Writes[HasAttachment] = Json.valueWrites[HasAttachment]
private implicit val headerNameWrites: Writes[EmailHeaderName] = Json.valueWrites[EmailHeaderName]
private implicit val rawHeaderWrites: Writes[RawHeaderValue] = Json.valueWrites[RawHeaderValue]
private implicit val textHeaderWrites: Writes[TextHeaderValue] = Json.valueWrites[TextHeaderValue]
private implicit val emailHeaderWrites: Writes[EmailHeaderValue] = {
case headerValue: RawHeaderValue => Json.toJson[RawHeaderValue](headerValue)
case headerValue: TextHeaderValue => Json.toJson[TextHeaderValue](headerValue)
}
private implicit val headersWrites: Writes[EmailHeader] = Json.writes[EmailHeader]
private implicit val bodyValueWrites: Writes[EmailBodyValue] = Json.writes[EmailBodyValue]
private implicit val emailIdsReads: Reads[EmailIds] = Json.valueReads[EmailIds]
private implicit val emailGetRequestReads: Reads[EmailGetRequest] = Json.reads[EmailGetRequest]
private implicit val subjectWrites: Writes[Subject] = Json.valueWrites[Subject]
private implicit val emailNotFoundWrites: Writes[EmailNotFound] = Json.valueWrites[EmailNotFound]
private implicit val messageIdWrites: Writes[MessageId] = id => JsString(id.serialize())
private implicit val keywordWrites: Writes[Keyword] = Json.valueWrites[Keyword]
private implicit val keywordsWrites: Writes[Keywords] = keywords => JsObject(keywords.asMap.map {
case (keyword, b) => (keyword.flagName, JsBoolean(b))
})
private implicit def bodyValueMapWrites(implicit bodyValueWriter: Writes[EmailBodyValue]): Writes[Map[PartId, EmailBodyValue]] =
mapWrites[PartId, EmailBodyValue](_.value.toString(), bodyValueWriter)
private def bodyPartWritesWithPropertyFilter(properties: Properties): Writes[EmailBodyPart] =
new Writes[EmailBodyPart] {
def removeJsNull(obj: JsObject): JsObject =
JsObject(obj.fields.filter({
case (_, JsNull) => false
case _ => true
}))
def writes(part: EmailBodyPart): JsValue = properties.filter(
removeJsNull(
Json.obj("partId" -> Json.toJson(part.partId),
"blobId" -> Json.toJson(part.blobId),
"headers" -> Json.toJson(part.headers),
"size" -> Json.toJson(part.size),
"name" -> Json.toJson(part.name),
"type" -> Json.toJson(part.`type`),
"charset" -> Json.toJson(part.charset),
"disposition" -> Json.toJson(part.disposition),
"cid" -> Json.toJson(part.cid),
"language" -> Json.toJson(part.language),
"location" -> Json.toJson(part.location),
"subParts" -> part.subParts.map(list => list.map(writes)))))
}
private def emailWritesWithPropertyFilter(properties: Properties)(implicit partsWrites: Writes[EmailBodyPart]): Writes[EmailView] = {
implicit val emailMetadataWrites: OWrites[EmailMetadata] = Json.writes[EmailMetadata]
implicit val emailHeadersWrites: Writes[EmailHeaders] = Json.writes[EmailHeaders]
implicit val emailBodyWrites: Writes[EmailBody] = Json.writes[EmailBody]
implicit val emailBodyMetadataWrites: Writes[EmailBodyMetadata] = Json.writes[EmailBodyMetadata]
val emailFullViewWrites: OWrites[EmailFullView] = (JsPath.write[EmailMetadata] and
JsPath.write[EmailHeaders] and
JsPath.write[EmailBody] and
JsPath.write[EmailBodyMetadata] and
JsPath.write[Map[String, Option[EmailHeaderValue]]]) (unlift(EmailFullView.unapply))
val emailFastViewWrites: OWrites[EmailFastView] = (JsPath.write[EmailMetadata] and
JsPath.write[EmailHeaders] and
JsPath.write[EmailBodyMetadata] and
JsPath.write[Map[String, Option[EmailHeaderValue]]]) (unlift(EmailFastView.unapply))
val emailHeaderViewWrites: OWrites[EmailHeaderView] = (JsPath.write[EmailMetadata] and
JsPath.write[EmailHeaders] and
JsPath.write[Map[String, Option[EmailHeaderValue]]]) (unlift(EmailHeaderView.unapply))
val emailMetadataViewWrites: OWrites[EmailMetadataView] = view => Json.toJsObject(view.metadata)
val emailWrites: OWrites[EmailView] = {
case view: EmailMetadataView => emailMetadataViewWrites.writes(view)
case view: EmailHeaderView => emailHeaderViewWrites.writes(view)
case view: EmailFastView => emailFastViewWrites.writes(view)
case view: EmailFullView => emailFullViewWrites.writes(view)
}
emailWrites.transform(properties.filter(_))
}
private implicit def emailGetResponseWrites(implicit emailWrites: Writes[EmailView]): Writes[EmailGetResponse] = Json.writes[EmailGetResponse]
def serialize(emailGetResponse: EmailGetResponse, properties: Properties, bodyProperties: Properties): JsValue =
Json.toJson(emailGetResponse)(emailGetResponseWrites(emailWritesWithPropertyFilter(properties)(bodyPartWritesWithPropertyFilter(bodyProperties))))
def deserializeEmailGetRequest(input: JsValue): JsResult[EmailGetRequest] = Json.fromJson[EmailGetRequest](input)
}