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

com.likethesalad.placeholder.resolver.RecursiveLevelDetector.kt Maven / Gradle / Ivy

Go to download

This is a Gradle plugin for Android applications which resolves XML string references in other XML strings.

There is a newer version: 1.3.0
Show newest version
package com.likethesalad.placeholder.resolver

import com.likethesalad.placeholder.data.Constants
import com.likethesalad.placeholder.models.StringResourceModel

class RecursiveLevelDetector {

    fun orderTemplatesByRecursiveLevel(templates: List)
            : List> {
        // Wrap templates:
        val templatesMap = templates.map { it.name to TemplateRecursiveLevel(it) }.toMap()

        // Get each's recursive level:
        for (it in templatesMap.values) {
            if (!it.hasLevelDefined) {
                it.recursiveLevel = getRecursiveLevel(it, templatesMap)
            }
        }

        // Group them by level:
        val recursiveLevelGroups = templatesMap.values.groupBy { it.recursiveLevel }
            .mapValues { it.value.map { p -> p.stringResourceModel } }

        // Turn them into an ordered metaList of lists:
        val templatesByLevel = mutableListOf>()
        for (level in 0 until recursiveLevelGroups.size) {
            templatesByLevel.add(recursiveLevelGroups.getValue(level))
        }

        return templatesByLevel
    }

    private fun getRecursiveLevel(
        template: TemplateRecursiveLevel,
        allTemplates: Map,
        idPath: MutableList = mutableListOf()
    ): Int {

        val templatesAsPlaceholder = Constants.TEMPLATE_AS_PLACEHOLDER_REGEX
            .findAll(template.stringResourceModel.content)

        return if (templatesAsPlaceholder.any()) {

            // Extract templates from text:
            val templatesPlaceholders = templatesAsPlaceholder.toList().map { it.groupValues[1] }.toSet()
                .map { allTemplates.getValue(it) }

            // Check for circular dependencies:
            if (templatesPlaceholders.any { it.stringResourceModel.name in idPath }) {
                throw IllegalArgumentException("Circular dependency on string templates")
            }

            // Add the current template id to the idPath metaList to avoid circular dependencies:
            idPath.add(template.stringResourceModel.name)

            // Check recursively for each template's level of dependencies
            val levels = templatesPlaceholders.map {
                if (!it.hasLevelDefined) {
                    it.recursiveLevel = getRecursiveLevel(it, allTemplates, idPath)
                }
                it.recursiveLevel + 1
            }

            // Grab the highest level, that will be this current template level
            levels.max()!!
        } else {
            0
        }
    }

    class TemplateRecursiveLevel(
        val stringResourceModel: StringResourceModel
    ) {
        var hasLevelDefined = false
            private set
        var recursiveLevel = NO_LEVEL
            set(value) {
                field = value
                hasLevelDefined = value != NO_LEVEL
            }

        companion object {
            const val NO_LEVEL = -1
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy