Skip to content

Commit c8d4fd3

Browse files
committed
Fixed to not get unbox-impl each time
1 parent 19a32d4 commit c8d4fd3

File tree

3 files changed

+16
-21
lines changed

3 files changed

+16
-21
lines changed

src/main/kotlin/io/github/projectmapk/jackson/module/kogera/Converters.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,6 @@ internal class ValueClassUnboxConverter<T : Any>(val valueClass: Class<T>) : Std
3636
override fun getInputType(typeFactory: TypeFactory): JavaType = typeFactory.constructType(valueClass)
3737
override fun getOutputType(typeFactory: TypeFactory): JavaType =
3838
typeFactory.constructType(unboxMethod.genericReturnType)
39+
40+
val delegatingSerializer: StdDelegatingSerializer by lazy { StdDelegatingSerializer(this) }
3941
}

src/main/kotlin/io/github/projectmapk/jackson/module/kogera/KotlinModule.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public class KotlinModule private constructor(
102102

103103
context.addDeserializers(KotlinDeserializers(cache, useJavaDurationConversion))
104104
context.addKeyDeserializers(KotlinKeyDeserializers)
105-
context.addSerializers(KotlinSerializers())
105+
context.addSerializers(KotlinSerializers(cache))
106106
context.addKeySerializers(KotlinKeySerializers(cache))
107107

108108
// ranges

src/main/kotlin/io/github/projectmapk/jackson/module/kogera/ser/serializers/KotlinSerializers.kt

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import com.fasterxml.jackson.databind.SerializationConfig
99
import com.fasterxml.jackson.databind.SerializerProvider
1010
import com.fasterxml.jackson.databind.ser.Serializers
1111
import 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
1214
import io.github.projectmapk.jackson.module.kogera.isUnboxableValueClass
1315
import java.lang.reflect.Method
1416
import 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.
5245
private 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

Comments
 (0)