From 95b618c28c9dbb4e2083e240b3e101a99e056b60 Mon Sep 17 00:00:00 2001 From: Pascal Christoph Date: Tue, 19 Mar 2024 13:45:46 +0100 Subject: [PATCH] Add parameter "namespaces" (#505) Set a namespace or a list of namespaces. A namespace is a Java Properties structure, i.e. a key-value structure where the key is separated from the value by an equal sign '='. Multiple namespaces are separated by a line feed '\n'. --- .../org/metafacture/xml/SimpleXmlEncoder.java | 47 ++++++++++++------- .../metafacture/xml/SimpleXmlEncoderTest.java | 33 +++++++++++-- 2 files changed, 59 insertions(+), 21 deletions(-) diff --git a/metafacture-xml/src/main/java/org/metafacture/xml/SimpleXmlEncoder.java b/metafacture-xml/src/main/java/org/metafacture/xml/SimpleXmlEncoder.java index 61ca0ee40..688d40142 100644 --- a/metafacture-xml/src/main/java/org/metafacture/xml/SimpleXmlEncoder.java +++ b/metafacture-xml/src/main/java/org/metafacture/xml/SimpleXmlEncoder.java @@ -29,12 +29,11 @@ import org.metafacture.framework.helpers.DefaultXmlPipe; import java.io.IOException; +import java.io.StringReader; import java.net.URL; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -70,6 +69,7 @@ public final class SimpleXmlEncoder extends DefaultStreamPipe\n"; private static final String XMLNS_MARKER = " xmlns"; + private static final String DEFAULT = "_default"; private final StringBuilder builder = new StringBuilder(); @@ -143,9 +143,7 @@ public void setNamespaceFile(final String file) { catch (final IOException e) { throw new MetafactureException("Failed to load namespaces list", e); } - for (final Entry entry : properties.entrySet()) { - namespaces.put(entry.getKey().toString(), entry.getValue().toString()); - } + propertiesToMap(properties); } /** @@ -161,9 +159,7 @@ public void setNamespaceFile(final URL url) { catch (final IOException e) { throw new MetafactureException("Failed to load namespaces list", e); } - for (final Entry entry : properties.entrySet()) { - namespaces.put(entry.getKey().toString(), entry.getValue().toString()); - } + propertiesToMap(properties); } /** @@ -223,15 +219,24 @@ public void setNamespaces(final Map namespaces) { /** * Sets the namespace(s). * - * @param namespacesString the namespaces as a String. Key and value are separated by a space. Multiple entries are - * separated by a semicolon ';' + * @param namespacesString the namespaces as a String. Key and value are separated by a '='. Multiple entries are + * separated by a line feed '\n'. */ public void setNamespaces(final String namespacesString) { - final String[] namespacesArray = namespacesString.split(";"); - for (Iterator it = Arrays.stream(namespacesArray).iterator(); it.hasNext(); ) { - final String[] entry = it.next().split(" "); - namespaces.put(entry[0], entry[1]); + final Properties properties = new Properties(); + final StringReader sr = new StringReader(namespacesString); + try { + properties.load(sr); + } + catch (final IOException e) { + throw new MetafactureException("Failed to create namespace list"); } + finally { + if (sr != null) { + sr.close(); + } + } + propertiesToMap(properties); } /** @@ -272,7 +277,7 @@ else if (atStreamStart) { private void addNamespacesToElement() { for (final Entry namespace : namespaces.entrySet()) { final String key = namespace.getKey(); - final String name = XMLNS_MARKER + (key.isEmpty() ? "" : ":") + key; + final String name = XMLNS_MARKER + (isDefaultNamespace(key) ? "" : ":" + key); element.addAttribute(name, namespace.getValue()); } } @@ -342,7 +347,7 @@ private void writeHeader() { builder.append(rootTag); for (final Entry entry : namespaces.entrySet()) { builder.append(XMLNS_MARKER); - if (!entry.getKey().isEmpty()) { + if (!isDefaultNamespace(entry.getKey())) { builder.append(':'); builder.append(entry.getKey()); } @@ -367,6 +372,16 @@ protected static void writeEscaped(final StringBuilder builder, final String str builder.append(XmlUtil.escape(str, false)); } + private boolean isDefaultNamespace(final String ns) { + return ns.isEmpty() || ns.equals(DEFAULT); + } + + private void propertiesToMap(final Properties properties) { + for (final Entry entry : properties.entrySet()) { + namespaces.put(entry.getKey().toString(), entry.getValue().toString()); + } + } + /** * An XML element. * diff --git a/metafacture-xml/src/test/java/org/metafacture/xml/SimpleXmlEncoderTest.java b/metafacture-xml/src/test/java/org/metafacture/xml/SimpleXmlEncoderTest.java index ac18c022d..f356d25d6 100644 --- a/metafacture-xml/src/test/java/org/metafacture/xml/SimpleXmlEncoderTest.java +++ b/metafacture-xml/src/test/java/org/metafacture/xml/SimpleXmlEncoderTest.java @@ -114,13 +114,11 @@ public void shouldAddNamespaceToRootElement() { @Test public void shouldAddMultipleNamespacesFromParameterToRootElement() { - final Map namespaces = new HashMap(); - namespaces.put("ns", "http://example.org/ns"); - simpleXmlEncoder.setNamespaces("ns http://example.org/ns;ns1 http://example.org/ns1"); + simpleXmlEncoder.setNamespaces("_default=http://default.org/ns\nns=http://example.org/ns\nns1=http://example.org/ns1"); emitEmptyRecord(); - assertEquals("", + assertEquals("", getResultXml()); } @Test @@ -135,6 +133,18 @@ public void shouldAddNamespaceWithEmptyKeyAsDefaultNamespaceToRootTag() { getResultXml()); } + @Test + public void shouldAddNamespaceWithDefaultKeyAsDefaultNamespaceToRootTag() { + final Map namespaces = new HashMap(); + namespaces.put("_default", "http://example.org/ns"); + simpleXmlEncoder.setNamespaces(namespaces); + + emitEmptyRecord(); + + assertEquals("", + getResultXml()); + } + @Test public void shouldAddNamespaceWithEmptyKeyFromPropertiesFileAsDefaultNamespaceToRootTag() { simpleXmlEncoder.setNamespaceFile("org/metafacture/xml/SimpleXmlEncoderTest_namespaces.properties"); @@ -181,6 +191,19 @@ public void shouldAddNamespaceWithEmptyKeyAsDefaultNamespaceToRecordTag() { getResultXml()); } + @Test + public void shouldAddNamespaceWithDefaultKeyAsDefaultNamespaceToRecordTag() { + final Map namespaces = new HashMap(); + namespaces.put("_default", "http://example.org/ns"); + simpleXmlEncoder.setNamespaces(namespaces); + simpleXmlEncoder.setWriteRootTag(false); + + emitEmptyRecord(); + + assertEquals("", + getResultXml()); + } + @Test public void shouldAddNamespaceWithEmptyKeyFromPropertiesFileAsDefaultNamespaceToRecordTag() { simpleXmlEncoder.setNamespaceFile("org/metafacture/xml/SimpleXmlEncoderTest_namespaces.properties"); @@ -193,7 +216,7 @@ public void shouldAddNamespaceWithEmptyKeyFromPropertiesFileAsDefaultNamespaceTo } @Test public void shouldAddNamespaceWithEmptyKeyFromParameterAsDefaultNamespaceToRecordTag() { - simpleXmlEncoder.setNamespaces(" http://example.org/ns"); + simpleXmlEncoder.setNamespaces("=http://example.org/ns"); simpleXmlEncoder.setWriteRootTag(false); emitEmptyRecord();