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

ru.pocketbyte.locolaser.kotlinmpp.KotlinMultiplatformResourcesConfigBuilder.kt Maven / Gradle / Ivy

The newest version!
package ru.pocketbyte.locolaser.kotlinmpp

import groovy.lang.Closure
import org.gradle.api.Project
import ru.pocketbyte.locolaser.config.resources.ResourcesConfig
import ru.pocketbyte.locolaser.config.resources.ResourcesConfigBuilder
import ru.pocketbyte.locolaser.config.resources.ResourcesSetConfig
import ru.pocketbyte.locolaser.config.resources.filter.RegExResourcesFilter
import ru.pocketbyte.locolaser.config.resources.filter.ResourcesFilter
import ru.pocketbyte.locolaser.kotlinmpp.builder.BaseKmpBuilder
import ru.pocketbyte.locolaser.kotlinmpp.builder.BaseKmpClassBuilder
import ru.pocketbyte.locolaser.kotlinmpp.builder.CustomFormattingClassBuilderFactory
import ru.pocketbyte.locolaser.kotlinmpp.builder.FixedFormattingClassBuilderFactory
import ru.pocketbyte.locolaser.kotlinmpp.builder.KmpClassCustomFormattingBuilder
import ru.pocketbyte.locolaser.kotlinmpp.builder.KmpClassFixedFormattingBuilder
import ru.pocketbyte.locolaser.kotlinmpp.builder.KmpInterfaceBuilder
import ru.pocketbyte.locolaser.kotlinmpp.extension.kotlin
import ru.pocketbyte.locolaser.utils.callWithDelegate
import java.io.File

