xyz.shoaky.sourcedownloader.sdk.component.ComponentProps.kt Maven / Gradle / Ivy
The newest version!
package xyz.shoaky.sourcedownloader.sdk.component
import com.fasterxml.jackson.module.kotlin.jacksonTypeRef
import xyz.shoaky.sourcedownloader.sdk.util.Jackson
import kotlin.reflect.KClass
import kotlin.reflect.full.isSuperclassOf
class ComponentProps
private constructor(val properties: MutableMap) {
inline fun parse(): T {
return Jackson.convert(properties, jacksonTypeRef())
}
inline fun get(key: String): T {
val any = properties[key] ?: throw ComponentException.props("属性${key}不存在")
try {
return Jackson.convert(any, jacksonTypeRef())
} catch (e: Exception) {
throw RuntimeException("组件属性${key}解析异常: value:$any", e)
}
}
inline fun getNotRequired(key: String): T? {
val any = properties[key] ?: return null
try {
return Jackson.convert(any, jacksonTypeRef())
} catch (e: Exception) {
throw RuntimeException("组件属性${key}解析异常: value:$any", e)
}
}
fun getRaw(key: String): Any {
return properties[key] ?: throw ComponentException.props("属性${key}不存在")
}
inline fun getOrDefault(key: String, default: T): T {
val any = properties[key] ?: return default
try {
return Jackson.convert(any, jacksonTypeRef())
} catch (e: Exception) {
throw RuntimeException("组件属性解析异常: $key", e)
}
}
companion object {
fun fromMap(map: Map): ComponentProps {
val mutableMapOf = mutableMapOf()
mutableMapOf.putAll(map)
for (entry in map) {
val value = entry.value
if (value is Map<*, *> && value["0"] != null) {
// yaml中的数组会被解析成map
mutableMapOf[entry.key] = value.values
}
}
return ComponentProps(mutableMapOf)
}
fun fromJson(json: String): ComponentProps {
val typeReference = jacksonTypeRef>()
return ComponentProps(Jackson.fromJson(json, typeReference))
}
fun empty(): ComponentProps {
return ComponentProps(mutableMapOf())
}
}
}
interface SdComponentSupplier {
fun apply(props: ComponentProps): R
fun supplyTypes(): List
fun rules(): List = emptyList()
/**
* 后面反射用
*/
fun getComponentClass(): Class
}
data class ComponentRule internal constructor(
val isAllow: Boolean,
val type: Components,
val value: KClass) {
fun isSameType(klass: KClass): Boolean {
return type.klass.isSuperclassOf(klass)
}
fun isSameType(component: SdComponent): Boolean {
return type.klass.isSuperclassOf(component::class)
}
fun verify(component: SdComponent) {
if (isSameType(component).not()) {
return
}
val componentClasses = component::class.componentSuperClasses()
if (isAllow) {
if (componentClasses.contains(value).not()) {
val classes = componentClasses.map { it.simpleName }.joinToString(",")
throw ComponentException.compatibility("组件类型不匹配, 期望:${value.simpleName}, 实际:$classes")
}
} else {
if (componentClasses.contains(value)) {
throw ComponentException.compatibility("组件类型不匹配, ${value.simpleName}不允许和${component::class.simpleName}组合")
}
}
}
companion object {
fun allow(type: Components, value: KClass) = ComponentRule(true, type, value)
fun notAllow(type: Components, value: KClass) = ComponentRule(false, type, value)
fun allowSource(value: KClass) = ComponentRule(true, Components.SOURCE, value)
fun notAllowSource(value: KClass) = ComponentRule(false, Components.SOURCE, value)
fun allowDownloader(value: KClass) = ComponentRule(true, Components.DOWNLOADER, value)
fun notAllowDownloader(value: KClass) = ComponentRule(false, Components.DOWNLOADER, value)
fun allowProvider(value: KClass) = ComponentRule(true, Components.VARIABLE_PROVIDER, value)
fun notAllowProvider(value: KClass) =
ComponentRule(false, Components.VARIABLE_PROVIDER, value)
fun allowTrigger(value: KClass) = ComponentRule(true, Components.TRIGGER, value)
fun notAllowTrigger(value: KClass) = ComponentRule(false, Components.TRIGGER, value)
fun allowMover(value: KClass) = ComponentRule(true, Components.FILE_MOVER, value)
fun notAllowMover(value: KClass) = ComponentRule(false, Components.FILE_MOVER, value)
fun allowRunAfterCompletion(value: KClass) =
ComponentRule(true, Components.RUN_AFTER_COMPLETION, value)
fun notAllowRunAfterCompletion(value: KClass) =
ComponentRule(false, Components.RUN_AFTER_COMPLETION, value)
fun allowSourceFilter(value: KClass) = ComponentRule(true, Components.SOURCE_ITEM_FILTER, value)
fun notAllowSourceFilter(value: KClass) = ComponentRule(false, Components.SOURCE_ITEM_FILTER, value)
}
}