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

com.blr19c.falowp.bot.system.plugin.hook.HookManager.kt Maven / Gradle / Ivy

There is a newer version: 2.0.0-RC2
Show newest version
package com.blr19c.falowp.bot.system.plugin.hook

import com.blr19c.falowp.bot.system.Log
import com.blr19c.falowp.bot.system.api.BotApi
import com.blr19c.falowp.bot.system.plugin.HookPluginRegister
import com.blr19c.falowp.bot.system.plugin.Plugin
import com.blr19c.falowp.bot.system.plugin.PluginInfo
import com.blr19c.falowp.bot.system.plugin.hook.HookTypeEnum.*
import java.util.concurrent.ConcurrentHashMap

/**
 * 钩子类插件管理
 */
object HookManager : Log {
    private val hookPlugins = ConcurrentHashMap>()
    private val pluginList = mutableListOf()

    fun configure(pluginList: List) {
        this.pluginList.addAll(pluginList)
        log().info("加载的钩子监听器数量:{}", hookPlugins.size)
    }

    fun  registerHook(hookPluginRegister: HookPluginRegister) {
        hookPlugins[hookPluginRegister.pluginId] = hookPluginRegister
    }


    fun  unregister(hookPluginRegister: HookPluginRegister) {
        hookPlugins.remove(hookPluginRegister.pluginId)
    }

    /**
     * 构建withHook
     */
    fun buildHookJoinPoint(
        hook: Plugin.Listener.Hook,
        botApi: BotApi,
        block: suspend () -> Unit
    ): HookJoinPoint {
        val pluginInfo = pluginList.find { botApi.originalClass == it.instance::class } ?: PluginInfo.empty()
        val allHooks = hookPlugins.values
            .filter { filterHookPlugin(pluginInfo, hook, it) }
            .sortedBy { it.order }
        val afterFinally = allHooks.filter { it.hookType == AFTER_FINALLY }
        val afterThrowing = allHooks.filter { it.hookType == AFTER_THROWING }
        val before = allHooks.filter { it.hookType == BEFORE }
        val around = allHooks.filter { it.hookType == AROUND }
        val target = listOf(TargetHookProcess(block))
        val afterReturning = allHooks.filter { it.hookType == AFTER_RETURNING }

        //Finally->Throwing->before->around->target->Returning
        val hooks = ArrayDeque()
        hooks.addAll(afterFinally.map { toHookProcess(botApi, it) })
        hooks.addAll(afterThrowing.map { toHookProcess(botApi, it) })
        hooks.addAll(before.map { toHookProcess(botApi, it) })
        hooks.addAll(around.map { toHookProcess(botApi, it) })
        hooks.addAll(target)
        hooks.addAll(afterReturning.map { toHookProcess(botApi, it) })
        return HookJoinPoint(pluginInfo, hook, hooks)
    }

    /**
     * 转为HookProcess
     */
    private fun toHookProcess(botApi: BotApi, register: HookPluginRegister): HookProcess {
        val hookBotApi = HookBotApi(botApi, register)
        return when (register.hookType) {
            AROUND -> AroundHookProcess(register, hookBotApi)
            AFTER_THROWING -> ThrowingHookProcess(register, hookBotApi)
            AFTER_FINALLY -> FinallyHookProcess(register, hookBotApi)
            else -> NormalHookProcess(register, hookBotApi)
        }
    }

    /**
     * 过滤合适的HookPlugin
     */
    private fun filterHookPlugin(
        pluginInfo: PluginInfo,
        hook: Plugin.Listener.Hook,
        plugin: HookPluginRegister
    ): Boolean {
        return plugin.listener.isInstance(hook)
                && plugin.match.customBlock?.invoke(pluginInfo) ?: true
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy