Skip to content

Commit

Permalink
#32 Add attribute description method
Browse files Browse the repository at this point in the history
  • Loading branch information
To-om committed Sep 19, 2017
1 parent b245683 commit c41bf4b
Show file tree
Hide file tree
Showing 17 changed files with 146 additions and 17 deletions.
29 changes: 28 additions & 1 deletion app/org/elastic4play/models/AttachmentAttributeFormat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import org.scalactic._

import org.elastic4play.controllers.JsonFormat._
import org.elastic4play.controllers.{ AttachmentInputValue, FileInputValue, InputValue, JsonInputValue }
import org.elastic4play.services.Attachment
import org.elastic4play.services.{ Attachment, DBLists }
import org.elastic4play.services.JsonFormat.attachmentFormat
import org.elastic4play.{ AttributeError, InvalidFormatAttributeError }

Expand Down Expand Up @@ -57,4 +57,31 @@ object AttachmentAttributeFormat extends AttributeFormat[Attachment]("attachment
longField("size"),
textField("contentType"),
textField("id"))

override def definition(dblists: DBLists, attribute: Attribute[Attachment]): Seq[AttributeDefinition] =
Seq(
AttributeDefinition(
s"${attribute.name}.name",
"string",
s"file name of ${attribute.description}",
Nil,
Nil),
AttributeDefinition(
s"${attribute.name}.hash",
"hash",
s"hash of ${attribute.description}",
Nil,
Nil),
AttributeDefinition(
s"${attribute.name}.size",
"number",
s"file size of ${attribute.description}",
Nil,
Nil),
AttributeDefinition(
s"${attribute.name}.contentType",
"string",
s"content type of ${attribute.description}",
Nil,
Nil))
}
10 changes: 10 additions & 0 deletions app/org/elastic4play/models/Attributes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import org.elastic4play.controllers.InputValue
import org.elastic4play.services.DBLists
import org.elastic4play.{ AttributeError, InvalidFormatAttributeError, MissingAttributeError, UpdateReadOnlyAttributeError }

case class AttributeDefinition(name: String, `type`: String, description: String, values: Seq[JsValue], labels: Seq[String])

