io.gitlab.arturbosch.detekt.report.XmlReportMerger.kt Maven / Gradle / Ivy
package io.gitlab.arturbosch.detekt.report
import org.w3c.dom.Document
import org.w3c.dom.Node
import java.io.File
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.transform.OutputKeys
import javax.xml.transform.TransformerFactory
import javax.xml.transform.dom.DOMSource
import javax.xml.transform.stream.StreamResult
/**
* A naive implementation to merge xml assuming all input xml are written by detekt.
*/
object XmlReportMerger {
private val documentBuilder by lazy { DocumentBuilderFactory.newInstance().newDocumentBuilder() }
fun merge(inputs: Collection, output: File) {
val document = documentBuilder.newDocument().apply {
xmlStandalone = true
val checkstyleNode = createElement("checkstyle")
checkstyleNode.setAttribute("version", "4.3")
appendChild(checkstyleNode)
}
inputs.filter { it.exists() }.forEach {
importNodesFromInput(it, document)
}
TransformerFactory.newInstance().newTransformer().run {
setOutputProperty(OutputKeys.INDENT, "yes")
setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2")
transform(DOMSource(document), StreamResult(output.writer()))
}
}
private fun importNodesFromInput(input: File, document: Document) {
val checkstyleNode = documentBuilder.parse(input.inputStream()).documentElement.also { removeWhitespaces(it) }
(0 until checkstyleNode.childNodes.length).forEach {
val node = checkstyleNode.childNodes.item(it)
document.documentElement.appendChild(document.importNode(node, true))
}
}
/**
* Use code instead of XSLT to exclude whitespaces.
*/
private fun removeWhitespaces(node: Node) {
(node.childNodes.length - 1 downTo 0).forEach { idx ->
val childNode = node.childNodes.item(idx)
if (childNode.nodeType == Node.TEXT_NODE && childNode.textContent.isBlank()) {
node.removeChild(childNode)
} else {
removeWhitespaces(childNode)
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy