/* * FindBugs - Find bugs in Java programs * Copyright (C) 2003-2005 University of Maryland * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package edu.umd.cs.findbugs.detect; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.bcel.Repository; import org.apache.bcel.classfile.JavaClass; import edu.umd.cs.findbugs.BugReporter; import edu.umd.cs.findbugs.ClassAnnotation; import edu.umd.cs.findbugs.ClassWarningSuppressor; import edu.umd.cs.findbugs.DelegatingBugReporter; import edu.umd.cs.findbugs.Detector; import edu.umd.cs.findbugs.FieldAnnotation; import edu.umd.cs.findbugs.FieldWarningSuppressor; import edu.umd.cs.findbugs.FilterBugReporter; import edu.umd.cs.findbugs.MethodAnnotation; import edu.umd.cs.findbugs.MethodWarningSuppressor; import edu.umd.cs.findbugs.NonReportingDetector; import edu.umd.cs.findbugs.PackageWarningSuppressor; import edu.umd.cs.findbugs.ParameterWarningSuppressor; import edu.umd.cs.findbugs.SuppressionMatcher; import edu.umd.cs.findbugs.ba.ClassContext; import edu.umd.cs.findbugs.bcel.BCELUtil; import edu.umd.cs.findbugs.visitclass.AnnotationVisitor; public class NoteSuppressedWarnings extends AnnotationVisitor implements Detector, NonReportingDetector { private Set<String> packages = new HashSet<String>(); private SuppressionMatcher suppressionMatcher; private NoteSuppressedWarnings recursiveDetector; public NoteSuppressedWarnings(BugReporter bugReporter) { this(bugReporter, false); } public NoteSuppressedWarnings(BugReporter bugReporter, boolean recursive) { if (!recursive) { DelegatingBugReporter b = (DelegatingBugReporter) bugReporter; BugReporter origBugReporter = b.getDelegate(); suppressionMatcher = new SuppressionMatcher(); BugReporter filterBugReporter = new FilterBugReporter(origBugReporter, suppressionMatcher, false); b.setDelegate(filterBugReporter); recursiveDetector = new NoteSuppressedWarnings(bugReporter, true); recursiveDetector.suppressionMatcher = suppressionMatcher; } } public void visitClassContext(ClassContext classContext) { JavaClass javaClass = classContext.getJavaClass(); if (!BCELUtil.preTiger(javaClass)) javaClass.accept(this); } @Override public void visit(JavaClass obj) { if (recursiveDetector == null) return; try { if (getClassName().endsWith("package-info")) return; String packageName = getPackageName().replace('/', '.'); if (!packages.add(packageName)) return; String packageInfo = "package-info"; if (packageName.length() > 0) packageInfo = packageName + "." + packageInfo; JavaClass packageInfoClass = Repository.lookupClass(packageInfo); recursiveDetector.visitJavaClass(packageInfoClass); } catch (ClassNotFoundException e) { // ignore } } @Override public void visitAnnotation(String annotationClass, Map<String, Object> map, boolean runtimeVisible) { if (!annotationClass.endsWith("SuppressWarnings")) return; Object value = map.get("value"); if (value == null || !(value instanceof Object[])) { suppressWarning(null); return; } Object[] suppressedWarnings = (Object[]) value; if (suppressedWarnings.length == 0) suppressWarning(null); else for (Object suppressedWarning : suppressedWarnings) if (suppressedWarning instanceof String) suppressWarning((String) suppressedWarning); } @Override public void visitParameterAnnotation(int p, String annotationClass, Map<String, Object> map, boolean runtimeVisible) { if (!annotationClass.endsWith("SuppressWarnings")) return; if (!getMethod().isStatic()) p++; Object value = map.get("value"); if (value == null || !(value instanceof Object[])) { suppressWarning(p, null); return; } Object[] suppressedWarnings = (Object[]) value; if (suppressedWarnings.length == 0) suppressWarning(p, null); else for (Object suppressedWarning : suppressedWarnings) if (suppressedWarning instanceof String) suppressWarning(p, (String) suppressedWarning); } private void suppressWarning(int parameter, String pattern) { String className = getDottedClassName(); ClassAnnotation clazz = new ClassAnnotation(className); suppressionMatcher.addSuppressor(new ParameterWarningSuppressor(pattern, clazz, MethodAnnotation.fromVisitedMethod(this), parameter)); } private void suppressWarning(String pattern) { String className = getDottedClassName(); ClassAnnotation clazz = new ClassAnnotation(className); if (className.endsWith("package-info") && recursiveDetector == null) suppressionMatcher.addPackageSuppressor(new PackageWarningSuppressor(pattern, getPackageName().replace('/', '.'))); else if (visitingMethod()) suppressionMatcher.addSuppressor(new MethodWarningSuppressor(pattern, clazz, MethodAnnotation.fromVisitedMethod(this))); else if (visitingField()) suppressionMatcher.addSuppressor(new FieldWarningSuppressor(pattern, clazz, FieldAnnotation.fromVisitedField(this))); else suppressionMatcher.addSuppressor(new ClassWarningSuppressor(pattern, clazz)); } public void report() { } }