package gb.svnfilter.findbugs; import gb.svnutils.SvnDiffManager; import gb.svnutils.SvnUtilsConsoleFactory; import java.util.List; import org.eclipse.core.resources.IProject; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import de.tobject.findbugs.reporter.IMarkerFilter; import edu.umd.cs.findbugs.BugAnnotation; import edu.umd.cs.findbugs.BugInstance; import edu.umd.cs.findbugs.ClassAnnotation; import edu.umd.cs.findbugs.MethodAnnotation; import edu.umd.cs.findbugs.SourceLineAnnotation; /** * Filter out markers which are present in clean code. */ public class SvnMarkerFilter implements IMarkerFilter { private SvnDiffManager diffManager = new SvnDiffManager(); public String getFilterID() { return SvnMarkerFilter.class.getCanonicalName(); } public String getName() { return "SVN Filter"; } public boolean isFiltered(IProject project, BugInstance bugInstance) { List<? extends BugAnnotation> annotations = bugInstance.getAnnotations(); IType element = null; for (BugAnnotation annot : annotations) { if (annot instanceof ClassAnnotation) { ClassAnnotation classAnnot = (ClassAnnotation)annot; String className = classAnnot.getClassName(); if ((className != null) && (className.indexOf("$") > -1)) { // This line makes anonymous inner classes imprecise. Any changes to // the java file which contains an anonymous inner class will cause // all bugs in these inner classes to be included. className = className.substring(0, className.indexOf("$")); } IJavaProject jproject = JavaCore.create(project); try { element = jproject.findType(className); if (element != null) { // Bug is filtered if the class is clean if (!diffManager.isSVNDirty(element)) { return true; } } } catch (JavaModelException e) { // Throw away the exception } } else if ((annot instanceof MethodAnnotation) && (element != null)) { MethodAnnotation methodAnnot = (MethodAnnotation)annot; try { MethodLocator locator = new MethodLocator(element); IMethod method = locator.findMethod(methodAnnot.getMethodName(), methodAnnot.getMethodSignature()); if (method != null) { // Bug is filtered if the method is clean if (!diffManager.isSVNDirty(method)) { return true; } } } catch (JavaModelException e) { // Throw away the exception } } else if ((annot instanceof SourceLineAnnotation) && (element != null)) { SourceLineAnnotation lineAnnot = (SourceLineAnnotation)annot; int startLine = lineAnnot.getStartLine(); int endLine = lineAnnot.getEndLine(); int numLines = startLine - endLine + 1; int[] lines = new int[numLines]; for (int ii = 0; ii < lines.length; ii++) { lines[ii] = startLine + ii; } lines = diffManager.filterSVNCleanLines(lines,element); // Check for unfiltered lines for (int ii = 0; ii < lines.length; ii++) { // Unfiltered line - one of the bugged lines is dirty - don't filter // this bug annotation! if (lines[ii] != -1) { return false; } } // All lines were filtered - filter this bug annotation return true; } } return false; } public void resetFilter() { diffManager = new SvnDiffManager(); SvnUtilsConsoleFactory.outputLine("FindBugs Marker filter reset"); } }