abstract class AttributeFormat[T](val name: String)(implicit val jsFormat: Format[T]) {
def checkJson(subNames: Seq[String], value: JsValue): JsValue Or Every[AttributeError]

Expand All @@ -26,6 +28,14 @@ abstract class AttributeFormat[T](val name: String)(implicit val jsFormat: Forma
def elasticType(attributeName: String): FieldDefinition

protected def formatError(value: InputValue) = Bad(One(InvalidFormatAttributeError("", name, value)))

def definition(dblists: DBLists, attribute: Attribute[T]): Seq[AttributeDefinition] =
Seq(AttributeDefinition(
attribute.name,
name,
attribute.description,
Nil,
Nil))
}

object AttributeFormat {
Expand Down
7 changes: 6 additions & 1 deletion app/org/elastic4play/models/BinaryAttributeFormat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,17 @@ import org.scalactic._

import org.elastic4play.controllers.{ InputValue, JsonInputValue }
import org.elastic4play.models.JsonFormat.binaryFormats
import org.elastic4play.services.DBLists
import org.elastic4play.{ AttributeError, InvalidFormatAttributeError }

object BinaryAttributeFormat extends AttributeFormat[Array[Byte]]("binary")(binaryFormats) {
class BinaryAttributeFormat extends AttributeFormat[Array[Byte]]("binary")(binaryFormats) {
override def checkJson(subNames: Seq[String], value: JsValue): Bad[One[InvalidFormatAttributeError]] = formatError(JsonInputValue(value))

override def fromInputValue(subNames: Seq[String], value: InputValue): Array[Byte] Or Every[AttributeError] = formatError(value)

override def elasticType(attributeName: String): BasicFieldDefinition = binaryField(attributeName)

override def definition(dblists: DBLists, attribute: Attribute[Array[Byte]]): Seq[AttributeDefinition] = Nil
}

object BinaryAttributeFormat extends BinaryAttributeFormat
6 changes: 4 additions & 2 deletions app/org/elastic4play/models/BooleanAttributeFormat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import org.scalactic._
import org.elastic4play.controllers.{ InputValue, JsonInputValue, StringInputValue }
import org.elastic4play.{ AttributeError, InvalidFormatAttributeError }

object BooleanAttributeFormat extends AttributeFormat[Boolean]("boolean") {
class BooleanAttributeFormat extends AttributeFormat[Boolean]("boolean") {
override def checkJson(subNames: Seq[String], value: JsValue): Or[JsValue, One[InvalidFormatAttributeError]] = value match {
case _: JsBoolean if subNames.isEmpty Good(value)
case _ formatError(JsonInputValue(value))
Expand All @@ -32,4 +32,6 @@ object BooleanAttributeFormat extends AttributeFormat[Boolean]("boolean") {
}

override def elasticType(attributeName: String): BasicFieldDefinition = booleanField(attributeName)
}
}

object BooleanAttributeFormat extends BooleanAttributeFormat
24 changes: 22 additions & 2 deletions app/org/elastic4play/models/CustomAttributeFormat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ package org.elastic4play.models
import play.api.Logger
import play.api.libs.json._

import com.sksamuel.elastic4s.ElasticDsl.{ booleanField, dateField, longField, objectField, keywordField }
import com.sksamuel.elastic4s.ElasticDsl.{ booleanField, dateField, keywordField, longField, objectField }
import com.sksamuel.elastic4s.mappings.ObjectFieldDefinition
import org.scalactic._

import org.elastic4play.AttributeError
import org.elastic4play.controllers.{ InputValue, JsonInputValue }
import org.elastic4play.services.DBLists

object CustomAttributeFormat extends AttributeFormat[JsValue]("custom") {
class CustomAttributeFormat extends AttributeFormat[JsValue]("custom") {
private[CustomAttributeFormat] lazy val logger = Logger(getClass)

override def checkJson(subNames: Seq[String], value: JsValue): Or[JsValue, Every[AttributeError]] = fromInputValue(subNames, JsonInputValue(value))
Expand Down Expand Up @@ -69,4 +70,23 @@ object CustomAttributeFormat extends AttributeFormat[JsValue]("custom") {
dateField("date").format("epoch_millis||basic_date_time_no_millis"),
booleanField("boolean"),
longField("order"))))

override def definition(dblists: DBLists, attribute: Attribute[JsValue]): Seq[AttributeDefinition] = {
dblists("custom_fields").cachedItems.flatMap { item
val itemObj = item.mapTo[JsObject]
for {
fieldName (itemObj \ "reference").asOpt[String]
tpe (itemObj \ "type").asOpt[String]
description (itemObj \ "description").asOpt[String]
options (itemObj \ "options").asOpt[Seq[JsString]]
} yield AttributeDefinition(
s"${attribute.name}.$fieldName",
tpe,
s"custom field: $description",
options,
Nil)
}
}
}

object CustomAttributeFormat extends CustomAttributeFormat
6 changes: 4 additions & 2 deletions app/org/elastic4play/models/DateAttributeFormat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import org.scalactic._
import org.elastic4play.controllers.{ InputValue, JsonInputValue, StringInputValue }
import org.elastic4play.{ AttributeError, InvalidFormatAttributeError }

object DateAttributeFormat extends AttributeFormat[Date]("date") {
class DateAttributeFormat extends AttributeFormat[Date]("date") {
def parse(d: String): Option[Date] = {
Try {
val datePattern = "yyyyMMdd'T'HHmmssZ"
Expand Down Expand Up @@ -45,4 +45,6 @@ object DateAttributeFormat extends AttributeFormat[Date]("date") {
}

override def elasticType(attributeName: String): BasicFieldDefinition = dateField(attributeName).format("epoch_millis||basic_date_time_no_millis")
}
}

object DateAttributeFormat extends DateAttributeFormat
9 changes: 9 additions & 0 deletions app/org/elastic4play/models/EnumerationAttributeFormat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.sksamuel.elastic4s.mappings.KeywordFieldDefinition
import org.scalactic._

import org.elastic4play.controllers.{ InputValue, JsonInputValue, StringInputValue }
import org.elastic4play.services.DBLists
import org.elastic4play.{ AttributeError, InvalidFormatAttributeError }

case class EnumerationAttributeFormat[T <: Enumeration](enum: T)(implicit format: Format[T#Value])
Expand Down Expand Up @@ -44,4 +45,12 @@ case class EnumerationAttributeFormat[T <: Enumeration](enum: T)(implicit format
}

override def elasticType(attributeName: String): KeywordFieldDefinition = keywordField(attributeName)

override def definition(dblists: DBLists, attribute: Attribute[T#Value]): Seq[AttributeDefinition] =
Seq(AttributeDefinition(
attribute.name,
name,
attribute.description,
enum.values.map(v JsString(v.toString)).toSeq,
Nil))
}
3 changes: 2 additions & 1 deletion app/org/elastic4play/models/JsonFormat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import play.api.libs.json._
object JsonFormat {
implicit val baseModelEntityWrites: Writes[BaseEntity] = Writes((entity: BaseEntity) entity.toJson)

implicit def multiFormat[T](implicit jsFormat: Format[T]) = Format(Reads.seq(jsFormat), Writes.seq(jsFormat))
implicit def multiFormat[T](implicit jsFormat: Format[T]): Format[Seq[T]] = Format(Reads.seq(jsFormat), Writes.seq(jsFormat))

private def optionReads[T](implicit jsReads: Reads[T]) = Reads[Option[T]] {
case JsNull JsSuccess(None)
Expand Down Expand Up @@ -36,4 +36,5 @@ object JsonFormat {
private val binaryWrites = Writes.apply { bin: Array[Byte] JsString(java.util.Base64.getEncoder.encodeToString(bin)) }
val binaryFormats: Format[Array[Byte]] = Format(binaryReads, binaryWrites)

implicit val attributeDefinitionWrites: OWrites[AttributeDefinition] = Json.writes[AttributeDefinition]
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import org.elastic4play.services.DBLists
import org.elastic4play.{ AttributeError, InvalidFormatAttributeError }

case class ListEnumerationAttributeFormat(enumerationName: String)(dblists: DBLists) extends AttributeFormat[String](s"enumeration") {
def items: Set[String] = dblists("list_" + enumerationName).cachedItems.map(_.mapTo[String]).toSet //getItems[String].map(_.map(_._2).toSet)
def items: Set[String] = dblists("list_" + enumerationName).cachedItems.map(_.mapTo[String]).toSet
override def checkJson(subNames: Seq[String], value: JsValue): Or[JsValue, One[InvalidFormatAttributeError]] = value match {
case JsString(v) if subNames.isEmpty && items.contains(v) Good(value)
case _ formatError(JsonInputValue(value))
Expand All @@ -29,4 +29,12 @@ case class ListEnumerationAttributeFormat(enumerationName: String)(dblists: DBLi
}

override def elasticType(attributeName: String): KeywordFieldDefinition = keywordField(attributeName)

override def definition(dblists: DBLists, attribute: Attribute[String]): Seq[AttributeDefinition] =
Seq(AttributeDefinition(
attribute.name,
name,
attribute.description,
items.map(JsString.apply).toSeq,
Nil))
}
24 changes: 21 additions & 3 deletions app/org/elastic4play/models/MetricsAttributeFormat.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.elastic4play.models

import play.api.libs.json.{ JsNull, JsNumber, JsObject, JsValue }
import play.api.libs.json._

import com.sksamuel.elastic4s.ElasticDsl.{ longField, nestedField }
import com.sksamuel.elastic4s.mappings.NestedFieldDefinition
Expand All @@ -9,8 +9,9 @@ import org.scalactic._

import org.elastic4play.AttributeError
import org.elastic4play.controllers.{ InputValue, JsonInputValue }
import org.elastic4play.services.DBLists

object MetricsAttributeFormat extends AttributeFormat[JsValue]("metrics") {
class MetricsAttributeFormat extends AttributeFormat[JsValue]("metrics") {
override def checkJson(subNames: Seq[String], value: JsValue): Or[JsValue, Every[AttributeError]] = fromInputValue(subNames, JsonInputValue(value))

override def fromInputValue(subNames: Seq[String], value: InputValue): JsValue Or Every[AttributeError] = {
Expand All @@ -33,4 +34,21 @@ object MetricsAttributeFormat extends AttributeFormat[JsValue]("metrics") {
}

override def elasticType(attributeName: String): NestedFieldDefinition = nestedField(attributeName).fields(Seq(longField("_default_")))
}

override def definition(dblists: DBLists, attribute: Attribute[JsValue]): Seq[AttributeDefinition] = {
dblists("case_metrics").cachedItems.flatMap { item
val itemObj = item.mapTo[JsObject]
for {
fieldName (itemObj \ "name").asOpt[String]
title (itemObj \ "title").asOpt[String]
} yield AttributeDefinition(
s"${attribute.name}.$fieldName",
"number",
s"metric: $title",
Nil,
Nil)
}
}
}

object MetricsAttributeFormat extends MetricsAttributeFormat
4 changes: 4 additions & 0 deletions app/org/elastic4play/models/MultiAttributeFormat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import org.scalactic._
import org.elastic4play.AttributeError
import org.elastic4play.controllers.{ InputValue, JsonInputValue, StringInputValue }
import org.elastic4play.models.JsonFormat.multiFormat
import org.elastic4play.services.DBLists

case class MultiAttributeFormat[T](attributeFormat: AttributeFormat[T]) extends AttributeFormat[Seq[T]]("multi-" + attributeFormat.name)(multiFormat(attributeFormat.jsFormat)) {
override def checkJsonForCreation(subNames: Seq[String], value: JsValue): Or[JsArray, Every[AttributeError]] = value match {
Expand Down Expand Up @@ -39,4 +40,7 @@ case class MultiAttributeFormat[T](attributeFormat: AttributeFormat[T]) extends
}

override def elasticType(attributeName: String): FieldDefinition = attributeFormat.elasticType(attributeName)

override def definition(dblists: DBLists, attribute: Attribute[Seq[T]]): Seq[AttributeDefinition] =
attributeFormat.definition(dblists, attribute.asInstanceOf[Attribute[T]])
}
5 changes: 4 additions & 1 deletion app/org/elastic4play/models/NumberAttributeFormat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import org.scalactic._
import org.elastic4play.controllers.{ InputValue, JsonInputValue, StringInputValue }
import org.elastic4play.{ AttributeError, InvalidFormatAttributeError }

object NumberAttributeFormat extends AttributeFormat[Long]("number") {
class NumberAttributeFormat extends AttributeFormat[Long]("number") {
override def checkJson(subNames: Seq[String], value: JsValue): Or[JsValue, One[InvalidFormatAttributeError]] = value match {
case _: JsNumber if subNames.isEmpty Good(value)
case _ formatError(JsonInputValue(value))
Expand All @@ -32,4 +32,7 @@ object NumberAttributeFormat extends AttributeFormat[Long]("number") {
}

override def elasticType(attributeName: String): BasicFieldDefinition = longField(attributeName)

}

object NumberAttributeFormat extends NumberAttributeFormat
10 changes: 10 additions & 0 deletions app/org/elastic4play/models/ObjectAttributeFormat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import org.scalactic._

import org.elastic4play.controllers.JsonFormat.inputValueFormat
import org.elastic4play.controllers.{ InputValue, JsonInputValue }
import org.elastic4play.services.DBLists
import org.elastic4play.{ AttributeError, UnknownAttributeError }

case class ObjectAttributeFormat(subAttributes: Seq[Attribute[_]]) extends AttributeFormat[JsObject]("nested") {
Expand Down Expand Up @@ -81,4 +82,13 @@ case class ObjectAttributeFormat(subAttributes: Seq[Attribute[_]]) extends Attri
}

override def elasticType(attributeName: String): NestedFieldDefinition = nestedField(attributeName).fields(subAttributes.map(_.elasticMapping))

override def definition(dblists: DBLists, attribute: Attribute[JsObject]): Seq[AttributeDefinition] =
subAttributes
.flatMap {
case subAttribute: Attribute[tpe] subAttribute.format.definition(dblists, subAttribute)
}
.map { attributeDefinition
attributeDefinition.copy(name = s"${attribute.name}.${attributeDefinition.name}")
}
}
4 changes: 4 additions & 0 deletions app/org/elastic4play/models/OptionalAttributeFormat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.scalactic._
import org.elastic4play.AttributeError
import org.elastic4play.controllers.{ InputValue, JsonInputValue, NullInputValue }
import org.elastic4play.models.JsonFormat.optionFormat
import org.elastic4play.services.DBLists

case class OptionalAttributeFormat[T](attributeFormat: AttributeFormat[T]) extends AttributeFormat[Option[T]]("optional-" + attributeFormat.name)(optionFormat(attributeFormat.jsFormat)) {
override def checkJson(subNames: Seq[String], value: JsValue): Or[JsValue, Every[AttributeError]] = value match {
Expand All @@ -26,4 +27,7 @@ case class OptionalAttributeFormat[T](attributeFormat: AttributeFormat[T]) exten
}

override def elasticType(attributeName: String): FieldDefinition = attributeFormat.elasticType(attributeName)

override def definition(dblists: DBLists, attribute: Attribute[Option[T]]): Seq[AttributeDefinition] =
attributeFormat.definition(dblists, attribute.asInstanceOf[Attribute[T]])
}
4 changes: 3 additions & 1 deletion app/org/elastic4play/models/StringAttributeFormat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import org.scalactic._
import org.elastic4play.controllers.{ InputValue, JsonInputValue }
import org.elastic4play.{ AttributeError, InvalidFormatAttributeError }

object StringAttributeFormat extends AttributeFormat[String]("string") {
class StringAttributeFormat extends AttributeFormat[String]("string") {
override def checkJson(subNames: Seq[String], value: JsValue): Or[JsValue, One[InvalidFormatAttributeError]] = value match {
case _: JsString if subNames.isEmpty Good(value)
case _ formatError(JsonInputValue(value))
Expand All @@ -22,3 +22,5 @@ object StringAttributeFormat extends AttributeFormat[String]("string") {

override def elasticType(attributeName: String): KeywordFieldDefinition = keywordField(attributeName)
}

object StringAttributeFormat extends StringAttributeFormat
4 changes: 3 additions & 1 deletion app/org/elastic4play/models/TextAttributeFormat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import org.scalactic._
import org.elastic4play.controllers.{ InputValue, JsonInputValue, StringInputValue }
import org.elastic4play.{ AttributeError, InvalidFormatAttributeError }

object TextAttributeFormat extends AttributeFormat[String]("text") {
class TextAttributeFormat extends AttributeFormat[String]("text") {
override def checkJson(subNames: Seq[String], value: JsValue): Or[JsValue, One[InvalidFormatAttributeError]] = value match {
case _: JsString if subNames.isEmpty Good(value)
case _ formatError(JsonInputValue(value))
Expand All @@ -28,3 +28,5 @@ object TextAttributeFormat extends AttributeFormat[String]("text") {

override def elasticType(attributeName: String): TextFieldDefinition = textField(attributeName).fielddata(true)
}

object TextAttributeFormat extends TextAttributeFormat
4 changes: 3 additions & 1 deletion app/org/elastic4play/models/UUIDAttributeFormat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import org.scalactic._
import org.elastic4play.controllers.{ InputValue, JsonInputValue, StringInputValue }
import org.elastic4play.{ AttributeError, InvalidFormatAttributeError }

object UUIDAttributeFormat extends AttributeFormat[UUID]("uuid") {
class UUIDAttributeFormat extends AttributeFormat[UUID]("uuid") {
override def checkJson(subNames: Seq[String], value: JsValue): Or[JsValue, One[InvalidFormatAttributeError]] = value match {
case JsString(v) if subNames.isEmpty try {
UUID.fromString(v); Good(value)
Expand Down Expand Up @@ -45,3 +45,5 @@ object UUIDAttributeFormat extends AttributeFormat[UUID]("uuid") {

override def elasticType(attributeName: String): KeywordFieldDefinition = keywordField(attributeName)
}

object UUIDAttributeFormat extends UUIDAttributeFormat

0 comments on commit c41bf4b

Please sign in to comment.