1
1
package com.fasterxml.jackson.module.kotlin
2
2
3
+ import com.fasterxml.jackson.annotation.JsonValue
3
4
import com.fasterxml.jackson.core.JsonGenerator
4
5
import com.fasterxml.jackson.databind.BeanDescription
5
6
import com.fasterxml.jackson.databind.JavaType
@@ -8,8 +9,9 @@ import com.fasterxml.jackson.databind.SerializationConfig
8
9
import com.fasterxml.jackson.databind.SerializerProvider
9
10
import com.fasterxml.jackson.databind.ser.Serializers
10
11
import com.fasterxml.jackson.databind.ser.std.StdSerializer
12
+ import java.lang.reflect.Method
13
+ import java.lang.reflect.Modifier
11
14
import java.math.BigInteger
12
- import kotlin.reflect.KClass
13
15
14
16
object SequenceSerializer : StdSerializer<Sequence<*>>(Sequence : :class.java) {
15
17
override fun serialize (value : Sequence <* >, gen : JsonGenerator , provider : SerializerProvider ) {
@@ -43,6 +45,10 @@ object ULongSerializer : StdSerializer<ULong>(ULong::class.java) {
43
45
}
44
46
}
45
47
48
+ // Class must be UnboxableValueClass.
49
+ private fun Class <* >.getStaticJsonValueGetter (): Method ? = this .declaredMethods
50
+ .find { method -> Modifier .isStatic(method.modifiers) && method.annotations.any { it is JsonValue } }
51
+
46
52
object ValueClassUnboxSerializer : StdSerializer<Any>(Any : :class.java) {
47
53
override fun serialize (value : Any , gen : JsonGenerator , provider : SerializerProvider ) {
48
54
val unboxed = value::class .java.getMethod(" unbox-impl" ).invoke(value)
@@ -89,3 +95,27 @@ internal class ValueClassBoxSerializer<T : Any>(
89
95
provider.findValueSerializer(outerClazz).serialize(boxed, gen, provider)
90
96
}
91
97
}
98
+
99
+ internal class ValueClassStaticJsonValueSerializer <T > private constructor(
100
+ innerClazz : Class <T >,
101
+ private val staticJsonValueGetter : Method
102
+ ) : StdSerializer<T>(innerClazz) {
103
+ override fun serialize (value : T ? , gen : JsonGenerator , provider : SerializerProvider ) {
104
+ // As shown in the processing of the factory function, jsonValueGetter is always a static method.
105
+ val jsonValue: Any? = staticJsonValueGetter.invoke(null , value)
106
+ jsonValue
107
+ ?.let { provider.findValueSerializer(it::class .java).serialize(it, gen, provider) }
108
+ ? : provider.findNullValueSerializer(null ).serialize(null , gen, provider)
109
+ }
110
+
111
+ // Since JsonValue can be processed correctly if it is given to a non-static getter/field,
112
+ // this class will only process if it is a `static` method.
113
+ companion object {
114
+ fun <T > createdOrNull (
115
+ outerClazz : Class <out Any >,
116
+ innerClazz : Class <T >
117
+ ): ValueClassStaticJsonValueSerializer <T >? = outerClazz
118
+ .getStaticJsonValueGetter()
119
+ ?.let { ValueClassStaticJsonValueSerializer (innerClazz, it) }
120
+ }
121
+ }
0 commit comments