1 19 20 package edu.umd.cs.findbugs; 21 22 23 import java.io.IOException ; 24 import java.io.OutputStream ; 25 import java.util.Iterator ; 26 import java.util.regex.Matcher ; 27 import java.util.regex.Pattern ; 28 29 import org.dom4j.Document; 30 import org.dom4j.DocumentHelper; 31 import org.dom4j.Element; 32 import org.dom4j.io.OutputFormat; 33 import org.dom4j.io.XMLWriter; 34 35 import edu.umd.cs.findbugs.classfile.ClassDescriptor; 36 37 42 public class XDocsBugReporter extends TextUIBugReporter { 43 private SortedBugCollection bugCollection = new SortedBugCollection(); 44 private Project project; 45 private Document document; 46 private Element root; 47 48 private static final String ROOT_ELEMENT_NAME = "BugCollection"; 49 private static final String PROJECT_ELEMENT_NAME = "Project"; 50 private static final String ERRORS_ELEMENT_NAME = "Errors"; 51 private static final String ANALYSIS_ERROR_ELEMENT_NAME = "AnalysisError"; 52 private static final String MISSING_CLASS_ELEMENT_NAME = "MissingClass"; 53 private static final String SUMMARY_HTML_ELEMENT_NAME = "SummaryHTML"; 54 55 private static final String ELEMENT_NAME = "BugInstance"; 56 private static final String FILE_ELEMENT_NAME = "file"; 57 58 59 public XDocsBugReporter(Project project) { 60 this.project = project; 61 62 this.document = DocumentHelper.createDocument(); 63 this.root = document.addElement(ROOT_ELEMENT_NAME); 64 65 66 } 67 68 public void observeClass(ClassDescriptor classDescriptor) { 69 } 70 71 @Override 72 public void logError(String message) { 73 bugCollection.addError(message); 74 super.logError(message); 75 } 76 77 @Override 78 public void reportMissingClass(ClassNotFoundException ex) { 79 bugCollection.addMissingClass(getMissingClassName(ex)); 80 super.reportMissingClass(ex); 81 } 82 83 @Override 84 public void doReportBug(BugInstance bugInstance) { 85 if (bugCollection.add(bugInstance)) { 86 printBug(bugInstance); 87 notifyObservers(bugInstance); 88 } 89 } 90 91 @Override 92 protected void printBug(BugInstance bugInstance) { 93 try { 94 toElement(bugInstance); 95 } catch (Exception e) { 96 logError("Couldn't add Element", e); 97 } 98 } 99 100 public void finish() { 101 102 try { 103 writeXML(outputStream, project); 104 } catch (Exception e) { 105 logError("Couldn't write XML output", e); 106 } 107 outputStream.close(); 108 } 109 110 private void writeXML(OutputStream out, Project project) throws IOException { 111 Document document = endDocument(project); 112 113 XMLWriter writer = new XMLWriter(out, OutputFormat.createPrettyPrint()); 114 writer.write(document); 115 } 116 117 private Document endDocument(Project project) { 118 119 Element errorsElement = root.addElement(ERRORS_ELEMENT_NAME); 121 for (Iterator <AnalysisError> i = bugCollection.errorIterator(); i.hasNext();) { 122 AnalysisError analysisError = i.next(); 123 errorsElement.addElement(ANALYSIS_ERROR_ELEMENT_NAME).setText(analysisError.getMessage()); 124 } 125 for (Iterator <String > i = bugCollection.missingClassIterator(); i.hasNext();) { 126 errorsElement.addElement(MISSING_CLASS_ELEMENT_NAME).setText(i.next()); 127 } 128 129 return document; 130 } 131 132 private static String xmlEscape(String theString) 133 { 134 StringBuffer buf = new StringBuffer (); 136 int len = theString.length(); 137 char theChar; 138 for (int i=0; i<len; i++) 139 { 140 theChar = theString.charAt(i); 141 switch(theChar){ 142 case '>': buf.append(">"); 143 break; 144 case '<': buf.append("<"); 145 break; 146 case '"': buf.append("""); 147 break; 148 case '&': buf.append("&"); 149 break; 150 case '\'': buf.append("'"); 151 break; 152 default: buf.append(theChar); 153 } 154 } 155 return buf.toString(); 156 } 157 158 public void toElement(BugInstance bugInstance) { 159 160 String className = bugInstance.getPrimaryClass().getClassName(); 161 Element element = (Element) root.selectSingleNode(FILE_ELEMENT_NAME + "[@classname='" + className + "']"); 162 163 if (element == null) { 164 element = root.addElement(FILE_ELEMENT_NAME); 165 element.addAttribute("classname", className); 166 } 167 168 element = element.addElement(ELEMENT_NAME); 169 170 171 element.addAttribute("type", bugInstance.getType()); 172 173 switch (bugInstance.getPriority()) { 174 case Detector.EXP_PRIORITY: 175 element.addAttribute("priority", "Experimental"); 176 break; 177 case Detector.LOW_PRIORITY: 178 element.addAttribute("priority", "Low"); 179 break; 180 case Detector.NORMAL_PRIORITY: 181 element.addAttribute("priority", "Normal"); 182 break; 183 case Detector.HIGH_PRIORITY: 184 element.addAttribute("priority", "High"); 185 break; 186 } 187 188 element.addAttribute("message", xmlEscape(bugInstance.getMessage())); 189 190 SourceLineAnnotation line = 191 bugInstance.getPrimarySourceLineAnnotation(); 192 if (line == null) { 193 element.addAttribute("line", "0"); 194 } else { 195 element.addAttribute("line", Integer.toString(line.getStartLine())); 196 } 197 198 199 } 200 209 210 } 211 212 | Popular Tags |