Несмотря на то, что scalaxb не упоминает способ де / сериализации в JSON с использованием сгенерированной схемы scalaxb, есть ли способ создания собственных форматеров с использованием Play JSON?
Проблема, с которой я сталкиваюсь, связана с де /сериализация сгенерированного класса с именем DataRecord
trait DataRecord[+A] {
val namespace: Option[String]
val key: Option[String]
val value: A
def as[B] = value.asInstanceOf[B]
override def toString: String = {
"DataRecord(" +
((namespace, key, value) match {
case (None, Some(k), _) => k + "," + value.toString
case (Some(n), Some(k), _) => "{" + n + "}" + k + "," + value.toString
case _ => value.toString
}) + ")"
}
}
object DataRecord extends XMLStandardTypes {
private case class DataWriter[+A](
namespace: Option[String],
key: Option[String],
xstypeNamespace: Option[String],
xstypeName: Option[String],
value: A,
writer: CanWriteXML[_]) extends DataRecord[A] {
override def equals(o: Any): Boolean =
o match {
case that: DataWriter[_] =>
namespace == that.namespace &&
key == that.key &&
value == that.value
case _ => false
}
override def hashCode: Int = {
var result = 17
result = result + 31 * namespace.hashCode
result = result + 31 * key.hashCode
result = result + 31 * value.hashCode
result
}
}
import Helper._
// this is for nil element.
def apply(namespace: Option[String], key: Option[String], value: None.type): DataRecord[Option[Nothing]] =
DataWriter(namespace, key, None, None, value, __NoneXMLWriter)
// this is for choice option: DataRecord(x.namespace, Some(x.name), fromXML[Address](x))
def apply[A:CanWriteXML](namespace: Option[String], key: Option[String], value: A): DataRecord[A] =
DataWriter(namespace, key, None, None, value, implicitly[CanWriteXML[A]])
def apply[A:CanWriteXML](node: Node, value: A): DataRecord[A] = node match {
case elem: Elem =>
val ns = scalaxb.Helper.nullOrEmpty(elem.scope.getURI(elem.prefix))
val key = Some(elem.label)
DataRecord(ns, key, value)
case _ => DataRecord(value)
}
// this is for long attributes
def apply[A:CanWriteXML](x: Node, parent: Node, value: A): DataRecord[A] = x match {
case _ => DataRecord(value)
}
def apply[A:CanWriteXML](value: A): DataRecord[A] =
apply(None, None, value)
def apply[A:CanWriteXML](namespace: Option[String], key: Option[String],
xstypeNamespace: Option[String], xstypeName: Option[String], value: A): DataRecord[A] =
DataWriter(namespace, key, xstypeNamespace, xstypeName, value, implicitly[CanWriteXML[A]])
// this is for any.
def apply(elemName: ElemName)(implicit handleNonDefault: scala.xml.Elem => Option[DataRecord[Any]]): DataRecord[Any] = fromAny(elemName.node, handleNonDefault)
def fromAny(seq: NodeSeq, handleNonDefault: scala.xml.Elem => Option[DataRecord[Any]]): DataRecord[Any] = {
seq match {
case elem: Elem => fromAny(elem, handleNonDefault)
case _ => DataRecord(None, None, None, None, seq.text)
}
}
def fromAny(elem: Elem, handleNonDefault: scala.xml.Elem => Option[DataRecord[Any]]): DataRecord[Any] = {
val ns = scalaxb.Helper.nullOrEmpty(elem.scope.getURI(elem.prefix))
val key = Some(elem.label)
val XS = Some(XML_SCHEMA_URI)
instanceType(elem) match {
case (XS, xstype) =>
xstype match {
case Some("int") => DataRecord(ns, key, XS, xstype, fromXML[Int](elem, Nil))
case Some("byte") => DataRecord(ns, key, XS, xstype, fromXML[Byte](elem, Nil))
case Some("short") => DataRecord(ns, key, XS, xstype, fromXML[Short](elem, Nil))
case Some("long") => DataRecord(ns, key, XS, xstype, fromXML[Long](elem, Nil))
case Some("float") => DataRecord(ns, key, XS, xstype, fromXML[Float](elem, Nil))
case Some("double") => DataRecord(ns, key, XS, xstype, fromXML[Double](elem, Nil))
case Some("integer") => DataRecord(ns, key, XS, xstype, fromXML[BigInt](elem, Nil))
case Some("nonPositiveInteger") => DataRecord(ns, key, XS, xstype, fromXML[BigInt](elem, Nil))
case Some("negativeInteger") => DataRecord(ns, key, XS, xstype, fromXML[BigInt](elem, Nil))
case Some("nonNegativeInteger") => DataRecord(ns, key, XS, xstype, fromXML[BigInt](elem, Nil))
case Some("positiveInteger") => DataRecord(ns, key, XS, xstype, fromXML[BigInt](elem, Nil))
case Some("unsignedLong") => DataRecord(ns, key, XS, xstype, fromXML[BigInt](elem, Nil))
case Some("unsignedInt") => DataRecord(ns, key, XS, xstype, fromXML[Long](elem, Nil))
case Some("unsignedShort") => DataRecord(ns, key, XS, xstype, fromXML[Int](elem, Nil))
case Some("unsignedByte") => DataRecord(ns, key, XS, xstype, fromXML[Int](elem, Nil))
case Some("decimal") => DataRecord(ns, key, XS, xstype, fromXML[BigDecimal](elem, Nil))
case Some("boolean") => DataRecord(ns, key, XS, xstype, fromXML[Boolean](elem, Nil))
case Some("string") => DataRecord(ns, key, XS, xstype, fromXML[String](elem, Nil))
case Some("normalizedString") => DataRecord(ns, key, XS, xstype, fromXML[String](elem, Nil))
case Some("token") => DataRecord(ns, key, XS, xstype, fromXML[String](elem, Nil))
case Some("language") => DataRecord(ns, key, XS, xstype, fromXML[String](elem, Nil))
case Some("Name") => DataRecord(ns, key, XS, xstype, fromXML[String](elem, Nil))
case Some("NCName") => DataRecord(ns, key, XS, xstype, fromXML[String](elem, Nil))
case Some("NMTOKEN") => DataRecord(ns, key, XS, xstype, fromXML[String](elem, Nil))
case Some("NMTOKENS") => DataRecord(ns, key, XS, xstype, fromXML[Seq[String]](elem, Nil))
case Some("ID") => DataRecord(ns, key, XS, xstype, fromXML[String](elem, Nil))
case Some("IDREF") => DataRecord(ns, key, XS, xstype, fromXML[String](elem, Nil))
case Some("IDREFS") => DataRecord(ns, key, XS, xstype, fromXML[Seq[String]](elem, Nil))
case Some("ENTITY") => DataRecord(ns, key, XS, xstype, fromXML[String](elem, Nil))
case Some("ENTITIES") => DataRecord(ns, key, XS, xstype, fromXML[Seq[String]](elem, Nil))
case Some("hexBinary") => DataRecord(ns, key, XS, xstype, fromXML[HexBinary](elem, Nil))
case Some("base64Binary") => DataRecord(ns, key, XS, xstype, fromXML[Base64Binary](elem, Nil))
case Some("anyURI") => DataRecord(ns, key, XS, xstype, fromXML[java.net.URI](elem, Nil))
case Some("QName") => DataRecord(ns, key, XS, xstype, fromXML[javax.xml.namespace.QName](elem, Nil))
case Some("NOTATION") => DataRecord(ns, key, XS, xstype, fromXML[javax.xml.namespace.QName](elem, Nil))
case Some("duration") => DataRecord(ns, key, XS, xstype, fromXML[javax.xml.datatype.Duration](elem, Nil))
case Some("dateTime") => DataRecord(ns, key, XS, xstype, fromXML[XMLGregorianCalendar](elem, Nil))
case Some("time") => DataRecord(ns, key, XS, xstype, fromXML[XMLGregorianCalendar](elem, Nil))
case Some("gYearMonth") => DataRecord(ns, key, XS, xstype, fromXML[XMLGregorianCalendar](elem, Nil))
case Some("gYear") => DataRecord(ns, key, XS, xstype, fromXML[XMLGregorianCalendar](elem, Nil))
case Some("gMonthDay") => DataRecord(ns, key, XS, xstype, fromXML[XMLGregorianCalendar](elem, Nil))
case Some("gDay") => DataRecord(ns, key, XS, xstype, fromXML[XMLGregorianCalendar](elem, Nil))
case Some("gMonth") => DataRecord(ns, key, XS, xstype, fromXML[XMLGregorianCalendar](elem, Nil))
case _ => DataRecord(ns, key, XS, xstype, elem)
}
case _ => handleNonDefault(elem).getOrElse {
val (xsns, xstype) = instanceType(elem)
DataRecord(ns, key, xsns, xstype, elem)
}
}
}
// this is for any.
def fromNillableAny(seq: NodeSeq): DataRecord[Option[Any]] = {
seq match {
case elem: Elem => fromNillableAny(elem)
case _ => DataRecord(None, None, None, None, Some(seq.text))
}
}
// this is for any.
def fromNillableAny(elem: Elem): DataRecord[Option[Any]] = {
val ns = scalaxb.Helper.nullOrEmpty(elem.scope.getURI(elem.prefix))
val key = Some(elem.label)
val XS = Some(XML_SCHEMA_URI)
if (isNil(elem)) DataRecord(ns, key, None)
else instanceType(elem) match {
case (XS, xstype) =>
xstype match {
case Some("int") => DataRecord(ns, key, XS, xstype, Some(fromXML[Int](elem, Nil)))
case Some("byte") => DataRecord(ns, key, XS, xstype, Some(fromXML[Byte](elem, Nil)))
case Some("short") => DataRecord(ns, key, XS, xstype, Some(fromXML[Short](elem, Nil)))
case Some("long") => DataRecord(ns, key, XS, xstype, Some(fromXML[Long](elem, Nil)))
case Some("float") => DataRecord(ns, key, XS, xstype, Some(fromXML[Float](elem, Nil)))
case Some("double") => DataRecord(ns, key, XS, xstype, Some(fromXML[Double](elem, Nil)))
case Some("integer") => DataRecord(ns, key, XS, xstype, Some(fromXML[BigInt](elem, Nil)))
case Some("nonPositiveInteger") => DataRecord(ns, key, XS, xstype, Some(fromXML[BigInt](elem, Nil)))
case Some("negativeInteger") => DataRecord(ns, key, XS, xstype, Some(fromXML[BigInt](elem, Nil)))
case Some("nonNegativeInteger") => DataRecord(ns, key, XS, xstype, Some(fromXML[BigInt](elem, Nil)))
case Some("positiveInteger") => DataRecord(ns, key, XS, xstype, Some(fromXML[BigInt](elem, Nil)))
case Some("unsignedLong") => DataRecord(ns, key, XS, xstype, Some(fromXML[BigInt](elem, Nil)))
case Some("unsignedInt") => DataRecord(ns, key, XS, xstype, Some(fromXML[Long](elem, Nil)))
case Some("unsignedShort") => DataRecord(ns, key, XS, xstype, Some(fromXML[Int](elem, Nil)))
case Some("unsignedByte") => DataRecord(ns, key, XS, xstype, Some(fromXML[Int](elem, Nil)))
case Some("decimal") => DataRecord(ns, key, XS, xstype, Some(fromXML[BigDecimal](elem, Nil)))
case Some("boolean") => DataRecord(ns, key, XS, xstype, Some(fromXML[Boolean](elem, Nil)))
case Some("string") => DataRecord(ns, key, XS, xstype, Some(fromXML[String](elem, Nil)))
case Some("normalizedString") => DataRecord(ns, key, XS, xstype, Some(fromXML[String](elem, Nil)))
case Some("token") => DataRecord(ns, key, XS, xstype, Some(fromXML[String](elem, Nil)))
case Some("language") => DataRecord(ns, key, XS, xstype, Some(fromXML[String](elem, Nil)))
case Some("Name") => DataRecord(ns, key, XS, xstype, Some(fromXML[String](elem, Nil)))
case Some("NCName") => DataRecord(ns, key, XS, xstype, Some(fromXML[String](elem, Nil)))
case Some("NMTOKEN") => DataRecord(ns, key, XS, xstype, Some(fromXML[String](elem, Nil)))
case Some("NMTOKENS") => DataRecord(ns, key, XS, xstype, Some(fromXML[Seq[String]](elem, Nil)))
case Some("ID") => DataRecord(ns, key, XS, xstype, Some(fromXML[String](elem, Nil)))
case Some("IDREF") => DataRecord(ns, key, XS, xstype, Some(fromXML[String](elem, Nil)))
case Some("IDREFS") => DataRecord(ns, key, XS, xstype, Some(fromXML[Seq[String]](elem, Nil)))
case Some("ENTITY") => DataRecord(ns, key, XS, xstype, Some(fromXML[String](elem, Nil)))
case Some("ENTITIES") => DataRecord(ns, key, XS, xstype, Some(fromXML[Seq[String]](elem, Nil)))
case Some("hexBinary") => DataRecord(ns, key, XS, xstype, Some(fromXML[HexBinary](elem, Nil)))
case Some("base64Binary") => DataRecord(ns, key, XS, xstype, Some(fromXML[Base64Binary](elem, Nil)))
case Some("anyURI") => DataRecord(ns, key, XS, xstype, Some(fromXML[java.net.URI](elem, Nil)))
case Some("QName") => DataRecord(ns, key, XS, xstype, Some(fromXML[javax.xml.namespace.QName](elem, Nil)))
case Some("NOTATION") => DataRecord(ns, key, XS, xstype, Some(fromXML[javax.xml.namespace.QName](elem, Nil)))
case Some("duration") => DataRecord(ns, key, XS, xstype, Some(fromXML[javax.xml.datatype.Duration](elem, Nil)))
case Some("dateTime") => DataRecord(ns, key, XS, xstype, Some(fromXML[XMLGregorianCalendar](elem, Nil)))
case Some("time") => DataRecord(ns, key, XS, xstype, Some(fromXML[XMLGregorianCalendar](elem, Nil)))
case Some("gYearMonth") => DataRecord(ns, key, XS, xstype, Some(fromXML[XMLGregorianCalendar](elem, Nil)))
case Some("gYear") => DataRecord(ns, key, XS, xstype, Some(fromXML[XMLGregorianCalendar](elem, Nil)))
case Some("gMonthDay") => DataRecord(ns, key, XS, xstype, Some(fromXML[XMLGregorianCalendar](elem, Nil)))
case Some("gDay") => DataRecord(ns, key, XS, xstype, Some(fromXML[XMLGregorianCalendar](elem, Nil)))
case Some("gMonth") => DataRecord(ns, key, XS, xstype, Some(fromXML[XMLGregorianCalendar](elem, Nil)))
case _ => DataRecord(ns, key, XS, xstype, Some(elem))
}
case _ =>
val (xsns, xstype) = instanceType(elem)
DataRecord(ns, key, xsns, xstype, Some(elem))
}
}
def unapply[A](record: DataRecord[A]): Option[(Option[String], Option[String], A)] =
Some((record.namespace, record.key, record.value))
def toXML[A](obj: DataRecord[A], namespace: Option[String], elementLabel: Option[String],
scope: scala.xml.NamespaceBinding, typeAttribute: Boolean): scala.xml.NodeSeq = obj match {
case w: DataWriter[_] =>
obj.value match {
case seq: NodeSeq =>
w.writer.asInstanceOf[CanWriteXML[A]].writes(obj.value, namespace, elementLabel, scope, typeAttribute)
case _ =>
w.writer.asInstanceOf[CanWriteXML[A]].writes(obj.value, namespace, elementLabel, scope, false) match {
case elem: Elem if (w.xstypeName.isDefined && scope.getPrefix(XSI_URL) != null) =>
elem % scala.xml.Attribute(scope.getPrefix(Helper.XSI_URL), "type",
Helper.prefixedName(w.xstypeNamespace, w.xstypeName.get, scope), scala.xml.Null)
case x => x
}
}
case _ => sys.error("unknown DataRecord.")
}
}
Насколько я понимаю, класс не важен для целей десериализации в JSON.
Однако у меня есть сгенерированные классы, которые продолжают использоватьmyFieldOnCaseClass: DataRecord[MyTypeY]
или даже myCaseClassNameOption2: Option[DataRecord[Any]] = None
.
Можно ли сгенерировать форматы воспроизведения json для DataRecord
, чтобы монада "игнорировалась"?
Документация относится к созданию средств форматирования как для реализующего класса, так и для признака, когда имеется и то и другое, однако реализующий класс DataRecord
, DataWriter
, является частным классом case иDataRecord
не запечатан, означает ли это, что мне нужно изменить сгенерированный код?
Если автоматическая генерация форматов невозможна, кто-нибудь со знанием scalaxb может создать экземпляр DataRecord[T]
?