This commit is contained in:
tursom 2022-01-08 21:22:42 +08:00
parent 3fb22b30bb
commit b5150955a0
19 changed files with 1571 additions and 10 deletions

View File

@ -20,6 +20,7 @@ include("ts-core:ts-json")
include("ts-core:ts-xml") include("ts-core:ts-xml")
include("ts-core:ts-async-http") include("ts-core:ts-async-http")
include("ts-core:ts-proxy") include("ts-core:ts-proxy")
include("ts-core:ts-reflect")
include("ts-socket") include("ts-socket")
include("ts-web") include("ts-web")
include("ts-web:ts-web-netty") include("ts-web:ts-web-netty")

View File

@ -30,12 +30,12 @@ import javax.mail.internet.MimeMultipart
data class EmailData( data class EmailData(
var host: String?, var port: Int?, var name: String?, var password: String?, var from: String?, var host: String?, var port: Int?, var name: String?, var password: String?, var from: String?,
var to: String?, var subject: String?, var html: String? = null, var text: String? = null, var to: String?, var subject: String?, var html: String? = null, var text: String? = null,
var image: Collection<Image>? = null, var attachment: Collection<DataSource>? = null var image: Collection<Image>? = null, var attachment: Collection<DataSource>? = null,
) { ) : Mail {
/** /**
* 发送邮件 * 发送邮件
*/ */
fun send(transportListener: TransportListener? = null) { override fun send(transportListener: TransportListener?) {
if (host == null || port == null || name == null || password == null || from == null || to == null || subject == null) return if (host == null || port == null || name == null || password == null || from == null || to == null || subject == null) return
val props = Properties() val props = Properties()
// props["mail.debug"] = "true" // 开启debug调试 // props["mail.debug"] = "true" // 开启debug调试
@ -69,7 +69,7 @@ data class EmailData(
html: String?, html: String?,
text: String?, text: String?,
image: Collection<Image>?, image: Collection<Image>?,
attachment: Collection<DataSource>? attachment: Collection<DataSource>?,
): MimeMessage { ): MimeMessage {
//邮件内容部分 //邮件内容部分
val msg = MimeMessage(session) val msg = MimeMessage(session)

View File

@ -15,9 +15,8 @@ data class GroupEmailData(
var host: String?, var port: Int?, var name: String?, var password: String?, var from: String?, var host: String?, var port: Int?, var name: String?, var password: String?, var from: String?,
var to: Collection<String>?, var subject: String?, var html: String? = null, var text: String? = null, var to: Collection<String>?, var subject: String?, var html: String? = null, var text: String? = null,
var image: Collection<Image>? = null, var attachment: Collection<DataSource>? = null, var image: Collection<Image>? = null, var attachment: Collection<DataSource>? = null,
) { ) : Mail {
fun send() = send(null) override fun send(transportListener: TransportListener?) {
fun send(transportListener: TransportListener?) {
if (host == null || port == null || name == null || password == null || from == null || to?.isEmpty() != false || subject == null) return if (host == null || port == null || name == null || password == null || from == null || to?.isEmpty() != false || subject == null) return
val props = Properties() val props = Properties()
// props["mail.debug"] = "true" // 开启debug调试 // props["mail.debug"] = "true" // 开启debug调试

View File

@ -0,0 +1,7 @@
package cn.tursom.mail
import javax.mail.event.TransportListener
interface Mail {
fun send(transportListener: TransportListener? = null)
}

View File

@ -4,6 +4,7 @@ import com.sun.mail.util.MailSSLSocketFactory
import java.util.* import java.util.*
import javax.mail.Address import javax.mail.Address
import javax.mail.Session import javax.mail.Session
import javax.mail.event.TransportListener
import javax.mail.internet.InternetAddress import javax.mail.internet.InternetAddress
data class MultipleEmailData( data class MultipleEmailData(
@ -12,9 +13,9 @@ data class MultipleEmailData(
var name: String?, var name: String?,
var password: String?, var password: String?,
var from: String?, var from: String?,
var to: Collection<MailStructure>? var to: Collection<MailStructure>?,
) { ) : Mail {
fun send() { override fun send(transportListener: TransportListener?) {
val from = from ?: return val from = from ?: return
val props = Properties() val props = Properties()
// props["mail.debug"] = "true" // 开启debug调试 // props["mail.debug"] = "true" // 开启debug调试
@ -32,6 +33,7 @@ data class MultipleEmailData(
//发送邮件 //发送邮件
val transport = session.transport val transport = session.transport
transport.connect(host, name, password) transport.connect(host, name, password)
transportListener?.apply { transport.addTransportListener(this) }
to?.forEach { (to, subject, html, text, image, attachment) -> to?.forEach { (to, subject, html, text, image, attachment) ->
//邮件内容部分 //邮件内容部分
val msg = EmailData.getMsg(session, from, subject, html, text, image, attachment) val msg = EmailData.getMsg(session, from, subject, html, text, image, attachment)

View File

@ -0,0 +1,22 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm")
`maven-publish`
id("ts-gradle")
kotlin("plugin.allopen") version "1.5.21"
}
dependencies {
api(project(":ts-core"))
api(project(":ts-core:ts-log"))
testApi(group = "junit", name = "junit", version = "4.13.2")
}
artifacts {
archives(tasks["kotlinSourcesJar"])
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions.freeCompilerArgs += "-Xjvm-default=all"
}

View File

@ -0,0 +1,98 @@
@file:Suppress("unused")
package cn.tursom.reflect
import cn.tursom.core.uncheckedCast
import java.lang.reflect.Method
inline fun <R> Class<*>.getDeclaredMethod(
returnType: Class<*>,
getMethod: Class<*>.() -> Method?,
staticReturn: (method: Method) -> R,
): R? {
val method = this.getDeclaredMethod(returnType, false, getMethod)
if (method != null) return staticReturn(method)
return null
}
inline fun <reified R : Any> Any.getMethod(
name: String,
clazz: Class<*> = javaClass,
returnType: Class<R> = R::class.java,
getMethod: Class<*>.() -> Method? = {
getMethodFully(name)
},
): (() -> R)? = clazz.getDeclaredMethod(returnType, getMethod) { method ->
{ method(this).uncheckedCast() }
} ?: clazz.getStaticDeclaredMethod(name, returnType, getMethod)
inline fun <reified R : Any, reified T1> Any.getMethod1(
name: String,
returnType: Class<R> = R::class.java,
arg1Type: Class<T1> = T1::class.java,
clazz: Class<*> = javaClass,
getMethod: Class<*>.() -> Method? = {
getMethodFully(name, arg1Type)
},
): ((T1) -> R)? = clazz.getDeclaredMethod(returnType, getMethod) { method ->
{ method(this, it).uncheckedCast() }
} ?: clazz.getStaticDeclaredMethod1(name, returnType, arg1Type, getMethod)
inline fun <reified R : Any, reified T1, reified T2> Any.getMethod2(
name: String,
returnType: Class<R> = R::class.java,
arg1Type: Class<T1> = T1::class.java,
arg2Type: Class<T2> = T2::class.java,
clazz: Class<*> = javaClass,
getMethod: Class<*>.() -> Method? = {
getMethodFully(name, arg1Type, arg2Type)
},
): ((T1, T2) -> R)? = clazz.getDeclaredMethod(returnType, getMethod) { method ->
{ v1, v2 -> method(this, v1, v2).uncheckedCast() }
} ?: clazz.getStaticDeclaredMethod2(name, returnType, arg1Type, arg2Type, getMethod)
inline fun <reified R : Any, reified T1, reified T2, reified T3> Any.getMethod3(
name: String,
returnType: Class<R> = R::class.java,
arg1Type: Class<T1> = T1::class.java,
arg2Type: Class<T2> = T2::class.java,
arg3Type: Class<T3> = T3::class.java,
clazz: Class<*> = javaClass,
getMethod: Class<*>.() -> Method? = {
getMethodFully(name, arg1Type, arg2Type, arg3Type)
},
): ((T1, T2, T3) -> R)? = clazz.getDeclaredMethod(returnType, getMethod) { method ->
{ v1, v2, v3 -> method(this, v1, v2, v3).uncheckedCast() }
} ?: clazz.getStaticDeclaredMethod3(name, returnType, arg1Type, arg2Type, arg3Type, getMethod)
inline fun <reified R : Any, reified T1, reified T2, reified T3, reified T4> Any.getMethod4(
name: String,
returnType: Class<R> = R::class.java,
arg1Type: Class<T1> = T1::class.java,
arg2Type: Class<T2> = T2::class.java,
arg3Type: Class<T3> = T3::class.java,
arg4Type: Class<T4> = T4::class.java,
clazz: Class<*> = javaClass,
getMethod: Class<*>.() -> Method? = {
getMethodFully(name, arg1Type, arg2Type, arg3Type, arg4Type)
},
): ((T1, T2, T3, T4) -> R)? = clazz.getDeclaredMethod(returnType, getMethod) { method ->
{ v1, v2, v3, v4 -> method(this, v1, v2, v3, v4).uncheckedCast() }
} ?: clazz.getStaticDeclaredMethod4(name, returnType, arg1Type, arg2Type, arg3Type, arg4Type, getMethod)
inline fun <reified R, reified T1, reified T2, reified T3, reified T4, reified T5> Any.getMethod5(
name: String,
returnType: Class<R> = R::class.java,
arg1Type: Class<T1> = T1::class.java,
arg2Type: Class<T2> = T2::class.java,
arg3Type: Class<T3> = T3::class.java,
arg4Type: Class<T4> = T4::class.java,
arg5Type: Class<T5> = T5::class.java,
clazz: Class<*> = javaClass,
getMethod: Class<*>.() -> Method? = {
getMethodFully(name, arg1Type, arg2Type, arg3Type, arg4Type, arg5Type)
},
): ((T1, T2, T3, T4, T5) -> R)? = clazz.getDeclaredMethod(returnType, getMethod) { method ->
{ v1, v2, v3, v4, v5 -> method(this, v1, v2, v3, v4, v5).uncheckedCast() }
} ?: clazz.getStaticDeclaredMethod5(name, returnType, arg1Type, arg2Type, arg3Type, arg4Type, arg5Type, getMethod)

View File

@ -0,0 +1,76 @@
@file:Suppress("unused")
package cn.tursom.reflect
import cn.tursom.core.uncheckedCast
import java.lang.reflect.Method
inline fun <This, reified R> Class<*>.getMethod(
name: String,
returnType: Class<out R> = R::class.java,
getMethod: Class<*>.() -> Method? = { getMethodFully(name) },
): (This.() -> R)? = getDeclaredMethod(returnType, getMethod) { method ->
{ method(this).uncheckedCast() }
}
inline fun <This, reified R, reified T1> Class<*>.getMethod1(
name: String,
returnType: Class<out R> = R::class.java,
arg1Type: Class<in T1> = T1::class.java,
getMethod: Class<*>.() -> Method? = { getMethodFully(name, arg1Type) },
): (This.(T1) -> R)? = getDeclaredMethod(returnType, getMethod) { method ->
{ method(this, it).uncheckedCast() }
}
inline fun <This, reified R, reified T1, reified T2> Class<*>.getMethod2(
name: String,
returnType: Class<out R> = R::class.java,
arg1Type: Class<in T1> = T1::class.java,
arg2Type: Class<in T2> = T2::class.java,
getMethod: Class<*>.() -> Method? = { getMethodFully(name, arg1Type, arg2Type) },
): (This.(T1, T2) -> R)? = getDeclaredMethod(returnType, getMethod) { method ->
{ v1, v2 -> method(this, v1, v2).uncheckedCast() }
}
inline fun <This, reified R, reified T1, reified T2, reified T3> Class<*>.getMethod3(
name: String,
returnType: Class<out R> = R::class.java,
arg1Type: Class<in T1> = T1::class.java,
arg2Type: Class<in T2> = T2::class.java,
arg3Type: Class<in T3> = T3::class.java,
getMethod: Class<*>.() -> Method? = {
getMethodFully(name, arg1Type, arg2Type, arg3Type)
},
): (This.(T1, T2, T3) -> R)? = getDeclaredMethod(returnType, getMethod) { method ->
{ v1, v2, v3 -> method(this, v1, v2, v3).uncheckedCast() }
}
inline fun <This, reified R, reified T1, reified T2, reified T3, reified T4> Class<*>.getMethod4(
name: String,
returnType: Class<out R> = R::class.java,
arg1Type: Class<in T1> = T1::class.java,
arg2Type: Class<in T2> = T2::class.java,
arg3Type: Class<in T3> = T3::class.java,
arg4Type: Class<in T4> = T4::class.java,
getMethod: Class<*>.() -> Method? = {
getMethodFully(name, arg1Type, arg2Type, arg3Type, arg4Type)
},
): (This.(T1, T2, T3, T4) -> R)? = getDeclaredMethod(returnType, getMethod) { method ->
{ v1, v2, v3, v4 -> method(this, v1, v2, v3, v4).uncheckedCast() }
}
inline fun <This, reified R, reified T1, reified T2, reified T3, reified T4, reified T5> Class<*>.getMethod5(
name: String,
returnType: Class<out R> = R::class.java,
arg1Type: Class<in T1> = T1::class.java,
arg2Type: Class<in T2> = T2::class.java,
arg3Type: Class<in T3> = T3::class.java,
arg4Type: Class<in T4> = T4::class.java,
arg5Type: Class<in T5> = T5::class.java,
getMethod: Class<*>.() -> Method? = {
getMethodFully(name, arg1Type, arg2Type, arg3Type, arg4Type)
},
): (This.(T1, T2, T3, T4, T5) -> R)? = getDeclaredMethod(returnType, getMethod) { method ->
{ v1, v2, v3, v4, v5 -> method(this, v1, v2, v3, v4, v5).uncheckedCast() }
}

View File

@ -0,0 +1,198 @@
@file:Suppress("unused")
package cn.tursom.reflect
import cn.tursom.core.allMethodsSequence
import cn.tursom.core.companionObjectInstanceOrNull
import cn.tursom.core.uncheckedCast
import java.lang.reflect.Method
inline fun <reified T> getType() = T::class.java
fun main() {
println(Int::class.java canCast getType<Byte>())
println(Int::class.java canCast getType<Int>())
}
infix fun Class<*>.canCast(target: Class<*>): Boolean {
return (target == Any::class.java || this == target) || (
(this == Void.TYPE || this == Void::class.java) &&
(target == Unit::class.java || target == Void.TYPE || target == Void::class.java)
) || (
(this == Byte::class.java || this == getType<Byte>()) &&
(target == Byte::class.java || target == getType<Byte>())
) || (
(this == Short::class.java || this == getType<Short>()) &&
(target == Short::class.java || target == getType<Short>())
) || (
(this == Int::class.java || this == getType<Int>()) &&
(target == Int::class.java || target == getType<Int>())
) || (
(this == Long::class.java || this == getType<Long>()) &&
(target == Long::class.java || target == getType<Long>())
) || (
(this == Float::class.java || this == getType<Float>()) &&
(target == Float::class.java || target == getType<Float>())
) || (
(this == Double::class.java || this == getType<Double>()) &&
(target == Double::class.java || target == getType<Double>())
) || (
(this == Boolean::class.java || this == getType<Boolean>()) &&
(target == Boolean::class.java || target == getType<Boolean>())
) || (
(this == Char::class.java || this == getType<Char>()) &&
(target == Char::class.java || target == getType<Char>())
) || target.isAssignableFrom(this)
}
private fun Method.match(name: String, vararg type: Class<*>): Boolean {
if (this.name != name) return false
if (this.parameterTypes.size != type.size) return false
this.parameterTypes.forEachIndexed { index, clazz ->
if (!(type[index] canCast clazz)) return false
}
return true
}
fun Class<*>.getFirstMatchMethod(
name: String,
vararg type: Class<*>,
): Method? {
allMethodsSequence.forEach { method ->
if (method.match(name, *type)) {
return method
}
}
return null
}
fun Class<*>.getMethodFully(
name: String,
vararg type: Class<*>,
): Method? {
val scanMethod = scanMethod(name, *type)
return (scanMethod.firstOrNull { method ->
method.parameterTypes.forEachIndexed { index, clazz ->
if (type[index] != clazz) return@firstOrNull false
}
true
} ?: scanMethod.firstOrNull())
}
fun Class<*>.scanMethod(
name: String,
vararg type: Class<*>,
): List<Method> {
@OptIn(ExperimentalStdlibApi::class)
return buildList {
allMethodsSequence.forEach { method ->
if (method.match(name, *type)) add(method)
}
}
}
inline fun Class<*>.getDeclaredMethod(
returnType: Class<*>,
isStatic: Boolean = true,
getMethod: Class<*>.() -> Method?,
) = try {
val method = getMethod()
method?.isAccessible = true
if (method != null && method.isStatic() == isStatic && method.returnType canCast returnType) method
else null
} catch (e: Exception) {
null
}
inline fun <R> Class<*>.getStaticDeclaredMethod(
returnType: Class<*>,
getMethod: Class<*>.() -> Method?,
staticReturn: (method: Method, companionObjectInstance: Any?) -> R,
): R? {
val method = getDeclaredMethod(returnType, true, getMethod)
if (method != null) return staticReturn(method, null)
val companionObjectInstance = kotlin.companionObjectInstanceOrNull ?: return null
val companionObjectClazz = companionObjectInstance.javaClass
val companionMethod = companionObjectClazz.getDeclaredMethod(returnType, false, getMethod)
if (companionMethod != null) return staticReturn(companionMethod, companionObjectInstance)
return null
}
inline fun <reified R : Any> Class<*>.getStaticDeclaredMethod(
name: String,
returnType: Class<R> = R::class.java,
getMethod: Class<*>.() -> Method? = {
getMethodFully(name)
},
): (() -> R)? = getStaticDeclaredMethod(
returnType, getMethod
) { method, companion -> { method(companion).uncheckedCast() } }
inline fun <reified R, reified T1> Class<*>.getStaticDeclaredMethod1(
name: String,
returnType: Class<R> = R::class.java,
arg1Type: Class<T1> = T1::class.java,
getMethod: Class<*>.() -> Method? = {
getMethodFully(name, arg1Type)
},
): ((T1) -> R)? = getStaticDeclaredMethod(
returnType, getMethod
) { method, companion -> { v1 -> method(companion, v1).uncheckedCast() } }
inline fun <reified R, reified T1, reified T2> Class<*>.getStaticDeclaredMethod2(
name: String,
returnType: Class<R> = R::class.java,
arg1Type: Class<T1> = T1::class.java,
arg2Type: Class<T2> = T2::class.java,
getMethod: Class<*>.() -> Method? = {
getMethodFully(name, arg1Type, arg2Type)
},
): ((T1, T2) -> R)? = getStaticDeclaredMethod(
returnType, getMethod
) { method, companion -> { v1, v2 -> method(companion, v1, v2).uncheckedCast() } }
inline fun <reified R, reified T1, reified T2, reified T3> Class<*>.getStaticDeclaredMethod3(
name: String,
returnType: Class<R> = R::class.java,
arg1Type: Class<T1> = T1::class.java,
arg2Type: Class<T2> = T2::class.java,
arg3Type: Class<T3> = T3::class.java,
getMethod: Class<*>.() -> Method? = {
getMethodFully(name, arg1Type, arg2Type, arg3Type)
},
): ((T1, T2, T3) -> R)? = getStaticDeclaredMethod(
returnType, getMethod
) { method, companion -> { v1, v2, v3 -> method(companion, v1, v2, v3).uncheckedCast() } }
inline fun <reified R, reified T1, reified T2, reified T3, reified T4> Class<*>.getStaticDeclaredMethod4(
name: String,
returnType: Class<R> = R::class.java,
arg1Type: Class<T1> = T1::class.java,
arg2Type: Class<T2> = T2::class.java,
arg3Type: Class<T3> = T3::class.java,
arg4Type: Class<T4> = T4::class.java,
getMethod: Class<*>.() -> Method? = {
getMethodFully(name, arg1Type, arg2Type, arg3Type, arg4Type)
},
): ((T1, T2, T3, T4) -> R)? = getStaticDeclaredMethod(
returnType, getMethod
) { method, companion -> { v1, v2, v3, v4 -> method(companion, v1, v2, v3, v4).uncheckedCast() } }
inline fun <reified R, reified T1, reified T2, reified T3, reified T4, reified T5> Class<*>.getStaticDeclaredMethod5(
name: String,
returnType: Class<R> = R::class.java,
arg1Type: Class<T1> = T1::class.java,
arg2Type: Class<T2> = T2::class.java,
arg3Type: Class<T3> = T3::class.java,
arg4Type: Class<T4> = T4::class.java,
arg5Type: Class<T5> = T5::class.java,
getMethod: Class<*>.() -> Method? = {
getMethodFully(name, arg1Type, arg2Type, arg3Type, arg4Type, arg5Type)
},
): ((T1, T2, T3, T4, T5) -> R)? = getStaticDeclaredMethod(
returnType, getMethod
) { method, companion -> { v1, v2, v3, v4, v5 -> method(companion, v1, v2, v3, v4, v5).uncheckedCast() } }

View File

@ -0,0 +1,58 @@
package cn.tursom.reflect
import cn.tursom.core.UncheckedCast
import cn.tursom.core.Unsafe
import cn.tursom.core.cast
import cn.tursom.core.uncheckedCast
import java.util.concurrent.ConcurrentHashMap
import kotlin.reflect.KClass
object InstantAllocator {
enum class AllocateFunction { INSTANCE, UNSAFE, KOBJECT, NONE }
private val allocateFunctionMap = ConcurrentHashMap<Class<*>, AllocateFunction>()
@Throws(NoSuchMethodException::class)
operator fun <T> invoke(clazz: Class<out T>, unsafe: Boolean = true): T = get(clazz, unsafe)
@Throws(NoSuchMethodException::class)
inline operator fun <reified T : Any> invoke(unsafe: Boolean = true): T = get(T::class.java, unsafe)
@Throws(NoSuchMethodException::class)
operator fun <T : Any> get(clazz: KClass<out T>, unsafe: Boolean = true): T = get(clazz.java, unsafe)
@Throws(NoSuchMethodException::class)
operator fun <T> get(clazz: Class<out T>, unsafe: Boolean = true): T {
return when (allocateFunctionMap[clazz]) {
null -> try {
val newInstance = clazz.newInstance()
allocateFunctionMap[clazz] = AllocateFunction.INSTANCE
newInstance
} catch (e: Exception) {
val kClass = clazz.kotlin
val objectInstance = kClass.objectInstance
if (objectInstance != null) {
allocateFunctionMap[clazz] = AllocateFunction.KOBJECT
objectInstance
} else if (unsafe) try {
allocateFunctionMap[clazz] = AllocateFunction.UNSAFE
@OptIn(UncheckedCast::class)
Unsafe.unsafe.allocateInstance(clazz).cast<T>()
} catch (e: Exception) {
allocateFunctionMap[clazz] = AllocateFunction.NONE
throw NoSuchMethodException("${clazz.name}:<init>()")
} else {
throw NoSuchMethodException("${clazz.name}:<init>()")
}
}
AllocateFunction.INSTANCE -> clazz.newInstance()
AllocateFunction.UNSAFE -> if (unsafe) {
Unsafe.unsafe.allocateInstance(clazz).uncheckedCast<T>()
} else {
throw NoSuchMethodException("${clazz.name}:<init>()")
}
AllocateFunction.KOBJECT -> clazz.kotlin.objectInstance!!
AllocateFunction.NONE -> throw NoSuchMethodException("${clazz.name}:<init>()")
}
}
}

View File

@ -0,0 +1,272 @@
@file:Suppress("unused")
package cn.tursom.reflect
import java.lang.reflect.Field
import java.lang.reflect.Member
import java.lang.reflect.Modifier
private val fieldModifiersField: Field? = try {
Field::class.java.getDeclaredField("modifiers").apply {
isAccessible = true
}
} catch (e: Throwable) {
null
}
var fieldModifiers: (Field, Int) -> Unit = { field, modifer ->
fieldModifiersField!!.set(field, modifer)
}
var Field.public: Boolean
get() = Modifier.isPublic(this.modifiers)
set(value) {
val modifier = Modifier.PUBLIC
fieldModifiers(
this,
if (value) {
modifiers or modifier
} else {
modifiers and modifier.inv()
}
)
}
var Field.private: Boolean
get() = Modifier.isPrivate(this.modifiers)
set(value) {
val modifier = Modifier.PRIVATE
fieldModifiers(
this,
if (value) {
modifiers or modifier
} else {
modifiers and modifier.inv()
}
)
}
var Field.protected: Boolean
get() = Modifier.isProtected(this.modifiers)
set(value) {
val modifier = Modifier.PROTECTED
fieldModifiers(
this,
if (value) {
modifiers or modifier
} else {
modifiers and modifier.inv()
}
)
}
var Field.static: Boolean
get() = Modifier.isStatic(this.modifiers)
set(value) {
val modifier = Modifier.STATIC
fieldModifiers(
this,
if (value) {
modifiers or modifier
} else {
modifiers and modifier.inv()
}
)
}
var Field.final: Boolean
get() = Modifier.isFinal(this.modifiers)
set(value) {
val modifier = Modifier.FINAL
fieldModifiers(
this,
if (value) {
modifiers or modifier
} else {
modifiers and modifier.inv()
}
)
}
var Field.synchronized: Boolean
get() = Modifier.isSynchronized(this.modifiers)
set(value) {
val modifier = Modifier.SYNCHRONIZED
fieldModifiers(
this,
if (value) {
modifiers or modifier
} else {
modifiers and modifier.inv()
}
)
}
var Field.volatile: Boolean
get() = Modifier.isVolatile(this.modifiers)
set(value) {
val modifier = Modifier.VOLATILE
fieldModifiers(
this,
if (value) {
modifiers or modifier
} else {
modifiers and modifier.inv()
}
)
}
var Field.transient: Boolean
get() = Modifier.isTransient(this.modifiers)
set(value) {
val modifier = Modifier.TRANSIENT
fieldModifiers(
this,
if (value) {
modifiers or modifier
} else {
modifiers and modifier.inv()
}
)
}
var Field.native: Boolean
get() = Modifier.isNative(this.modifiers)
set(value) {
val modifier = Modifier.NATIVE
fieldModifiers(
this,
if (value) {
modifiers or modifier
} else {
modifiers and modifier.inv()
}
)
}
var Field.`interface`: Boolean
get() = Modifier.isInterface(this.modifiers)
set(value) {
val modifier = Modifier.INTERFACE
fieldModifiers(
this,
if (value) {
modifiers or modifier
} else {
modifiers and modifier.inv()
}
)
}
var Field.abstract: Boolean
get() = Modifier.isAbstract(this.modifiers)
set(value) {
val modifier = Modifier.ABSTRACT
fieldModifiers(
this,
if (value) {
modifiers or modifier
} else {
modifiers and modifier.inv()
}
)
}
var Field.strict: Boolean
get() = Modifier.isStrict(this.modifiers)
set(value) {
val modifier = Modifier.STRICT
fieldModifiers(
this,
if (value) {
modifiers or modifier
} else {
modifiers and modifier.inv()
}
)
}
fun Member.isPublic(): Boolean {
return Modifier.isPublic(this.modifiers)
}
fun Member.isPrivate(): Boolean {
return Modifier.isPrivate(this.modifiers)
}
fun Member.isProtected(): Boolean {
return Modifier.isProtected(this.modifiers)
}
fun Member.isStatic(): Boolean {
return Modifier.isStatic(this.modifiers)
}
fun Member.isFinal(): Boolean {
return Modifier.isFinal(this.modifiers)
}
fun Member.isSynchronized(): Boolean {
return Modifier.isSynchronized(this.modifiers)
}
fun Member.isVolatile(): Boolean {
return Modifier.isVolatile(this.modifiers)
}
fun Member.isTransient(): Boolean {
return Modifier.isTransient(this.modifiers)
}
fun Member.isNative(): Boolean {
return Modifier.isNative(this.modifiers)
}
fun Member.isInterface(): Boolean {
return Modifier.isInterface(this.modifiers)
}
fun Member.isAbstract(): Boolean {
return Modifier.isAbstract(this.modifiers)
}
fun Member.isStrict(): Boolean {
return Modifier.isStrict(this.modifiers)
}
val Class<*>.isPublic: Boolean
get() = Modifier.isPublic(this.modifiers)
val Class<*>.isPrivate: Boolean
get() = Modifier.isPrivate(this.modifiers)
val Class<*>.isProtected: Boolean
get() = Modifier.isProtected(this.modifiers)
val Class<*>.isStatic: Boolean
get() = Modifier.isStatic(this.modifiers)
val Class<*>.isFinal: Boolean
get() = Modifier.isFinal(this.modifiers)
val Class<*>.isSynchronized: Boolean
get() = Modifier.isSynchronized(this.modifiers)
val Class<*>.isVolatile: Boolean
get() = Modifier.isVolatile(this.modifiers)
val Class<*>.isTransient: Boolean
get() = Modifier.isTransient(this.modifiers)
val Class<*>.isNative: Boolean
get() = Modifier.isNative(this.modifiers)
//val Class<*>.isInterface: Boolean
// get() = Modifier.isInterface(this.modifiers)
val Class<*>.isAbstract
get() = Modifier.isAbstract(this.modifiers)
val Class<*>.isStrict
get() = Modifier.isStrict(this.modifiers)

View File

@ -0,0 +1,36 @@
package cn.tursom.reflect
import java.lang.reflect.Method
interface MethodFilter {
fun filterMethod(clazz: Class<*>): Sequence<Method>
companion object
}
class Arg1MethodFilter<R>(
val prevFilter: ReturnTypeMethodFilter<R>,
) : MethodFilter {
override fun filterMethod(clazz: Class<*>): Sequence<Method> {
return prevFilter.filterMethod(clazz).filter { method ->
method.parameterCount == 1
}
}
fun <T> filter(clazz: Class<T>): Sequence<T.() -> R> {
return filterMethod(clazz).map {
{
it.invoke(this) as R
}
}
}
fun filter(obj: Any): Sequence<() -> R> {
return filterMethod(obj.javaClass).map {
{
it.invoke(obj) as R
}
}
}
}

View File

@ -0,0 +1,456 @@
package cn.tursom.reflect
import cn.tursom.core.UncheckedCast
import cn.tursom.core.cast
import cn.tursom.core.forAllMethods
import cn.tursom.log.impl.Slf4jImpl
import java.lang.reflect.Method
import java.lang.reflect.ParameterizedType
import kotlin.coroutines.Continuation
import kotlin.reflect.jvm.javaType
import kotlin.reflect.jvm.kotlinFunction
@Suppress("unused", "MemberVisibilityCanBePrivate")
object MethodInspector : Slf4jImpl() {
fun <R> forEachMethod(
clazz: Class<*>,
returnType: Class<out R>,
argumentType: Array<Class<*>>,
self: Any? = null,
handler: (Method, (Array<Any?>) -> R) -> Unit,
) {
clazz.forAllMethods { method ->
val parameterTypes = method.parameterTypes
val methodReturnType = if (
method.returnType == Void.TYPE ||
method.returnType == Void::class.java
) Unit::class.java else method.returnType
val argumentTypeIterator = argumentType.iterator()
if (parameterTypes.size == argumentType.size &&
parameterTypes.all {
argumentTypeIterator.next().isAssignableFrom(it)
} &&
returnType.isAssignableFrom(methodReturnType)
) {
method.isAccessible = true
@OptIn(UncheckedCast::class)
handler(method) { method.invoke(self, *it).cast() }
}
}
}
fun <R> forEachSuspendMethod(
clazz: Class<*>,
returnType: Class<out R>,
argumentType: Array<Class<*>>,
self: Any? = null,
handler: (Method, suspend (Array<Any?>) -> R) -> Unit,
) {
clazz.forAllMethods { method ->
val parameterTypes = method.parameterTypes
val kotlinFunction = method.kotlinFunction ?: return@forAllMethods
var methodReturnType = kotlinFunction.returnType.javaType
while (methodReturnType is ParameterizedType) {
methodReturnType = methodReturnType.rawType
}
if (methodReturnType !is Class<*>) {
warn("method return type {}({}) is not Class", methodReturnType, methodReturnType.javaClass)
return@forAllMethods
}
val argumentTypeIterator = argumentType.iterator()
if (parameterTypes.size - 1 == argumentType.size &&
parameterTypes.dropLast(1).all {
argumentTypeIterator.next().isAssignableFrom(it)
} &&
Continuation::class.java.isAssignableFrom(parameterTypes.last()) &&
returnType.isAssignableFrom(methodReturnType)
) {
method.isAccessible = true
@OptIn(UncheckedCast::class)
handler(method, { it: Array<Any?>, cont: Continuation<*> -> method.invoke(self, *it, cont) }.cast())
}
}
}
fun forEachMethod(clazz: Class<*>, self: Any? = null, handler: (Method, () -> Unit) -> Unit) {
forEachMethod(clazz, Unit::class.java, self, handler)
}
fun <R> forEachMethod(
clazz: Class<*>,
returnType: Class<out R>,
self: Any? = null,
handler: (Method, () -> R) -> Unit,
) {
clazz.javaClass.forAllMethods { method ->
val parameterTypes = method.parameterTypes
val methodReturnType = if (
method.returnType == Void.TYPE ||
method.returnType == Void::class.java
) Unit::class.java else method.returnType
if (parameterTypes.isEmpty() && returnType.isAssignableFrom(methodReturnType)) {
method.isAccessible = true
@OptIn(UncheckedCast::class)
handler(method) { method.invoke(self).cast() }
}
}
}
fun <T, R> forEachMethod(
clazz: Class<*>,
returnType: Class<out R>,
argumentType: Class<T>,
self: Any? = null,
handler: (Method, (T) -> R) -> Unit,
) {
forEachMethod(clazz, returnType, arrayOf(argumentType), self) { method: Method, m: (Array<Any?>) -> R ->
handler(method) {
m(arrayOf(it))
}
}
}
fun <T1, T2, R> forEachMethod(
clazz: Class<*>,
returnType: Class<out R>,
argumentType1: Class<T1>,
argumentType2: Class<T2>,
self: Any? = null,
handler: (Method, (T1, T2) -> R) -> Unit,
) {
forEachMethod(
clazz,
returnType,
arrayOf(argumentType1, argumentType2),
self
) { method: Method, m: (Array<Any?>) -> R ->
handler(method) { t1, t2 ->
m(arrayOf(t1, t2))
}
}
}
fun <T1, T2, T3, R> forEachMethod(
clazz: Class<*>,
returnType: Class<out R>,
argumentType1: Class<T1>,
argumentType2: Class<T2>,
argumentType3: Class<T3>,
self: Any? = null,
handler: (Method, (T1, T2, T3) -> R) -> Unit,
) {
forEachMethod(
clazz,
returnType,
arrayOf(argumentType1, argumentType2, argumentType3),
self
) { method: Method, m: (Array<Any?>) -> R ->
handler(method) { t1, t2, t3 ->
m(arrayOf(t1, t2, t3))
}
}
}
fun <T1, T2, T3, T4, R> forEachMethod(
clazz: Class<*>,
returnType: Class<out R>,
argumentType1: Class<T1>,
argumentType2: Class<T2>,
argumentType3: Class<T3>,
argumentType4: Class<T4>,
self: Any? = null,
handler: (Method, (T1, T2, T3, T4) -> R) -> Unit,
) {
forEachMethod(
clazz,
returnType,
arrayOf(argumentType1, argumentType2, argumentType3, argumentType4),
self
) { method: Method, m: (Array<Any?>) -> R ->
handler(method) { t1, t2, t3, t4 ->
m(arrayOf(t1, t2, t3, t4))
}
}
}
fun forEachSuspendMethod(clazz: Class<*>, self: Any? = null, handler: (Method, suspend () -> Unit) -> Unit) {
forEachSuspendMethod(clazz, Unit::class.java, self, handler)
}
fun <R> forEachSuspendMethod(
clazz: Class<*>,
returnType: Class<out R>,
self: Any? = null,
handler: (Method, suspend () -> R) -> Unit,
) {
forEachSuspendMethod(clazz, returnType, arrayOf(), self) { method: Method, m: suspend (Array<Any?>) -> R ->
handler(method) {
m(arrayOf())
}
}
}
fun <T, R> forEachSuspendMethod(
clazz: Class<*>,
returnType: Class<out R>,
argumentType: Class<T>,
self: Any? = null,
handler: (Method, suspend (T) -> R) -> Unit,
) {
forEachSuspendMethod(
clazz,
returnType,
arrayOf(argumentType),
self
) { method: Method, m: suspend (Array<Any?>) -> R ->
handler(method) {
m(arrayOf(it))
}
}
}
fun <T1, T2, R> forEachSuspendMethod(
clazz: Class<*>,
returnType: Class<out R>,
argumentType1: Class<T1>,
argumentType2: Class<T2>,
self: Any? = null,
handler: (Method, suspend (T1, T2) -> R) -> Unit,
) {
forEachSuspendMethod(
clazz,
returnType,
arrayOf(argumentType1, argumentType2),
self
) { method: Method, m: suspend (Array<Any?>) -> R ->
handler(method) { t1, t2 ->
m(arrayOf(t1, t2))
}
}
}
fun <T1, T2, T3, R> forEachSuspendMethod(
clazz: Class<*>,
returnType: Class<out R>,
argumentType1: Class<T1>,
argumentType2: Class<T2>,
argumentType3: Class<T3>,
self: Any? = null,
handler: (Method, suspend (T1, T2, T3) -> R) -> Unit,
) {
forEachSuspendMethod(
clazz,
returnType,
arrayOf(argumentType1, argumentType2, argumentType3),
self
) { method: Method, m: suspend (Array<Any?>) -> R ->
handler(method) { t1, t2, t3 ->
m(arrayOf(t1, t2, t3))
}
}
}
fun <T1, T2, T3, T4, R> forEachSuspendMethod(
clazz: Class<*>,
returnType: Class<out R>,
argumentType1: Class<T1>,
argumentType2: Class<T2>,
argumentType3: Class<T3>,
argumentType4: Class<T4>,
self: Any? = null,
handler: (Method, suspend (T1, T2, T3, T4) -> R) -> Unit,
) {
forEachSuspendMethod(
clazz,
returnType,
arrayOf(argumentType1, argumentType2, argumentType3, argumentType4),
self
) { method: Method, m: suspend (Array<Any?>) -> R ->
handler(method) { t1, t2, t3, t4 ->
m(arrayOf(t1, t2, t3, t4))
}
}
}
fun <R> forEachMethod(
self: Any,
returnType: Class<out R>,
argumentType: Array<Class<*>>,
handler: (Method, (Array<Any?>) -> R) -> Unit,
) {
forEachMethod(self.javaClass, returnType, argumentType, self, handler)
}
fun <R> forEachSuspendMethod(
self: Any,
returnType: Class<out R>,
argumentType: Array<Class<*>>,
handler: (Method, suspend (Array<Any?>) -> R) -> Unit,
) {
forEachSuspendMethod(self.javaClass, returnType, argumentType, self, handler)
}
fun forEachMethod(self: Any, handler: (Method, () -> Unit) -> Unit) {
forEachMethod(self, Unit::class.java, handler)
}
fun <R> forEachMethod(self: Any, returnType: Class<out R>, handler: (Method, () -> R) -> Unit) {
forEachMethod(self.javaClass, returnType, self, handler)
}
fun <T, R> forEachMethod(
self: Any,
returnType: Class<out R>,
argumentType: Class<T>,
handler: (Method, (T) -> R) -> Unit,
) {
forEachMethod(self, returnType, arrayOf(argumentType)) { method: Method, m: (Array<Any?>) -> R ->
handler(method) {
m(arrayOf(it))
}
}
}
fun <T1, T2, R> forEachMethod(
self: Any,
returnType: Class<out R>,
argumentType1: Class<T1>,
argumentType2: Class<T2>,
handler: (Method, (T1, T2) -> R) -> Unit,
) {
forEachMethod(
self,
returnType,
arrayOf(argumentType1, argumentType2)
) { method: Method, m: (Array<Any?>) -> R ->
handler(method) { t1, t2 ->
m(arrayOf(t1, t2))
}
}
}
fun <T1, T2, T3, R> forEachMethod(
self: Any,
returnType: Class<out R>,
argumentType1: Class<T1>,
argumentType2: Class<T2>,
argumentType3: Class<T3>,
handler: (Method, (T1, T2, T3) -> R) -> Unit,
) {
forEachMethod(
self,
returnType,
arrayOf(argumentType1, argumentType2, argumentType3)
) { method: Method, m: (Array<Any?>) -> R ->
handler(method) { t1, t2, t3 ->
m(arrayOf(t1, t2, t3))
}
}
}
fun <T1, T2, T3, T4, R> forEachMethod(
self: Any,
returnType: Class<out R>,
argumentType1: Class<T1>,
argumentType2: Class<T2>,
argumentType3: Class<T3>,
argumentType4: Class<T4>,
handler: (Method, (T1, T2, T3, T4) -> R) -> Unit,
) {
forEachMethod(
self,
returnType,
arrayOf(argumentType1, argumentType2, argumentType3, argumentType4)
) { method: Method, m: (Array<Any?>) -> R ->
handler(method) { t1, t2, t3, t4 ->
m(arrayOf(t1, t2, t3, t4))
}
}
}
fun forEachSuspendMethod(self: Any, handler: (Method, suspend () -> Unit) -> Unit) {
forEachSuspendMethod(self, Unit::class.java, handler)
}
fun <R> forEachSuspendMethod(self: Any, returnType: Class<out R>, handler: (Method, suspend () -> R) -> Unit) {
forEachSuspendMethod(self, returnType, arrayOf()) { method: Method, m: suspend (Array<Any?>) -> R ->
handler(method) {
m(arrayOf())
}
}
}
fun <T, R> forEachSuspendMethod(
self: Any,
returnType: Class<out R>,
argumentType: Class<T>,
handler: (Method, suspend (T) -> R) -> Unit,
) {
forEachSuspendMethod(self, returnType, arrayOf(argumentType)) { method: Method, m: suspend (Array<Any?>) -> R ->
handler(method) {
m(arrayOf(it))
}
}
}
fun <T1, T2, R> forEachSuspendMethod(
self: Any,
returnType: Class<out R>,
argumentType1: Class<T1>,
argumentType2: Class<T2>,
handler: (Method, suspend (T1, T2) -> R) -> Unit,
) {
forEachSuspendMethod(
self,
returnType,
arrayOf(argumentType1, argumentType2)
) { method: Method, m: suspend (Array<Any?>) -> R ->
handler(method) { t1, t2 ->
m(arrayOf(t1, t2))
}
}
}
fun <T1, T2, T3, R> forEachSuspendMethod(
self: Any,
returnType: Class<out R>,
argumentType1: Class<T1>,
argumentType2: Class<T2>,
argumentType3: Class<T3>,
handler: (Method, suspend (T1, T2, T3) -> R) -> Unit,
) {
forEachSuspendMethod(
self,
returnType,
arrayOf(argumentType1, argumentType2, argumentType3)
) { method: Method, m: suspend (Array<Any?>) -> R ->
handler(method) { t1, t2, t3 ->
m(arrayOf(t1, t2, t3))
}
}
}
fun <T1, T2, T3, T4, R> forEachSuspendMethod(
self: Any,
returnType: Class<out R>,
argumentType1: Class<T1>,
argumentType2: Class<T2>,
argumentType3: Class<T3>,
argumentType4: Class<T4>,
handler: (Method, suspend (T1, T2, T3, T4) -> R) -> Unit,
) {
forEachSuspendMethod(
self,
returnType,
arrayOf(argumentType1, argumentType2, argumentType3, argumentType4)
) { method: Method, m: suspend (Array<Any?>) -> R ->
handler(method) { t1, t2, t3, t4 ->
m(arrayOf(t1, t2, t3, t4))
}
}
}
}

View File

@ -0,0 +1,31 @@
package cn.tursom.reflect
import java.lang.reflect.Method
class NoargMethodFilter<R>(
val prevFilter: ReturnTypeMethodFilter<R>,
) : MethodFilter {
override fun filterMethod(clazz: Class<*>): Sequence<Method> {
return prevFilter.filterMethod(clazz).filter { method ->
method.parameterCount == 0
}
}
fun <T> filter(clazz: Class<T>): Sequence<T.() -> R> {
return filterMethod(clazz).map {
{
it.invoke(this) as R
}
}
}
fun filter(obj: Any): Sequence<() -> R> {
return filterMethod(obj.javaClass).map {
{
it.invoke(obj) as R
}
}
}
}
fun <R> ReturnTypeMethodFilter<R>.noarg() = NoargMethodFilter(this)

View File

@ -0,0 +1,210 @@
package cn.tursom.reflect
import cn.tursom.core.*
import java.lang.reflect.Array
import java.lang.reflect.Field
import java.lang.reflect.Modifier
import java.lang.reflect.ParameterizedType
import java.util.*
object Parser {
private val simpleDateFormat = ThreadLocalSimpleDateFormat()
private val Field.actualTypeArguments get() = (genericType as ParameterizedType).actualTypeArguments[0] as Class<*>
fun <T> parse(yaml: Any, clazz: Class<T>): T? {
@Suppress("UNCHECKED_CAST")
@OptIn(UncheckedCast::class)
return when {
clazz.isInstance(yaml) -> yaml.cast()
clazz.isInheritanceFrom(Enum::class.java) -> (clazz as Class<out Enum<*>>).valueOf(yaml.toString()) as? T?
clazz.isInheritanceFrom(Map::class.java) -> {
val map = try {
clazz.newInstance()
} catch (e: Exception) {
try {
Unsafe.unsafe.allocateInstance(clazz)
} catch (e: Exception) {
HashMap<Any?, Any?>()
}
}.cast<MutableMap<Any?, Any?>>()
if (yaml !is Map<*, *>) return null
yaml.forEach { (any, u) ->
map[any] = u
}
map.cast<T>()
}
yaml is List<*> && clazz.isArray -> parseArray(yaml, clazz) as T
else -> when (clazz) {
Any::class.java -> yaml
Int::class.java -> yaml.toInt()
Long::class.java -> yaml.toLong()
Float::class.java -> yaml.toFloat()
Double::class.java -> yaml.toDouble()
Boolean::class.java -> yaml.toBoolean()
getClazz<Int>() -> yaml.toInt()
getClazz<Long>() -> yaml.toLong()
getClazz<Float>() -> yaml.toFloat()
getClazz<Double>() -> yaml.toDouble()
getClazz<Boolean>() -> yaml.toBoolean()
Date::class.java -> yaml.toDate()
String::class.java -> yaml.toString()
else -> {
if (yaml !is Map<*, *>) return null
val instance = try {
clazz.newInstance()
} catch (e: Exception) {
Unsafe.unsafe.allocateInstance(clazz)
}
val fields = clazz.declaredFields
fields.forEach {
if ((it.modifiers and (Modifier.STATIC or Modifier.TRANSIENT)) != 0) return@forEach
try {
val parse = parseField(yaml[it.name] ?: return@forEach, it) ?: return@forEach
it.isAccessible = true
it.set(instance, parse)
} catch (e: Exception) {
}
}
instance
}
} as T
}
}
private fun parseField(yaml: Any, field: Field): Any? {
val clazz = field.type
@Suppress("UNCHECKED_CAST")
return when (yaml) {
is List<*> -> {
when {
clazz.isAssignableFrom(List::class.java) -> {
val type = field.actualTypeArguments
if (type == Any::class.java) {
yaml
} else {
val list = try {
clazz.newInstance() as MutableList<Any>
} catch (e: Exception) {
try {
Unsafe.unsafe.allocateInstance(clazz) as MutableList<Any>
} catch (e: Exception) {
ArrayList<Any>()
}
}
yaml.forEach {
list.add(parse(it ?: return@forEach, type) ?: return@forEach)
}
list
}
}
clazz.isAssignableFrom(Set::class.java) -> {
val type = field.actualTypeArguments
if (type == Any::class.java) {
yaml
} else {
val set: MutableSet<Any> = try {
clazz.newInstance() as MutableSet<Any>
} catch (e: Exception) {
try {
Unsafe.unsafe.allocateInstance(clazz) as MutableSet<Any>
} catch (e: Exception) {
HashSet()
}
}
yaml.forEach {
set.add(parse(it ?: return@forEach, type) ?: return@forEach)
}
set
}
}
clazz.isArray -> parseArray(yaml, clazz)
else -> null
}
}
else -> parse(yaml, clazz)
}
}
private fun <T> parseArray(yaml: List<Any?>, clazz: Class<T>): kotlin.Array<T>? {
val componentType = clazz.componentType
val list = ArrayList<Any>()
yaml.forEach {
list.add(parse(it ?: return@forEach, componentType) ?: return@forEach)
}
val instance = Array.newInstance(componentType, list.size)
list.forEachIndexed { index, any -> Array.set(instance, index, any) }
@Suppress("UNCHECKED_CAST")
return instance as kotlin.Array<T>?
}
private fun Any.toInt() = when (this) {
is Number -> toInt()
is Boolean -> if (this) 1 else 0
is String -> toIntOrNull()
is Iterable<*> -> null
is Iterator<*> -> null
is Map<*, *> -> null
else -> toString().toIntOrNull()
}
private fun Any.toLong() = when (this) {
is Number -> toLong()
is Boolean -> if (this) 1L else 0L
is String -> toLongOrNull()
is Iterable<*> -> null
is Iterator<*> -> null
is Map<*, *> -> null
else -> toString().toLongOrNull()
}
private fun Any.toFloat() = when (this) {
is Number -> toFloat()
is Boolean -> if (this) 1.0f else 0.0f
is String -> toFloatOrNull()
is Iterable<*> -> null
is Iterator<*> -> null
is Map<*, *> -> null
else -> toString().toFloatOrNull()
}
private fun Any.toDouble() = when (this) {
is Number -> toDouble()
is Boolean -> if (this) 1.0 else 0.0
is String -> toDoubleOrNull()
is Iterable<*> -> null
is Iterator<*> -> null
is Map<*, *> -> null
else -> toString().toDoubleOrNull()
}
private fun Any.toBoolean(): Boolean? = when (this) {
is Boolean -> this
is Number -> 0 != toInt()
is String -> equals("t", true) || equals("true", true)
is Iterable<*> -> null
is Iterator<*> -> null
is Map<*, *> -> null
else -> toString().toBoolean()
}
private fun Any.toDate(): Date? = when (this) {
is Number -> Date(toLong())
is Boolean -> null
is String -> when (val time = toLongOrNull()) {
null -> simpleDateFormat.get().parse(this)
else -> Date(time)
}
is Iterable<*> -> null
is Iterator<*> -> null
is Map<*, *> -> null
else -> {
val str = toString()
when (val time = str.toLongOrNull()) {
null -> simpleDateFormat.get().parse(str)
else -> Date(time)
}
}
}
}

View File

@ -0,0 +1,22 @@
package cn.tursom.reflect
import cn.tursom.core.allMethodsSequence
import java.lang.reflect.Method
class ReturnTypeMethodFilter<R>(
val returnType: Class<R>,
) : MethodFilter {
override fun filterMethod(clazz: Class<*>): Sequence<Method> {
return clazz.allMethodsSequence.filter { method ->
val methodReturnType = if (
method.returnType == Void.TYPE ||
method.returnType == Void::class.java
) Unit::class.java else method.returnType
returnType.isAssignableFrom(methodReturnType)
}
}
companion object
}
inline fun <reified R> MethodFilter.Companion.returnType() = ReturnTypeMethodFilter(R::class.java)

View File

@ -0,0 +1,47 @@
package cn.tursom.reflect
import cn.tursom.core.Unsafe.get
import cn.tursom.core.companionObjectInstanceOrNull
import cn.tursom.core.uncheckedCast
import java.lang.reflect.Field
import java.lang.reflect.Method
inline fun <reified T : Annotation> Class<*>.getAnnotation(): T? = getAnnotation(T::class.java)
inline fun <reified T : Annotation> Field.getAnnotation(): T? = getAnnotation(T::class.java)
inline fun <reified T : Annotation> Method.getAnnotation(): T? = getAnnotation(T::class.java)
operator fun Class<*>.contains(obj: Any): Boolean = isInstance(obj)
fun <T> Class<*>.getStaticField(name: String): T? {
val staticField = getDeclaredField(name)
if (staticField.isStatic()) {
staticField.isAccessible = true
return staticField.get(null).uncheckedCast()
}
val companionObjectInstance = kotlin.companionObjectInstanceOrNull
if (companionObjectInstance != null) {
return companionObjectInstance[name]?.uncheckedCast()
}
return null
}
inline fun <reified C : Any, T> getStaticField(name: String): T? {
return C::class.java.getStaticField(name)
}
@Suppress("UNCHECKED_CAST")
fun <T : Enum<out T>> Class<out T>.valueOf(value: String): T? {
var valueOf: Method? = null
return try {
valueOf = getDeclaredMethod("valueOf", String::class.java)
valueOf.invoke(null, value) as T
} catch (e: Exception) {
try {
valueOf?.invoke(null, value.toUpperCase()) as? T?
} catch (e: Exception) {
null
}
}
}

View File

@ -0,0 +1,19 @@
package cn.tursom.database.ktorm
import org.ktorm.dsl.AssignmentsBuilder
import org.ktorm.schema.ColumnDeclaring
import kotlin.reflect.KProperty1
inline fun <reified T : Any, C : Any> AssignmentsBuilder.set(
column: KProperty1<T, C?>,
value: C?,
) {
set(AutoTable[T::class.java][column], value)
}
inline fun <reified T : Any, C : Any> AssignmentsBuilder.set(
column: KProperty1<T, C?>,
expr: ColumnDeclaring<C>,
) {
set(AutoTable[T::class.java][column], expr)
}

View File

@ -0,0 +1,7 @@
package cn.tursom.database.ktorm
import org.ktorm.dsl.QueryRowSet
import kotlin.reflect.KProperty1
inline operator fun <reified T : Any, C : Any> QueryRowSet.get(column: KProperty1<in T, C?>) =
get(AutoTable[T::class.java][column])