We have a polymorphic behaviour, and to cater it with deserialisation, we have written a custom Moshi adapter for it.
@JsonClass(generateAdapter = true)
open class Field
@JsonClass(generateAdapter = true)
data class Field1 (
@Json(name = "name")
val name: String
): Field()
@JsonClass(generateAdapter = true)
data class Field2 (
@Json(name = "address")
val address: String
): Field()
The above is a very simplified version of what we are doing. We would like to use Moshi generated adapter for child classes (Field1 and Field2) and this custom adapter only delegates the fromJson based on the available fields. Here is the custom adapter for Field:
class FieldAdapter {
var moshi = Moshi.Builder().build()
@ToJson
fun toJson(field: Field): String {
return ""
}
@FromJson
fun fromJson(json: String): Field {
val jsonObject = gson.fromJson(json, JsonObject::class.java)
var field: Field? = null
if (jsonObject.has("name")) {
val field1JsonAdapter: JsonAdapter<Field1> = moshi.adapter(Field1::class.java)
field = field1JsonAdapter.fromJson(json)
} else if (jsonObject.has("address")) {
val field2JsonAdapter: JsonAdapter<Field2> = moshi.adapter(Field2::class.java)
field = field2JsonAdapter.fromJson(json)
}
field?.let {
return it
}
throw JsonDataException("Not a valid field JSON")
}
}
The following test does not work:
@Test
fun testField1Serialization() {
val json = MockResponseFileReader("field1.json").content
val moshi = Moshi.Builder().add(FieldAdapter()).build()
val adapter = moshi.adapter(Field::class.java)
val field = adapter.fromJson(json)
val field1 = field as Field1
assertEquals("abc", field1.name)
}
The above test does not call the fromJson of our custom adapter, however if we change val adapter = moshi.adapter(Field::class.java) to val adapter = FieldAdapter() (to hardcode the custom adapter), it works.
Can you please guide what are we doing wrong?
Any help would be appreciated.
TIA