Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 25 additions & 30 deletions elastic4play/app/org/elastic4play/JsonFormat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import java.util.Date

import scala.util.{Failure, Success, Try}

import scala.reflect.ClassTag

import play.api.libs.json._

import org.elastic4play.controllers.JsonFormat.inputValueFormat
Expand All @@ -14,38 +16,31 @@ object JsonFormat {
private val dateWrites: Writes[Date] = Writes[Date](d => JsNumber(d.getTime))
implicit val dateFormat: Format[Date] = Format(dateReads, dateWrites)

private val invalidFormatAttributeErrorWrites = Writes[InvalidFormatAttributeError] { ifae =>
Json.writes[InvalidFormatAttributeError].writes(ifae) +
("type" -> JsString("InvalidFormatAttributeError")) +
("message" -> JsString(ifae.toString))
}
private val unknownAttributeErrorWrites = Writes[UnknownAttributeError] { uae =>
Json.writes[UnknownAttributeError].writes(uae) +
("type" -> JsString("UnknownAttributeError")) +
("message" -> JsString(uae.toString))
}
private val updateReadOnlyAttributeErrorWrites = Writes[UpdateReadOnlyAttributeError] { uroae =>
Json.writes[UpdateReadOnlyAttributeError].writes(uroae) +
("type" -> JsString("UpdateReadOnlyAttributeError")) +
("message" -> JsString(uroae.toString))
}
private val missingAttributeErrorWrites = Writes[MissingAttributeError] { mae =>
Json.writes[MissingAttributeError].writes(mae) +
("type" -> JsString("MissingAttributeError")) +
("message" -> JsString(mae.toString))
private def attributeErrorWrites[E <: AttributeError](underlying: OWrites[E]): OWrites[E] = {
OWrites.transform(underlying) { (origErr, obj) =>
obj + ("message" -> JsString(origErr.toString))
}
}

implicit val attributeCheckingExceptionWrites: OWrites[AttributeCheckingError] = OWrites[AttributeCheckingError] { ace =>
Json.obj(
"tableName" -> ace.tableName,
"type" -> "AttributeCheckingError",
"errors" -> JsArray(ace.errors.map {
case e: InvalidFormatAttributeError => invalidFormatAttributeErrorWrites.writes(e)
case e: UnknownAttributeError => unknownAttributeErrorWrites.writes(e)
case e: UpdateReadOnlyAttributeError => updateReadOnlyAttributeErrorWrites.writes(e)
case e: MissingAttributeError => missingAttributeErrorWrites.writes(e)
})
)
private[elastic4play] implicit val invalidFormatAttributeErrorWrites: OWrites[InvalidFormatAttributeError] = attributeErrorWrites[InvalidFormatAttributeError](Json.writes[InvalidFormatAttributeError])

private[elastic4play] implicit val unknownAttributeErrorWrites: OWrites[UnknownAttributeError] = attributeErrorWrites[UnknownAttributeError](Json.writes[UnknownAttributeError])

private[elastic4play] implicit val updateReadOnlyAttributeErrorWrites: OWrites[UpdateReadOnlyAttributeError] = attributeErrorWrites[UpdateReadOnlyAttributeError](Json.writes[UpdateReadOnlyAttributeError])

private[elastic4play] implicit val missingAttributeErrorWrites: OWrites[MissingAttributeError] = attributeErrorWrites(Json.writes[MissingAttributeError])

implicit val attributeCheckingExceptionWrites: OWrites[AttributeCheckingError] = {
val pkgName = classOf[AttributeError].getPackage.getName + '.'

implicit def errWrites: OWrites[AttributeError] = Json.configured(JsonConfiguration(
discriminator = "type",
typeNaming = JsonNaming(_.stripPrefix(pkgName))
)).writes

val discriminator = "type" -> JsString("AttributeCheckingError")

Json.writes[AttributeCheckingError].transform(_ + discriminator)
}

implicit def tryWrites[A](implicit aWrites: Writes[A]): Writes[Try[A]] = Writes[Try[A]] {
Expand Down
98 changes: 98 additions & 0 deletions elastic4play/test/org/elastic4play/JsonFormatSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package org.elastic4play

import play.api.libs.json._

import org.elastic4play.controllers.JsonInputValue

final class JsonFormatSpec extends org.specs2.mutable.Specification {
"Play JSON format for Elastic".title

"Format for attribute errors" should {
val invalidFormatAttrErr = InvalidFormatAttributeError(
name = "Test 1",
format = "Foo",
value = JsonInputValue(JsString("Input")))

val invalidFormatAttrErrJson = Json.obj(
"name" -> "Test 1",
"format" -> "Foo",
"value" -> Json.obj("type" -> "JsonInputValue", "value" -> "Input"),
"message" -> "Invalid format for Test 1: JsonInputValue(\"Input\"), expected Foo")

"support InvalidFormatAttributeError" in {
implicit def w: OWrites[InvalidFormatAttributeError] =
JsonFormat.invalidFormatAttributeErrorWrites

Json.toJsObject(invalidFormatAttrErr) must_=== invalidFormatAttrErrJson
}

val unknownAttrErr = UnknownAttributeError(
name = "Test 2",
value = JsString("Bar"))

val unknownAttrErrJson = Json.obj(
"name" -> "Test 2",
"value" -> "Bar",
"message" -> "Unknown attribute Test 2: \"Bar\"")

"support UnknownAttributeError" in {
implicit def w: OWrites[UnknownAttributeError] =
JsonFormat.unknownAttributeErrorWrites

Json.toJsObject(unknownAttrErr) must_=== unknownAttrErrJson
}

val updateRoAttrErr = UpdateReadOnlyAttributeError("Lorem")

val updateRoAttrErrJson = Json.obj(
"name" -> "Lorem",
"message" -> "Attribute Lorem is read-only")

"support UpdateReadOnlyAttributeError" in {
implicit def w: OWrites[UpdateReadOnlyAttributeError] =
JsonFormat.updateReadOnlyAttributeErrorWrites

Json.toJsObject(updateRoAttrErr) must_=== updateRoAttrErrJson
}

val missingAttrErr = MissingAttributeError("Ipsum")

val missingAttrErrJson = Json.obj(
"name" -> "Ipsum",
"message" -> "Attribute Ipsum is missing")

"support MissingAttributeError" in {
implicit def w: OWrites[MissingAttributeError] =
JsonFormat.missingAttributeErrorWrites

Json.toJsObject(missingAttrErr) must_=== missingAttrErrJson
}

"support AttributeCheckingError" in {
import JsonFormat.attributeCheckingExceptionWrites

val errors = Seq(invalidFormatAttrErr, unknownAttrErr, updateRoAttrErr, missingAttrErr)

val errorsJson = Seq(
(invalidFormatAttrErrJson + ("type" -> JsString("InvalidFormatAttributeError"))),
(unknownAttrErrJson + ("type" -> JsString("UnknownAttributeError"))),
(updateRoAttrErrJson + ("type" -> JsString("UpdateReadOnlyAttributeError"))),
(missingAttrErrJson + ("type" -> JsString("MissingAttributeError"))))

Json.toJsObject(AttributeCheckingError(
tableName = "Table 1",
errors = errors)) must_=== Json.obj(
"tableName" -> "Table 1",
"type" -> "AttributeCheckingError",
"errors" -> errorsJson) and {
// Reverse errors to make sure the order is preserved
Json.toJsObject(AttributeCheckingError(
tableName = "Table 2",
errors = errors.reverse)) must_=== Json.obj(
"tableName" -> "Table 2",
"type" -> "AttributeCheckingError",
"errors" -> errorsJson.reverse)
}
}
}
}