Skip to content

Commit

Permalink
experimenting on JDataClassReflect
Browse files Browse the repository at this point in the history
  • Loading branch information
uberto committed Jun 15, 2024
1 parent 78891f4 commit 96ee529
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 5 deletions.
4 changes: 4 additions & 0 deletions kondor-core/src/main/kotlin/com/ubertob/kondor/json/JAny.kt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ abstract class JAny<T : Any> : ObjectNodeConverterWriters<T>() {
}
}

internal fun <FT> registerPropertyHack(jsonProperty: JsonProperty<FT>, binder: (T) -> Any) =
registerProperty(jsonProperty, binder as (T) -> FT)


override fun fieldAppenders(valueObject: T): List<NamedAppender> =
appenders.flatMap { it(valueObject) }

Expand Down
62 changes: 57 additions & 5 deletions kondor-core/src/main/kotlin/com/ubertob/kondor/json/JDataClass.kt
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package com.ubertob.kondor.json

import com.ubertob.kondor.json.jsonnode.FieldMap
import com.ubertob.kondor.json.jsonnode.JsonNodeObject
import com.ubertob.kondor.json.jsonnode.NodePath
import com.ubertob.kondor.json.jsonnode.NodePathRoot
import com.ubertob.kondor.json.jsonnode.*
import com.ubertob.kondor.json.parser.ObjectFields
import com.ubertob.kondor.outcome.asFailure
import com.ubertob.kondor.outcome.asSuccess
import com.ubertob.kondor.outcome.onFailure
import java.lang.reflect.Constructor
import kotlin.reflect.KClass
import kotlin.reflect.KProperty1

abstract class JAnyAuto<T : Any>() : JAny<T>() {

Expand All @@ -35,7 +33,12 @@ abstract class JDataClass<T : Any>(klazz: KClass<T>) : JAnyAuto<T>() {

val clazz: Class<T> = klazz.java

private val constructor: Constructor<T> by lazy { clazz.constructors.first() as Constructor<T> }
private val constructor: Constructor<T> by lazy {
if (!klazz.isData)
println("Warning! The class $klazz doesn't seem to be a DataClass!")

clazz.constructors.first() as Constructor<T>
}

override fun buildInstance(args: ObjectFields, path: NodePath) =
try {
Expand Down Expand Up @@ -72,4 +75,53 @@ fun <T : Any> JDataClass<T>.testParserAndRender(times: Int = 100, generator: (in

assert(value == valFromJson)
}
}

abstract class JDataClassReflect<T : Any>(val klazz: KClass<T>) : JDataClass<T>(klazz) {


fun registerAllProperties() {
//assuming the declared fields are always in the construtor order we can fix the order problem in JDataClass


klazz.members.filterIsInstance<KProperty1<Any,*>>() .forEach { property ->
println(property.name)
println(property.returnType)
println("#")

//this sees more promising...
}
klazz.java.declaredFields.forEach { field ->
val fieldType: Class<*> = field.type
val fieldTypeClass = field.type::class.java
println(field.name)
println(fieldType)
println("-")

val converter: JsonConverter<out Comparable<*>, out JsonNode> = when (fieldType) {
Int::class.java, Integer::class.java -> JInt
Long::class.java -> JLong
Float::class.java, Double::class.java -> JDouble
String::class.java -> JString
Boolean::class.java -> JBoolean
else -> fieldType.classLoader.loadClass("J${fieldType.simpleName}") as JsonConverter<out Comparable<*>, out JsonNode> //how to get the object from a javaclass or get a Koltin class by name??!!!
}

//is there a way to detect nullable fields?

val prop= JsonPropMandatory(field.name, converter)


when (fieldType) {
Int::class.java -> registerProperty( JsonPropMandatory(field.name, JInt)){ o -> field.getInt(o)}
String::class.java -> registerProperty( JsonPropMandatory(field.name, JString)){ o -> field.get(o) as String}
}


registerPropertyHack(prop) {obj -> field. get(obj) } // !!!!!!!!
}


//
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.ubertob.kondor.outcome.Failure
import com.ubertob.kondor.randomList
import com.ubertob.kondortools.expectSuccess
import com.ubertob.kondortools.printIt
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test
import strikt.api.expectThat
import strikt.assertions.isA
Expand Down Expand Up @@ -129,4 +130,19 @@ class JDataClassTest {

expectThat(error.reason).isEqualTo("Error calling constructor with signature [int, String] using params {name=${person.name}, id=${person.id}}")
}


object PersonRefl : JDataClassReflect<Person>(Person::class)

@Disabled("Work in progress")
@Test
fun `JDataClassAuto doesn't need the fields declaration`() {

PersonRefl.registerAllProperties() //temp hack

PersonRefl.toJson(randomPerson(), JsonStyle.prettyWithNulls)

PersonRefl.testParserAndRender(100) { randomPerson() }

}
}

0 comments on commit 96ee529

Please sign in to comment.