| 1 19 20 package edu.umd.cs.findbugs; 21 22 import java.util.Iterator ; 23 import java.util.NoSuchElementException ; 24 25 import edu.umd.cs.findbugs.model.ClassNameRewriter; 26 import edu.umd.cs.findbugs.model.ClassNameRewriterUtil; 27 import edu.umd.cs.findbugs.model.IdentityClassNameRewriter; 28 29 33 public class VersionInsensitiveBugComparator implements WarningComparator { 34 35 private ClassNameRewriter classNameRewriter = IdentityClassNameRewriter.instance(); 36 37 private boolean exactBugPatternMatch = true; 38 39 private boolean comparePriorities = false; 40 public VersionInsensitiveBugComparator() { 41 } 42 43 public void setClassNameRewriter(ClassNameRewriter classNameRewriter) { 44 this.classNameRewriter = classNameRewriter; 45 } 46 public void setComparePriorities(boolean b) { 47 comparePriorities = b; 48 } 49 50 54 private class FilteringAnnotationIterator implements Iterator <BugAnnotation> { 55 private Iterator <BugAnnotation> iter; 56 private BugAnnotation next; 57 58 public FilteringAnnotationIterator(Iterator <BugAnnotation> iter) { 59 this.iter = iter; 60 this.next = null; 61 } 62 63 public boolean hasNext() { 64 findNext(); 65 return next != null; 66 } 67 68 public BugAnnotation next() { 69 findNext(); 70 if (next == null) 71 throw new NoSuchElementException (); 72 BugAnnotation result = next; 73 next = null; 74 return result; 75 } 76 77 public void remove() { 78 throw new UnsupportedOperationException (); 79 } 80 81 private void findNext() { 82 while (next == null) { 83 if (!iter.hasNext()) 84 break; 85 BugAnnotation candidate = iter.next(); 86 if (!isBoring(candidate)) { 87 next = candidate; 88 break; 89 } 90 } 91 } 92 93 } 94 95 private boolean isBoring(BugAnnotation annotation) { 96 if (annotation.getClass() == IntAnnotation.class) { 98 if (annotation.getDescription().equals(IntAnnotation.INT_SYNC_PERCENT)) 99 return true; 100 } 101 102 if (annotation instanceof SourceLineAnnotation) { 104 return true; 105 } 106 107 return false; 108 } 109 110 private static int compareNullElements(Object a, Object b) { 111 if (a != null) 112 return 1; 113 else if (b != null) 114 return -1; 115 else 116 return 0; 117 } 118 119 private static String getCode(String pattern) { 120 int sep = pattern.indexOf('_'); 121 if (sep < 0) 122 return ""; 123 return pattern.substring(0, sep); 124 } 125 126 public int compare(BugInstance lhs, BugInstance rhs) { 127 132 int cmp; 133 134 BugPattern lhsPattern = lhs.getBugPattern(); 135 BugPattern rhsPattern = rhs.getBugPattern(); 136 137 if (lhsPattern == null || rhsPattern == null) { 138 143 String lhsCode = getCode(lhs.getType()); 144 String rhsCode = getCode(rhs.getType()); 145 146 if ((cmp = lhsCode.compareTo(rhsCode)) != 0) { 147 return cmp; 148 } 149 } else { 150 if ((cmp = lhsPattern.getAbbrev().compareTo(rhsPattern.getAbbrev())) != 0) 157 return cmp; 158 if (isExactBugPatternMatch() && (cmp = lhsPattern.getType().compareTo(rhsPattern.getType())) != 0) 159 return cmp; 160 } 161 162 163 164 165 if (comparePriorities) { 166 cmp = lhs.getPriority() - rhs.getPriority(); 167 if (cmp != 0) return cmp; 168 } 169 170 171 Iterator <BugAnnotation> lhsIter = new FilteringAnnotationIterator(lhs.annotationIterator()); 172 Iterator <BugAnnotation> rhsIter = new FilteringAnnotationIterator(rhs.annotationIterator()); 173 174 while (lhsIter.hasNext() && rhsIter.hasNext()) { 175 BugAnnotation lhsAnnotation = lhsIter.next(); 176 BugAnnotation rhsAnnotation = rhsIter.next(); 177 178 if (lhsAnnotation.getClass() != rhsAnnotation.getClass()) 181 return lhsAnnotation.getClass().getName().compareTo(rhsAnnotation.getClass().getName()); 182 183 if (lhsAnnotation.getClass() == ClassAnnotation.class) { 184 187 String lhsClassName = classNameRewriter.rewriteClassName( 188 ((ClassAnnotation)lhsAnnotation).getClassName()); 189 String rhsClassName = classNameRewriter.rewriteClassName( 190 ((ClassAnnotation)rhsAnnotation).getClassName()); 191 192 return lhsClassName.compareTo(rhsClassName); 193 194 } else if(lhsAnnotation.getClass() == MethodAnnotation.class ) { 195 MethodAnnotation lhsMethod = ClassNameRewriterUtil.convertMethodAnnotation( 197 classNameRewriter, (MethodAnnotation) lhsAnnotation); 198 MethodAnnotation rhsMethod = ClassNameRewriterUtil.convertMethodAnnotation( 199 classNameRewriter, (MethodAnnotation) rhsAnnotation); 200 201 cmp = lhsMethod.compareTo(rhsMethod); 202 if (cmp != 0) 203 return cmp; 204 205 } else if(lhsAnnotation.getClass() == FieldAnnotation.class) { 206 FieldAnnotation lhsField = ClassNameRewriterUtil.convertFieldAnnotation( 208 classNameRewriter, (FieldAnnotation) lhsAnnotation); 209 FieldAnnotation rhsField = ClassNameRewriterUtil.convertFieldAnnotation( 210 classNameRewriter, (FieldAnnotation) rhsAnnotation); 211 212 cmp = lhsField.compareTo(rhsField); 213 if (cmp != 0) 214 return cmp; 215 } else if (isBoring(lhsAnnotation)) { 216 throw new IllegalStateException ("Impossible"); 217 } else 218 throw new IllegalStateException ("Unknown annotation type: " + lhsAnnotation.getClass().getName()); 219 } 220 221 if (rhsIter.hasNext()) 222 return -1; 223 else if (lhsIter.hasNext()) 224 return 1; 225 else 226 return 0; 227 } 228 229 232 public void setExactBugPatternMatch(boolean exactBugPatternMatch) { 233 this.exactBugPatternMatch = exactBugPatternMatch; 234 } 235 236 239 public boolean isExactBugPatternMatch() { 240 return exactBugPatternMatch; 241 } 242 } 243 244 245 246 | Popular Tags |