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