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 }