Skip to content

Commit 19a32d4

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

File tree

3 files changed

+30
-19
lines changed

3 files changed

+30
-19
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ internal class ValueClassBoxConverter<S : Any?, D : Any>(
2525
val delegatingSerializer: StdDelegatingSerializer by lazy { StdDelegatingSerializer(this) }
2626
}
2727

28-
internal class ValueClassUnboxConverter<T : Any>(private val valueClass: Class<T>) : StdConverter<T, Any?>() {
28+
internal class ValueClassUnboxConverter<T : Any>(val valueClass: Class<T>) : StdConverter<T, Any?>() {
2929
private val unboxMethod = valueClass.getDeclaredMethod("unbox-impl").apply {
3030
if (!this.isAccessible) this.isAccessible = true
3131
}
@@ -34,4 +34,6 @@ internal class ValueClassUnboxConverter<T : Any>(private val valueClass: Class<T
3434
override fun convert(value: T): Any? = unboxMethod.invoke(value)
3535

3636
override fun getInputType(typeFactory: TypeFactory): JavaType = typeFactory.constructType(valueClass)
37+
override fun getOutputType(typeFactory: TypeFactory): JavaType =
38+
typeFactory.constructType(unboxMethod.genericReturnType)
3739
}

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
@@ -103,7 +103,7 @@ public class KotlinModule private constructor(
103103
context.addDeserializers(KotlinDeserializers(cache, useJavaDurationConversion))
104104
context.addKeyDeserializers(KotlinKeyDeserializers)
105105
context.addSerializers(KotlinSerializers())
106-
context.addKeySerializers(KotlinKeySerializers())
106+
context.addKeySerializers(KotlinKeySerializers(cache))
107107

108108
// ranges
109109
context.setMixInAnnotations(ClosedRange::class.java, ClosedRangeMixin::class.java)

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

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,20 @@ 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
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

Comments
 (0)