From f2ef7c8a8b4273f81eeccc8469b423639327353e Mon Sep 17 00:00:00 2001 From: Larry Meadors Date: Wed, 9 Mar 2022 07:11:11 -0700 Subject: [PATCH] adding null support for type adapters --- .../src/main/java/com/beust/klaxon/TypeFor.kt | 3 ++ .../com/beust/klaxon/JsonObjectConverter.kt | 4 +- .../com/beust/klaxon/TypeAdapterTest.kt | 37 +++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/klaxon/src/main/java/com/beust/klaxon/TypeFor.kt b/klaxon/src/main/java/com/beust/klaxon/TypeFor.kt index dedd4325..2ac449ed 100644 --- a/klaxon/src/main/java/com/beust/klaxon/TypeFor.kt +++ b/klaxon/src/main/java/com/beust/klaxon/TypeFor.kt @@ -4,6 +4,9 @@ import kotlin.reflect.KClass interface TypeAdapter where Output: Any { fun classFor(type: Any): KClass + fun classForNullable(type: Any?): KClass{ + return classFor(type as Any) + } } @Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS) diff --git a/klaxon/src/main/kotlin/com/beust/klaxon/JsonObjectConverter.kt b/klaxon/src/main/kotlin/com/beust/klaxon/JsonObjectConverter.kt index 835339cd..1e475993 100644 --- a/klaxon/src/main/kotlin/com/beust/klaxon/JsonObjectConverter.kt +++ b/klaxon/src/main/kotlin/com/beust/klaxon/JsonObjectConverter.kt @@ -230,8 +230,8 @@ class JsonObjectConverter(private val klaxon: Klaxon, private val allPaths: Hash // We have polymorphic information for this field. Retrieve its TypeAdapter, // instantiate it, and invoke it with the discriminant value. val discriminantFieldName = Annotations.retrieveJsonFieldName(klaxon, kc, polymorphicInfo.discriminantField) - val discriminant = jsonObject[discriminantFieldName] as Any - polymorphicInfo.adapter.createInstance().classFor(discriminant) + val discriminant = jsonObject[discriminantFieldName] + polymorphicInfo.adapter.createInstance().classForNullable(discriminant) } else { null } diff --git a/klaxon/src/test/kotlin/com/beust/klaxon/TypeAdapterTest.kt b/klaxon/src/test/kotlin/com/beust/klaxon/TypeAdapterTest.kt index 47ea8ac4..a33d84a6 100644 --- a/klaxon/src/test/kotlin/com/beust/klaxon/TypeAdapterTest.kt +++ b/klaxon/src/test/kotlin/com/beust/klaxon/TypeAdapterTest.kt @@ -97,4 +97,41 @@ class TypeAdapterTest { assertThat(r[1]).isInstanceOf(Cat::class.java) } + + @TypeFor(field = "type", adapter = VehicleTypeAdapter::class) + open class Vehicle(open val type: String) + data class Car(override val type: String = "car") : Vehicle(type) + data class Truck(override val type: String = "truck") : Vehicle(type) + + class VehicleTypeAdapter : TypeAdapter { + + override fun classFor(type: Any): KClass { + TODO("Not used - classForNullable replaces this") + } + + override fun classForNullable(type: Any?): KClass = when (type) { + null -> Car::class + "car" -> Car::class + "truck" -> Truck::class + else -> throw IllegalArgumentException("Unknown type: $type") + } + + } + + @Test + fun should_default_to_car() { + val json = """ + [ + { "type": "car" }, + { "type": "truck" } + { "no_type": "should default to car..." } + ] + """ + val r = Klaxon().parseArray(json) + println(r) + assertThat(r!![0]).isInstanceOf(Car::class.java) + assertThat(r[1]).isInstanceOf(Truck::class.java) + assertThat(r[2]).isInstanceOf(Car::class.java) + } + }