1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.esigate.xml;
17
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.io.StringReader;
21 import java.io.Writer;
22
23 import javax.xml.transform.Source;
24 import javax.xml.transform.Transformer;
25 import javax.xml.transform.TransformerConfigurationException;
26 import javax.xml.transform.TransformerException;
27 import javax.xml.transform.TransformerFactory;
28 import javax.xml.transform.dom.DOMResult;
29 import javax.xml.transform.dom.DOMSource;
30 import javax.xml.transform.stream.StreamSource;
31 import javax.xml.XMLConstants;
32
33 import nu.validator.htmlparser.common.DoctypeExpectation;
34 import nu.validator.htmlparser.dom.Dom2Sax;
35 import nu.validator.htmlparser.dom.HtmlDocumentBuilder;
36
37 import org.apache.commons.io.IOUtils;
38 import org.apache.http.client.methods.CloseableHttpResponse;
39 import org.esigate.Driver;
40 import org.esigate.HttpErrorPage;
41 import org.esigate.Renderer;
42 import org.esigate.http.HttpResponseUtils;
43 import org.esigate.impl.DriverRequest;
44 import org.w3c.dom.Document;
45 import org.xml.sax.InputSource;
46 import org.xml.sax.SAXException;
47
48
49
50
51
52
53
54
55
56
57 public class XsltRenderer implements Renderer {
58 private static final TransformerFactory TRANSFORMER_FACTORY = TransformerFactory.newInstance();
59 private Transformer transformer;
60
61
62
63
64
65
66
67
68
69
70
71 public XsltRenderer(String template, Driver driver, DriverRequest originalRequest) throws IOException,
72 HttpErrorPage {
73 StringBuilder templateStringBuilder = new StringBuilder();
74 CloseableHttpResponse response = driver.render(template, originalRequest.getOriginalRequest());
75 templateStringBuilder.append(HttpResponseUtils.toString(response));
76 transformer = createTransformer(IOUtils.toInputStream(templateStringBuilder));
77 }
78
79
80
81
82
83
84
85 public XsltRenderer(String xsl) throws IOException {
86 InputStream templateStream = IOUtils.toInputStream(xsl);
87 transformer = createTransformer(templateStream);
88 }
89
90 private static Transformer createTransformer(InputStream templateStream) throws IOException {
91 try {
92
93 TRANSFORMER_FACTORY.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
94 return TRANSFORMER_FACTORY.newTransformer(new StreamSource(templateStream));
95 } catch (TransformerConfigurationException e) {
96 throw new ProcessingFailedException("Failed to create XSLT template", e);
97 } finally {
98 templateStream.close();
99 }
100 }
101
102
103 @Override
104 public void render(DriverRequest httpRequest, String src, Writer out) throws IOException {
105 try {
106 HtmlDocumentBuilder htmlDocumentBuilder = new HtmlDocumentBuilder();
107 htmlDocumentBuilder.setDoctypeExpectation(DoctypeExpectation.NO_DOCTYPE_ERRORS);
108 Document document = htmlDocumentBuilder.parse(new InputSource(new StringReader(src)));
109 Source source = new DOMSource(document);
110 DOMResult result = new DOMResult();
111 transformer.transform(source, result);
112 XhtmlSerializer serializer = new XhtmlSerializer(out);
113 Dom2Sax dom2Sax = new Dom2Sax(serializer, serializer);
114 dom2Sax.parse(result.getNode());
115 } catch (TransformerException e) {
116 throw new ProcessingFailedException("Failed to transform source", e);
117 } catch (SAXException e) {
118 throw new ProcessingFailedException("Failed serialize transformation result", e);
119 }
120 }
121 }