Skip to content

Commit 473e24e

Browse files
committed
[6.0.10][publish] update persistent-container & update database & supported kotlin-reflect
1 parent 7e53091 commit 473e24e

File tree

30 files changed

+955
-106
lines changed

30 files changed

+955
-106
lines changed

build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ subprojects {
2727

2828
dependencies {
2929
compileOnly(kotlin("stdlib"))
30+
compileOnly(kotlin("reflect"))
3031
}
3132

3233
java {

common/src/main/java/taboolib/common/env/KotlinEnv.java

+6
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,10 @@
1818
relocate = {"!kotlin.", "!kotlin@kotlin_version_escape@."},
1919
initiative = true
2020
)
21+
@RuntimeDependency(
22+
value = "!org.jetbrains.kotlin:kotlin-reflect:@kotlin_version@",
23+
test = "!kotlin@[email protected]",
24+
relocate = {"!kotlin.", "!kotlin@kotlin_version_escape@."},
25+
initiative = true
26+
)
2127
public class KotlinEnv { }

common/src/main/kotlin/taboolib/common/io/Project1.kt

+11-6
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ val runningExactClassMap by unsafeLazy { runningClassMap.filter { !it.key.contai
5151
*/
5252
val runningExactClasses by unsafeLazy { LinkedList(runningExactClassMap.values) }
5353

54+
/**
55+
* 从 TabooLibCommon 的 ClassLoader 中获取类,且不触发类的初始化
56+
*/
57+
fun getClass(name: String): Class<*> {
58+
return Class.forName(name, false, TabooLibCommon::class.java.classLoader)
59+
}
60+
5461
/**
5562
* 取该类在当前项目中被加载的任何实例
5663
* 例如:@Awake 自唤醒类,或是 Kotlin Companion Object、Kotlin Object 对象
@@ -74,13 +81,11 @@ fun <T> Class<T>.getInstance(newInstance: Boolean = false): Supplier<T>? {
7481
return null
7582
}
7683
return try {
77-
// 获取 Kotlin Companion 字段
7884
val field = if (simpleName == "Companion") {
79-
val companion = Class.forName(name.substringBeforeLast('$'), false, TabooLibCommon::class.java.classLoader)
80-
ReflexClass.of(companion).getField("Companion", findToParent = false, remap = false)
81-
}
82-
// 获取 Kotlin Object 字段
83-
else {
85+
// 获取 Kotlin Companion 字段
86+
ReflexClass.of(getClass(name.substringBeforeLast('$'))).getField("Companion", findToParent = false, remap = false)
87+
} else {
88+
// 获取 Kotlin Object 字段
8489
ReflexClass.of(this).getField("INSTANCE", findToParent = false, remap = false)
8590
}
8691
lazySupplier { field.get() as T }

common/src/main/kotlin/taboolib/common/util/Common.kt

+2-4
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,10 @@ fun Class<*>.nonPrimitive(): Class<*> {
3434
fun <T> lazySupplier(supplier: () -> T): Supplier<T> {
3535
return object : Supplier<T> {
3636

37-
val obj by lazy {
38-
supplier()
39-
}
37+
val value by unsafeLazy { supplier() }
4038

4139
override fun get(): T {
42-
return obj
40+
return value
4341
}
4442
}
4543
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
dependencies {
2+
compileOnly(project(":common"))
3+
compileOnly(project(":common-5"))
4+
compileOnly(project(":module:module-database-core"))
5+
compileOnly(project(":module:module-configuration"))
6+
compileOnly("ink.ptms.core:v11701:11701-minimize:universal")
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
package taboolib.expansion
2+
3+
import taboolib.common.platform.function.info
4+
import taboolib.common.platform.function.warning
5+
import taboolib.common5.*
6+
import java.sql.ResultSet
7+
import java.util.UUID
8+
import java.util.concurrent.ConcurrentHashMap
9+
import kotlin.reflect.KParameter
10+
import kotlin.reflect.full.*
11+
import kotlin.reflect.jvm.javaType
12+
13+
/**
14+
* TabooLib
15+
* taboolib.expansion.AnalyzedClass
16+
*
17+
* @author 坏黑
18+
* @since 2023/3/29 11:28
19+
*/
20+
@Suppress("UNCHECKED_CAST")
21+
class AnalyzedClass private constructor(val clazz: Class<*>) {
22+
23+
/** 主构造器 */
24+
private val primaryConstructor = clazz.kotlin.primaryConstructor ?: error("No primary constructor found for $clazz")
25+
26+
/** 成员列表 */
27+
private val memberProperties = clazz.kotlin.memberProperties.associateBy { it.name }
28+
29+
/** 成员列表 */
30+
val members = primaryConstructor.valueParameters.map {
31+
// 不知道为什么,isFinal 方法在这里会失效,全部都是 true
32+
// 测试日志:
33+
// name=username, p=val com.github.username.GameHistory.username: java.util.UUID, f=true
34+
// name=game, p=val com.github.username.GameHistory.game: kotlin.String, f=true
35+
// name=playTimes, p=var com.github.username.GameHistory.playTimes: kotlin.Int, f=true
36+
// name=deepLevel, p=var com.github.username.GameHistory.deepLevel: kotlin.Int, f=true
37+
// name=useTime, p=var com.github.username.GameHistory.useTime: kotlin.Long, f=true
38+
AnalyzedClassMember(validation(it), memberProperties[it.name]?.toString()?.startsWith("var") != true)
39+
}
40+
41+
/** 主成员 */
42+
val primaryMember = members.firstOrNull { it.isPrimary }
43+
44+
/** 主成员名称 */
45+
val primaryMemberName = primaryMember?.name
46+
47+
/** 反序列化所在伴生类实例 */
48+
val wrapperObjectInstance = clazz.kotlin.companionObjectInstance
49+
50+
/** 反序列化方法 */
51+
val wrapperFunction = clazz.kotlin.companionObject?.functions?.firstOrNull {
52+
it.valueParameters.size == 1 && BundleMap::class.java.isAssignableFrom(it.valueParameters[0].type.javaType as Class<*>)
53+
}
54+
55+
init {
56+
val customs = members.filter { it.isCustomObject }
57+
if (customs.isNotEmpty()) {
58+
error("The following members are not supported: $customs")
59+
}
60+
if (members.count { it.isPrimary } > 1) {
61+
error("The primary member only supports one, but found ${members.count { it.isPrimary }}")
62+
}
63+
}
64+
65+
/** 获取主成员值 */
66+
fun getPrimaryMemberValue(data: Any): Any {
67+
val property = memberProperties[primaryMember?.propertyName] ?: error("Primary member \"$primaryMemberName\" not found in $clazz")
68+
return property.call(data)!!
69+
}
70+
71+
/** 获取成员值 */
72+
fun getValue(data: Any, member: AnalyzedClassMember): Any {
73+
val property = memberProperties[member.propertyName] ?: error("Member \"${member.name}\" not found in $clazz")
74+
return property.call(data)!!
75+
}
76+
77+
/** 读取数据 */
78+
fun read(result: ResultSet): Map<String, Any?> {
79+
val map = hashMapOf<String, Any?>()
80+
members.forEach { member ->
81+
val obj = result.getObject(member.name)
82+
val wrap = when {
83+
member.isBoolean -> obj.cbool
84+
member.isByte -> obj.cbyte
85+
member.isShort -> obj.cshort
86+
member.isInt -> obj.cint
87+
member.isLong -> obj.clong
88+
member.isFloat -> obj.cfloat
89+
member.isDouble -> obj.cdouble
90+
member.isChar -> obj.cint.toChar()
91+
member.isString -> obj.toString()
92+
member.isUUID -> UUID.fromString(obj.toString())
93+
member.isEnum -> member.returnType.enumConstants.first { it.toString() == obj.toString() }
94+
else -> error("Unsupported type ${member.returnType} for ${member.name} in $clazz")
95+
}
96+
map[member.name] = wrap
97+
}
98+
return map
99+
}
100+
101+
/** 创建实例 */
102+
fun <T> createInstance(map: Map<String, Any?>): T {
103+
return if (wrapperFunction != null) {
104+
wrapperFunction.call(wrapperObjectInstance, BundleMapImpl(map)) ?: error("Failed to create instance for $clazz")
105+
} else {
106+
val args = members.map { map[it.name] }
107+
try {
108+
primaryConstructor.call(*args.toTypedArray())
109+
} catch (ex: Throwable) {
110+
error("Failed to create instance for $clazz ($args), map=$map")
111+
}
112+
} as T
113+
}
114+
115+
/** 验证参数 */
116+
fun validation(parameter: KParameter): KParameter {
117+
if (parameter.name == null) {
118+
error("Parameter name is null for $parameter")
119+
}
120+
if (parameter.isVararg) {
121+
error("Vararg parameters are not supported for $parameter")
122+
}
123+
return parameter
124+
}
125+
126+
companion object {
127+
128+
val cached = ConcurrentHashMap<Class<*>, AnalyzedClass>()
129+
130+
fun of(clazz: Class<*>): AnalyzedClass {
131+
return cached.computeIfAbsent(clazz) { AnalyzedClass(it) }
132+
}
133+
}
134+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package taboolib.expansion
2+
3+
import kotlin.reflect.KParameter
4+
import kotlin.reflect.full.findAnnotation
5+
import kotlin.reflect.jvm.javaType
6+
7+
/**
8+
* TabooLib
9+
* taboolib.expansion.AnalyzedClassMember
10+
*
11+
* @author 坏黑
12+
* @since 2023/3/29 11:28
13+
*/
14+
class AnalyzedClassMember(private val root: KParameter, val isFinal: Boolean) {
15+
16+
/** 名称 */
17+
val name = root.findAnnotation<Alias>()?.value ?: root.name!!.toColumnName()
18+
19+
/** 属性名称 */
20+
val propertyName = root.name
21+
22+
/** 返回类型 */
23+
val returnType = root.type.javaType as Class<*>
24+
25+
/** 是否为 ID 键 */
26+
val isPrimary = root.findAnnotation<Id>() != null
27+
28+
/** 是否建立索引 */
29+
val isKey = root.findAnnotation<Key>() != null
30+
31+
/** 是否建立唯一索引 */
32+
val isUniqueKey = root.findAnnotation<UniqueKey>() != null
33+
34+
/** 长度 */
35+
val length = root.findAnnotation<Length>()?.value ?: 64
36+
37+
/** 是否为基础类型(Boolean) */
38+
val isBoolean: Boolean
39+
get() = returnType == Boolean::class.java || returnType == Boolean::class.javaPrimitiveType
40+
41+
/** 是否为基础类型(Byte) */
42+
val isByte: Boolean
43+
get() = returnType == Byte::class.java || returnType == Byte::class.javaPrimitiveType
44+
45+
/** 是否为基础类型(Short) */
46+
val isShort: Boolean
47+
get() = returnType == Short::class.java || returnType == Short::class.javaPrimitiveType
48+
49+
/** 是否为基础类型(Int) */
50+
val isInt: Boolean
51+
get() = returnType == Int::class.java || returnType == Int::class.javaPrimitiveType
52+
53+
/** 是否为基础类型(Long) */
54+
val isLong: Boolean
55+
get() = returnType == Long::class.java || returnType == Long::class.javaPrimitiveType
56+
57+
/** 是否为基础类型(Float) */
58+
val isFloat: Boolean
59+
get() = returnType == Float::class.java || returnType == Float::class.javaPrimitiveType
60+
61+
/** 是否为基础类型(Double) */
62+
val isDouble: Boolean
63+
get() = returnType == Double::class.java || returnType == Double::class.javaPrimitiveType
64+
65+
/** 是否为基础类型(Char) */
66+
val isChar: Boolean
67+
get() = returnType == Char::class.java || returnType == Char::class.javaPrimitiveType
68+
69+
/** 是否为字符串 */
70+
val isString: Boolean
71+
get() = returnType == String::class.java
72+
73+
/** 是否为 UUID */
74+
val isUUID: Boolean
75+
get() = returnType == java.util.UUID::class.java
76+
77+
/** 是否为枚举 */
78+
val isEnum: Boolean
79+
get() = Enum::class.java.isAssignableFrom(returnType)
80+
81+
/** 是否为自定义对象 */
82+
val isCustomObject: Boolean
83+
get() = !isBoolean && !isByte && !isShort && !isInt && !isLong && !isFloat && !isDouble && !isChar && !isString && !isEnum && !isUUID
84+
85+
/** 是否可以转换成字符串类型 */
86+
fun canConvertedString(): Boolean {
87+
return isString || isEnum || isUUID
88+
}
89+
90+
/** 是否可以转化为数字类型 */
91+
fun canConvertedNumber(): Boolean {
92+
return canConvertedInteger() || canConvertedDecimal()
93+
}
94+
95+
/** 是否可以转化为整数类型 */
96+
fun canConvertedInteger(): Boolean {
97+
return isBoolean || isByte || isShort || isInt || isLong || isChar
98+
}
99+
100+
/** 是否可以转化为小数类型 */
101+
fun canConvertedDecimal(): Boolean {
102+
return isFloat || isDouble
103+
}
104+
105+
/** 转换为数据库字段名称 */
106+
private fun String.toColumnName(): String {
107+
return toCharArray().joinToString("") { if (it.isUpperCase()) "_${it.lowercase()}" else it.toString() }
108+
}
109+
110+
override fun toString(): String {
111+
return "$name(${returnType})"
112+
}
113+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package taboolib.expansion
2+
3+
import kotlin.reflect.KCallable
4+
5+
@Retention(AnnotationRetention.RUNTIME)
6+
annotation class Id
7+
8+
@Retention(AnnotationRetention.RUNTIME)
9+
annotation class Key
10+
11+
@Retention(AnnotationRetention.RUNTIME)
12+
annotation class UniqueKey
13+
14+
@Retention(AnnotationRetention.RUNTIME)
15+
annotation class Length(val value: Int = 64)
16+
17+
@Retention(AnnotationRetention.RUNTIME)
18+
annotation class Alias(val value: String)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package taboolib.expansion
2+
3+
/**
4+
* TabooLib
5+
* taboolib.expansion.BundleMap
6+
*
7+
* @author 坏黑
8+
* @since 2023/3/29 14:21
9+
*/
10+
abstract class BundleMap {
11+
12+
/** 获取数据 */
13+
abstract operator fun <T> get(name: String): T
14+
15+
/** 获取数据 */
16+
abstract fun <T> getOrNull(name: String): T?
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package taboolib.expansion
2+
3+
/**
4+
* TabooLib
5+
* taboolib.expansion.BundleMapImpl
6+
*
7+
* @author 坏黑
8+
* @since 2023/3/29 14:27
9+
*/
10+
class BundleMapImpl(val map: Map<String, Any?>) : BundleMap() {
11+
12+
@Suppress("UNCHECKED_CAST")
13+
override fun <T> get(name: String): T {
14+
return map[name] as T
15+
}
16+
17+
override fun <T> getOrNull(name: String): T? {
18+
return if (map.containsKey(name)) get(name) else null
19+
}
20+
}

0 commit comments

Comments
 (0)