001: package net.sourceforge.pmd.dfa.report;
002:
003: import net.sourceforge.pmd.IRuleViolation;
004: import net.sourceforge.pmd.PMD;
005:
006: import java.io.BufferedWriter;
007: import java.io.File;
008: import java.io.FileWriter;
009: import java.io.IOException;
010:
011: /**
012: * @author raik
013: * <p/>
014: * * Uses the generated result tree instead of the result list. The visitor
015: * * traverses the tree and creates several html files. The "package view" file
016: * * (index.html) displays an overview of packgages, classes and the number of
017: * * rule violations they contain. All the other html files represent a class
018: * * and show detailed information about the violations.
019: */
020: public class ReportHTMLPrintVisitor extends ReportVisitor {
021:
022: private StringBuffer packageBuf = new StringBuffer();
023: private StringBuffer classBuf = new StringBuffer();
024: private int length;
025: private String baseDir;
026:
027: private static final String fs = System
028: .getProperty("file.separator");
029:
030: public ReportHTMLPrintVisitor(String baseDir) {
031: this .baseDir = baseDir;
032: }
033:
034: /**
035: * Writes the buffer to file.
036: */
037: private void write(String filename, StringBuffer buf)
038: throws IOException {
039: BufferedWriter bw = new BufferedWriter(new FileWriter(new File(
040: baseDir + fs + filename)));
041: bw.write(buf.toString(), 0, buf.length());
042: bw.close();
043: }
044:
045: /**
046: * Generates a html table with violation information.
047: */
048: private String displayRuleViolation(IRuleViolation vio) {
049:
050: StringBuffer sb = new StringBuffer(200);
051: sb.append("<table border=\"0\">");
052: sb.append("<tr><td><b>Rule:</b></td><td>").append(
053: vio.getRule().getName()).append("</td></tr>");
054: sb.append("<tr><td><b>Description:</b></td><td>").append(
055: vio.getDescription()).append("</td></tr>");
056:
057: if (vio.getVariableName().length() > 0) {
058: sb.append("<tr><td><b>Variable:</b></td><td>").append(
059: vio.getVariableName()).append("</td></tr>");
060: }
061:
062: if (vio.getEndLine() > 0) {
063: sb.append("<tr><td><b>Line:</b></td><td>").append(
064: vio.getEndLine()).append(" and ").append(
065: vio.getBeginLine()).append("</td></tr>");
066: } else {
067: sb.append("<tr><td><b>Line:</b></td><td>").append(
068: vio.getBeginLine()).append("</td></tr>");
069: }
070:
071: sb.append("</table>");
072: return sb.toString();
073: }
074:
075: /**
076: * The visit method (Visitor Pattern). There are 3 types of ReportNodes:
077: * RuleViolation - contains a RuleViolation, Class - represents a class and
078: * contains the name of the class, Package - represents a package and
079: * contains the name(s) of the package.
080: */
081: public void visit(AbstractReportNode node) {
082:
083: /*
084: * The first node of result tree.
085: */
086: if (node.getParent() == null) {
087: this .packageBuf
088: .insert(
089: 0,
090: "<html>"
091: + " <head>"
092: + " <title>PMD</title>"
093: + " </head>"
094: + " <body>"
095: + PMD.EOL
096: + "<h2>Package View</h2>"
097: + "<table border=\"1\" align=\"center\" cellspacing=\"0\" cellpadding=\"3\">"
098: + " <tr>" + PMD.EOL
099: + "<th>Package</th>"
100: + "<th>Class</th>" + "<th>#</th>"
101: + " </tr>" + PMD.EOL);
102:
103: this .length = this .packageBuf.length();
104: }
105:
106: super .visit(node);
107:
108: if (node instanceof ViolationNode) {
109: ViolationNode vnode = (ViolationNode) node;
110: vnode.getParent().addNumberOfViolation(1);
111: IRuleViolation vio = vnode.getRuleViolation();
112: classBuf.append("<tr>" + " <td>" + vio.getMethodName()
113: + "</td>" + " <td>"
114: + this .displayRuleViolation(vio) + "</td>"
115: + "</tr>");
116: }
117: if (node instanceof ClassNode) {
118: ClassNode cnode = (ClassNode) node;
119: String str = cnode.getClassName();
120:
121: classBuf
122: .insert(
123: 0,
124: "<html><head><title>PMD - "
125: + str
126: + "</title></head><body>"
127: + PMD.EOL
128: + "<h2>Class View</h2>"
129: + "<h3 align=\"center\">Class: "
130: + str
131: + "</h3>"
132: + "<table border=\"\" align=\"center\" cellspacing=\"0\" cellpadding=\"3\">"
133: + " <tr>" + PMD.EOL
134: + "<th>Method</th>"
135: + "<th>Violation</th>" + " </tr>"
136: + PMD.EOL);
137:
138: classBuf.append("</table>" + " </body>" + "</html>");
139:
140: try {
141: this .write(str + ".html", classBuf);
142: } catch (Exception e) {
143: throw new RuntimeException(
144: "Error while writing HTML report: "
145: + e.getMessage());
146: }
147: classBuf = new StringBuffer();
148:
149: this .packageBuf.insert(this .length, "<tr>" + " <td>-</td>"
150: + " <td><a href=\"" + str + ".html\">" + str
151: + "</a></td>" + " <td>"
152: + node.getNumberOfViolations() + "</td>" + "</tr>"
153: + PMD.EOL);
154: node.getParent().addNumberOfViolation(
155: node.getNumberOfViolations());
156: }
157: if (node instanceof PackageNode) {
158: PackageNode pnode = (PackageNode) node;
159: String str;
160:
161: // rootNode
162: if (node.getParent() == null) {
163: str = "Aggregate";
164: } else { // all the other nodes
165: str = pnode.getPackageName();
166: node.getParent().addNumberOfViolation(
167: node.getNumberOfViolations());
168: }
169:
170: this .packageBuf.insert(this .length, "<tr><td><b>" + str
171: + "</b></td>" + " <td>-</td>" + " <td>"
172: + node.getNumberOfViolations() + "</td>" + "</tr>"
173: + PMD.EOL);
174: }
175: // The first node of result tree.
176: if (node.getParent() == null) {
177: this .packageBuf.append("</table> </body></html>");
178: try {
179: this .write("index.html", this .packageBuf);
180: } catch (Exception e) {
181: throw new RuntimeException(
182: "Error while writing HTML report: "
183: + e.getMessage());
184: }
185: }
186: }
187: }
|