XMLTransformer.kt 2.46 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
 * 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 <https://www.gnu.org/licenses/>.
 */
Jonas Waeber's avatar
Jonas Waeber committed
18
package org.memobase.xml
19
20
21
22
23
24
25

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
Jonas Waeber's avatar
Jonas Waeber committed
26
27
28
29
import org.memobase.utils.MissingIdentifierException
import org.memobase.utils.XsltException
import settings.HeaderMetadata
import java.io.ByteArrayInputStream
30
31
32
import java.io.InputStream
import javax.xml.transform.stream.StreamSource

Jonas Waeber's avatar
Jonas Waeber committed
33
class XMLTransformer {
34
35
    private val processor = Processor(false)

Jonas Waeber's avatar
Jonas Waeber committed
36
37
38
39
40
41
    fun xsltFunction(xsltData: ByteArray): ByteArray {
        return xsltData
    }

    fun applyXSLT(key: String, headers: HeaderMetadata, data: InputStream, xsltFile: ByteArray): Pair<String, SAXContentHandler> {
        val contentHandler = SAXContentHandler(key, headers.xmlIdentifierFieldName, headers.xmlRecordTag)
42
43
44
        val errorList = mutableListOf<StaticError>()
        val xsltCompiler = processor.newXsltCompiler()
        xsltCompiler.setErrorList(errorList)
Jonas Waeber's avatar
Jonas Waeber committed
45
        val source = StreamSource(ByteArrayInputStream(xsltFile))
46
        val executable = xsltCompiler.compile(source)
Jonas Waeber's avatar
Jonas Waeber committed
47
48
        if (errorList.isNotEmpty()) {
            throw XsltException(errorList)
49
        }
Jonas Waeber's avatar
Jonas Waeber committed
50
        val transformer = executable.load()
Jonas Waeber's avatar
Jonas Waeber committed
51
52
53
54
        data.use { stream ->
            transformer.setSource(StreamSource(stream))
            transformer.destination = SAXDestination(contentHandler)
            transformer.transform()
55
        }
Jonas Waeber's avatar
Jonas Waeber committed
56
        if (contentHandler.identifier == null || contentHandler.identifier?.isEmpty() == true) {
Jonas Waeber's avatar
Jonas Waeber committed
57
            throw MissingIdentifierException(key, headers.xmlIdentifierFieldName)
58
        } else {
Jonas Waeber's avatar
Jonas Waeber committed
59
            return Pair(contentHandler.identifier!!, contentHandler)
60
61
62
        }
    }
}