Skip to content

Commit 52979cb

Browse files
committed
refactor scala object deserialization (#657)
* refactor scala object deserialization * Update build.sbt * Update Classes.scala * refactor beanintrospector * Update build.sbt * Update CaseObjectDeserializerTest.scala
1 parent da17299 commit 52979cb

File tree

5 files changed

+20
-23
lines changed

5 files changed

+20
-23
lines changed

build.sbt

+3-1
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,9 @@ mimaBinaryIssueFilters ++= Seq(
241241
ProblemFilters.exclude[DirectMissingMethodProblem]("com.fasterxml.jackson.module.scala.introspect.ScalaAnnotationIntrospector.findSerializationKeyType"),
242242
ProblemFilters.exclude[DirectMissingMethodProblem]("com.fasterxml.jackson.module.scala.introspect.ScalaAnnotationIntrospector.findSerializationType"),
243243
ProblemFilters.exclude[DirectMissingMethodProblem]("com.fasterxml.jackson.module.scala.introspect.ScalaAnnotationIntrospector.findSerializationInclusionForContent"),
244-
ProblemFilters.exclude[DirectMissingMethodProblem]("com.fasterxml.jackson.module.scala.introspect.ScalaAnnotationIntrospector.findSerializationInclusion")
244+
ProblemFilters.exclude[DirectMissingMethodProblem]("com.fasterxml.jackson.module.scala.introspect.ScalaAnnotationIntrospector.findSerializationInclusion"),
245+
ProblemFilters.exclude[ReversedMissingMethodProblem]("com.fasterxml.jackson.module.scala.util.ClassW.getModuleField"),
246+
ProblemFilters.exclude[ReversedMissingMethodProblem]("com.fasterxml.jackson.module.scala.util.ClassW.com$fasterxml$jackson$module$scala$util$ClassW$$moduleField")
245247
)
246248

247249
def compareVersions(version1: String, version2: String): Int = {

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

+5-12
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,15 @@ import com.fasterxml.jackson.module.scala.util.ClassW
1010
import scala.languageFeature.postfixOps
1111
import scala.util.control.NonFatal
1212

13-
private class ScalaObjectDeserializer(clazz: Class[_]) extends StdDeserializer[Any](classOf[Any]) {
14-
override def deserialize(p: JsonParser, ctxt: DeserializationContext): Any = {
15-
try {
16-
clazz.getField("MODULE$").get(null)
17-
} catch {
18-
case NonFatal(_) => null
19-
}
20-
}
13+
private class ScalaObjectDeserializer(value: Any) extends StdDeserializer[Any](classOf[Any]) {
14+
override def deserialize(p: JsonParser, ctxt: DeserializationContext): Any = value
2115
}
2216

2317
private object ScalaObjectDeserializerResolver extends Deserializers.Base {
2418
override def findBeanDeserializer(javaType: JavaType, config: DeserializationConfig, beanDesc: BeanDescription): JsonDeserializer[_] = {
25-
val clazz = javaType.getRawClass
26-
if (ClassW(clazz).isScalaObject)
27-
new ScalaObjectDeserializer(clazz)
28-
else null
19+
ClassW(javaType.getRawClass).getModuleField.flatMap { field =>
20+
Option(field.get(null))
21+
}.map(new ScalaObjectDeserializer(_)).orNull
2922
}
3023
}
3124

src/main/scala/com/fasterxml/jackson/module/scala/introspect/BeanIntrospector.scala

+2-3
Original file line numberDiff line numberDiff line change
@@ -184,12 +184,11 @@ object BeanIntrospector {
184184
//create properties for all appropriate fields
185185
val fields = for {
186186
cls <- hierarchy
187-
scalaCaseObject = isScalaCaseObject(cls)
188-
isScalaObject = ClassW(cls).isScalaObject
189187
field <- cls.getDeclaredFields
188+
isScalaObject = ClassW(cls).isScalaObject || isScalaCaseObject(cls)
190189
name = maybePrivateName(field)
191190
if !name.contains('$')
192-
if (isScalaObject || scalaCaseObject || isAcceptableField(field))
191+
if isScalaObject || isAcceptableField(field)
193192
beanGetter = findBeanGetter(cls, name)
194193
beanSetter = findBeanSetter(cls, name)
195194
} yield PropertyDescriptor(name, findConstructorParam(hierarchy.head, name), Some(field), findGetter(cls, name), findSetter(cls, name), beanGetter, beanSetter)

src/main/scala/com/fasterxml/jackson/module/scala/util/Classes.scala

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.fasterxml.jackson.module.scala.util
22

3+
import java.lang.reflect.Field
34
import scala.annotation.tailrec
45
import scala.language.implicitConversions
56
import scala.reflect.{ScalaLongSignature, ScalaSignature}
@@ -28,9 +29,11 @@ trait ClassW extends PimpedType[Class[_]] {
2829
hasSigHelper(value)
2930
}
3031

31-
def isScalaObject: Boolean = {
32-
Try(value.getField("MODULE$")).isSuccess
33-
}
32+
def isScalaObject: Boolean = moduleField.isSuccess
33+
34+
def getModuleField: Option[Field] = moduleField.toOption
35+
36+
private lazy val moduleField: Try[Field] = Try(value.getField("MODULE$"))
3437
}
3538

3639
object ClassW {

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ class CaseObjectDeserializerTest extends DeserializerTest {
2222
val original = TestObject
2323
val json = mapper.writeValueAsString(original)
2424
val deserialized = mapper.readValue(json, TestObject.getClass)
25-
assert(deserialized == original)
25+
assert(deserialized === original)
2626
}
2727

2828
it should "deserialize Foo and not create a new instance" in {
2929
val mapper = JsonMapper.builder().addModule(DefaultScalaModule).addModule(ScalaObjectDeserializerModule).build()
3030
val original = Foo
3131
val json = mapper.writeValueAsString(original)
3232
val deserialized = mapper.readValue(json, Foo.getClass)
33-
assert(deserialized == original)
33+
assert(deserialized === original)
3434
}
3535

3636
it should "deserialize Foo and not create a new instance (visibility settings)" in {
@@ -42,7 +42,7 @@ class CaseObjectDeserializerTest extends DeserializerTest {
4242
val original = Foo
4343
val json = mapper.writeValueAsString(original)
4444
val deserialized = mapper.readValue(json, Foo.getClass)
45-
assert(deserialized == original)
45+
assert(deserialized === original)
4646
}
4747

4848
"An ObjectMapper with ClassTagExtensions and DefaultScalaModule" should "deserialize a case object and not create a new instance" in {
@@ -52,7 +52,7 @@ class CaseObjectDeserializerTest extends DeserializerTest {
5252
val original = TestObject
5353
val json = mapper.writeValueAsString(original)
5454
val deserialized = mapper.readValue[TestObject.type](json)
55-
assert(deserialized == original)
55+
assert(deserialized === original)
5656
}
5757

5858
"An ObjectMapper without ScalaObjectDeserializerModule" should "deserialize a case object but create a new instance" in {

0 commit comments

Comments
 (0)