1 /***
2 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3 */
4 package net.sourceforge.pmd.renderers;
5
6 import net.sourceforge.pmd.PMD;
7 import net.sourceforge.pmd.Report;
8 import net.sourceforge.pmd.IRuleViolation;
9 import net.sourceforge.pmd.util.StringUtil;
10
11 import java.util.Iterator;
12
13 public class HTMLRenderer extends AbstractRenderer implements Renderer {
14
15 private String linkPrefix;
16
17 public HTMLRenderer(String linkPrefix) {
18 this.linkPrefix = linkPrefix;
19 }
20
21 public HTMLRenderer() {
22 this(null);
23 }
24
25 public String render(Report report) {
26 StringBuffer buf = new StringBuffer("<html><head><title>PMD</title></head><body>" + PMD.EOL);
27 buf.append(renderBody(report));
28 buf.append("</body></html>");
29 return buf.toString();
30 }
31
32 public String renderBody(Report report) {
33 StringBuffer buf = glomIRuleViolations(report);
34 glomProcessingErrors(report, buf);
35 if (showSuppressedViolations) {
36 glomSuppressions(report, buf);
37 }
38 return buf.toString();
39 }
40
41 private StringBuffer glomIRuleViolations(Report report) {
42 boolean colorize = true;
43 int violationCount = 1;
44 StringBuffer buf = new StringBuffer();
45 buf.append("<center><h3>PMD report</h3></center>");
46 buf.append("<center><h3>Problems found</h3></center>");
47 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);
48 for (Iterator i = report.iterator(); i.hasNext();) {
49 IRuleViolation rv = (IRuleViolation) i.next();
50 buf.append("<tr");
51 if (colorize) {
52 buf.append(" bgcolor=\"lightgrey\"");
53 }
54 colorize = !colorize;
55 buf.append("> " + PMD.EOL);
56 buf.append("<td align=\"center\">" + violationCount + "</td>" + PMD.EOL);
57 buf.append("<td width=\"*%\">" + maybeWrap(rv.getFilename(), Integer.toString(rv.getBeginLine())) + "</td>" + PMD.EOL);
58 buf.append("<td align=\"center\" width=\"5%\">" + Integer.toString(rv.getBeginLine()) + "</td>" + PMD.EOL);
59
60 String d = rv.getDescription();
61 d = StringUtil.replaceString(d, '&', "&");
62 d = StringUtil.replaceString(d, '<', "<");
63 d = StringUtil.replaceString(d, '>', ">");
64 if (rv.getRule().getExternalInfoUrl() != null && rv.getRule().getExternalInfoUrl().length() != 0) {
65 d = "<a href=\"" + rv.getRule().getExternalInfoUrl() + "\">" + d + "</a>";
66 }
67 buf.append("<td width=\"*\">" + d + "</td>" + PMD.EOL);
68 buf.append("</tr>" + PMD.EOL);
69 violationCount++;
70 }
71 if (violationCount > 0) {
72 buf.append("</table>");
73 }
74 return buf;
75 }
76
77 private void glomProcessingErrors(Report report, StringBuffer buf) {
78 boolean colorize = true;
79 int violationCount;
80
81 if (report.errors().hasNext()) {
82 buf.append("<hr/>");
83 buf.append("<center><h3>Processing errors</h3></center>");
84 buf.append("<table align=\"center\" cellspacing=\"0\" cellpadding=\"3\"><tr>" + PMD.EOL + "<th>File</th><th>Problem</th></tr>" + PMD.EOL);
85 }
86 violationCount = 0;
87 for (Iterator i = report.errors(); i.hasNext();) {
88 Report.ProcessingError pe = (Report.ProcessingError) i.next();
89 buf.append("<tr");
90 if (colorize) {
91 buf.append(" bgcolor=\"lightgrey\"");
92 }
93 colorize = !colorize;
94 buf.append("> " + PMD.EOL);
95 buf.append("<td>" + pe.getFile() + "</td>" + PMD.EOL);
96 buf.append("<td>" + pe.getMsg() + "</td>" + PMD.EOL);
97 buf.append("</tr>" + PMD.EOL);
98 violationCount++;
99 }
100 if (violationCount > 0) {
101 buf.append("</table>");
102 }
103 }
104
105 private void glomSuppressions(Report report, StringBuffer buf) {
106 boolean colorize = true;
107 if (!report.getSuppressedRuleViolations().isEmpty()) {
108 buf.append("<hr/>");
109 buf.append("<center><h3>Suppressed warnings</h3></center>");
110 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></tr>" + PMD.EOL);
111 }
112 for (Iterator i = report.getSuppressedRuleViolations().iterator(); i.hasNext();) {
113 Report.SuppressedViolation sv = (Report.SuppressedViolation) i.next();
114 buf.append("<tr");
115 if (colorize) {
116 buf.append(" bgcolor=\"lightgrey\"");
117 }
118 colorize = !colorize;
119 buf.append("> " + PMD.EOL);
120 buf.append("<td align=\"left\">" + sv.getRuleViolation().getFilename() + "</td>" + PMD.EOL);
121 buf.append("<td align=\"center\">" + sv.getRuleViolation().getBeginLine() + "</td>" + PMD.EOL);
122 buf.append("<td align=\"center\">" + sv.getRuleViolation().getRule().getName() + "</td>" + PMD.EOL);
123 buf.append("<td align=\"center\">" + (sv.suppressedByNOPMD() ? "NOPMD" : "Annotation") + "</td>" + PMD.EOL);
124 buf.append("</tr>" + PMD.EOL);
125 }
126 if (!report.getSuppressedRuleViolations().isEmpty()) {
127 buf.append("</table>");
128 }
129 }
130
131 private String maybeWrap(String filename, String line) {
132 if (linkPrefix == null) {
133 return filename;
134 }
135 String newFileName = filename.substring(0, filename.lastIndexOf("."));
136 return "<a href=\"" + linkPrefix + newFileName + ".html#" + line + "\">" + newFileName + "</a>";
137 }
138 }