001 /**
002 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
003 */
004
005 package net.sourceforge.pmd.renderers;
006
007 import java.io.ByteArrayInputStream;
008 import java.io.File;
009 import java.io.FileInputStream;
010 import java.io.FileNotFoundException;
011 import java.io.IOException;
012 import java.io.InputStream;
013 import java.io.StringWriter;
014 import java.io.Writer;
015 import java.util.Properties;
016
017 import javax.xml.parsers.DocumentBuilder;
018 import javax.xml.parsers.DocumentBuilderFactory;
019 import javax.xml.parsers.ParserConfigurationException;
020 import javax.xml.transform.Transformer;
021 import javax.xml.transform.TransformerConfigurationException;
022 import javax.xml.transform.TransformerException;
023 import javax.xml.transform.TransformerFactory;
024 import javax.xml.transform.dom.DOMSource;
025 import javax.xml.transform.stream.StreamResult;
026 import javax.xml.transform.stream.StreamSource;
027
028 import org.w3c.dom.Document;
029 import org.xml.sax.SAXException;
030
031 /**
032 * Renderer to XML format with a XSL Transformation applied.
033 *
034 * @author Romain Pelisse, belaran@gmail.com
035 */
036 public class XSLTRenderer extends XMLRenderer {
037
038 public static final String NAME = "xslt";
039
040 public static final String XSLT_FILENAME = "xsltFilename";
041
042 private Transformer transformer;
043 private String xsltFilename = "/etc/pmd-nicerhtml.xsl";
044 private Writer outputWriter;
045
046 public XSLTRenderer(Properties properties) {
047 super(properties);
048 super.setName(NAME);
049 super.setDescription("XML with a XSL Transformation applied.");
050 super.defineProperty(XSLT_FILENAME, "The XSLT file name.");
051
052 String xsltFilename = properties.getProperty(XSLT_FILENAME);
053 if (xsltFilename != null) {
054 File file = new File(xsltFilename);
055 if (file.exists() && file.canRead()) {
056 this.xsltFilename = xsltFilename;
057 }
058 }
059 }
060
061 /**
062 * {@inheritDoc}
063 */
064 @Override
065 public void start() throws IOException {
066 // We keep the inital writer to put the final html output
067 this.outputWriter = getWriter();
068 // We use a new one to store the XML...
069 Writer w = new StringWriter();
070 setWriter(w);
071 // If don't find the xsl no need to bother doing the all report,
072 // so we check this here...
073 InputStream xslt = null;
074 File file = new File(this.xsltFilename);
075 if (file.exists() && file.canRead()) {
076 xslt = new FileInputStream(file);
077 } else {
078 xslt = this.getClass().getResourceAsStream(xsltFilename);
079 }
080 if (xslt == null) {
081 throw new FileNotFoundException("Can't file XSLT sheet :" + xsltFilename);
082 }
083 this.prepareTransformer(xslt);
084 // Now we build the XML file
085 super.start();
086 }
087
088 /**
089 * Prepare the transformer, doing the proper "building"...
090 *
091 * @param xslt The stylesheet provided as an InputStream
092 */
093 private void prepareTransformer(InputStream xslt) {
094 if (xslt != null) {
095 try {
096 //Get a TransformerFactory object
097 TransformerFactory factory = TransformerFactory.newInstance();
098 StreamSource src = new StreamSource(xslt);
099 //Get an XSL Transformer object
100 this.transformer = factory.newTransformer(src);
101 } catch (TransformerConfigurationException e) {
102 e.printStackTrace();
103 }
104 }
105 }
106
107 /**
108 * {@inheritDoc}
109 */
110 @Override
111 public void end() throws IOException {
112 // First we finish the XML report
113 super.end();
114 // Now we transform it using XSLT
115 Writer writer = super.getWriter();
116 if (writer instanceof StringWriter) {
117 StringWriter w = (StringWriter) writer;
118 StringBuffer buffer = w.getBuffer();
119 // FIXME: If we change the encoding in XMLRenderer, we should change this too !
120 InputStream xml = new ByteArrayInputStream(buffer.toString().getBytes(this.encoding));
121 Document doc = this.getDocument(xml);
122 this.transform(doc);
123 } else {
124 // Should not happen !
125 new RuntimeException("Wrong writer").printStackTrace();
126 }
127
128 }
129
130 private void transform(Document doc) {
131 DOMSource source = new DOMSource(doc);
132 this.setWriter(new StringWriter());
133 StreamResult result = new StreamResult(this.outputWriter);
134 try {
135 transformer.transform(source, result);
136 } catch (TransformerException e) {
137 e.printStackTrace();
138 }
139 }
140
141 private Document getDocument(InputStream xml) {
142 try {
143 DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
144 return parser.parse(xml);
145 } catch (ParserConfigurationException e) {
146 e.printStackTrace();
147 } catch (SAXException e) {
148 e.printStackTrace();
149 } catch (IOException e) {
150 e.printStackTrace();
151 }
152 return null;
153 }
154 }
|