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

com.gabrielittner.github.diff.manifest.AndroidManifestParser.kt Maven / Gradle / Ivy

There is a newer version: 0.8.0
Show newest version
package com.gabrielittner.github.diff.manifest

import org.w3c.dom.Document
import org.w3c.dom.Node
import org.w3c.dom.NodeList
import javax.xml.xpath.XPathConstants
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.xpath.XPathFactory

class AndroidManifestParser(manifest: String) {

    private val doc = doc(manifest)

    fun parsePermissions(): List {
        val permissions = doc.nodes("/manifest/uses-permission").map { it.permission("uses-permission") }
        val permissions23 = doc.nodes("/manifest/uses-permission-sdk-23").map { it.permission("uses-permission-sdk-23") }
        return permissions + permissions23
    }

    private fun Node.permission(label: String): String {
        val name = attributes.getNamedItem("name").textContent
        val maxSdkVersion = attributes.getNamedItem("maxSdkVersion")
        if (maxSdkVersion != null) {
            return "$label $name maxSdkVersion=${maxSdkVersion.textContent}"
        }
        return "$label $name"
    }

    fun parseFeatures(): List {
        return doc.nodes("/manifest/uses-feature").map { it.feature() }
    }

    private fun Node.feature(): String {
        val name = attributes.getNamedItem("name").textContent
        val required = attributes.getNamedItem("required").textContent ?: "true"
        return "uses-feature $name required=$required"
    }

    private fun doc(manifest: String): Document {
        val factory = DocumentBuilderFactory.newInstance()
        factory.isNamespaceAware = true
        val builder = factory.newDocumentBuilder()
        return builder.parse(manifest.byteInputStream())
    }

    private fun Document.nodes(path: String): NodeList {
        val xpathFactory = XPathFactory.newInstance()
        val xpath = xpathFactory.newXPath()
        val expr = xpath.compile(path)
        return expr.evaluate(this, XPathConstants.NODESET) as NodeList
    }

    private fun  NodeList.map(mapper: (Node) -> T): List {
        return List(length) { mapper(item(it)) }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy