Skip to content

Commit 783b08a

Browse files
committed
refactor(errordoc): remove XOM dependency by replacing with Java native XML (DOM) #9
1 parent dc54b5c commit 783b08a

File tree

2 files changed

+87
-74
lines changed

2 files changed

+87
-74
lines changed

pom.xml

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -128,17 +128,6 @@
128128
<artifactId>jena-core</artifactId>
129129
<version>${jena.version}</version>
130130
</dependency>
131-
<dependency>
132-
<groupId>xom</groupId>
133-
<artifactId>xom</artifactId>
134-
<version>${xom.version}</version>
135-
<exclusions>
136-
<exclusion>
137-
<groupId>xml-apis</groupId>
138-
<artifactId>xml-apis</artifactId>
139-
</exclusion>
140-
</exclusions>
141-
</dependency>
142131

143132
<dependency>
144133
<groupId>org.slf4j</groupId>

src/main/java/org/swordapp/server/ErrorDocument.java

Lines changed: 87 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
package org.swordapp.server;
22

3-
import nu.xom.Attribute;
4-
import nu.xom.Document;
5-
import nu.xom.Element;
6-
import nu.xom.Serializer;
3+
import org.w3c.dom.Document;
4+
import org.w3c.dom.Element;
75

86
import javax.servlet.http.HttpServletResponse;
9-
import java.io.ByteArrayOutputStream;
10-
import java.io.IOException;
11-
import java.io.UnsupportedEncodingException;
7+
import javax.xml.parsers.DocumentBuilder;
8+
import javax.xml.parsers.DocumentBuilderFactory;
9+
import javax.xml.parsers.ParserConfigurationException;
10+
import javax.xml.transform.OutputKeys;
11+
import javax.xml.transform.Transformer;
12+
import javax.xml.transform.TransformerException;
13+
import javax.xml.transform.TransformerFactory;
14+
import javax.xml.transform.dom.DOMSource;
15+
import javax.xml.transform.stream.StreamResult;
1216
import java.io.Writer;
1317
import java.time.ZonedDateTime;
1418
import java.time.format.DateTimeFormatter;
@@ -69,63 +73,83 @@ public int getStatus() {
6973
}
7074
}
7175

