@@ -4,6 +4,7 @@ import iris.json.JsonEntry
44import iris.json.JsonItem
55import iris.json.JsonObject
66import java.util.*
7+ import kotlin.collections.ArrayList
78import kotlin.collections.HashMap
89import kotlin.reflect.*
910
@@ -12,7 +13,11 @@ import kotlin.reflect.*
1213 * @author [Ivan Ivanov](https://vk.com/irisism)
1314 */
1415
15- class DeserializerClassImpl (private val constructorFunction : KFunction <* >, private val fields : Map <String , PropertyInfo >, private val hasPolymorphisms : Boolean ) : DeserializerClass {
16+ class DeserializerClassImpl : DeserializerClass {
17+
18+ var hasPolymorphisms = false
19+ lateinit var fields: Map <String , PropertyInfo >
20+ lateinit var constructorFunction: KFunction <* >
1621
1722 class PolymorphInfo (val sourceField : String , val inheritClasses : Map <Any , Deserializer >)
1823
@@ -22,6 +27,8 @@ class DeserializerClassImpl(private val constructorFunction: KFunction<*>, priva
2227 , val polymorphInfo : PolymorphInfo ? = null
2328 )
2429
30+ class SetterPropertyException (message : String , cause : Throwable ) : Throwable(message, cause)
31+
2532 override fun <T > deserialize (item : JsonItem ): T {
2633 return getObject((item as JsonObject ).getEntries())
2734 }
@@ -44,8 +51,14 @@ class DeserializerClassImpl(private val constructorFunction: KFunction<*>, priva
4451 result = null
4552 }
4653
47- val otherFields = mutableListOf<Pair <KProperty <* >, Any? >> ()
48- val constructorMap = HashMap <KParameter , Any ?>(info.constructorFunction.parameters.size)
54+ val conscructorParametersSize = info.constructorFunction.parameters.size
55+ val otherSize = fields.size - conscructorParametersSize
56+ val constructorMap = HashMap <KParameter , Any ?>(conscructorParametersSize)
57+ val otherFields = (if (otherSize == 0 )
58+ null
59+ else
60+ ArrayList <Pair <KProperty <* >, Any? >> (fields.size - conscructorParametersSize))
61+
4962 for ((key, jsonItem) in entries) {
5063 val field = key.toString()
5164 val param = fields[field]? : continue
@@ -54,10 +67,10 @@ class DeserializerClassImpl(private val constructorFunction: KFunction<*>, priva
5467 val sourceValue = result!! [polymorphInfo.sourceField]
5568 if (sourceValue != null ) { // already know what type is it
5669 val inherit = polymorphInfo.inheritClasses[sourceValue]!!
57- val newValue: Any? = inherit.deserialize(jsonItem)// jsonItem.asObject(inherit)
70+ val newValue: Any? = inherit.deserialize(jsonItem)
5871 result[field] = newValue
5972 param.constructorParameter?.let { constructorMap[it] = newValue }
60- ? : run { otherFields + = param.property to newValue }
73+ ? : run { otherFields!! + = param.property to newValue }
6174
6275 } else { // need delay initialization until we know source info
6376 val item = delayedInit!! [polymorphInfo.sourceField]
@@ -76,28 +89,34 @@ class DeserializerClassImpl(private val constructorFunction: KFunction<*>, priva
7689 val inherit = property.polymorphInfo!! .inheritClasses[value]!!
7790 val newValue: Any = inherit.deserialize(item.json)
7891 item.propertyInfo.constructorParameter?.let { constructorMap[it] = newValue }
79- ? : run { otherFields + = property.property to newValue }
92+ ? : run { otherFields!! + = property.property to newValue }
8093
8194 if (delayed.items != null ) {
8295 for (item in delayed.items!! ) {
8396 val property = item.propertyInfo
8497 val inherit = property.polymorphInfo!! .inheritClasses[value]!!
8598 val newValue: Any = inherit.deserialize(item.json)
8699 item.propertyInfo.constructorParameter?.let { constructorMap[it] = newValue }
87- ? : run { otherFields + = property.property to newValue }
100+ ? : run { otherFields!! + = property.property to newValue }
88101 }
89102 }
90103 }
91104 result!! [field] = value
92105 }
93106
94107 param.constructorParameter?.let { constructorMap[it] = value }
95- ? : run { otherFields + = param.property to value }
108+ ? : run { otherFields!! + = param.property to value }
96109 }
97110 }
98111 val item = info.constructorFunction.callBy(constructorMap) as T
99- for (field in otherFields) {
100- (field.first as KMutableProperty <* >).setter.call(item, field.second)
112+ if (otherFields != null ) {
113+ for (field in otherFields) {
114+ try {
115+ (field.first as KMutableProperty <* >).setter.call(item, field.second)
116+ } catch (e: ClassCastException ) {
117+ throw SetterPropertyException (" Property $field does not have available setter" , e)
118+ }
119+ }
101120 }
102121 return item
103122 }
0 commit comments