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