1 package net.sourceforge.pmd.dfa.report;
2
3 import net.sourceforge.pmd.IRuleViolation;
4 import net.sourceforge.pmd.PMD;
5
6 import java.io.BufferedWriter;
7 import java.io.File;
8 import java.io.FileWriter;
9 import java.io.IOException;
10
11 /***
12 * @author raik
13 * <p/>
14 * * Uses the generated result tree instead of the result list. The visitor
15 * * traverses the tree and creates several html files. The "package view" file
16 * * (index.html) displays an overview of packgages, classes and the number of
17 * * rule violations they contain. All the other html files represent a class
18 * * and show detailed information about the violations.
19 */
20 public class ReportHTMLPrintVisitor extends ReportVisitor {
21
22 private StringBuffer packageBuf = new StringBuffer()/package-summary.html">ong> StringBuffer packageBuf = new StringBuffer();
23 private StringBuffer classBuf = new StringBuffer();
24 private int length;
25
26 private static final String fs = System.getProperty("file.separator");
27
28 /***
29 * Writes the buffer to file.
30 */
31 private void write(String filename, StringBuffer buf) throws IOException {
32
33 String baseDir = ".." + fs;
34
35 BufferedWriter bw = new BufferedWriter(new FileWriter(new File(baseDir + fs + filename)));
36 bw.write(buf.toString(), 0, buf.length());
37 bw.close();
38 }
39
40 /***
41 * Generates a html table with violation information.
42 */
43 private String displayRuleViolation(IRuleViolation vio) {
44
45 StringBuffer sb = new StringBuffer(200);
46 sb.append("<table border=\"0\">");
47 sb.append("<tr><td><b>Rule:</b></td><td>").append(vio.getRule().getName()).append("</td></tr>");
48 sb.append("<tr><td><b>Description:</b></td><td>").append(vio.getDescription()).append("</td></tr>");
49
50 if (vio.getVariableName().length() > 0) {
51 sb.append("<tr><td><b>Variable:</b></td><td>").append(vio.getVariableName()).append("</td></tr>");
52 }
53
54 if (vio.getEndLine() > 0) {
55 sb.append("<tr><td><b>Line:</b></td><td>").append(vio.getEndLine()).append(" and ").append(vio.getBeginLine()).append("</td></tr>");
56 } else {
57 sb.append("<tr><td><b>Line:</b></td><td>").append(vio.getBeginLine()).append("</td></tr>");
58 }
59
60 sb.append("</table>");
61 return sb.toString();
62 }
63
64 /***
65 * The visit method (Visitor Pattern). There are 3 types of ReportNodes:
66 * RuleViolation - contains a RuleViolation, Class - represents a class and
67 * contains the name of the class, Package - represents a package and
68 * contains the name(s) of the package.
69 */
70 public void visit(AbstractReportNode node) {
71
72
73
74
75 if (node.getParent() == null) {
76 this.packageBuf.insert(0,
77 "<html>" +
78 " <head>" +
79 " <title>PMD</title>" +
80 " </head>" +
81 " <body>" + PMD.EOL + "" +
82 "<h2>Package View</h2>" +
83 "<table border=\"1\" align=\"center\" cellspacing=\"0\" cellpadding=\"3\">" +
84 " <tr>" + PMD.EOL + "" +
85 "<th>Package</th>" +
86 "<th>Class</th>" +
87 "<th>#</th>" +
88 " </tr>" + PMD.EOL);
89
90 this/length = this/packageBuf/length()/package-summary.html">rong>.length = this.packageBuf.length();
91 }
92
93
94 super.visit(node);
95
96
97 if (node instanceof ViolationNode) {
98 ViolationNode vnode = (ViolationNode) node;
99 vnode.getParent().addNumberOfViolation(1);
100 IRuleViolation vio = vnode.getRuleViolation();
101 classBuf.append("<tr>" +
102 " <td>" + vio.getMethodName() + "</td>" +
103 " <td>" + this.displayRuleViolation(vio) + "</td>" +
104 "</tr>");
105 }
106 if (node instanceof ClassNode) {
107 ClassNode cnode = (ClassNode) node;
108 String str = cnode.getClassName();
109
110 classBuf.insert(0,
111 "<html><head><title>PMD - " + str + "</title></head><body>" + PMD.EOL + "" +
112 "<h2>Class View</h2>" +
113 "<h3 align=\"center\">Class: " + str + "</h3>" +
114 "<table border=\"\" align=\"center\" cellspacing=\"0\" cellpadding=\"3\">" +
115 " <tr>" + PMD.EOL + "" +
116 "<th>Method</th>" +
117 "<th>Violation</th>" +
118 " </tr>" + PMD.EOL);
119
120 classBuf.append("</table>" +
121 " </body>" +
122 "</html>");
123
124
125 try {
126 this.write(str + ".html", classBuf);
127 } catch (Exception e) {
128 throw new RuntimeException("Error while writing HTML report: " + e.getMessage());
129 }
130 classBuf = new StringBuffer();
131
132
133 this.packageBuf.insert(this.length,
134 "<tr>" +
135 " <td>-</td>" +
136 " <td><a href=\"" + str + ".html\">" + str + "</a></td>" +
137 " <td>" + node.getNumberOfViolations() + "</td>" +
138 "</tr>" + PMD.EOL);
139 node.getParent().addNumberOfViolation(node.getNumberOfViolations());
140 }
141 if (node instanceof PackageNode) {
142 PackageNode pnode = (PackageNode) node;
143 String str;
144
145
146 if (node.getParent() == null) {
147 str = "Aggregate";
148 } else {
149 str = pnode.getPackageName();
150 node.getParent().addNumberOfViolation(node.getNumberOfViolations());
151 }
152
153 this.packageBuf.insert(this.length,
154 "<tr><td><b>" + str + "</b></td>" +
155 " <td>-</td>" +
156 " <td>" + node.getNumberOfViolations() + "</td>" +
157 "</tr>" + PMD.EOL);
158 }
159
160 if (node.getParent() == null) {
161 this.packageBuf.append("</table> </body></html>");
162 try {
163 this.write("index.html", this.packageBuf);
164 } catch (Exception e) {
165 throw new RuntimeException("Error while writing HTML report: " + e.getMessage());
166 }
167 }
168 }
169 }