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

com.freeletics.khonshu.deeplinks.plugin.DeeplinksManifestConfigurator.kt Maven / Gradle / Ivy

Go to download

The newest version!
package com.freeletics.khonshu.deeplinks.plugin

import com.freeletics.khonshu.navigation.deeplinks.DeepLinkDefinition
import com.freeletics.khonshu.navigation.deeplinks.DeepLinkDefinitions
import com.freeletics.khonshu.navigation.deeplinks.PatternDefinition
import com.freeletics.khonshu.navigation.deeplinks.PrefixDefinition
import java.io.File

private const val PLACEHOLDER = ""

internal fun configure(
    configurationFile: File,
    inputManifestFile: File,
    outputManifestFile: File,
) {
    val manifest = inputManifestFile.readLines().toMutableList()
    val placeholderIndex = manifest.indexOfFirst { it.contains(PLACEHOLDER) }
    check(placeholderIndex >= 0) {
        "Did not find $PLACEHOLDER in given manifest ${inputManifestFile.absolutePath}"
    }

    val definitions = DeepLinkDefinitions.decodeFromString(configurationFile.readText())
    val indentation = manifest[placeholderIndex].takeWhile { it == ' ' }
    manifest[placeholderIndex] = intentFiltersFromConfig(definitions, indentation)

    outputManifestFile.writeText(manifest.joinToString(separator = "\n"))
}

private fun intentFiltersFromConfig(definitions: DeepLinkDefinitions, indentation: String): String {
    val builder = IntentFilterBuilder(indentation)

    val deepLinksWithGlobalPrefixes = definitions.deepLinks.values.filter { it.prefixes.isEmpty() }
    if (deepLinksWithGlobalPrefixes.isNotEmpty()) {
        check(definitions.prefixes.isNotEmpty()) {
            "Configuration contains deep links without a prefix but has no global prefixes"
        }

        definitions.prefixes.forEach { prefix ->
            builder.appendIntentFilter(prefix, deepLinksWithGlobalPrefixes)
        }
    }

    definitions.deepLinks.values.filter { it.prefixes.isNotEmpty() }.forEach {
        it.prefixes.forEach { prefix ->
            builder.appendIntentFilter(prefix, listOf(it))
        }
    }

    return builder.toString()
}

private fun IntentFilterBuilder.appendIntentFilter(prefix: PrefixDefinition, deepLinks: List) {
    start(prefix.autoVerified)
    appendAction("android.intent.action.VIEW")
    appendCategory("android.intent.category.DEFAULT")
    appendCategory("android.intent.category.BROWSABLE")

    deepLinks.forEach { deepLink ->
        deepLink.patterns.forEach { pattern ->
            appendData(prefix.scheme, prefix.host, pattern)
        }
    }
    end()
}

private class IntentFilterBuilder(
    private val indentation: String,
) {
    private val builder = StringBuilder()

    fun start(autoVerify: Boolean) {
        builder.appendLine("$indentation")
    }

    fun appendAction(action: String) {
        builder.appendLine("$indentation    ")
    }

    fun appendCategory(category: String) {
        builder.appendLine("$indentation    ")
    }

    fun appendData(scheme: String, host: String, pattern: PatternDefinition) {
        val pathPattern = pattern.replacePlaceholders { ".*" }
        builder.appendLine("$indentation    ")
    }

    fun end() {
        builder.appendLine("$indentation")
    }

    override fun toString(): String {
        return builder.toString().trimEnd()
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy