PageRenderTime 25ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/findbugs/src/java/edu/umd/cs/findbugs/XDocsBugReporter.java

http://findbugs.googlecode.com/
Java | 225 lines | 167 code | 33 blank | 25 comment | 6 complexity | d31473a0a90d2041229501a1536a0fbc MD5 | raw file
Possible License(s): Unlicense, GPL-2.0, LGPL-2.0, LGPL-2.1, BSD-3-Clause, Apache-2.0
  1. /*
  2. * FindBugs - Find bugs in Java programs
  3. * Copyright (C) 2004, Garvin LeClaire <garvin.leclaire@insightbb.com>
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2.1 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. */
  19. package edu.umd.cs.findbugs;
  20. import java.io.IOException;
  21. import java.io.Writer;
  22. import java.util.Iterator;
  23. import javax.annotation.Nonnull;
  24. import org.dom4j.Document;
  25. import org.dom4j.DocumentHelper;
  26. import org.dom4j.Element;
  27. import org.dom4j.io.OutputFormat;
  28. import org.dom4j.io.XMLWriter;
  29. import edu.umd.cs.findbugs.classfile.ClassDescriptor;
  30. /**
  31. * BugReporter to output warnings in xdocs format for Maven.
  32. *
  33. * @author Garvin LeClaire
  34. */
  35. public class XDocsBugReporter extends TextUIBugReporter {
  36. final private SortedBugCollection bugCollection;
  37. final private Project project;
  38. private Document document;
  39. private Element root;
  40. private static final String ROOT_ELEMENT_NAME = "BugCollection";
  41. private static final String PROJECT_ELEMENT_NAME = "Project";
  42. private static final String ERRORS_ELEMENT_NAME = "Errors";
  43. private static final String ANALYSIS_ERROR_ELEMENT_NAME = "AnalysisError";
  44. private static final String MISSING_CLASS_ELEMENT_NAME = "MissingClass";
  45. private static final String SUMMARY_HTML_ELEMENT_NAME = "SummaryHTML";
  46. private static final String ELEMENT_NAME = "BugInstance";
  47. private static final String FILE_ELEMENT_NAME = "file";
  48. public XDocsBugReporter(Project project) {
  49. this.project = project;
  50. this.bugCollection = new SortedBugCollection(project);
  51. this.document = DocumentHelper.createDocument();
  52. this.root = document.addElement(ROOT_ELEMENT_NAME);
  53. }
  54. public void observeClass(ClassDescriptor classDescriptor) {
  55. }
  56. @Override
  57. public void logError(String message) {
  58. bugCollection.addError(message);
  59. super.logError(message);
  60. }
  61. @Override
  62. public void reportMissingClass(ClassNotFoundException ex) {
  63. String missing = AbstractBugReporter.getMissingClassName(ex);
  64. if (!isValidMissingClassMessage(missing)) {
  65. return;
  66. }
  67. bugCollection.addMissingClass(missing);
  68. super.reportMissingClass(ex);
  69. }
  70. @Override
  71. public void doReportBug(BugInstance bugInstance) {
  72. if (bugCollection.add(bugInstance)) {
  73. printBug(bugInstance);
  74. notifyObservers(bugInstance);
  75. }
  76. }
  77. @Override
  78. protected void printBug(BugInstance bugInstance) {
  79. try {
  80. toElement(bugInstance);
  81. } catch (Exception e) {
  82. logError("Couldn't add Element", e);
  83. }
  84. }
  85. public void finish() {
  86. try {
  87. writeXML(outputStream, project);
  88. } catch (Exception e) {
  89. logError("Couldn't write XML output", e);
  90. }
  91. outputStream.flush();
  92. }
  93. private void writeXML(Writer out, Project project) throws IOException {
  94. Document document = endDocument(project);
  95. XMLWriter writer = new XMLWriter(out, OutputFormat.createPrettyPrint());
  96. writer.write(document);
  97. }
  98. private Document endDocument(Project project) {
  99. // Save the error information
  100. Element errorsElement = root.addElement(ERRORS_ELEMENT_NAME);
  101. for (AnalysisError analysisError : bugCollection.getErrors()) {
  102. errorsElement.addElement(ANALYSIS_ERROR_ELEMENT_NAME).setText(analysisError.getMessage());
  103. }
  104. for (Iterator<String> i = bugCollection.missingClassIterator(); i.hasNext();) {
  105. errorsElement.addElement(MISSING_CLASS_ELEMENT_NAME).setText(i.next());
  106. }
  107. return document;
  108. }
  109. private static String xmlEscape(String theString) {
  110. // Replaces characters '>', '<', '"', '&', ''' with XML equivalents
  111. StringBuilder buf = new StringBuilder();
  112. int len = theString.length();
  113. char theChar;
  114. for (int i = 0; i < len; i++) {
  115. theChar = theString.charAt(i);
  116. switch (theChar) {
  117. case '>':
  118. buf.append("&gt;");
  119. break;
  120. case '<':
  121. buf.append("&lt;");
  122. break;
  123. case '"':
  124. buf.append("&quot;");
  125. break;
  126. case '&':
  127. buf.append("&amp;");
  128. break;
  129. case '\'':
  130. buf.append("&apos;");
  131. break;
  132. default:
  133. buf.append(theChar);
  134. }
  135. }
  136. return buf.toString();
  137. }
  138. public void toElement(BugInstance bugInstance) {
  139. String className = bugInstance.getPrimaryClass().getClassName();
  140. Element element = (Element) root.selectSingleNode(FILE_ELEMENT_NAME + "[@classname='" + className + "']");
  141. if (element == null) {
  142. element = root.addElement(FILE_ELEMENT_NAME);
  143. element.addAttribute("classname", className);
  144. }
  145. element = element.addElement(ELEMENT_NAME);
  146. element.addAttribute("type", bugInstance.getType());
  147. switch (bugInstance.getPriority()) {
  148. case Priorities.EXP_PRIORITY:
  149. element.addAttribute("priority", "Experimental");
  150. break;
  151. case Priorities.LOW_PRIORITY:
  152. element.addAttribute("priority", "Low");
  153. break;
  154. case Priorities.NORMAL_PRIORITY:
  155. element.addAttribute("priority", "Normal");
  156. break;
  157. case Priorities.HIGH_PRIORITY:
  158. element.addAttribute("priority", "High");
  159. break;
  160. default:
  161. assert false;
  162. }
  163. element.addAttribute("message", xmlEscape(bugInstance.getMessage()));
  164. SourceLineAnnotation line = bugInstance.getPrimarySourceLineAnnotation();
  165. element.addAttribute("line", Integer.toString(line.getStartLine()));
  166. }
  167. /*
  168. * public static void main(String args[]) { String x =
  169. * "Less than: < Greater than: > Ampersand: & Quotation mark: \" Apostrophe: '"
  170. * ; String y = xmlEscape(x); System.out.println(x); System.out.println(y);
  171. * }
  172. */
  173. public @Nonnull
  174. BugCollection getBugCollection() {
  175. return bugCollection;
  176. }
  177. }
  178. // vim:ts=3