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

io.github.freya022.botcommands.internal.utils.AnnotationUtils.kt Maven / Gradle / Ivy

Go to download

A Kotlin-first (and Java) framework that makes creating Discord bots a piece of cake, using the JDA library.

There is a newer version: 3.0.0-alpha.18
Show newest version
package io.github.freya022.botcommands.internal.utils

import gnu.trove.set.TLongSet
import gnu.trove.set.hash.TLongHashSet
import io.github.freya022.botcommands.api.commands.annotations.BotPermissions
import io.github.freya022.botcommands.api.commands.annotations.UserPermissions
import io.github.freya022.botcommands.api.commands.application.annotations.Test
import io.github.freya022.botcommands.api.core.BContext
import io.github.freya022.botcommands.api.core.Filter
import io.github.freya022.botcommands.api.core.service.getService
import io.github.freya022.botcommands.api.core.utils.*
import io.github.freya022.botcommands.internal.utils.ReflectionUtils.declaringClass
import net.dv8tion.jda.api.Permission
import java.util.*
import kotlin.reflect.KClass
import kotlin.reflect.KFunction
import kotlin.reflect.full.declaredMemberProperties
import io.github.freya022.botcommands.api.commands.annotations.Filter as FilterAnnotation

internal object AnnotationUtils {
    internal fun getEffectiveTestGuildIds(context: BContext, func: KFunction<*>): TLongSet {
        val set = TLongHashSet(context.applicationConfig.testGuildIds)
        val annotation = func.findAnnotationRecursive() ?: return set

        val methodValue = annotation.guildIds
        set.addAll(methodValue)

        if (!annotation.append && methodValue.isNotEmpty()) {
            return set
        }

        val classValue: LongArray = func.declaringClass.findAnnotationRecursive()?.guildIds ?: LongArray(0)
        set.addAll(classValue)

        return set
    }

    internal fun getUserPermissions(func: KFunction<*>): EnumSet {
        val set: EnumSet = enumSetOf()
        val annotation = func.findAnnotationRecursive() ?: return set

        val methodPermissions = annotation.permissions
        set += methodPermissions

        if (annotation.append) {
            val classPermissions = func.declaringClass.findAnnotationRecursive()?.permissions ?: emptyArray()
            set += classPermissions
        }

        return set
    }

    internal fun getBotPermissions(func: KFunction<*>): EnumSet {
        val set: EnumSet = enumSetOf()
        val annotation = func.findAnnotationRecursive() ?: return set

        val methodPermissions = annotation.permissions
        set += methodPermissions

        if (annotation.append) {
            val classPermissions = func.declaringClass.findAnnotationRecursive()?.permissions ?: emptyArray()
            set += classPermissions
        }

        return set
    }

    @Suppress("UNCHECKED_CAST")
    internal fun  getFilters(context: BContext, func: KFunction<*>, filterType: KClass): List {
        return func.findAllAnnotations()
            .flatMap { it.classes }
            .onEach {
                require(it.isSubclassOf(filterType)) {
                    "Filter ${it.simpleNestedName} must implement ${filterType.simpleNestedName}"
                }
            }
            .map { context.getService(it) as T }
    }

    @Suppress("UNCHECKED_CAST")
    internal fun  getAnnotationValue(annotation: A, methodName: String): T {
        val kFunction = annotation.annotationClass.declaredMemberProperties.find { it.name == methodName }
            ?: throwInternal("Could not read '$methodName' from annotation '${annotation.annotationClass.simpleName}'")
        return kFunction.call(annotation) as? T
            ?: throwInternal("Could not read '$methodName' from annotation '${annotation.annotationClass.simpleName}' as the type is incorrect, annotation type: ${kFunction.returnType.simpleNestedName}")
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy