Skip to content

Commit

Permalink
Add parameter "namespaces" (#505)
Browse files Browse the repository at this point in the history
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'.
  • Loading branch information
dr0i committed Mar 19, 2024
1 parent c0ed493 commit dc1f6c8
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -70,6 +69,7 @@ public final class SimpleXmlEncoder extends DefaultStreamPipe<ObjectReceiver<Str

private static final String XML_HEADER = "<?xml version=\"%s\" encoding=\"%s\"?>\n";
private static final String XMLNS_MARKER = " xmlns";
private static final String DEFAULT = "__default";

private final StringBuilder builder = new StringBuilder();

Expand Down Expand Up @@ -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<Object, Object> entry : properties.entrySet()) {
namespaces.put(entry.getKey().toString(), entry.getValue().toString());
}
propertiesToMap(properties);
}

/**
Expand All @@ -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<Object, Object> entry : properties.entrySet()) {
namespaces.put(entry.getKey().toString(), entry.getValue().toString());
}
propertiesToMap(properties);
}

/**
Expand Down Expand Up @@ -223,15 +219,24 @@ public void setNamespaces(final Map<String, String> 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<String> 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);
}

/**
Expand Down Expand Up @@ -272,7 +277,7 @@ else if (atStreamStart) {
private void addNamespacesToElement() {
for (final Entry<String, String> 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());
}
}
Expand Down Expand Up @@ -342,7 +347,7 @@ private void writeHeader() {
builder.append(rootTag);
for (final Entry<String, String> entry : namespaces.entrySet()) {
builder.append(XMLNS_MARKER);
if (!entry.getKey().isEmpty()) {
if (!isDefaultNamespace(entry.getKey())) {
builder.append(':');
builder.append(entry.getKey());
}
Expand All @@ -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<Object, Object> entry : properties.entrySet()) {
namespaces.put(entry.getKey().toString(), entry.getValue().toString());
}
}

/**
* An XML element.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,11 @@ public void shouldAddNamespaceToRootElement() {

@Test
public void shouldAddMultipleNamespacesFromParameterToRootElement() {
final Map<String, String> namespaces = new HashMap<String, String>();
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("<?xml version=\"1.0\" encoding=\"UTF-8\"?><records xmlns:ns=\"http://example.org/ns\" xmlns:ns1=\"http://example.org/ns1\"><record /></records>",
assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><records xmlns=\"http://default.org/ns\" xmlns:ns=\"http://example.org/ns\" xmlns:ns1=\"http://example.org/ns1\"><record /></records>",
getResultXml());
}
@Test
Expand All @@ -135,6 +133,18 @@ public void shouldAddNamespaceWithEmptyKeyAsDefaultNamespaceToRootTag() {
getResultXml());
}

@Test
public void shouldAddNamespaceWithDefaultKeyAsDefaultNamespaceToRootTag() {
final Map<String, String> namespaces = new HashMap<String, String>();
namespaces.put("__default", "http://example.org/ns");
simpleXmlEncoder.setNamespaces(namespaces);

emitEmptyRecord();

assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><records xmlns=\"http://example.org/ns\"><record /></records>",
getResultXml());
}

@Test
public void shouldAddNamespaceWithEmptyKeyFromPropertiesFileAsDefaultNamespaceToRootTag() {
simpleXmlEncoder.setNamespaceFile("org/metafacture/xml/SimpleXmlEncoderTest_namespaces.properties");
Expand Down Expand Up @@ -181,6 +191,19 @@ public void shouldAddNamespaceWithEmptyKeyAsDefaultNamespaceToRecordTag() {
getResultXml());
}

@Test
public void shouldAddNamespaceWithDefaultKeyAsDefaultNamespaceToRecordTag() {
final Map<String, String> namespaces = new HashMap<String, String>();
namespaces.put("__default", "http://example.org/ns");
simpleXmlEncoder.setNamespaces(namespaces);
simpleXmlEncoder.setWriteRootTag(false);

emitEmptyRecord();

assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><record xmlns=\"http://example.org/ns\" />",
getResultXml());
}

@Test
public void shouldAddNamespaceWithEmptyKeyFromPropertiesFileAsDefaultNamespaceToRecordTag() {
simpleXmlEncoder.setNamespaceFile("org/metafacture/xml/SimpleXmlEncoderTest_namespaces.properties");
Expand All @@ -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();
Expand Down

0 comments on commit dc1f6c8

Please sign in to comment.