From 7e212fe31cf53def323428e7c7ac35938f4ca691 Mon Sep 17 00:00:00 2001 From: Godin Date: Mon, 18 Oct 2010 14:48:32 +0000 Subject: [PATCH] SONAR-1772: Remove the use of the Maven Findbugs plugin to directly pilot the Findbugs library --- plugins/sonar-findbugs-plugin/pom.xml | 42 +- .../findbugs/FindbugsConfiguration.java | 67 + .../plugins/findbugs/FindbugsConstants.java | 6 + .../plugins/findbugs/FindbugsExecutor.java | 85 ++ .../findbugs/FindbugsNativeSensor.java | 56 + .../plugins/findbugs/FindbugsPlugin.java | 6 +- .../findbugs/FindbugsExecutorTest.java | 42 + .../test-resources/classes/Hello.class | Bin 0 -> 397 bytes .../test-resources/findbugs-exclude.xml | 1 + .../test-resources/findbugs-include.xml | 1129 +++++++++++++++++ .../test-resources/src/Hello.java | 13 + 11 files changed, 1443 insertions(+), 4 deletions(-) create mode 100644 plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsConfiguration.java create mode 100644 plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsExecutor.java create mode 100644 plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsNativeSensor.java create mode 100644 plugins/sonar-findbugs-plugin/src/test/java/org/sonar/plugins/findbugs/FindbugsExecutorTest.java create mode 100644 plugins/sonar-findbugs-plugin/test-resources/classes/Hello.class create mode 100644 plugins/sonar-findbugs-plugin/test-resources/findbugs-exclude.xml create mode 100644 plugins/sonar-findbugs-plugin/test-resources/findbugs-include.xml create mode 100644 plugins/sonar-findbugs-plugin/test-resources/src/Hello.java diff --git a/plugins/sonar-findbugs-plugin/pom.xml b/plugins/sonar-findbugs-plugin/pom.xml index e5a6a2de718..22c29a476a9 100644 --- a/plugins/sonar-findbugs-plugin/pom.xml +++ b/plugins/sonar-findbugs-plugin/pom.xml @@ -17,11 +17,50 @@ 1.3.9 + + + + + xerces + xercesImpl + 2.6.2 + + + xalan + xalan + 2.6.0 + + + + org.codehaus.sonar sonar-plugin-api ${project.version} + + + xalan + xalan + + + jaxen + jaxen + + + dom4j + dom4j + + + xerces + xercesImpl + + + + + com.google.code.findbugs + findbugs + ${findbugs.version} org.codehaus.sonar @@ -63,12 +102,11 @@ org.codehaus.sonar sonar-packaging-maven-plugin - true - findbugs Findbugs Findbugs ${findbugs.version}.]]> org.sonar.plugins.findbugs.FindbugsPlugin + true diff --git a/plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsConfiguration.java b/plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsConfiguration.java new file mode 100644 index 00000000000..fe0e05e6bf1 --- /dev/null +++ b/plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsConfiguration.java @@ -0,0 +1,67 @@ +package org.sonar.plugins.findbugs; + +import org.sonar.api.BatchExtension; +import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.resources.Project; +import org.sonar.api.utils.SonarException; +import org.sonar.plugins.findbugs.xml.ClassFilter; +import org.sonar.plugins.findbugs.xml.FindBugsFilter; +import org.sonar.plugins.findbugs.xml.Match; + +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; + +/** + * @since 2.4 + */ +public class FindbugsConfiguration implements BatchExtension { + + private Project project; + private RulesProfile profile; + private FindbugsProfileExporter exporter; + + public FindbugsConfiguration(Project project, RulesProfile profile, FindbugsProfileExporter exporter) { + this.project = project; + this.profile = profile; + this.exporter = exporter; + } + + public File getTargetXMLReport() { + if (project.getConfiguration().getBoolean(FindbugsConstants.GENERATE_XML_KEY, FindbugsConstants.GENERATE_XML_DEFAULT_VALUE)) { + return new File(project.getFileSystem().getSonarWorkingDirectory(), "findbugs-result.xml"); + } + return null; + } + + public edu.umd.cs.findbugs.Project getFindbugsProject() { + try { + edu.umd.cs.findbugs.Project findbugsProject = new edu.umd.cs.findbugs.Project(); + for (File dir : project.getFileSystem().getSourceDirs()) { + findbugsProject.addSourceDir(dir.getAbsolutePath()); + } + findbugsProject.addFile(project.getFileSystem().getBuildOutputDir().getAbsolutePath()); + findbugsProject.setCurrentWorkingDirectory(project.getFileSystem().getBuildDir()); + return findbugsProject; + } catch (Exception e) { + throw new SonarException(e); + } + } + + public File saveIncludeConfigXml() throws IOException { + StringWriter conf = new StringWriter(); + exporter.exportProfile(profile, conf); + return project.getFileSystem().writeToWorkingDirectory(conf.toString(), "findbugs-include.xml"); + } + + public File saveExcludeConfigXml() throws IOException { + FindBugsFilter findBugsFilter = new FindBugsFilter(); + if (project.getExclusionPatterns() != null) { + for (String exclusion : project.getExclusionPatterns()) { + ClassFilter classFilter = new ClassFilter(FindbugsAntConverter.antToJavaRegexpConvertor(exclusion)); + findBugsFilter.addMatch(new Match(classFilter)); + } + } + return project.getFileSystem().writeToWorkingDirectory(findBugsFilter.toXml(), "findbugs-exclude.xml"); + } +} diff --git a/plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsConstants.java b/plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsConstants.java index a49d06f620a..363cf01ddf2 100644 --- a/plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsConstants.java +++ b/plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsConstants.java @@ -27,4 +27,10 @@ public final class FindbugsConstants { public static final String REPOSITORY_NAME = "Findbugs"; public static final String PLUGIN_NAME = "Findbugs"; public static final String PLUGIN_KEY = CoreProperties.FINDBUGS_PLUGIN; + + /** + * @since 2.4 + */ + public static final String GENERATE_XML_KEY = "sonar.findbugs.generateXml"; + public static final boolean GENERATE_XML_DEFAULT_VALUE = true; // TODO should be false } diff --git a/plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsExecutor.java b/plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsExecutor.java new file mode 100644 index 00000000000..d6465723b46 --- /dev/null +++ b/plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsExecutor.java @@ -0,0 +1,85 @@ +package org.sonar.plugins.findbugs; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.output.NullOutputStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.BatchExtension; +import org.sonar.api.utils.SonarException; +import org.sonar.api.utils.TimeProfiler; + +import edu.umd.cs.findbugs.*; +import edu.umd.cs.findbugs.annotations.Priority; +import edu.umd.cs.findbugs.config.UserPreferences; + +import java.io.File; +import java.io.OutputStream; +import java.io.PrintStream; + +/** + * @since 2.4 + */ +public class FindbugsExecutor implements BatchExtension { + private static Logger LOG = LoggerFactory.getLogger(FindbugsExecutor.class); + + private FindbugsConfiguration configuration; + + public FindbugsExecutor(FindbugsConfiguration configuration) { + this.configuration = configuration; + } + + public File execute() { + TimeProfiler profiler = new TimeProfiler().start("Execute Findbugs"); + ClassLoader initialClassLoader = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(FindBugs2.class.getClassLoader()); + + OutputStream xmlOutput = null; + try { + final FindBugs2 engine = new FindBugs2(); + + Project project = configuration.getFindbugsProject(); + engine.setProject(project); + + XMLBugReporter xmlBugReporter = new XMLBugReporter(project); + xmlBugReporter.setPriorityThreshold(Priority.LOW.getPriorityValue()); + // xmlBugReporter.setErrorVerbosity(BugReporter.SILENT); + + File xmlReport = configuration.getTargetXMLReport(); + if (xmlReport != null) { + LOG.info("Findbugs output report: " + xmlReport.getAbsolutePath()); + xmlOutput = FileUtils.openOutputStream(xmlReport); + } else { + xmlOutput = new NullOutputStream(); + } + xmlBugReporter.setOutputStream(new PrintStream(xmlOutput)); + + engine.setBugReporter(xmlBugReporter); + + engine.setProject(project); + + engine.setDetectorFactoryCollection(DetectorFactoryCollection.instance()); + UserPreferences userPreferences = UserPreferences.createDefaultUserPreferences(); + userPreferences.setEffort(UserPreferences.EFFORT_DEFAULT); + + engine.addFilter(configuration.saveIncludeConfigXml().getAbsolutePath(), true); + engine.addFilter(configuration.saveExcludeConfigXml().getAbsolutePath(), false); + + engine.setUserPreferences(userPreferences); + engine.setAnalysisFeatureSettings(FindBugs.DEFAULT_EFFORT); + + engine.finishSettings(); + + engine.execute(); + + profiler.stop(); + return xmlReport; + } catch (Exception e) { + throw new SonarException("Can not execute Findbugs", e); + } finally { + IOUtils.closeQuietly(xmlOutput); + Thread.currentThread().setContextClassLoader(initialClassLoader); + } + } + +} diff --git a/plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsNativeSensor.java b/plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsNativeSensor.java new file mode 100644 index 00000000000..9d0d823e234 --- /dev/null +++ b/plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsNativeSensor.java @@ -0,0 +1,56 @@ +package org.sonar.plugins.findbugs; + +import org.apache.commons.lang.StringUtils; +import org.sonar.api.batch.Sensor; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.resources.JavaFile; +import org.sonar.api.resources.Project; +import org.sonar.api.rules.Rule; +import org.sonar.api.rules.RuleFinder; +import org.sonar.api.rules.Violation; + +import java.util.List; + +/** + * EXPERIMENTAL! + * + * @since 2.4 + */ +public class FindbugsNativeSensor implements Sensor { + + private RulesProfile profile; + private RuleFinder ruleFinder; + private FindbugsExecutor executor; + + public FindbugsNativeSensor(RulesProfile profile, RuleFinder ruleFinder, FindbugsExecutor executor) { + this.profile = profile; + this.ruleFinder = ruleFinder; + this.executor = executor; + } + + public boolean shouldExecuteOnProject(Project project) { + return project.getFileSystem().hasJavaSourceFiles() + && ( !profile.getActiveRulesByRepository(FindbugsConstants.REPOSITORY_KEY).isEmpty() || project.getReuseExistingRulesConfig()) + && project.getPom() != null && !StringUtils.equalsIgnoreCase(project.getPom().getPackaging(), "ear"); + } + + public void analyse(Project project, SensorContext context) { + FindbugsXmlReportParser reportParser = new FindbugsXmlReportParser(executor.execute()); + List fbViolations = reportParser.getViolations(); + for (FindbugsXmlReportParser.Violation fbViolation : fbViolations) { + Rule rule = ruleFinder.findByKey(FindbugsConstants.REPOSITORY_KEY, fbViolation.getType()); + JavaFile resource = new JavaFile(fbViolation.getSonarJavaFileKey()); + if (context.getResource(resource) != null) { + Violation violation = Violation.create(rule, resource).setLineId(fbViolation.getStart()).setMessage(fbViolation.getLongMessage()); + context.saveViolation(violation); + } + } + } + + @Override + public String toString() { + return getClass().getSimpleName(); + } + +} diff --git a/plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsPlugin.java b/plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsPlugin.java index c43965d1b3b..0dec503b018 100644 --- a/plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsPlugin.java +++ b/plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsPlugin.java @@ -69,8 +69,10 @@ public class FindbugsPlugin implements Plugin { public List> getExtensions() { List> list = new ArrayList>(); - list.add(FindbugsSensor.class); - list.add(FindbugsMavenPluginHandler.class); + list.add(FindbugsNativeSensor.class); + list.add(FindbugsConfiguration.class); + list.add(FindbugsExecutor.class); + // list.add(FindbugsMavenPluginHandler.class); list.add(FindbugsRuleRepository.class); list.add(FindbugsProfileExporter.class); list.add(FindbugsProfileImporter.class); diff --git a/plugins/sonar-findbugs-plugin/src/test/java/org/sonar/plugins/findbugs/FindbugsExecutorTest.java b/plugins/sonar-findbugs-plugin/src/test/java/org/sonar/plugins/findbugs/FindbugsExecutorTest.java new file mode 100644 index 00000000000..cae79c1cf01 --- /dev/null +++ b/plugins/sonar-findbugs-plugin/src/test/java/org/sonar/plugins/findbugs/FindbugsExecutorTest.java @@ -0,0 +1,42 @@ +package org.sonar.plugins.findbugs; + +import org.apache.commons.io.FileUtils; +import org.junit.Test; + +import edu.umd.cs.findbugs.Project; + +import java.io.File; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; +import static org.junit.internal.matchers.StringContains.containsString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class FindbugsExecutorTest { + + @Test + public void canGenerateXMLReport() throws Exception { + FindbugsConfiguration conf = mockConf(); + File report = new File("target/test-tmp/findbugs-report.xml"); + when(conf.getTargetXMLReport()).thenReturn(report); + FindbugsExecutor executor = new FindbugsExecutor(conf); + executor.execute(); + + assertThat(report.exists(), is(true)); + assertThat(FileUtils.readFileToString(report), containsString("=n39eb6%8T?+@ZbaZ zP~v1Q6zU-}!#BTtGxPoP`32w--2?#+>hRHyaTue+5NMtYhW2R5-}pdrJs*s1A@zL7 z5M4rV*1F*8D&BdNuGnP;MS|uX{A8l~Y Of8VifP^U?nht@B7=0$%1 literal 0 HcmV?d00001 diff --git a/plugins/sonar-findbugs-plugin/test-resources/findbugs-exclude.xml b/plugins/sonar-findbugs-plugin/test-resources/findbugs-exclude.xml new file mode 100644 index 00000000000..f1255e54f86 --- /dev/null +++ b/plugins/sonar-findbugs-plugin/test-resources/findbugs-exclude.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/plugins/sonar-findbugs-plugin/test-resources/findbugs-include.xml b/plugins/sonar-findbugs-plugin/test-resources/findbugs-include.xml new file mode 100644 index 00000000000..e9a13f8b40c --- /dev/null +++ b/plugins/sonar-findbugs-plugin/test-resources/findbugs-include.xml @@ -0,0 +1,1129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/sonar-findbugs-plugin/test-resources/src/Hello.java b/plugins/sonar-findbugs-plugin/test-resources/src/Hello.java new file mode 100644 index 00000000000..5bb582c7254 --- /dev/null +++ b/plugins/sonar-findbugs-plugin/test-resources/src/Hello.java @@ -0,0 +1,13 @@ +class Hello { + + static String name; + + public void methodWithViolations(String n) { + name = n; + } + + @Override + public boolean equals(Object obj) { + return false; + } +} \ No newline at end of file -- 2.39.5