1 19 20 package edu.umd.cs.findbugs.tools.xml; 21 22 import java.io.File ; 23 import java.net.MalformedURLException ; 24 import java.util.HashSet ; 25 import java.util.Iterator ; 26 import java.util.Set ; 27 28 import org.dom4j.Attribute; 29 import org.dom4j.Document; 30 import org.dom4j.DocumentException; 31 import org.dom4j.Element; 32 import org.dom4j.Node; 33 import org.dom4j.io.SAXReader; 34 35 39 public class CheckMessages { 40 41 private static class CheckMessagesException extends DocumentException { 42 45 private static final long serialVersionUID = 1L; 46 47 public CheckMessagesException(String msg, XMLFile xmlFile, Node node) { 48 super("In " + xmlFile.getFilename() + ", " + node.toString() + ": " + msg); 49 } 50 51 public CheckMessagesException(String msg, XMLFile xmlFile) { 52 super("In " + xmlFile.getFilename() + ": " + msg); 53 } 54 } 55 56 private static class XMLFile { 57 private String filename; 58 private Document document; 59 60 public XMLFile(String filename) throws DocumentException, MalformedURLException { 61 this.filename = filename; 62 63 File file = new File (filename); 64 SAXReader saxReader = new SAXReader(); 65 this.document = saxReader.read(file); 66 } 67 68 public String getFilename() { return filename; } 69 70 public Document getDocument() { return document; } 71 72 76 public Iterator <Node> xpathIterator(String xpath) { 77 return document.selectNodes(xpath).iterator(); 78 } 79 80 84 public Set <String > collectAttributes(String xpath, String attrName) 85 throws DocumentException { 86 Set <String > result = new HashSet <String >(); 87 88 for (Iterator <Node> i = xpathIterator(xpath); i.hasNext(); ) { 89 Node node = i.next(); 90 String value = checkAttribute(node, attrName).getValue(); 91 result.add(value); 92 } 93 94 return result; 95 } 96 97 public Attribute checkAttribute(Node node, String attrName) throws DocumentException { 98 if (!(node instanceof Element)) 99 throw new CheckMessagesException("Node is not an element", this, node); 100 Element element = (Element) node; 101 Attribute attr = element.attribute(attrName); 102 if (attr == null) 103 throw new CheckMessagesException("Missing " + attrName + " attribute", this, node); 104 return attr; 105 } 106 107 public Element checkElement(Node node, String elementName) throws DocumentException { 108 if (!(node instanceof Element)) 109 throw new CheckMessagesException("Node is not an element", this, node); 110 Element element = (Element) node; 111 Element child = element.element(elementName); 112 if (child == null) 113 throw new CheckMessagesException("Missing " + elementName + " element", this, node); 114 return child; 115 } 116 117 public String checkNonEmptyText(Node node) throws DocumentException { 118 if (!(node instanceof Element)) 119 throw new CheckMessagesException("Node is not an element", this, node); 120 Element element = (Element) node; 121 String text = element.getText(); 122 if (text.equals("")) 123 throw new CheckMessagesException("Empty text in element", this, node); 124 return text; 125 } 126 } 127 128 private Set <String > declaredDetectorsSet; 129 private Set <String > declaredAbbrevsSet; 130 131 public CheckMessages(String pluginDescriptorFilename) 132 throws DocumentException, MalformedURLException { 133 134 XMLFile pluginDescriptorDoc = new XMLFile(pluginDescriptorFilename); 135 136 declaredDetectorsSet = 137 pluginDescriptorDoc.collectAttributes("/FindbugsPlugin/Detector", "class"); 138 139 declaredAbbrevsSet = 140 pluginDescriptorDoc.collectAttributes("/FindbugsPlugin/BugPattern", "abbrev"); 141 } 142 143 147 public void checkMessages(XMLFile messagesDoc) throws DocumentException { 148 for (Iterator <Node> i = messagesDoc.xpathIterator("/MessageCollection/Detector"); i.hasNext(); ) { 151 Node node = i.next(); 152 messagesDoc.checkAttribute(node, "class"); 153 messagesDoc.checkElement(node, "Details"); 154 } 155 156 for (Iterator <Node> i = messagesDoc.xpathIterator("/MessageCollection/BugPattern"); i.hasNext(); ) { 160 Node node = i.next(); 161 messagesDoc.checkAttribute(node, "type"); 162 messagesDoc.checkElement(node, "ShortDescription"); 163 messagesDoc.checkElement(node, "LongDescription"); 164 messagesDoc.checkElement(node, "Details"); 165 } 166 167 for (Iterator <Node> i = messagesDoc.xpathIterator("/MessageCollection/BugCode"); i.hasNext(); ) { 170 Node node = i.next(); 171 messagesDoc.checkAttribute(node, "abbrev"); 172 messagesDoc.checkNonEmptyText(node); 173 } 174 175 Set <String > describedDetectorsSet = 177 messagesDoc.collectAttributes("/MessageCollection/Detector", "class"); 178 checkDescribed("Bug detectors not described by Detector elements", 179 messagesDoc, declaredDetectorsSet, describedDetectorsSet); 180 181 Set <String > describedAbbrevsSet = 183 messagesDoc.collectAttributes("/MessageCollection/BugCode", "abbrev"); 184 checkDescribed("Abbreviations not described by BugCode elements", 185 messagesDoc, declaredAbbrevsSet, describedAbbrevsSet); 186 } 187 188 public void checkDescribed(String description, XMLFile xmlFile, 189 Set <String > declared, Set <String > described) throws DocumentException { 190 191 Set <String > notDescribed = new HashSet <String >(); 192 notDescribed.addAll(declared); 193 notDescribed.removeAll(described); 194 195 if (!notDescribed.isEmpty()) 196 throw new CheckMessagesException(description + ": " + notDescribed.toString(), xmlFile); 197 } 198 199 public static void main(String [] argv) throws Exception { 200 if (argv.length < 2) { 201 System.err.println("Usage: " + CheckMessages.class.getName() + 202 " <plugin descriptor xml> <bug description xml> [<bug description xml>...]"); 203 System.exit(1); 204 } 205 206 String pluginDescriptor = argv[0]; 207 208 try { 209 CheckMessages checkMessages = new CheckMessages(pluginDescriptor); 210 for (int i = 1; i < argv.length; ++i) { 211 String messagesFile = argv[i]; 212 System.out.println("Checking messages file " + messagesFile); 213 checkMessages.checkMessages(new XMLFile(messagesFile)); 214 } 215 } catch (DocumentException e) { 216 System.err.println("Could not verify messages files: " + e.getMessage()); 217 System.exit(1); 218 } 219 220 System.out.println("Messages files look OK!"); 221 } 222 } 223 224 | Popular Tags |