/*
* xml-data-transform
* Copyright (C) 2020 Memoriav
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package org.memobase.xml
import net.sf.saxon.s9api.Processor
import net.sf.saxon.s9api.SAXDestination
import net.sf.saxon.s9api.StaticError
import net.sf.saxon.s9api.XsltExecutable
import org.apache.kafka.streams.KeyValue
import org.apache.logging.log4j.LogManager
import org.memobase.utils.MissingIdentifierException
import org.memobase.utils.XsltException
import settings.HeaderMetadata
import java.io.ByteArrayInputStream
import java.io.InputStream
import javax.xml.transform.stream.StreamSource
class XMLTransformer {
private val processor = Processor(false)
fun xsltFunction(xsltData: ByteArray): ByteArray {
return xsltData
}
fun applyXSLT(key: String, headers: HeaderMetadata, data: InputStream, xsltFile: ByteArray): Pair {
val contentHandler = SAXContentHandler(key, headers.xmlIdentifierFieldName, headers.xmlRecordTag)
val errorList = mutableListOf()
val xsltCompiler = processor.newXsltCompiler()
xsltCompiler.setErrorList(errorList)
val source = StreamSource(ByteArrayInputStream(xsltFile))
val executable = xsltCompiler.compile(source)
if (errorList.isNotEmpty()) {
throw XsltException(errorList)
}
val transformer = executable.load()
data.use { stream ->
transformer.setSource(StreamSource(stream))
transformer.destination = SAXDestination(contentHandler)
transformer.transform()
}
if (contentHandler.identifier == null || contentHandler.identifier?.isEmpty() == true) {
throw MissingIdentifierException(key, headers.xmlIdentifierFieldName)
} else {
return Pair(contentHandler.identifier!!, contentHandler)
}
}
}