1 /**
2 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3 */
4
5 package net.sourceforge.pmd.renderers;
6
7 import java.io.ByteArrayInputStream;
8 import java.io.File;
9 import java.io.FileInputStream;
10 import java.io.FileNotFoundException;
11 import java.io.IOException;
12 import java.io.InputStream;
13 import java.io.StringWriter;
14 import java.io.Writer;
15
16 import javax.xml.parsers.DocumentBuilder;
17 import javax.xml.parsers.DocumentBuilderFactory;
18 import javax.xml.parsers.ParserConfigurationException;
19 import javax.xml.transform.Transformer;
20 import javax.xml.transform.TransformerConfigurationException;
21 import javax.xml.transform.TransformerException;
22 import javax.xml.transform.TransformerFactory;
23 import javax.xml.transform.dom.DOMSource;
24 import javax.xml.transform.stream.StreamResult;
25 import javax.xml.transform.stream.StreamSource;
26
27 import org.w3c.dom.Document;
28 import org.xml.sax.SAXException;
29
30 /**
31 * @author Romain Pelisse, belaran@gmail.com
32 *
33 */
34 public class XSLTRenderer extends XMLRenderer {
35
36 private Transformer transformer;
37 private String xsltFilename = "/etc/pmd-nicerhtml.xsl";
38 private Writer outputWriter;
39
40 public XSLTRenderer() {
41
42 }
43 /**
44 * This constuctor provides a way to override default stylesheet
45 * @param xsltFilename
46 */
47 public XSLTRenderer(String xsltFilename) {
48 File file = new File(xsltFilename);
49 if ( xsltFilename != null && file.exists() && file.canRead() ) {
50 this.xsltFilename = xsltFilename;
51 }
52 }
53
54 @Override
55 public void start() throws IOException {
56
57 this.outputWriter = getWriter();
58
59 Writer w = new StringWriter();
60 setWriter(w);
61
62
63 InputStream xslt = null;
64 File file = new File(this.xsltFilename);
65 if ( file.exists() && file.canRead() ) {
66 xslt = new FileInputStream(file);
67 }
68 else {
69 xslt = this.getClass().getResourceAsStream(xsltFilename);
70 }
71 if ( xslt == null ) {
72 throw new FileNotFoundException("Can't file XSLT sheet :" + xsltFilename);
73 }
74 this.prepareTransformer(xslt);
75
76 super.start();
77 }
78
79 /**
80 * Prepare the transformer, doing the proper "building"...
81 *
82 * @param xslt, the xslt provided as an InputStream
83 */
84 private void prepareTransformer(InputStream xslt) {
85 if ( xslt != null ) {
86 try {
87
88 TransformerFactory factory = TransformerFactory.newInstance();
89 StreamSource src = new StreamSource(xslt);
90
91 this.transformer = factory.newTransformer(src);
92 } catch (TransformerConfigurationException e) {
93 e.printStackTrace();
94 }
95 }
96 }
97
98 @Override
99 public void end() throws IOException {
100
101 super.end();
102
103 Writer writer = super.getWriter();
104 if ( writer instanceof StringWriter ) {
105 StringWriter w = (StringWriter)writer;
106 StringBuffer buffer = w.getBuffer();
107
108 InputStream xml = new ByteArrayInputStream(buffer.toString().getBytes(this.encoding));
109 Document doc = this.getDocument(xml);
110 this.transform(doc);
111 }
112 else {
113
114 new RuntimeException("Wrong writer").printStackTrace();
115 }
116
117 }
118
119 private void transform(Document doc) {
120 DOMSource source = new DOMSource(doc);
121 this.setWriter(new StringWriter());
122 StreamResult result = new StreamResult(this.outputWriter);
123 try {
124 transformer.transform(source, result);
125 } catch (TransformerException e) {
126 e.printStackTrace();
127 }
128 }
129
130 private Document getDocument(InputStream xml) {
131 try {
132 DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
133 return parser.parse(xml);
134 } catch (ParserConfigurationException e) {
135 e.printStackTrace();
136 } catch (SAXException e) {
137 e.printStackTrace();
138 } catch (IOException e) {
139 e.printStackTrace();
140 }
141 return null;
142 }
143 }