|
1 | 1 | package org.swordapp.server;
|
2 | 2 |
|
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; |
7 | 5 |
|
8 | 6 | 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; |
12 | 16 | import java.io.Writer;
|
13 | 17 | import java.time.ZonedDateTime;
|
14 | 18 | import java.time.format.DateTimeFormatter;
|
@@ -69,63 +73,83 @@ public int getStatus() {
|
69 | 73 | }
|
70 | 74 | }
|
71 | 75 |
|
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 | + |
121 | 78 | 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) { |
129 | 153 | throw new SwordServerException(e);
|
130 | 154 | }
|
131 | 155 | }
|
|
0 commit comments