Skip to content

Commit e850313

Browse files
committed
Issue 382 (#537)
1 parent 3ad9690 commit e850313

File tree

2 files changed

+45
-5
lines changed

2 files changed

+45
-5
lines changed

src/main/scala/com/fasterxml/jackson/module/scala/deser/OptionDeserializerModule.scala

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import com.fasterxml.jackson.core.{JsonParser, JsonToken}
44
import com.fasterxml.jackson.databind.JacksonModule.SetupContext
55
import com.fasterxml.jackson.databind._
66
import com.fasterxml.jackson.databind.`type`.{ReferenceType, TypeFactory}
7+
import com.fasterxml.jackson.databind.deser.std.ReferenceTypeDeserializer
78
import com.fasterxml.jackson.databind.deser.Deserializers
8-
import com.fasterxml.jackson.databind.deser.std.StdDeserializer
99
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer
1010
import com.fasterxml.jackson.module.scala.JacksonModule.InitializerBuilder
1111
import com.fasterxml.jackson.module.scala.ScalaModule
@@ -15,7 +15,7 @@ private class OptionDeserializer(fullType: JavaType,
1515
valueTypeDeserializer: Option[TypeDeserializer],
1616
valueDeserializer: Option[ValueDeserializer[AnyRef]],
1717
beanProperty: Option[BeanProperty] = None)
18-
extends StdDeserializer[Option[AnyRef]](fullType) {
18+
extends ReferenceTypeDeserializer[Option[AnyRef]](fullType, None.orNull, valueTypeDeserializer.orNull, valueDeserializer.orNull) {
1919

2020
override def getValueType: JavaType = fullType
2121

@@ -29,9 +29,10 @@ private class OptionDeserializer(fullType: JavaType,
2929
typeDeser == this.valueTypeDeserializer &&
3030
valueDeser == this.valueDeserializer &&
3131
beanProperty == this.beanProperty) {
32-
return this
32+
this
33+
} else {
34+
new OptionDeserializer(fullType, typeDeser, valueDeser.asInstanceOf[Option[ValueDeserializer[AnyRef]]], beanProperty)
3335
}
34-
new OptionDeserializer(fullType, typeDeser, valueDeser.asInstanceOf[Option[ValueDeserializer[AnyRef]]], beanProperty)
3536
}
3637

3738
override def createContextual(ctxt: DeserializationContext, property: BeanProperty): ValueDeserializer[Option[AnyRef]] = {
@@ -71,9 +72,32 @@ private class OptionDeserializer(fullType: JavaType,
7172
if (t == JsonToken.VALUE_NULL) {
7273
getNullValue(ctxt)
7374
} else {
74-
typeDeserializer.deserializeTypedFromAny(jp, ctxt).asInstanceOf[Option[AnyRef]]
75+
valueTypeDeserializer match {
76+
case Some(vtd) => Option(vtd.deserializeTypedFromAny(jp, ctxt))
77+
case _ => {
78+
typeDeserializer.deserializeTypedFromAny(jp, ctxt) match {
79+
case Some(any) => referenceValue(any)
80+
case any => referenceValue(any)
81+
}
82+
}
83+
}
84+
}
85+
}
86+
87+
override def referenceValue(contents: Any): Option[AnyRef] = {
88+
Option(contents) match {
89+
case Some(anyRef: AnyRef) => Some(anyRef)
90+
case _ => None
7591
}
7692
}
93+
94+
override def withResolved(typeDeser: TypeDeserializer, valueDeser: ValueDeserializer[_]): ReferenceTypeDeserializer[Option[AnyRef]] = {
95+
new OptionDeserializer(fullType, Some(typeDeser), valueDeser.asInstanceOf[Option[ValueDeserializer[AnyRef]]], beanProperty)
96+
}
97+
98+
override def updateReference(reference: Option[AnyRef], contents: Any): Option[AnyRef] = referenceValue(contents)
99+
100+
override def getReferenced(reference: Option[AnyRef]): AnyRef = reference.orNull
77101
}
78102

79103
private class OptionDeserializerResolver(config: ScalaModule.Config) extends Deserializers.Base {

src/test/scala/com/fasterxml/jackson/module/scala/deser/OptionDeserializerTest.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ object OptionDeserializerTest {
3333

3434
case class Foo(bar: String)
3535
case class Wrapper[T](t: T)
36+
37+
trait Marker
38+
case class AMarker(a: Int) extends Marker
39+
case class XMarker(x: Option[Marker])
3640
}
3741

3842
class OptionDeserializerTest extends DeserializerTest {
@@ -97,4 +101,16 @@ class OptionDeserializerTest extends DeserializerTest {
97101
val result2 = mapper.readValue(json, classOf[OptionWrapper])
98102
result2 shouldEqual OptionWrapper(None)
99103
}
104+
105+
//https://github.com/FasterXML/jackson-module-scala/issues/382
106+
it should "handle generics" in {
107+
val mapper = newBuilder.
108+
mapper.registerModule(DefaultScalaModule)
109+
mapper.enableDefaultTypingAsProperty(ObjectMapper.DefaultTyping.OBJECT_AND_NON_CONCRETE, "_t")
110+
val v = XMarker(Some(AMarker(1)))
111+
val str = mapper.writeValueAsString(v)
112+
println(str) // 1
113+
val d = mapper.readValue(str, classOf[XMarker]) // 2
114+
println(d)
115+
}
100116
}

0 commit comments

Comments
 (0)