72-
public void writeTo(final Writer out, final SwordConfiguration config) throws IOException, SwordServerException {
73-
// do the XML serialisation
74-
Element error = new Element("sword:error", UriRegistry.SWORD_TERMS_NAMESPACE);
75-
error.addAttribute(new Attribute("href", this.errorUri));
76-
77-
// write some boiler-plate text into the document
78-
Element title = new Element("atom:title", UriRegistry.ATOM_NAMESPACE);
79-
title.appendChild("ERROR");
80-
Element updates = new Element("atom:updated", UriRegistry.ATOM_NAMESPACE);
81-
updates.appendChild(DateTimeFormatter.ISO_INSTANT.format(ZonedDateTime.now().truncatedTo(ChronoUnit.SECONDS)));
82-
Element generator = new Element("atom:generator", UriRegistry.ATOM_NAMESPACE);
83-
generator.addAttribute(new Attribute("uri", config.generator()));
84-
generator.addAttribute(new Attribute("version", config.generatorVersion()));
85-
if (config.administratorEmail() != null) {
86-
generator.appendChild(config.administratorEmail());
87-
}
88-
Element treatment = new Element("sword:treatment", UriRegistry.SWORD_TERMS_NAMESPACE);
89-
treatment.appendChild("Processing failed");
90-
91-
error.appendChild(title);
92-
error.appendChild(updates);
93-
error.appendChild(generator);
94-
error.appendChild(treatment);
95-
96-
// now add the operational bits
97-
if (this.summary != null) {
98-
Element summary = new Element("atom:summary", UriRegistry.ATOM_NAMESPACE);
99-
summary.appendChild(this.summary);
100-
error.appendChild(summary);
101-
}
102-
103-
if (this.verboseDescription != null) {
104-
Element vd = new Element("sword:verboseDescription", UriRegistry.SWORD_TERMS_NAMESPACE);
105-
vd.appendChild(this.verboseDescription);
106-
error.appendChild(vd);
107-
}
108-
109-
String alternate = config.getAlternateUrl();
110-
String altContentType = config.getAlternateUrlContentType();
111-
if (alternate != null && !"".equals(alternate)) {
112-
Element altLink = new Element("atom:link", UriRegistry.ATOM_NAMESPACE);
113-
altLink.addAttribute(new Attribute("rel", "alternate"));
114-
if (altContentType != null && !"".equals(altContentType)) {
115-
altLink.addAttribute(new Attribute("type", altContentType));
116-
}
117-
altLink.addAttribute(new Attribute("href", alternate));
118-
error.appendChild(altLink);
119-
}
120-
76+
public void writeTo(final Writer out, final SwordConfiguration config) throws SwordServerException {
77+
12178
try {
122-
// now get it written out
123-
Document doc = new Document(error);
124-
ByteArrayOutputStream baos = new ByteArrayOutputStream();
125-
Serializer serializer = new Serializer(baos, "ISO-8859-1");
126-
serializer.write(doc);
127-
out.write(baos.toString());
128-
} catch (UnsupportedEncodingException e) {
79+
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
80+
docFactory.setNamespaceAware(true);
81+
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
82+
83+
// Root element <sword:error>
84+
Document doc = docBuilder.newDocument();
85+
Element swordError = doc.createElementNS(UriRegistry.SWORD_TERMS_NAMESPACE, "sword:error");
86+
// Make the atom namespace the default (without prefix)
87+
swordError.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", UriRegistry.ATOM_NAMESPACE);
88+
swordError.setAttribute("href", this.errorUri);
89+
doc.appendChild(swordError);
90+
91+
// Write Atom related parts
92+
// <sword:error><title>
93+
Element title = doc.createElementNS(UriRegistry.ATOM_NAMESPACE, "title");
94+
title.setTextContent("ERROR");
95+
swordError.appendChild(title);
96+
97+
// <sword:error><updated>
98+
Element updated = doc.createElementNS(UriRegistry.ATOM_NAMESPACE, "updated");
99+
updated.setTextContent(DateTimeFormatter.ISO_INSTANT.format(ZonedDateTime.now().truncatedTo(ChronoUnit.SECONDS)));
100+
swordError.appendChild(updated);
101+
102+
// <sword:error><generator>
103+
Element generator = doc.createElementNS(UriRegistry.ATOM_NAMESPACE, "generator");
104+
generator.setAttribute("uri", config.generator());
105+
generator.setAttribute("version", config.generatorVersion());
106+
if (config.administratorEmail() != null) {
107+
generator.setTextContent(config.administratorEmail());
108+
}
109+
swordError.appendChild(generator);
110+
111+
// <sword:error><summary>
112+
if (this.summary != null) {
113+
Element summary = doc.createElementNS(UriRegistry.ATOM_NAMESPACE, "summary");
114+
summary.setTextContent(this.summary);
115+
swordError.appendChild(summary);
116+
}
117+
118+
// <sword:error><link rel="alternate">
119+
String alternate = config.getAlternateUrl();
120+
String altContentType = config.getAlternateUrlContentType();
121+
if (alternate != null && !"".equals(alternate)) {
122+
Element altLink = doc.createElementNS(UriRegistry.ATOM_NAMESPACE, "link");
123+
altLink.setAttribute("rel", "alternate");
124+
if (altContentType != null && !"".equals(altContentType)) {
125+
altLink.setAttribute("type", altContentType);
126+
}
127+
altLink.setAttribute("href", alternate);
128+
swordError.appendChild(altLink);
129+
}
130+
131+
// Write SWORD specific parts
132+
// <sword:error><sword:treatment>
133+
Element treatment = doc.createElementNS(UriRegistry.SWORD_TERMS_NAMESPACE, "sword:treatment");
134+
treatment.setTextContent("Processing failed");
135+
swordError.appendChild(treatment);
136+
137+
// <sword:error><sword:verboseDescription>
138+
if (this.verboseDescription != null) {
139+
Element verbose = doc.createElementNS(UriRegistry.SWORD_TERMS_NAMESPACE, "sword:verboseDescription");
140+
verbose.setTextContent(this.verboseDescription);
141+
swordError.appendChild(verbose);
142+
}
143+
144+
// Actually write the model to a stream
145+
TransformerFactory transformerFactory = TransformerFactory.newInstance();
146+
Transformer transformer = transformerFactory.newTransformer();
147+
DOMSource source = new DOMSource(doc);
148+
transformer.setOutputProperty(OutputKeys.STANDALONE, "no");
149+
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
150+
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
151+
transformer.transform(source, new StreamResult(out));
152+
} catch (TransformerException | ParserConfigurationException e) {
129153
throw new SwordServerException(e);
130154
}
131155
}

0 commit comments

Comments
 (0)