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