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

main.phraseapp.internal.xml.Visitor.kt Maven / Gradle / Ivy

The newest version!
package phraseapp.internal.xml

import java.text.SimpleDateFormat
import java.util.*

interface Visitor {
    fun visit(resource: Resource)
    fun visit(string: StringTranslation)
    fun visit(stringsArray: StringsArrayTranslation)
    fun visit(plural: PluralsTranslation)
    fun visit(comment: CommentTranslation)
}

class XmlPrinterScanner : Visitor {
    private val contexts = Stack()

    fun start(resource: Resource): String {
        enter(ResultContext(""))
        scan(resource)
        return (exit() as ResultContext).content
    }

    private fun scan(elements: List) = elements.forEach { scan(it) }

    private fun scan(element: Translation) = element.accept(this)

    private fun enter(context: Context) {
        contexts.push(context)
    }

    private fun exit() = contexts.pop()

    override fun visit(resource: Resource) {
        enter(ResourceContext())
        scan(resource.strings.filter { it.translatable })
        val context = exit() as ResourceContext

        when (val parentContext = contexts.peek()) {
            is ResultContext -> parentContext.content = """

${context.items.joinToString("\n")}
"""
            else -> TODO()
        }
    }

    override fun visit(string: StringTranslation) {
        val parentContext = contexts.peek()
        enter(StringContext(parentContext.level + 1))
        scan(string.comment)
        val context = exit() as StringContext

        val value = string.value
            .replace("|1<", "|1<")
        when (parentContext) {
            is ResourceContext -> parentContext.items.add("""${context.comment}${context.tabs()}$value""")
            is PluralsContext -> parentContext.items.add("""${context.comment}${context.tabs()}$value""")
            is StringsArrayContext -> parentContext.items.add("""${context.comment}${context.tabs()}$value""")
            else -> TODO()
        }
    }

    override fun visit(stringsArray: StringsArrayTranslation) {
        enter(StringsArrayContext())
        scan(stringsArray.comment)
        scan(stringsArray.values)
        val context = exit() as StringsArrayContext

        when (val parentContext = contexts.peek()) {
            is ResourceContext -> parentContext.items.add(
                """${context.comment}${context.tabs()}
${context.items.joinToString("\n")}
${context.tabs()}"""
            )
            else -> TODO()
        }
    }

    override fun visit(plural: PluralsTranslation) {
        enter(PluralsContext())
        scan(plural.comment)
        scan(plural.plurals)
        val context = exit() as PluralsContext

        when (val parentContext = contexts.peek()) {
            is ResourceContext -> parentContext.items.add(
                """${context.comment}${context.tabs()}
${context.items.joinToString("\n")}
${context.tabs()}"""
            )
            else -> TODO()
        }
    }

    override fun visit(comment: CommentTranslation) {
        if (comment.text.isEmpty()) return
        val parentContext = contexts.peek()
        val commentNode = """${parentContext.tabs()}
"""
        when (parentContext) {
            is StringContext -> parentContext.comment = commentNode
            is StringsArrayContext -> parentContext.comment = commentNode
            is PluralsContext -> parentContext.comment = commentNode
            else -> TODO()
        }
    }
}

class ArbPrinterScanner : Visitor {
    private val contexts = Stack()
    private var dateStr: String? = null

    fun start(resource: Resource): String {
        enter(ResultContext(""))
        scan(resource)
        return (exit() as ResultContext).content
    }

    private fun scan(elements: List) = elements.forEach { scan(it) }

    private fun scan(element: Translation) = element.accept(this)

    private fun enter(context: Context) {
        contexts.push(context)
    }

    private fun exit() = contexts.pop()

    override fun visit(resource: Resource) {
        enter(ResourceContext())
        scan(resource.strings)
        val context = exit() as ResourceContext

        when (val parentContext = contexts.peek()) {
            is ResultContext -> {
                val dateStr = getDate()
                val displayDate = "\t\"@@last_modified\":\"$dateStr\""
                var items = arrayListOf()
                items.add(displayDate)
                items.addAll(context.items)
                parentContext.content = """{
${items.joinToString(",\n")}
}"""
            }
            else -> TODO()
        }
    }

    override fun visit(string: StringTranslation) {
        val parentContext = contexts.peek()
        enter(StringContext(parentContext.level + 1))
        scan(string.comment)
        val context = exit() as StringContext

        val value = string.value
            .replace("|1<", "|1<")
            .replace("\\'", "'")
            .replace("\"", "\\\"")
        when (parentContext) {
            is ResourceContext -> parentContext.items.add("""${context.comment}${context.tabs()}"${string.key}":"$value"""")
            else -> TODO()
        }
    }

    override fun visit(stringsArray: StringsArrayTranslation) {
        enter(StringsArrayContext())
        scan(stringsArray.comment)
        scan(stringsArray.values)
    }

    override fun visit(plural: PluralsTranslation) {
        enter(PluralsContext())
        scan(plural.comment)
        scan(plural.plurals)
    }

    override fun visit(comment: CommentTranslation) {
        return
    }

    fun getDate(): String {
        if (dateStr == null) {
            val date = Date()
            val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssSSS")
            dateStr = simpleDateFormat.format(date)
        }
        return dateStr!!
    }
}

interface Context {
    val level: Int
    fun tabs(): String = (0 until level).joinToString("") { "\t" }
}

class ResultContext(var content: String) : Context {
    override val level: Int = 0
}

class ResourceContext(val items: MutableList = arrayListOf()) : Context {
    override val level: Int = 0
}

class StringContext(override val level: Int = 1, var comment: String = "") : Context
class StringsArrayContext(
    override val level: Int = 1,
    val items: MutableList = arrayListOf(),
    var comment: String = ""
) : Context

class PluralsContext(
    override val level: Int = 1,
    val items: MutableList = arrayListOf(),
    var comment: String = ""
) : Context




© 2015 - 2024 Weber Informatics LLC | Privacy Policy