Renderers use less memory when generating reports.

The previous implementation built the entire report as a single String. Testing
all rules on the JDK generates a report larger than 100M and that created a
spike in memory usage at the very end.


git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/trunk@4814 51baf565-9d33-0410-a72c-fc3788e3496d
This commit is contained in:
Xavier Le Vourch
2006-11-19 01:54:09 +00:00
parent 22bca13115
commit 4bc641bf51
16 changed files with 175 additions and 92 deletions

View File

@ -42,6 +42,7 @@ Better 'create rule XML' panel in Designer.
use of entrySet to iterate over Maps.
1.6 added as a valid option for targetjdk.
PMD now allows rules to use Type Resolution. This was referenced in patch 1257259.
Renderers use less memory when generating reports.
Performance Refactoring, XPath rules re-written as Java:
AssignmentInOperand
AvoidDollarSigns

View File

@ -17,6 +17,7 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
@ -274,7 +275,10 @@ public class PMD {
try {
Renderer r = opts.createRenderer();
System.out.println(r.render(ctx.getReport()));
OutputStreamWriter w = new OutputStreamWriter(System.out);
r.render(w, ctx.getReport());
w.flush();
System.out.println();
} catch (Exception e) {
System.out.println(e.getMessage());
System.out.println(opts.usage());

View File

@ -127,8 +127,8 @@ public class Formatter {
}
private void outputReportTo(Writer writer, Report report, boolean consoleRenderer) throws IOException {
String renderedReport = getRenderer(consoleRenderer).render(report) + PMD.EOL;
writer.write(renderedReport, 0, renderedReport.length());
getRenderer(consoleRenderer).render(writer, report);
writer.write(PMD.EOL);
writer.close();
}

View File

@ -1,5 +1,8 @@
package net.sourceforge.pmd.renderers;
import java.io.IOException;
import java.io.StringWriter;
import net.sourceforge.pmd.Report;
public abstract class AbstractRenderer implements Renderer {
@ -10,5 +13,14 @@ public abstract class AbstractRenderer implements Renderer {
this.showSuppressedViolations = show;
}
public abstract String render(Report report);
public String render(Report report) {
StringWriter w = new StringWriter();
try {
render(w, report);
} catch (IOException e) {
throw new Error("StringWriter doesn't throw IOException", e);
}
return w.toString();
}
}

View File

@ -8,11 +8,13 @@ import net.sourceforge.pmd.PMD;
import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.util.StringUtil;
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
public class CSVRenderer extends AbstractRenderer implements Renderer {
public class CSVRenderer extends AbstractRenderer {
public String render(Report report) {
public void render(Writer writer, Report report) throws IOException {
StringBuffer buf = new StringBuffer(300);
quoteAndCommify(buf, "Problem");
quoteAndCommify(buf, "Package");
@ -23,15 +25,16 @@ public class CSVRenderer extends AbstractRenderer implements Renderer {
quoteAndCommify(buf, "Rule set");
quote(buf, "Rule");
buf.append(PMD.EOL);
writer.write(buf.toString());
addViolations(report, buf);
return buf.toString();
addViolations(writer, report, buf);
}
private void addViolations(Report report, StringBuffer buf) {
private void addViolations(Writer writer, Report report, StringBuffer buf) throws IOException {
int violationCount = 1;
IRuleViolation rv;
for (Iterator i = report.iterator(); i.hasNext();) {
buf.setLength(0);
rv = (IRuleViolation) i.next();
quoteAndCommify(buf, Integer.toString(violationCount));
quoteAndCommify(buf, rv.getPackageName());
@ -42,6 +45,7 @@ public class CSVRenderer extends AbstractRenderer implements Renderer {
quoteAndCommify(buf, rv.getRule().getRuleSetName());
quote(buf, rv.getRule().getName());
buf.append(PMD.EOL);
writer.write(buf.toString());
violationCount++;
}
}

View File

@ -6,20 +6,23 @@ package net.sourceforge.pmd.renderers;
import net.sourceforge.pmd.IRuleViolation;
import net.sourceforge.pmd.Report;
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
public class EmacsRenderer extends AbstractRenderer implements Renderer {
public class EmacsRenderer extends AbstractRenderer {
protected static final String EOL = System.getProperty("line.separator", "\n");
public String render(Report report) {
public void render(Writer writer, Report report) throws IOException {
StringBuffer buf = new StringBuffer();
for (Iterator i = report.iterator(); i.hasNext();) {
IRuleViolation rv = (IRuleViolation) i.next();
buf.setLength(0);
buf.append(EOL).append(rv.getFilename());
buf.append(':').append(Integer.toString(rv.getBeginLine()));
buf.append(": ").append(rv.getDescription());
writer.write(buf.toString());
}
return buf.toString();
}
}

View File

@ -8,9 +8,11 @@ import net.sourceforge.pmd.PMD;
import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.util.StringUtil;
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
public class HTMLRenderer extends AbstractRenderer implements Renderer {
public class HTMLRenderer extends AbstractRenderer {
private String linkPrefix;
private String linePrefix;
@ -25,31 +27,30 @@ public class HTMLRenderer extends AbstractRenderer implements Renderer {
this(null, null);
}
public String render(Report report) {
StringBuffer buf = new StringBuffer("<html><head><title>PMD</title></head><body>" + PMD.EOL);
buf.append(renderBody(report));
buf.append("</body></html>");
return buf.toString();
public void render(Writer writer, Report report) throws IOException {
writer.write("<html><head><title>PMD</title></head><body>" + PMD.EOL);
renderBody(writer, report);
writer.write("</body></html>");
}
public String renderBody(Report report) {
StringBuffer buf = glomIRuleViolations(report);
glomProcessingErrors(report, buf);
public void renderBody(Writer writer, Report report) throws IOException {
glomIRuleViolations(writer, report);
glomProcessingErrors(writer, report);
if (showSuppressedViolations) {
glomSuppressions(report, buf);
glomSuppressions(writer, report);
}
return buf.toString();
}
private StringBuffer glomIRuleViolations(Report report) {
private void glomIRuleViolations(Writer writer, Report report) throws IOException {
boolean colorize = true;
int violationCount = 1;
StringBuffer buf = new StringBuffer(500);
buf.append("<center><h3>PMD report</h3></center>");
buf.append("<center><h3>Problems found</h3></center>");
buf.append("<table align=\"center\" cellspacing=\"0\" cellpadding=\"3\"><tr>" + PMD.EOL + "<th>#</th><th>File</th><th>Line</th><th>Problem</th></tr>" + PMD.EOL);
writer.write("<center><h3>PMD report</h3></center>");
writer.write("<center><h3>Problems found</h3></center>");
writer.write("<table align=\"center\" cellspacing=\"0\" cellpadding=\"3\"><tr>" + PMD.EOL + "<th>#</th><th>File</th><th>Line</th><th>Problem</th></tr>" + PMD.EOL);
for (Iterator i = report.iterator(); i.hasNext();) {
IRuleViolation rv = (IRuleViolation) i.next();
buf.setLength(0);
buf.append("<tr");
if (colorize) {
buf.append(" bgcolor=\"lightgrey\"");
@ -67,26 +68,28 @@ public class HTMLRenderer extends AbstractRenderer implements Renderer {
}
buf.append("<td width=\"*\">" + d + "</td>" + PMD.EOL);
buf.append("</tr>" + PMD.EOL);
writer.write(buf.toString());
violationCount++;
}
if (violationCount > 0) {
buf.append("</table>");
writer.write("</table>");
}
return buf;
}
private void glomProcessingErrors(Report report, StringBuffer buf) {
private void glomProcessingErrors(Writer writer, Report report) throws IOException {
boolean colorize = true;
int violationCount;
// errors
if (report.errors().hasNext()) {
buf.append("<hr/>");
buf.append("<center><h3>Processing errors</h3></center>");
buf.append("<table align=\"center\" cellspacing=\"0\" cellpadding=\"3\"><tr>" + PMD.EOL + "<th>File</th><th>Problem</th></tr>" + PMD.EOL);
writer.write("<hr/>");
writer.write("<center><h3>Processing errors</h3></center>");
writer.write("<table align=\"center\" cellspacing=\"0\" cellpadding=\"3\"><tr>" + PMD.EOL + "<th>File</th><th>Problem</th></tr>" + PMD.EOL);
}
violationCount = 0;
StringBuffer buf = new StringBuffer(500);
for (Iterator i = report.errors(); i.hasNext();) {
Report.ProcessingError pe = (Report.ProcessingError) i.next();
buf.setLength(0);
buf.append("<tr");
if (colorize) {
buf.append(" bgcolor=\"lightgrey\"");
@ -96,24 +99,27 @@ public class HTMLRenderer extends AbstractRenderer implements Renderer {
buf.append("<td>" + pe.getFile() + "</td>" + PMD.EOL);
buf.append("<td>" + pe.getMsg() + "</td>" + PMD.EOL);
buf.append("</tr>" + PMD.EOL);
writer.write(buf.toString());
violationCount++;
}
if (violationCount > 0) {
buf.append("</table>");
writer.write("</table>");
}
}
private void glomSuppressions(Report report, StringBuffer buf) {
private void glomSuppressions(Writer writer, Report report) throws IOException {
boolean colorize = true;
boolean hasSuppressedViolations = !report.getSuppressedRuleViolations().isEmpty();
if (hasSuppressedViolations) {
buf.append("<hr/>");
buf.append("<center><h3>Suppressed warnings</h3></center>");
buf.append("<table align=\"center\" cellspacing=\"0\" cellpadding=\"3\"><tr>" + PMD.EOL + "<th>File</th><th>Line</th><th>Rule</th><th>NOPMD or Annotation</th><th>Reason</th></tr>" + PMD.EOL);
writer.write("<hr/>");
writer.write("<center><h3>Suppressed warnings</h3></center>");
writer.write("<table align=\"center\" cellspacing=\"0\" cellpadding=\"3\"><tr>" + PMD.EOL + "<th>File</th><th>Line</th><th>Rule</th><th>NOPMD or Annotation</th><th>Reason</th></tr>" + PMD.EOL);
}
Report.SuppressedViolation sv;
StringBuffer buf = new StringBuffer(500);
for (Iterator i = report.getSuppressedRuleViolations().iterator(); i.hasNext();) {
sv = (Report.SuppressedViolation) i.next();
buf.setLength(0);
buf.append("<tr");
if (colorize) {
buf.append(" bgcolor=\"lightgrey\"");
@ -126,9 +132,10 @@ public class HTMLRenderer extends AbstractRenderer implements Renderer {
buf.append("<td align=\"center\">" + (sv.suppressedByNOPMD() ? "NOPMD" : "Annotation") + "</td>" + PMD.EOL);
buf.append("<td align=\"center\">" + (sv.getUserMessage() == null ? "" : sv.getUserMessage()) + "</td>" + PMD.EOL);
buf.append("</tr>" + PMD.EOL);
writer.write(buf.toString());
}
if (hasSuppressedViolations) {
buf.append("</table>");
writer.write("</table>");
}
}

View File

@ -7,12 +7,14 @@ import net.sourceforge.pmd.IRuleViolation;
import net.sourceforge.pmd.PMD;
import net.sourceforge.pmd.Report;
import java.io.IOException;
import java.io.Writer;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.StringTokenizer;
public class IDEAJRenderer extends AbstractRenderer implements Renderer {
public class IDEAJRenderer extends AbstractRenderer {
private static final String FILE_SEPARATOR = System.getProperty("file.separator");
private static final String PATH_SEPARATOR = System.getProperty("path.separator");
@ -44,38 +46,41 @@ public class IDEAJRenderer extends AbstractRenderer implements Renderer {
this.args = args;
}
public String render(Report report) {
public void render(Writer writer, Report report) throws IOException {
if (args[4].equals(".method")) {
// working on a directory tree
String sourcePath = args[3];
return render(report, sourcePath);
render(writer, report, sourcePath);
return;
}
// working on one file
String classAndMethodName = args[4];
String singleFileName = args[5];
return render(report, classAndMethodName, singleFileName);
render(writer, report, classAndMethodName, singleFileName);
}
private String render(Report report, String sourcePathString) {
private void render(Writer writer, Report report, String sourcePathString) throws IOException {
SourcePath sourcePath = new SourcePath(sourcePathString);
StringBuffer buf = new StringBuffer();
for (Iterator i = report.iterator(); i.hasNext();) {
buf.setLength(0);
IRuleViolation rv = (IRuleViolation) i.next();
buf.append(rv.getDescription() + PMD.EOL);
buf.append(" at ").append(getFullyQualifiedClassName(rv.getFilename(), sourcePath)).append(".method(");
buf.append(getSimpleFileName(rv.getFilename())).append(':').append(rv.getBeginLine()).append(')').append(PMD.EOL);
writer.write(buf.toString());
}
return buf.toString();
}
private String render(Report report, String classAndMethod, String file) {
private void render(Writer writer, Report report, String classAndMethod, String file) throws IOException {
StringBuffer buf = new StringBuffer();
for (Iterator i = report.iterator(); i.hasNext();) {
buf.setLength(0);
IRuleViolation rv = (IRuleViolation) i.next();
buf.append(rv.getDescription()).append(PMD.EOL);
buf.append(" at ").append(classAndMethod).append('(').append(file).append(':').append(rv.getBeginLine()).append(')').append(PMD.EOL);
writer.write(buf.toString());
}
return buf.toString();
}
private String getFullyQualifiedClassName(String in, SourcePath sourcePath) {

View File

@ -11,6 +11,7 @@ import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
import java.util.Map;
@ -44,7 +45,7 @@ import java.util.Map;
* colorization is atm only supported under *nix terminals accepting ansi escape
* sequences, such as xterm, rxvt et cetera.</p>
*/
public class PapariTextRenderer extends AbstractRenderer implements Renderer {
public class PapariTextRenderer extends AbstractRenderer {
/**
* Directory from where java was invoked.
*/
@ -78,7 +79,7 @@ public class PapariTextRenderer extends AbstractRenderer implements Renderer {
}
}
public String render(Report report) {
public void render(Writer writer, Report report) throws IOException {
StringBuffer buf = new StringBuffer(PMD.EOL);
initializeColorsIfSupported();
String lastFile = null;
@ -86,6 +87,7 @@ public class PapariTextRenderer extends AbstractRenderer implements Renderer {
int numberOfWarnings = 0;
for (Iterator i = report.iterator(); i.hasNext();) {
buf.setLength(0);
numberOfWarnings++;
IRuleViolation rv = (IRuleViolation) i.next();
if (!rv.getFilename().equals(lastFile)) {
@ -96,17 +98,21 @@ public class PapariTextRenderer extends AbstractRenderer implements Renderer {
buf.append(this.green + " rule: " + this.colorReset + rv.getRule().getName() + PMD.EOL);
buf.append(this.green + " msg: " + this.colorReset + rv.getDescription() + PMD.EOL);
buf.append(this.green + " code: " + this.colorReset + this.getLine(lastFile, rv.getBeginLine()) + PMD.EOL + PMD.EOL);
writer.write(buf.toString());
}
buf.append(PMD.EOL + PMD.EOL);
buf.append("Summary:" + PMD.EOL + PMD.EOL);
writer.write(PMD.EOL + PMD.EOL);
writer.write("Summary:" + PMD.EOL + PMD.EOL);
Map summary = report.getCountSummary();
for (Iterator i = summary.entrySet().iterator(); i.hasNext();) {
buf.setLength(0);
Map.Entry entry = (Map.Entry) i.next();
String key = (String) entry.getKey();
buf.append(key + " : " + ((Integer) entry.getValue()).intValue() + PMD.EOL);
writer.write(buf.toString());
}
for (Iterator i = report.errors(); i.hasNext();) {
buf.setLength(0);
numberOfErrors++;
Report.ProcessingError error = (Report.ProcessingError) i.next();
if (error.getFile().equals(lastFile)) {
@ -114,15 +120,14 @@ public class PapariTextRenderer extends AbstractRenderer implements Renderer {
buf.append(this.redBold + "*" + this.colorReset + " file: " + this.whiteBold + this.getRelativePath(lastFile) + this.colorReset + PMD.EOL);
}
buf.append(this.green + " err: " + this.cyan + error.getMsg() + this.colorReset + PMD.EOL + PMD.EOL);
writer.write(buf.toString());
}
// adding error message count, if any
if (numberOfErrors > 0) {
buf.append(this.redBold + "*" + this.colorReset + " errors: " + this.whiteBold + numberOfWarnings + this.colorReset + PMD.EOL);
writer.write(this.redBold + "*" + this.colorReset + " errors: " + this.whiteBold + numberOfWarnings + this.colorReset + PMD.EOL);
}
buf.append(this.yellowBold + "*" + this.colorReset + " warnings: " + this.whiteBold + numberOfWarnings + this.colorReset + PMD.EOL);
return buf.toString();
writer.write(this.yellowBold + "*" + this.colorReset + " warnings: " + this.whiteBold + numberOfWarnings + this.colorReset + PMD.EOL);
}
/**

View File

@ -3,10 +3,23 @@
*/
package net.sourceforge.pmd.renderers;
import java.io.IOException;
import java.io.Writer;
import net.sourceforge.pmd.Report;
public interface Renderer {
void showSuppressedViolations(boolean show);
/**
*
* @deprecated This method consumes too much memory.
* Use the render method with the Writer argument instead.
*
*/
String render(Report report);
void render(Writer writer, Report report) throws IOException;
}

View File

@ -3,10 +3,12 @@ package net.sourceforge.pmd.renderers;
import net.sourceforge.pmd.PMD;
import net.sourceforge.pmd.Report;
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
import java.util.Map;
public class SummaryHTMLRenderer extends AbstractRenderer implements Renderer {
public class SummaryHTMLRenderer extends AbstractRenderer {
private String linePrefix,linkPrefix;
public SummaryHTMLRenderer(String linkPrefix, String linePrefix) {
this.linePrefix = linePrefix;
@ -17,32 +19,33 @@ public class SummaryHTMLRenderer extends AbstractRenderer implements Renderer {
this(null,null);
}
public String render(Report report) {
StringBuffer buf = new StringBuffer("<html><head><title>PMD</title></head><body>" + PMD.EOL);
buf.append(renderSummary(report));
buf.append("<h2><center>Detail</h2></center>");
buf.append("<table align=\"center\" cellspacing=\"0\" cellpadding=\"3\"><tr>" + PMD.EOL + "<th>#</th><th>File</th><th>Line</th><th>Problem</th></tr>" + PMD.EOL);
buf.append(new HTMLRenderer(linkPrefix,linePrefix).renderBody(report));
buf.append("</table></body></html>");
return buf.toString();
public void render(Writer writer, Report report) throws IOException {
writer.write("<html><head><title>PMD</title></head><body>" + PMD.EOL);
renderSummary(writer, report);
writer.write("<h2><center>Detail</h2></center>");
writer.write("<table align=\"center\" cellspacing=\"0\" cellpadding=\"3\"><tr>" + PMD.EOL + "<th>#</th><th>File</th><th>Line</th><th>Problem</th></tr>" + PMD.EOL);
new HTMLRenderer(linkPrefix,linePrefix).renderBody(writer, report);
writer.write("</table></body></html>");
}
public String renderSummary(Report report) {
public void renderSummary(Writer writer, Report report) throws IOException {
StringBuffer buf = new StringBuffer();
buf.append("<h2><center>Summary</h2></center>");
buf.append("<table align=\"center\" cellspacing=\"0\" cellpadding=\"3\">");
buf.append("<th>Rule name</th>");
buf.append("<th>Number of violations</th>");
writer.write(buf.toString());
Map summary = report.getSummary();
for (Iterator i = summary.entrySet().iterator(); i.hasNext();) {
Map.Entry entry = (Map.Entry) i.next();
String ruleName = (String) entry.getKey();
buf.setLength(0);
buf.append("<tr>");
buf.append("<td>" + ruleName + "</td>");
buf.append("<td align=center>" + ((Integer) entry.getValue()).intValue() + "</td>");
buf.append("</tr>");
writer.write(buf.toString());
}
buf.append("</table>");
return buf.toString();
writer.write("</table>");
}
}

View File

@ -7,6 +7,8 @@ import net.sourceforge.pmd.IRuleViolation;
import net.sourceforge.pmd.PMD;
import net.sourceforge.pmd.Report;
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
/**
@ -24,8 +26,8 @@ import java.util.Iterator;
*
* @author Jeff Epstein, based upon <a href="EmacsRenderer.html">EmacsRenderer</a>, Tuesday, September 23, 2003
*/
public class TextPadRenderer extends AbstractRenderer implements Renderer {
public String render(Report report) {
public class TextPadRenderer extends AbstractRenderer {
public void render(Writer writer, Report report) throws IOException {
StringBuffer buf = new StringBuffer();
Iterator i;
try {
@ -35,6 +37,7 @@ public class TextPadRenderer extends AbstractRenderer implements Renderer {
}
while (i.hasNext()) {
IRuleViolation rv = (IRuleViolation) i.next();
buf.setLength(0);
//Filename
buf.append(PMD.EOL).append(rv.getFilename() + "(");
//Line number
@ -43,7 +46,7 @@ public class TextPadRenderer extends AbstractRenderer implements Renderer {
buf.append(rv.getRule().getName()).append("): ");
//Specific violation message
buf.append(rv.getDescription());
writer.write(buf.toString());
}
return buf.toString();
}
}

View File

@ -7,11 +7,13 @@ import net.sourceforge.pmd.IRuleViolation;
import net.sourceforge.pmd.PMD;
import net.sourceforge.pmd.Report;
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
public class TextRenderer extends AbstractRenderer implements Renderer {
public class TextRenderer extends AbstractRenderer {
public String render(Report report) {
public void render(Writer writer, Report report) throws IOException {
StringBuffer buf = new StringBuffer();
if (report.isEmpty()) {
@ -19,28 +21,33 @@ public class TextRenderer extends AbstractRenderer implements Renderer {
if (showSuppressedViolations) {
addSuppressed(report, buf);
}
return buf.toString();
writer.write(buf.toString());
return;
}
Iterator i;
for (i = report.iterator(); i.hasNext();) {
buf.setLength(0);
IRuleViolation rv = (IRuleViolation) i.next();
buf.append(PMD.EOL).append(rv.getFilename());
buf.append(':').append(Integer.toString(rv.getBeginLine()));
buf.append('\t').append(rv.getDescription());
writer.write(buf.toString());
}
for (i = report.errors(); i.hasNext();) {
buf.setLength(0);
Report.ProcessingError error = (Report.ProcessingError) i.next();
buf.append(PMD.EOL).append(error.getFile());
buf.append("\t-\t").append(error.getMsg());
writer.write(buf.toString());
}
if (showSuppressedViolations) {
buf.setLength(0);
addSuppressed(report, buf);
writer.write(buf.toString());
}
return buf.toString();
}
private void addSuppressed(Report report, StringBuffer buf) {

View File

@ -7,17 +7,19 @@ import net.sourceforge.pmd.IRuleViolation;
import net.sourceforge.pmd.PMD;
import net.sourceforge.pmd.Report;
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
/**
* @author Vladimir
* @version $Revision$ $Date$
*/
public class VBHTMLRenderer extends AbstractRenderer implements Renderer {
public class VBHTMLRenderer extends AbstractRenderer {
public String render(Report report) {
public void render(Writer writer, Report report) throws IOException {
if (report.isEmpty()) {
return "";
return;
}
StringBuffer sb = new StringBuffer(header());
@ -27,6 +29,7 @@ public class VBHTMLRenderer extends AbstractRenderer implements Renderer {
boolean colorize = false;
for (Iterator iter = report.iterator(); iter.hasNext();) {
sb.setLength(0);
IRuleViolation rv = (IRuleViolation) iter.next();
if (!rv.getFilename().equals(filename)) { // New File
if (filename != null) {
@ -50,15 +53,17 @@ public class VBHTMLRenderer extends AbstractRenderer implements Renderer {
sb.append("<td><font class=body>" + rv.getDescription() + "</font></td>");
sb.append("</tr>");
sb.append(lineSep);
writer.write(sb.toString());
}
if (filename != null) {
sb.append("</table>");
writer.write("</table>");
}
sb.append("<br>");
writer.write("<br>");
// output the problems
Iterator iter = report.errors();
if (iter.hasNext()) {
sb.setLength(0);
sb.append("<table border=\"0\" width=\"80%\">");
sb.append("<tr id=TableHeader><td><font class=title>&nbsp;Problems found</font></td></tr>");
colorize = false;
@ -72,11 +77,10 @@ public class VBHTMLRenderer extends AbstractRenderer implements Renderer {
sb.append("<td><font class=body>").append(iter.next()).append("\"</font></td></tr>");
}
sb.append("</table>");
writer.write(sb.toString());
}
sb.append(footer());
return sb.toString();
writer.write(footer());
}
private String header() {

View File

@ -8,19 +8,23 @@ import net.sourceforge.pmd.PMD;
import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.util.StringUtil;
import java.io.IOException;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
public class XMLRenderer extends AbstractRenderer implements Renderer {
public class XMLRenderer extends AbstractRenderer {
public String render(Report report) {
public void render(Writer writer, Report report) throws IOException {
StringBuffer buf = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + PMD.EOL + createVersionAttr() + createTimestampAttr() + createTimeElapsedAttr(report) + '>' + PMD.EOL);
StringBuffer buf = new StringBuffer();
writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + PMD.EOL + createVersionAttr() + createTimestampAttr() + createTimeElapsedAttr(report) + '>' + PMD.EOL);
String filename = null;
// rule violations
for (Iterator i = report.iterator(); i.hasNext();) {
buf.setLength(0);
IRuleViolation rv = (IRuleViolation) i.next();
if (!rv.getFilename().equals(filename)) { // New File
if (filename != null) {// Not first file ?
@ -50,24 +54,29 @@ public class XMLRenderer extends AbstractRenderer implements Renderer {
buf.append(PMD.EOL);
buf.append("</violation>");
buf.append(PMD.EOL);
writer.write(buf.toString());
}
if (filename != null) { // Not first file ?
buf.append("</file>").append(PMD.EOL);
writer.write("</file>");
writer.write(PMD.EOL);
}
// errors
for (Iterator i = report.errors(); i.hasNext();) {
buf.setLength(0);
Report.ProcessingError pe = (Report.ProcessingError) i.next();
buf.append("<error ").append("filename=\"");
StringUtil.appendXmlEscaped(buf, pe.getFile());
buf.append("\" msg=\"");
StringUtil.appendXmlEscaped(buf, pe.getMsg());
buf.append("\"/>").append(PMD.EOL);
writer.write(buf.toString());
}
// suppressed violations
if (showSuppressedViolations) {
for (Iterator i = report.getSuppressedRuleViolations().iterator(); i.hasNext();) {
buf.setLength(0);
Report.SuppressedViolation suppressed = (Report.SuppressedViolation) i.next();
buf.append("<suppressedviolation ").append("filename=\"");
StringUtil.appendXmlEscaped(buf, suppressed.getRuleViolation().getFilename());
@ -78,11 +87,11 @@ public class XMLRenderer extends AbstractRenderer implements Renderer {
buf.append("\" usermsg=\"");
StringUtil.appendXmlEscaped(buf, suppressed.getUserMessage());
buf.append("\"/>").append(PMD.EOL);
writer.write(buf.toString());
}
}
buf.append("</pmd>");
return buf.toString();
writer.write("</pmd>");
}
private void maybeAdd(String attr, String value, StringBuffer buf) {

View File

@ -1,15 +1,18 @@
package net.sourceforge.pmd.renderers;
import java.io.IOException;
import java.io.Writer;
import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.dfa.report.ReportHTMLPrintVisitor;
import net.sourceforge.pmd.dfa.report.ReportTree;
public class YAHTMLRenderer extends AbstractRenderer implements Renderer {
public class YAHTMLRenderer extends AbstractRenderer {
public String render(Report report) {
public void render(Writer writer, Report report) throws IOException {
ReportTree tree = report.getViolationTree();
tree.getRootNode().accept(new ReportHTMLPrintVisitor());
return "<h3 align=\"center\">The HTML files are created above the project directory.</h3>";
writer.write("<h3 align=\"center\">The HTML files are created above the project directory.</h3>");
}
}