All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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)
    }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy