diff --git a/komga/src/main/kotlin/org/gotson/komga/infrastructure/xml/MappingJackson2XmlHttpMessageConverterConfiguration.kt b/komga/src/main/kotlin/org/gotson/komga/infrastructure/xml/MappingJackson2XmlHttpMessageConverterConfiguration.kt new file mode 100644 index 000000000..9d53f781f --- /dev/null +++ b/komga/src/main/kotlin/org/gotson/komga/infrastructure/xml/MappingJackson2XmlHttpMessageConverterConfiguration.kt @@ -0,0 +1,17 @@ +package org.gotson.komga.infrastructure.xml + +import org.gotson.komga.interfaces.api.opds.v1.dto.prefixToNamespace +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder +import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter + +@Configuration +class MappingJackson2XmlHttpMessageConverterConfiguration { + + @Bean + fun mappingJackson2XmlHttpMessageConverter(builder: Jackson2ObjectMapperBuilder) = + MappingJackson2XmlHttpMessageConverter( + builder.createXmlMapper(true).factory(NamespaceXmlFactory(prefixToNamespace = prefixToNamespace)).build(), + ) +} diff --git a/komga/src/main/kotlin/org/gotson/komga/infrastructure/xml/NamespaceXmlFactory.kt b/komga/src/main/kotlin/org/gotson/komga/infrastructure/xml/NamespaceXmlFactory.kt new file mode 100644 index 000000000..ce0ea2a73 --- /dev/null +++ b/komga/src/main/kotlin/org/gotson/komga/infrastructure/xml/NamespaceXmlFactory.kt @@ -0,0 +1,46 @@ +package org.gotson.komga.infrastructure.xml + +import com.fasterxml.jackson.core.JsonEncoding +import com.fasterxml.jackson.core.io.IOContext +import com.fasterxml.jackson.dataformat.xml.XmlFactory +import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator +import com.fasterxml.jackson.dataformat.xml.util.StaxUtil +import java.io.File +import java.io.OutputStream +import java.io.Writer +import javax.xml.stream.XMLStreamException +import javax.xml.stream.XMLStreamWriter + +class NamespaceXmlFactory( + private val defaultNamespace: String? = null, + private val prefixToNamespace: Map = emptyMap(), +) : XmlFactory() { + + override fun _createXmlWriter(ctxt: IOContext?, w: Writer?): XMLStreamWriter = + super._createXmlWriter(ctxt, w).apply { configure() } + + override fun createGenerator(out: OutputStream?, enc: JsonEncoding?): ToXmlGenerator = + super.createGenerator(out, enc).apply { staxWriter.configure() } + + override fun createGenerator(out: OutputStream?): ToXmlGenerator = + super.createGenerator(out).apply { staxWriter.configure() } + + override fun createGenerator(out: Writer?): ToXmlGenerator = + super.createGenerator(out).apply { staxWriter.configure() } + + override fun createGenerator(f: File?, enc: JsonEncoding?): ToXmlGenerator = + super.createGenerator(f, enc).apply { staxWriter.configure() } + + override fun createGenerator(sw: XMLStreamWriter?): ToXmlGenerator = + super.createGenerator(sw).apply { staxWriter.configure() } + + private fun XMLStreamWriter.configure() = + try { + defaultNamespace?.let { this.setDefaultNamespace(it) } + for ((key, value) in prefixToNamespace) { + this.setPrefix(key, value) + } + } catch (e: XMLStreamException) { + StaxUtil.throwAsGenerationException(e, null) + } +} diff --git a/komga/src/main/kotlin/org/gotson/komga/interfaces/api/opds/v1/dto/XmlNamespaces.kt b/komga/src/main/kotlin/org/gotson/komga/interfaces/api/opds/v1/dto/XmlNamespaces.kt index 146fe03de..7aa1558c9 100644 --- a/komga/src/main/kotlin/org/gotson/komga/interfaces/api/opds/v1/dto/XmlNamespaces.kt +++ b/komga/src/main/kotlin/org/gotson/komga/interfaces/api/opds/v1/dto/XmlNamespaces.kt @@ -3,3 +3,7 @@ package org.gotson.komga.interfaces.api.opds.v1.dto const val ATOM = "http://www.w3.org/2005/Atom" const val OPDS_PSE = "http://vaemendis.net/opds-pse/ns" const val OPENSEARCH = "http://a9.com/-/spec/opensearch/1.1/" + +val prefixToNamespace = mapOf( + "pse" to OPDS_PSE, +)