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

name.remal.gradle_plugins.dsl.BaseReflectiveProjectPlugin.kt Maven / Gradle / Ivy

package name.remal.gradle_plugins.dsl

import name.remal.findDeclaredConstructor
import name.remal.getMetaAnnotation
import name.remal.gradle_plugins.dsl.extensions.afterEvaluateOrNow
import name.remal.gradle_plugins.dsl.extensions.applyPlugin
import name.remal.gradle_plugins.dsl.extensions.tryApplyPlugin
import name.remal.gradle_plugins.dsl.extensions.withPlugins
import name.remal.gradle_plugins.dsl.reflective_project_plugin.action_param_injector.invoke
import name.remal.gradle_plugins.dsl.reflective_project_plugin.info.ActionMethodInfo
import name.remal.gradle_plugins.dsl.reflective_project_plugin.info.ActionsGroupInfo
import name.remal.gradle_plugins.dsl.reflective_project_plugin.info.PluginInfoCollector
import name.remal.gradle_plugins.dsl.reflective_project_plugin.info.WithPluginActions
import org.gradle.api.Project
import kotlin.Any
import kotlin.IllegalStateException
import kotlin.UnsupportedOperationException
import kotlin.let
import java.lang.Deprecated as JavaDeprecated
import kotlin.Deprecated as KotlinDeprecated

abstract class BaseReflectiveProjectPlugin : BaseProjectPlugin() {

    final override fun applyImpl(project: Project) {
        val pluginInfo = PluginInfoCollector.collect(javaClass) ?: throw IllegalStateException("Plugin info can't be collected for $javaClass")

        val deprecationMessage = javaClass.getMetaAnnotation(KotlinDeprecated::class.java)?.message ?: javaClass.getMetaAnnotation(JavaDeprecated::class.java)?.let { "" }
        if (null != deprecationMessage) {
            if (deprecationMessage.isNotEmpty()) {
                logger.warn("Plugin {} is deprecated: {}", pluginInfo.id, deprecationMessage)
            } else {
                logger.warn("Plugin {} is deprecated", pluginInfo.id)
            }
        }

        doActions(project, this, pluginInfo)
    }

    private fun doActions(project: Project, actionsGroup: Any, actionsInfo: WithPluginActions) {
        for (conditionInfo in actionsInfo.conditionMethods) {
            if (!conditionInfo.invoke(actionsGroup, project)) {
                logger.debug("Skipping because of failed condition {}", conditionInfo)
                return
            }
        }

        project.withPlugins(actionsInfo.requirePluginIds) {
            logger.debug("Preparing plugin actions group: {}", actionsInfo)
            actionsInfo.applyPluginIds.forEach { project.applyPlugin(it) }
            actionsInfo.applyOptionalPluginIds.forEach { project.tryApplyPlugin(it) }
            actionsInfo.applyPluginClasses.forEach { project.applyPlugin(it) }

            for (action in actionsInfo.actions) {
                if (action is ActionMethodInfo) {
                    project.withPlugins(action.requirePluginIds) {
                        logger.debug("Preparing plugin action: {}", action)
                        action.applyPluginIds.forEach { project.applyPlugin(it) }
                        action.applyOptionalPluginIds.forEach { project.tryApplyPlugin(it) }
                        action.applyPluginClasses.forEach { project.applyPlugin(it) }

                        if (action.isAfterProjectEvaluation) {
                            project.afterEvaluateOrNow {
                                logger.debug("Executing plugin action: {}", action)
                                action.invoke(actionsGroup, project)
                            }
                        } else {
                            logger.debug("Executing plugin action: {}", action)
                            action.invoke(actionsGroup, project)
                        }

                        action.applyPluginIdsAtTheEnd.forEach { project.applyPlugin(it) }
                        action.applyOptionalPluginIdsAtTheEnd.forEach { project.tryApplyPlugin(it) }
                        action.applyPluginClassesAtTheEnd.forEach { project.applyPlugin(it) }
                    }

                } else if (action is ActionsGroupInfo) {
                    val innerActionsGroup = action.actionsGroupClass.let {
                        it.findDeclaredConstructor(actionsGroup.javaClass)?.newInstance(actionsGroup)
                            ?: it.getDeclaredConstructor().newInstance()
                    }
                    doActions(project, innerActionsGroup, action)

                } else {
                    throw UnsupportedOperationException("Unsupported action type: ${action.javaClass}")
                }
            }

            actionsInfo.applyPluginIdsAtTheEnd.forEach { project.applyPlugin(it) }
            actionsInfo.applyOptionalPluginIdsAtTheEnd.forEach { project.tryApplyPlugin(it) }
            actionsInfo.applyPluginClassesAtTheEnd.forEach { project.applyPlugin(it) }
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy