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