View Javadoc

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