@@ -9,17 +9,20 @@ 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
1517
16- internal object ValueClassUnboxKeySerializer : StdSerializer<Any>(Any : :class.java) {
17- override fun serialize (value : Any , gen : JsonGenerator , provider : SerializerProvider ) {
18- val method = value::class .java.getMethod(" unbox-impl" )
19- val unboxed = method.invoke(value)
18+ internal class ValueClassUnboxKeySerializer <T : Any >(
19+ private val converter : ValueClassUnboxConverter <T >
20+ ) : StdSerializer<T>(converter.valueClass) {
21+ override fun serialize (value : T , gen : JsonGenerator , provider : SerializerProvider ) {
22+ val unboxed = converter.convert(value)
2023
2124 if (unboxed == null ) {
22- val javaType = provider.typeFactory.constructType(method.genericReturnType )
25+ val javaType = converter.getOutputType(provider.typeFactory )
2326 provider.findNullKeySerializer(javaType, null ).serialize(null , gen, provider)
2427 return
2528 }
@@ -33,15 +36,14 @@ private fun Class<*>.getStaticJsonKeyGetter(): Method? = this.declaredMethods.fi
3336 Modifier .isStatic(method.modifiers) && method.annotations.any { it is JsonKey && it.value }
3437}
3538
36- internal class ValueClassStaticJsonKeySerializer <T >(
37- t : Class <T >,
39+ internal class ValueClassStaticJsonKeySerializer <T : Any >(
40+ private val converter : ValueClassUnboxConverter <T >,
3841 private val staticJsonKeyGetter : Method
39- ) : StdSerializer<T>(t ) {
42+ ) : StdSerializer<T>(converter.valueClass ) {
4043 private val keyType: Class <* > = staticJsonKeyGetter.returnType
41- private val unboxMethod: Method = t.getMethod(" unbox-impl" )
4244
4345 override fun serialize (value : T , gen : JsonGenerator , provider : SerializerProvider ) {
44- val unboxed = unboxMethod.invoke (value)
46+ val unboxed = converter.convert (value)
4547 // As shown in the processing of the factory function, jsonValueGetter is always a static method.
4648 val jsonKey: Any? = staticJsonKeyGetter.invoke(null , unboxed)
4749
@@ -57,19 +59,26 @@ internal class ValueClassStaticJsonKeySerializer<T>(
5759 // If create a function with a JsonValue in the value class,
5860 // it will be compiled as a static method (= cannot be processed properly by Jackson),
5961 // so use a ValueClassSerializer.StaticJsonValue to handle this.
60- fun createOrNull (t : Class < * >): StdSerializer <* >? =
61- t. getStaticJsonKeyGetter()?.let { ValueClassStaticJsonKeySerializer (t , it) }
62+ fun < T : Any > createOrNull (converter : ValueClassUnboxConverter < T >): StdSerializer <T >? =
63+ converter.valueClass. getStaticJsonKeyGetter()?.let { ValueClassStaticJsonKeySerializer (converter , it) }
6264 }
6365}
6466
65- internal class KotlinKeySerializers : Serializers .Base () {
67+ internal class KotlinKeySerializers ( private val cache : ReflectionCache ) : Serializers.Base() {
6668 override fun findSerializer (
6769 config : SerializationConfig ,
6870 type : JavaType ,
6971 beanDesc : BeanDescription
70- ): JsonSerializer <* >? = when {
71- type.rawClass.isUnboxableValueClass() -> ValueClassStaticJsonKeySerializer .createOrNull(type.rawClass)
72- ? : ValueClassUnboxKeySerializer
73- else -> null
72+ ): JsonSerializer <* >? {
73+ val rawClass = type.rawClass
74+
75+ return when {
76+ rawClass.isUnboxableValueClass() -> {
77+ val unboxConverter = cache.getValueClassUnboxConverter(rawClass)
78+ ValueClassStaticJsonKeySerializer .createOrNull(unboxConverter)
79+ ? : ValueClassUnboxKeySerializer (unboxConverter)
80+ }
81+ else -> null
82+ }
7483 }
7584}
0 commit comments