11package iris.json.serialization
22
33import iris.json.JsonItem
4- import iris.json.serialization.DeserializerClassImpl.PolymorphInfo
5- import iris.json.serialization.DeserializerClassImpl.PropertyInfo
6- import kotlin.reflect.*
7- import kotlin.reflect.full.*
4+ import kotlin.reflect.KClass
5+ import kotlin.reflect.KType
6+ import kotlin.reflect.full.isSubclassOf
7+ import kotlin.reflect.full.isSubtypeOf
8+ import kotlin.reflect.full.starProjectedType
9+ import kotlin.reflect.full.superclasses
810import kotlin.reflect.jvm.jvmErasure
911
1012/* *
@@ -16,34 +18,24 @@ object DeserializerFactory {
1618 private val cache = mutableMapOf<KClass <* >, Deserializer > ()
1719 private val typeCache = mutableMapOf<KType , Deserializer >()
1820
19- fun getDeserializer (d : KClass <* >): Deserializer {
20- return cache.getOrPut(d) { buildInstance(d) }
21+ fun getDeserializer (d : KClass <* >, allowSuperclasses : Boolean = true): Deserializer {
22+ return cache.getOrPut(d) {
23+ if (allowSuperclasses) {
24+ for (supers in d.superclasses)
25+ cache[supers]?.let { return @getOrPut it.forSubclass(d) }
26+ }
27+ DeserializerClassBuilder .build(d)
28+ }
2129 }
2230
23- fun registerDeserializer (d : KClass <* >, deserializer : Deserializer , force : Boolean = false ) {
31+ fun registerDeserializer (d : KClass <* >, deserializer : Deserializer ) {
2432 cache[d] = deserializer
25- val supers = d.superclasses
26- if (supers.isEmpty())
27- return
28- val lastDes = if (force) null else cache[supers.last()]
29- if (lastDes == null ) {
30- for (c in supers)
31- cache[c] = deserializer
32- } else {
33- for (c in supers) {
34- if (cache.contains(c))
35- break
36- cache[c] = deserializer
37- }
38- }
3933 }
4034
4135 fun getDeserializer (type : KType ): Deserializer {
4236 return typeCache.getOrPut(type) {
4337 DeserializerPrimitiveImpl .convertType(type, null )
44- ?.let {
45- return @getOrPut it
46- }
38+ ?.let { return @getOrPut it }
4739
4840 with (type.jvmErasure) { when {
4941 isSubclassOf(Collection ::class ) ->
@@ -64,56 +56,4 @@ object DeserializerFactory {
6456 throw IllegalStateException (" Map key cannot be non CharSequence inherited" )
6557 return value.type!!
6658 }
67-
68- private fun buildInstance (d : KClass <* >): DeserializerClassImpl {
69- var hasPolymorphies = false
70- val constructorInfo = getFieldsOrder(d.constructors)
71- val (constr, constructorFields) = constructorInfo
72-
73- val mProperties = d.memberProperties
74- val fieldsList = mProperties.associateTo(HashMap (mProperties.size)) { property ->
75- val objectItemName = property.name
76- val jsonItemName = property.findAnnotation<JsonField >()?.name
77- ?.let { t -> if (t.isNotEmpty()) t else objectItemName }
78- ? : objectItemName
79- val p = getPropertyInfo(property, constructorFields.find { it.name == objectItemName })
80- if (! hasPolymorphies && p.polymorphInfo != null )
81- hasPolymorphies = true
82- jsonItemName to p
83- }
84-
85- return DeserializerClassImpl (constr, fieldsList, hasPolymorphies)
86- }
87-
88- private fun getPropertyInfo (it : KProperty <* >, constructorParameter : KParameter ? ): PropertyInfo {
89- val tType = DeserializerPrimitiveImpl .convertType(it.returnType, null )
90- var type: DeserializerPrimitiveImpl ? = null
91- var inheritInfo: PolymorphInfo ? = null
92- var innerClass: Deserializer ? = null
93- if (tType != null ) { // simple type int/string/boolean
94- type = tType
95- } else { // there some complex class
96- val data = it.findAnnotation<PolymorphData >()
97- if (data != null ) { // is polymorphic
98- val cases = mutableMapOf<Any , Deserializer >()
99- data.strings.associateTo(cases) { it.label to getDeserializer(it.instance) }
100- data.ints.associateTo(cases) { it.label to getDeserializer(it.instance) }
101- inheritInfo = PolymorphInfo (data.sourceField, cases)
102- } else {
103- innerClass = getDeserializer(it.returnType)
104- }
105- }
106-
107- return PropertyInfo (/* it.name, */ it, constructorParameter, type, innerClass, inheritInfo)
108- }
109-
110- private fun getFieldsOrder (constructors : Collection <KFunction <* >>): Pair <KFunction <* >, List<KParameter>> {
111- var best: KFunction <* >? = null
112- for (c in constructors)
113- if (best == null || c.parameters.size > best.parameters.size)
114- best = c
115- if (best == null )
116- throw IllegalArgumentException (" No any constructor" )
117- return best to best.parameters
118- }
11959}
0 commit comments