Skip to content

Commit

Permalink
Find jsonClass from all fields. Fixes lift#1132
Browse files Browse the repository at this point in the history
  • Loading branch information
Joni Freeman committed Oct 19, 2011
1 parent e3cc1e1 commit 9758e19
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 8 deletions.
18 changes: 14 additions & 4 deletions core/json/src/main/scala/net/liftweb/json/Extraction.scala
Expand Up @@ -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 + "'")
Expand All @@ -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) = {
Expand Down
Expand Up @@ -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 {
Expand Down

0 comments on commit 9758e19

Please sign in to comment.