Permalink
Browse files

Find jsonClass from all fields. Fixes #1132

  • Loading branch information...
1 parent e3cc1e1 commit 9758e195af2a9d61127a0446a36e6eb037a4b76b Joni Freeman committed Oct 19, 2011
@@ -266,7 +266,7 @@ object Extraction {
}
def mkWithTypeHint(typeHint: String, fields: List[JField], typeInfo: TypeInfo) = {
- val obj = JObject(fields)
+ val obj = JObject(fields filterNot (_.name == formats.typeHintFieldName))
val deserializer = formats.typeHints.deserialize
if (!deserializer.isDefinedAt(typeHint, obj)) {
val concreteClass = formats.typeHints.classFor(typeHint) getOrElse fail("Do not know how to deserialize '" + typeHint + "'")
@@ -277,16 +277,26 @@ object Extraction {
}
val custom = formats.customDeserializer(formats)
- val JsonClass = formats.typeHintFieldName
if (custom.isDefinedAt(constructor.targetType, json)) custom(constructor.targetType, json)
else json match {
case JNull => null
- case JObject(JField(JsonClass, JString(t)) :: xs) => mkWithTypeHint(t, xs, constructor.targetType)
- case JField(_, JObject(JField(JsonClass, JString(t)) :: xs)) => mkWithTypeHint(t, xs, constructor.targetType)
+ case JObject(TypeHint(t, fs)) => mkWithTypeHint(t, fs, constructor.targetType)
+ case JField(_, JObject(TypeHint(t, fs))) => mkWithTypeHint(t, fs, constructor.targetType)
case _ => instantiate
}
}
+ object TypeHint {
+ def unapply(fs: List[JField]): Option[(String, List[JField])] =
+ if (formats.typeHints == NoTypeHints) None
+ else {
+ val grouped = fs groupBy (_.name == formats.typeHintFieldName)
+ if (grouped.isDefinedAt(true))
+ Some((grouped(true).head.value.values.toString, grouped.get(false).getOrElse(Nil)))
+ else None
+ }
+ }
+
def newPrimitive(elementType: Class[_], elem: JValue) = convert(elem, elementType, formats)
def newCollection(root: JValue, m: Mapping, constructor: Array[_] => Any) = {
@@ -139,10 +139,10 @@ object SerializationExamples extends Specification {
object ShortTypeHintExamples extends TypeHintExamples {
implicit val formats = Serialization.formats(ShortTypeHints(classOf[Fish] :: classOf[Dog] :: Nil))
-// "Deserialization succeeds even if jsonClass is not the first field" in {
-// val ser = """{"animals":[],"pet":{"name":"pluto","jsonClass":"Dog"}}"""
-// Serialization.read[Animals](ser) mustEqual Animals(Nil, Dog("pluto"))
-// }
+ "Deserialization succeeds even if jsonClass is not the first field" in {
+ val ser = """{"animals":[],"pet":{"name":"pluto","jsonClass":"Dog"}}"""
+ Serialization.read[Animals](ser) mustEqual Animals(Nil, Dog("pluto"))
+ }
}
object FullTypeHintExamples extends TypeHintExamples {

0 comments on commit 9758e19

Please sign in to comment.