HTMLRenderer.java
001 /**
002  * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
003  */
004 package net.sourceforge.pmd.renderers;
005 
006 import java.io.IOException;
007 import java.io.Writer;
008 import java.util.Iterator;
009 import java.util.List;
010 import java.util.Properties;
011 
012 import net.sourceforge.pmd.PMD;
013 import net.sourceforge.pmd.Report;
014 import net.sourceforge.pmd.RuleViolation;
015 import net.sourceforge.pmd.util.StringUtil;
016 
017 /**
018  * Renderer to basic HTML format.
019  */
020 public class HTMLRenderer extends AbstractIncrementingRenderer {
021 
022     public static final String NAME = "html";
023 
024     public static final String LINK_PREFIX = "linkPrefix";
025     public static final String LINE_PREFIX = "linePrefix";
026 
027     private final String linkPrefix;
028     private final String linePrefix;
029 
030     private int violationCount = 1;
031     boolean colorize = true;
032 
033     public HTMLRenderer(Properties properties) {
034   super(NAME, "HTML format.", properties);
035 
036   this.linkPrefix = properties.getProperty(LINK_PREFIX);
037   this.linePrefix = properties.getProperty(LINE_PREFIX);
038     }
039 
040     /**
041      * Write the body of the main body of the HTML content.
042      *
043      @param writer
044      @param report
045      @throws IOException
046      */
047     public void renderBody(Writer writer, Report reportthrows IOException {
048   writer.write("<center><h3>PMD report</h3></center>");
049   writer.write("<center><h3>Problems found</h3></center>");
050   writer.write("<table align=\"center\" cellspacing=\"0\" cellpadding=\"3\"><tr>" + PMD.EOL
051     "<th>#</th><th>File</th><th>Line</th><th>Problem</th></tr>" + PMD.EOL);
052   setWriter(writer);
053   renderFileReport(report);
054   writer.write("</table>");
055   glomProcessingErrors(writer, errors);
056   if (showSuppressedViolations) {
057       glomSuppressions(writer, suppressed);
058   }
059     }
060 
061     /**
062      * {@inheritDoc}
063      */
064     @Override
065     public void start() throws IOException {
066   Writer writer = getWriter();
067   writer.write("<html><head><title>PMD</title></head><body>" + PMD.EOL);
068   writer.write("<center><h3>PMD report</h3></center>");
069   writer.write("<center><h3>Problems found</h3></center>");
070   writer.write("<table align=\"center\" cellspacing=\"0\" cellpadding=\"3\"><tr>" + PMD.EOL
071     "<th>#</th><th>File</th><th>Line</th><th>Problem</th></tr>" + PMD.EOL);
072     }
073 
074     /**
075      * {@inheritDoc}
076      */
077     @Override
078     public void renderFileViolations(Iterator<RuleViolation> violationsthrows IOException {
079   Writer writer = getWriter();
080   glomRuleViolations(writer, violations);
081     }
082 
083     /**
084      * {@inheritDoc}
085      */
086     @Override
087     public void end() throws IOException {
088   Writer writer = getWriter();
089   writer.write("</table>");
090   glomProcessingErrors(writer, errors);
091   if (showSuppressedViolations) {
092       glomSuppressions(writer, suppressed);
093   }
094   writer.write("</body></html>" + PMD.EOL);
095     }
096 
097     private void glomRuleViolations(Writer writer, Iterator<RuleViolation> violationsthrows IOException {
098   StringBuffer buf = new StringBuffer(500);
099   while (violations.hasNext()) {
100       RuleViolation rv = violations.next();
101       buf.setLength(0);
102       buf.append("<tr");
103       if (colorize) {
104     buf.append(" bgcolor=\"lightgrey\"");
105       }
106       colorize = !colorize;
107       buf.append("> " + PMD.EOL);
108       buf.append("<td align=\"center\">" + violationCount + "</td>" + PMD.EOL);
109       buf.append("<td width=\"*%\">"
110         + maybeWrap(rv.getFilename(), linePrefix == null "" : linePrefix
111           + Integer.toString(rv.getBeginLine())) "</td>" + PMD.EOL);
112       buf.append("<td align=\"center\" width=\"5%\">" + Integer.toString(rv.getBeginLine()) "</td>" + PMD.EOL);
113 
114       String d = StringUtil.htmlEncode(rv.getDescription());
115 
116       if (rv.getRule().getExternalInfoUrl() != null && rv.getRule().getExternalInfoUrl().length() != 0) {
117     d = "<a href=\"" + rv.getRule().getExternalInfoUrl() "\">" + d + "</a>";
118       }
119       buf.append("<td width=\"*\">" + d + "</td>" + PMD.EOL);
120       buf.append("</tr>" + PMD.EOL);
121       writer.write(buf.toString());
122       violationCount++;
123   }
124     }
125 
126     private void glomProcessingErrors(Writer writer, List<Report.ProcessingError> errorsthrows IOException {
127   if (!errors.isEmpty()) {
128       writer.write("<hr/>");
129       writer.write("<center><h3>Processing errors</h3></center>");
130       writer.write("<table align=\"center\" cellspacing=\"0\" cellpadding=\"3\"><tr>" + PMD.EOL
131         "<th>File</th><th>Problem</th></tr>" + PMD.EOL);
132 
133       StringBuffer buf = new StringBuffer(500);
134       boolean colorize = true;
135       for (Report.ProcessingError pe : errors) {
136     buf.setLength(0);
137     buf.append("<tr");
138     if (colorize) {
139         buf.append(" bgcolor=\"lightgrey\"");
140     }
141     colorize = !colorize;
142     buf.append("> " + PMD.EOL);
143     buf.append("<td>" + pe.getFile() "</td>" + PMD.EOL);
144     buf.append("<td>" + pe.getMsg() "</td>" + PMD.EOL);
145     buf.append("</tr>" + PMD.EOL);
146     writer.write(buf.toString());
147 
148       }
149       writer.write("</table>");
150   }
151     }
152 
153     private void glomSuppressions(Writer writer, List<Report.SuppressedViolation> suppressedthrows IOException {
154   if (!suppressed.isEmpty()) {
155       writer.write("<hr/>");
156       writer.write("<center><h3>Suppressed warnings</h3></center>");
157       writer.write("<table align=\"center\" cellspacing=\"0\" cellpadding=\"3\"><tr>" + PMD.EOL
158         "<th>File</th><th>Line</th><th>Rule</th><th>NOPMD or Annotation</th><th>Reason</th></tr>"
159         + PMD.EOL);
160 
161       StringBuffer buf = new StringBuffer(500);
162       boolean colorize = true;
163       for (Report.SuppressedViolation sv : suppressed) {
164     buf.setLength(0);
165     buf.append("<tr");
166     if (colorize) {
167         buf.append(" bgcolor=\"lightgrey\"");
168     }
169     colorize = !colorize;
170     buf.append("> " + PMD.EOL);
171     buf.append("<td align=\"left\">" + sv.getRuleViolation().getFilename() "</td>" + PMD.EOL);
172     buf.append("<td align=\"center\">" + sv.getRuleViolation().getBeginLine() "</td>" + PMD.EOL);
173     buf.append("<td align=\"center\">" + sv.getRuleViolation().getRule().getName() "</td>" + PMD.EOL);
174     buf.append("<td align=\"center\">" (sv.suppressedByNOPMD() "NOPMD" "Annotation""</td>"
175       + PMD.EOL);
176     buf.append("<td align=\"center\">" (sv.getUserMessage() == null "" : sv.getUserMessage()) "</td>"
177       + PMD.EOL);
178     buf.append("</tr>" + PMD.EOL);
179     writer.write(buf.toString());
180       }
181       writer.write("</table>");
182   }
183     }
184 
185     private String maybeWrap(String filename, String line) {
186   if (linkPrefix == null) {
187       return filename;
188   }
189   String newFileName = filename;
190   int index = filename.lastIndexOf('.');
191   if (index >= 0) {
192       newFileName = filename.substring(0, index).replace('\\''/');
193   }
194   return "<a href=\"" + linkPrefix + newFileName + ".html#" + line + "\">" + newFileName + "</a>";
195     }
196 }