class KotlinMultiplatformResourcesConfigBuilder(
    private val project: Project?
) : ResourcesConfigBuilder {

    /**
     * Package of the Repository that should be used in interface and class names.
     * Package will be ignored if interface name or class name contains canonical name.
     * By default package will taken from project.group if it provided.
     */
    var repositoryPackage: String? = null
        get() = if (field == null) {
            project?.group?.toString()
        } else {
            field
        }

    /**
     * Canonical or Simple name of the Repository interface that
     * should be implemented by generated classes.
     * If empty there will no interfaces implemented by generated Repository classes.
     */
    var repositoryInterface: String? = null

    /**
     * Canonical or Simple name of the Repository class that
     * should be generated for each platform.
     */
    var repositoryClass: String? = null

    /**
     * Source dir path.
     */
    var srcDir: String = "./build/generated/locolaser/"

    /**
     * Filter function.
     * If defined, only strings that suits the filter will be added as Repository fields.
     */
    @Deprecated(
        "Lambda function for filter is deprecated and will be replaced with ResourcesFilter" +
                " in future builds. Please, use filter(filter: ResourcesFilter?) or" +
                " filter(regExp: String) instead."
    )
    var filter: ((key: String) -> Boolean)? = null

    /**
     * Filter function.
     * If defined, only strings that suits the filter will be added as Repository fields.
     */
    var resourcesFilter: ResourcesFilter? = null
        set(value) {
            field = value
            filter = null
        }

    private val platformCommon: KmpInterfaceBuilder = KmpInterfaceBuilder()
    private val platformMap = mutableMapOf>()

    init {
        project?.afterEvaluate {
            it.kotlin {
                sourceSets.apply {
                    commonMain {
                        val sourcesDir = platformCommon.sourcesDir
                            ?: BaseKmpBuilder.defaultSourcesDir(srcDir, platformCommon)

                        kotlin.srcDir(sourcesDir)
                    }

                    platformMap.values.forEach { builder ->
                        val sourcesDir = builder.sourcesDir
                            ?: BaseKmpBuilder.defaultSourcesDir(srcDir, builder)
                        val sourceSet = findByName(builder.sourceSet)
                            ?: throw IllegalArgumentException(
                                "Missing sourceSet `${builder.sourceSet}`"
                            )

                        sourceSet.kotlin.srcDir(sourcesDir)
                    }
                }
            }
        }
    }

    /**
     * If defined, only strings with keys that matches filter will be added as Repository fields.
     * @param filter Only strings with keys that matches filter will be added as Repository fields.
     */
    fun filter(filter: ResourcesFilter?) {
        this.resourcesFilter = filter
        this.filter = null
    }

    /**
     * If defined, only strings with keys that matches RegExp will be added as Repository fields.
     * @param regExp RegExp String. Only strings with keys that matches RegExp will be added as Repository fields.
     */
    fun filter(regExp: String) {
        resourcesFilter = RegExResourcesFilter(regExp)
        this.filter = null
    }

    /**
     * Configure Repository interface in common module.
     */
    fun common(action: KmpInterfaceBuilder.() -> Unit) {
        action.invoke(platformCommon)
    }

    /**
     * Configure Repository interface in common module.
     */
    fun common(action: Closure) {
        common { action.callWithDelegate(this) }
    }

    /**
     * Configure Repository implementation for Android platform.
     * There is no Android implementation will be generated if Android platform wasn't be configured.
     */
    fun android() {
        android(null)
    }

    /**
     * Configure Repository implementation for Android platform.
     * There is no Android implementation will be generated if Android platform wasn't be configured.
     */
    fun android(action: (KmpClassFixedFormattingBuilder.() -> Unit)?) {
        platform("android", KotlinAndroidResourcesConfig, action ?: {})
    }

    /**
     * Configure Repository implementation for Android platform.
     * There is no Android implementation will be generated if Android platform wasn't be configured.
     */
    fun android(action: Closure) {
        android { action.callWithDelegate(this) }
    }

    /**
     * Configure Repository implementation for iOS platform.
     * There is no iOS implementation will be generated if iOS platform wasn't be configured.
     */
    fun ios() {
        ios(null)
    }

    /**
     * Configure Repository implementation for iOS platform.
     * There is no iOS implementation will be generated if iOS platform wasn't be configured.
     */
    fun ios(action: (KmpClassFixedFormattingBuilder.() -> Unit)?) {
        platform("ios", KotlinIosResourcesConfig, action ?: {})
    }

    /**
     * Configure Repository implementation for iOS platform.
     * There is no iOS implementation will be generated if iOS platform wasn't be configured.
     */
    fun ios(action: Closure) {
        ios { action.callWithDelegate(this) }
    }

    /**
     * Configure Repository implementation for JS platform.
     * There is no JS implementation will be generated if JS platform wasn't be configured.
     */
    fun js() {
        js(null)
    }

    /**
     * Configure Repository implementation for JS platform.
     * There is no JS implementation will be generated if JS platform wasn't be configured.
     */
    fun js(action: (KmpClassFixedFormattingBuilder.() -> Unit)?) {
        platform("js", KotlinJsResourcesConfig, action ?: {})
    }

    /**
     * Configure Repository implementation for JS platform.
     * There is no JS implementation will be generated if JS platform wasn't be configured.
     */
    fun js(action: Closure) {
        js { action.callWithDelegate(this) }
    }

    /**
     * Configure abstract KeyValue Repository implementation for provided platform name.
     * This config generates abstract strings Repository implementation, that can be used in any target.
     */
    fun absKeyValue(
        name: String,
        action: (KmpClassCustomFormattingBuilder.() -> Unit)?
    ) {
        platformWithFormat(name, KotlinAbsKeyValueResourcesConfig, action ?: {})
    }

    /**
     * Configure abstract KeyValue Repository implementation for provided platform name.
     * This config generates abstract strings Repository implementation, that can be used in any target.
     */
    fun absKeyValue(
        name: String,
        action: Closure
    ) {
        absKeyValue(name) { action.callWithDelegate(this) }
    }

    /**
     * Configure abstract Static Repository implementation for provided platform name.
     * This config generates abstract strings Repository implementation, that can be used in any target.
     */
    fun absStatic(
        name: String,
        action: (KmpClassCustomFormattingBuilder.() -> Unit)?
    ) {
        platformWithFormat(name, KotlinAbsStaticResourcesConfig, action ?: {})
    }

    /**
     * Configure abstract Static Repository implementation for provided platform name.
     * This config generates abstract strings Repository implementation, that can be used in any target.
     */
    fun absStatic(
        name: String,
        action: Closure
    ) {
        absStatic(name) { action.callWithDelegate(this) }
    }

    /**
     * Configure abstract Proxy Repository implementation for provided platform name.
     * This config generates abstract strings Repository implementation, that can be used in any target.
     */
    fun absProxy(
        name: String,
        action: (KmpClassFixedFormattingBuilder.() -> Unit)?
    ) {
        platform(name, KotlinAbsProxyResourcesConfig, action ?: {})
    }

    /**
     * Configure abstract Proxy Repository implementation for provided platform name.
     * This config generates abstract strings Repository implementation, that can be used in any target.
     */
    fun absProxy(
        name: String,
        action: Closure
    ) {
        absProxy(name) { action.callWithDelegate(this) }
    }

    /**
     * Configure Repository implementation for provided platform type.
     * @param name Name of platform.
     * @param config Platform Configuration instance.
     * Class should not be abstract and should have a constructor without parameters.
     * @param action Configure action.
     */
    fun platform (
        name: String,
        builderFactory: FixedFormattingClassBuilderFactory,
        action: (KmpClassFixedFormattingBuilder.() -> Unit)
    ) {
        val platformBuilder = platformMap[name] as? KmpClassFixedFormattingBuilder
            ?: KmpClassFixedFormattingBuilder(name, builderFactory).apply {
                sourceSet = "${name}Main"
                platformMap[name] = this
            }

        action(platformBuilder)
    }

    /**
     * Configure Repository implementation for provided platform type.
     * @param name Name of platform.
     * @param config Platform Configuration instance.
     * Class should not be abstract and should have a constructor without parameters.
     * @param action Configure action.
     */
    fun platform (
        name: String,
        builderFactory: FixedFormattingClassBuilderFactory,
        action: Closure
    ) {
        platform(name, builderFactory) {
            action.callWithDelegate(this)
        }
    }

    /**
     * Configure Repository implementation for provided platform type.
     * @param name Name of platform.
     * @param config Platform Configuration instance.
     * Class should not be abstract and should have a constructor without parameters.
     * @param action Configure action.
     */
    private fun platformWithFormat (
        name: String,
        builderFactory: CustomFormattingClassBuilderFactory,
        action: (KmpClassCustomFormattingBuilder.() -> Unit)
    ) {
        val platformBuilder = platformMap[name] as? KmpClassCustomFormattingBuilder
            ?: KmpClassCustomFormattingBuilder(name, builderFactory).apply {
                sourceSet = "${name}Main"
                platformMap[name] = this
            }

        action(platformBuilder)
    }

    override fun build(workDir: File?): ResourcesConfig {
        val resultSet = LinkedHashSet()

        val commonConfig = platformCommon.build(workDir, this)
        resultSet.add(commonConfig)

        platformMap.values.forEach { builder ->
            builder.build(workDir, this) {
                this.implements = commonConfig.resourceName
            }.let {
                resultSet.add(it)
            }
        }

        return ResourcesSetConfig(resultSet)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy