@@ -9,6 +9,8 @@ import com.fasterxml.jackson.databind.SerializationConfig
99import com.fasterxml.jackson.databind.SerializerProvider
1010import com.fasterxml.jackson.databind.ser.Serializers
1111import com.fasterxml.jackson.databind.ser.std.StdSerializer
12+ import io.github.projectmapk.jackson.module.kogera.ReflectionCache
13+ import io.github.projectmapk.jackson.module.kogera.ValueClassUnboxConverter
1214import io.github.projectmapk.jackson.module.kogera.isUnboxableValueClass
1315import java.lang.reflect.Method
1416import java.lang.reflect.Modifier
@@ -39,28 +41,17 @@ internal object ULongSerializer : StdSerializer<ULong>(ULong::class.java) {
3941 }
4042}
4143
42- // In accordance with kotlinx.serialization,
43- // value classes are unboxed and serialized if they do not have a specified serializer.
44- internal object ValueClassUnboxSerializer : StdSerializer<Any>(Any : :class.java) {
45- override fun serialize (value : Any , gen : JsonGenerator , provider : SerializerProvider ) {
46- val unboxed = value::class .java.getMethod(" unbox-impl" ).invoke(value)
47- provider.defaultSerializeValue(unboxed, gen)
48- }
49- }
50-
5144// Class must be UnboxableValueClass.
5245private fun Class <* >.getStaticJsonValueGetter (): Method ? = this .declaredMethods.find { method ->
5346 Modifier .isStatic(method.modifiers) && method.annotations.any { it is JsonValue && it.value }
5447}
5548
56- internal class ValueClassStaticJsonValueSerializer <T >(
57- t : Class <T >,
49+ internal class ValueClassStaticJsonValueSerializer <T : Any >(
50+ private val converter : ValueClassUnboxConverter <T >,
5851 private val staticJsonValueGetter : Method
59- ) : StdSerializer<T>(t) {
60- private val unboxMethod: Method = t.getMethod(" unbox-impl" )
61-
52+ ) : StdSerializer<T>(converter.valueClass) {
6253 override fun serialize (value : T , gen : JsonGenerator , provider : SerializerProvider ) {
63- val unboxed = unboxMethod.invoke (value)
54+ val unboxed = converter.convert (value)
6455 // As shown in the processing of the factory function, jsonValueGetter is always a static method.
6556 val jsonValue: Any? = staticJsonValueGetter.invoke(null , unboxed)
6657 provider.defaultSerializeValue(jsonValue, gen)
@@ -71,12 +62,12 @@ internal class ValueClassStaticJsonValueSerializer<T>(
7162 // If create a function with a JsonValue in the value class,
7263 // it will be compiled as a static method (= cannot be processed properly by Jackson),
7364 // so use a ValueClassSerializer.StaticJsonValue to handle this.
74- fun createOrNull (t : Class < * >): StdSerializer <* >? =
75- t. getStaticJsonValueGetter()?.let { ValueClassStaticJsonValueSerializer (t , it) }
65+ fun < T : Any > createOrNull (converter : ValueClassUnboxConverter < T >): StdSerializer <T >? =
66+ converter.valueClass. getStaticJsonValueGetter()?.let { ValueClassStaticJsonValueSerializer (converter , it) }
7667 }
7768}
7869
79- internal class KotlinSerializers : Serializers .Base () {
70+ internal class KotlinSerializers ( private val cache : ReflectionCache ) : Serializers.Base() {
8071 override fun findSerializer (
8172 config : SerializationConfig ? ,
8273 type : JavaType ,
@@ -90,8 +81,10 @@ internal class KotlinSerializers : Serializers.Base() {
9081 UInt ::class .java == rawClass -> UIntSerializer
9182 ULong ::class .java == rawClass -> ULongSerializer
9283 // The priority of Unboxing needs to be lowered so as not to break the serialization of Unsigned Integers.
93- rawClass.isUnboxableValueClass() -> ValueClassStaticJsonValueSerializer .createOrNull(rawClass)
94- ? : ValueClassUnboxSerializer
84+ rawClass.isUnboxableValueClass() -> {
85+ val unboxConverter = cache.getValueClassUnboxConverter(rawClass)
86+ ValueClassStaticJsonValueSerializer .createOrNull(unboxConverter) ? : unboxConverter.delegatingSerializer
87+ }
9588 else -> null
9689 }
9790 }
0 commit comments