| 1 19 20 package edu.umd.cs.findbugs.filter; 21 22 import java.io.BufferedInputStream ; 23 import java.io.File ; 24 import java.io.FileInputStream ; 25 import java.io.IOException ; 26 import java.net.URL ; 27 import java.util.Iterator ; 28 29 import org.dom4j.Attribute; 30 import org.dom4j.Document; 31 import org.dom4j.DocumentException; 32 import org.dom4j.Element; 33 import org.dom4j.io.SAXReader; 34 35 import edu.umd.cs.findbugs.SystemProperties; 36 import edu.umd.cs.findbugs.util.Strings; 37 38 44 45 public class Filter extends OrMatcher { 46 private static final boolean DEBUG = SystemProperties.getBoolean("filter.debug"); 47 48 55 public Filter(String fileName) throws IOException , FilterException { 56 parse(fileName); 57 } 58 59 66 private void parse(String fileName) throws IOException , FilterException { 67 68 Document filterDoc = null; 69 70 try { 71 SAXReader reader = new SAXReader(); 72 filterDoc = reader.read(new BufferedInputStream (new FileInputStream (fileName))); 73 } catch (DocumentException e) { 74 throw new FilterException("Couldn't parse filter file " + fileName, e); 75 } 76 77 int count = 1; 78 for (Object matchObj : filterDoc.selectNodes("/FindBugsFilter/Match")) { 80 Element matchNode = (Element) matchObj; 81 AndMatcher matchMatcher = new AndMatcher(); 82 83 Matcher classMatcher = null; 85 String classAttr = matchNode.valueOf("@class"); 86 if (!classAttr.equals("")) { 87 classMatcher = new ClassMatcher(classAttr); 88 } else { 89 String classRegex = matchNode.valueOf("@classregex"); 90 if (!classRegex.equals("")) 91 classMatcher = new ClassMatcher("~" + classRegex); 92 } 93 if (classMatcher != null) 94 matchMatcher.addChild(classMatcher); 95 96 if (DEBUG) System.out.println("Match node"); 97 98 Iterator <Element> j = matchNode.elementIterator(); 100 while (j.hasNext()) { 101 Element child = j.next(); 102 Matcher matcher = getMatcher(child); 103 matchMatcher.addChild(matcher); 104 } 105 if (matchMatcher.numberChildren() == 0) 106 throw new IllegalArgumentException ("Match element #" + count + " (starting at 1) is invalid in filter file " + fileName); 107 this.addChild(matchMatcher); 109 count++; 110 } 111 if (this.numberChildren() == 0) 112 throw new IllegalArgumentException ("Could not find any /FindBugsFilter/Match nodes in filter file " + fileName); 113 114 } 115 116 123 private static Matcher getMatcher(Element element) throws FilterException { 124 String name = element.getName(); 126 if (name.equals("BugCode")) { 127 return new BugMatcher(element.valueOf("@name"), "", ""); 128 } else if (name.equals("Local")) { 129 return new LocalMatcher(element.valueOf("@name")); 130 } else if (name.equals("BugPattern")) { 131 return new BugMatcher("", element.valueOf("@name"), ""); 132 } else if (name.equals("Bug")) { 133 return new BugMatcher(element.valueOf("@code"), element 134 .valueOf("@pattern"), element.valueOf("@category")); 135 } else if (name.equals("Priority")) { 136 return new PriorityMatcher(element.valueOf("@value")); 137 } else if (name.equals("Class")) { 138 Attribute nameAttr = element.attribute("name"); 139 140 if (nameAttr == null) 141 throw new FilterException("Missing name attribute in Class element"); 142 143 return new ClassMatcher(nameAttr.getValue()); 144 } else if (name.equals("Package")) { 145 Attribute nameAttr = element.attribute("name"); 146 147 if (nameAttr == null) 148 throw new FilterException("Missing name attribute in Package element"); 149 150 String pName = nameAttr.getValue(); 151 pName = pName.startsWith("~") ? pName : "~" + Strings.replace(pName, ".", "\\."); 152 return new ClassMatcher(pName + "\\.[^.]+"); 153 } else if (name.equals("Method")) { 154 Attribute nameAttr = element.attribute("name"); 155 String nameValue; 156 Attribute paramsAttr = element.attribute("params"); 157 Attribute returnsAttr = element.attribute("returns"); 158 159 if (nameAttr == null) 160 if(paramsAttr == null || returnsAttr == null) 161 throw new FilterException("Method element must have eiter name or params and returnss attributes"); 162 else 163 nameValue = "~.*"; else 165 nameValue = nameAttr.getValue(); 166 167 if ((paramsAttr != null || returnsAttr != null) && (paramsAttr == null || returnsAttr == null)) 168 throw new FilterException("Method element must have both params and returns attributes if either is used"); 169 170 if (paramsAttr == null) 171 return new MethodMatcher(nameValue); 172 else 173 return new MethodMatcher(nameValue, paramsAttr.getValue(), returnsAttr.getValue()); 174 } else if (name.equals("Field")) { 175 Attribute nameAttr = element.attribute("name"); 176 String nameValue; 177 Attribute typeAttr = element.attribute("type"); 178 179 if (nameAttr == null) 180 if(typeAttr == null) 181 throw new FilterException("Field element must have either name or type attribute"); 182 else 183 nameValue = "~.*"; else 185 nameValue = nameAttr.getValue(); 186 187 if (typeAttr == null) 188 return new FieldMatcher(nameValue); 189 else 190 return new FieldMatcher(nameValue, typeAttr.getValue()); 191 } else if (name.equals("Or")) { 192 OrMatcher orMatcher = new OrMatcher(); 193 Iterator <Element> i = element.elementIterator(); 194 while (i.hasNext()) { 195 orMatcher.addChild(getMatcher(i.next())); 196 } 197 return orMatcher; 198 } else 199 throw new FilterException("Unknown element: " + name); 200 } 201 202 public static void main(String [] argv) { 203 try { 204 if (argv.length != 1) { 205 System.err.println("Usage: " + Filter.class.getName() + " <filename>"); 206 System.exit(1); 207 } 208 209 new Filter(argv[0]); 210 } catch (Exception e) { 211 e.printStackTrace(); 212 System.exit(1); 213 } 214 } 215 216 } 217 218 | Popular Tags |