View Javadoc

    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.File;
    8   import java.io.FileInputStream;
    9   import java.io.FileNotFoundException;
    10  import java.io.IOException;
    11  import java.io.InputStream;
    12  import java.io.StringReader;
    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 net.sourceforge.pmd.lang.rule.properties.StringProperty;
    28
    29  import org.w3c.dom.Document;
    30  import org.xml.sax.InputSource;
    31  import org.xml.sax.SAXException;
    32
    33  /**
    34   * Renderer to XML format with a XSL Transformation applied.
    35   *
    36   * @author Romain Pelisse, belaran@gmail.com
    37   */
    38  public class XSLTRenderer extends XMLRenderer {
    39
    40      public static final String NAME = "xslt";
    41
    42      public static final StringProperty XSLT_FILENAME = new StringProperty("xsltFilename", "The XSLT file name.", null, 0);
    43
    44      private Transformer transformer;
    45      private String xsltFilename = "/pmd-nicerhtml.xsl";
    46      private Writer outputWriter;
    47
    48      public XSLTRenderer() {
    49  	super();
    50  	setName(NAME);
    51  	setDescription("XML with a XSL Transformation applied.");
    52  	definePropertyDescriptor(XSLT_FILENAME);
    53      }
    54
    55      public String defaultFileExtension() { return "xsl"; }
    56
    57      /**
    58       * {@inheritDoc}
    59       */
    60      @Override
    61      public void start() throws IOException {
    62  	String xsltFilenameProperty = getProperty(XSLT_FILENAME);
    63  	if (xsltFilenameProperty != null) {
    64  	    File file = new File(xsltFilenameProperty);
    65  	    if (file.exists() && file.canRead()) {
    66  		this.xsltFilename = xsltFilenameProperty;
    67  	    }
    68  	}
    69
    70  	// We keep the inital writer to put the final html output
    71  	this.outputWriter = getWriter();
    72  	// We use a new one to store the XML...
    73  	Writer w = new StringWriter();
    74  	setWriter(w);
    75  	// If don't find the xsl no need to bother doing the all report,
    76  	// so we check this here...
    77  	InputStream xslt = null;
    78  	File file = new File(this.xsltFilename);
    79  	if (file.exists() && file.canRead()) {
    80  	    xslt = new FileInputStream(file);
    81  	} else {
    82  	    xslt = this.getClass().getResourceAsStream(this.xsltFilename);
    83  	}
    84  	if (xslt == null) {
    85  	    throw new FileNotFoundException("Can't file XSLT sheet :" + this.xsltFilename);
    86  	}
    87  	this.prepareTransformer(xslt);
    88  	// Now we build the XML file
    89  	super.start();
    90      }
    91
    92      /**
    93       * Prepare the transformer, doing the proper "building"...
    94       *
    95       * @param xslt The stylesheet provided as an InputStream
    96       */
    97      private void prepareTransformer(InputStream xslt) {
    98  	if (xslt != null) {
    99  	    try {
    100 		//Get a TransformerFactory object
    101 		TransformerFactory factory = TransformerFactory.newInstance();
    102 		StreamSource src = new StreamSource(xslt);
    103 		//Get an XSL Transformer object
    104 		this.transformer = factory.newTransformer(src);
    105 	    } catch (TransformerConfigurationException e) {
    106 		e.printStackTrace();
    107 	    }
    108 	}
    109     }
    110
    111     /**
    112      * {@inheritDoc}
    113      */
    114     @Override
    115     public void end() throws IOException {
    116 	// First we finish the XML report
    117 	super.end();
    118 	// Now we transform it using XSLT
    119 	Writer writer = super.getWriter();
    120 	if (writer instanceof StringWriter) {
    121 	    StringWriter w = (StringWriter) writer;
    122 	    StringBuffer buffer = w.getBuffer();
    123 	    Document doc = this.getDocument(buffer.toString());
    124 	    this.transform(doc);
    125 	} else {
    126 	    // Should not happen !
    127 	    throw new RuntimeException("Wrong writer");
    128 	}
    129
    130     }
    131
    132     private void transform(Document doc) {
    133 	DOMSource source = new DOMSource(doc);
    134 	this.setWriter(new StringWriter());
    135 	StreamResult result = new StreamResult(this.outputWriter);
    136 	try {
    137 	    transformer.transform(source, result);
    138 	} catch (TransformerException e) {
    139 	    e.printStackTrace();
    140 	}
    141     }
    142
    143     private Document getDocument(String xml) {
    144 	try {
    145 	    DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    146 	    return parser.parse(new InputSource(new StringReader(xml)));
    147 	} catch (ParserConfigurationException e) {
    148 	    e.printStackTrace();
    149 	} catch (SAXException e) {
    150 	    e.printStackTrace();
    151 	} catch (IOException e) {
    152 	    e.printStackTrace();
    153 	}
    154 	return null;
    155     }
    156 }