refactor: more secure DataCopy.kt

This commit is contained in:
SOR
2026-07-25 14:35:25 +08:00
parent 999ce5a68a
commit 994b2ff5b3
2 changed files with 25 additions and 41 deletions
@@ -1,56 +1,39 @@
package club.itstudio.itmanager.entity
import kotlin.reflect.KClass
import kotlin.reflect.KProperty
import kotlin.reflect.KMutableProperty1
import kotlin.reflect.KProperty1
import kotlin.reflect.full.createInstance
import kotlin.reflect.full.declaredMemberProperties
import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.javaField
import kotlin.reflect.jvm.isAccessible
interface DataCopy {
fun <T : Any> toAnotherObject(
toClass: KClass<T>,
otherProperties: Map<String, Any?>
otherProperties: Map<String, Any?> = emptyMap()
): T {
try {
val voProperties = toClass.declaredMemberProperties
@Suppress("UNCHECKED_CAST")
val sourceProps = this::class.memberProperties
.associate { it.name to (it as KProperty1<Any, *>).get(this) }
return try {
val vo = toClass.createInstance()
for (voProperty in voProperties)
copyFieldData(voProperty, otherProperties, vo)
return vo
for (prop in toClass.declaredMemberProperties) {
@Suppress("UNCHECKED_CAST")
val mutableProp = prop as? KMutableProperty1<Any, Any?> ?: continue
val value = when {
sourceProps.containsKey(prop.name) -> sourceProps[prop.name]
otherProperties.containsKey(prop.name) -> otherProperties[prop.name]
else -> continue
}
mutableProp.isAccessible = true
mutableProp.set(vo, value)
}
vo
} catch (e: ReflectiveOperationException) {
throw RuntimeException(
"${toClass.simpleName} has no fields.",
e
"Failed to instantiate ${toClass.simpleName}. Does it have a no-arg constructor?", e
)
}
}
private fun copyFieldData(
toProperty: KProperty<*>,
otherProperties: Map<String, Any?>,
another: Any
) {
try {
val thisProperty = this::class.memberProperties
.firstOrNull { it.name == toProperty.name }
val value =
if (thisProperty != null) {
thisProperty.getter.call(this)
} else if (otherProperties.containsKey(toProperty.name))
otherProperties[toProperty.name]
else
throw RuntimeException(
"Property ${toProperty.name} not found."
)
val field = toProperty.javaField!!
field.isAccessible = true
field.set(another, value)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
@@ -12,5 +12,6 @@ object Const {
const val FLOW_LIMIT_COUNTER = "flow:counter:"
const val FLOW_LIMIT_BLOCK = "flow:block:"
val INTERNAL_ERROR_MONO = Mono.just("something went wrong. Please contact the administrator.")
const val INTERNAL_ERROR_STR = "something went wrong. Please contact the administrator."
val INTERNAL_ERROR_MONO = Mono.just(INTERNAL_ERROR_STR)
}