Moreover, the Findbugs plugin now uses the new Rule APItags/2.6
@@ -22,7 +22,7 @@ package org.sonar.plugins.findbugs; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
public final class Category { | |||
public final class FindbugsCategory { | |||
private final static Map<String, String> findbugsToSonar = new HashMap<String, String>(); | |||
static { |
@@ -1,33 +1,30 @@ | |||
/* | |||
* Sonar, open source software quality management tool. | |||
* Copyright (C) 2009 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* Sonar 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 3 of the License, or (at your option) any later version. | |||
* | |||
* Sonar 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 Sonar; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.plugins.findbugs.xml; | |||
import static org.hamcrest.CoreMatchers.*; | |||
import static org.junit.Assert.*; | |||
import org.sonar.plugins.findbugs.FindbugsTests; | |||
public class FindBugsXmlTests extends FindbugsTests { | |||
protected static void assertChild(Match child, String configKey) { | |||
Bug bug = child.getBug(); | |||
assertNotNull(bug); | |||
assertThat(bug.getPattern(), is(configKey)); | |||
} | |||
} | |||
/* | |||
* Sonar, open source software quality management tool. | |||
* Copyright (C) 2009 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* Sonar 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 3 of the License, or (at your option) any later version. | |||
* | |||
* Sonar 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 Sonar; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.plugins.findbugs; | |||
import org.sonar.api.CoreProperties; | |||
public final class FindbugsConstants { | |||
public static final String REPOSITORY_KEY = CoreProperties.FINDBUGS_PLUGIN; | |||
public static final String REPOSITORY_NAME = "Findbugs"; | |||
public static final String PLUGIN_NAME = "Findbugs"; | |||
public static final String PLUGIN_KEY = CoreProperties.FINDBUGS_PLUGIN; | |||
} |
@@ -20,9 +20,8 @@ | |||
package org.sonar.plugins.findbugs; | |||
import org.sonar.api.rules.RulePriority; | |||
import org.sonar.api.rules.RulePriorityMapper; | |||
public class FindbugsRulePriorityMapper implements RulePriorityMapper<String, String> { | |||
public class FindbugsLevelUtils { | |||
public RulePriority from(String priority) { | |||
if (priority.equals("1")) { | |||
@@ -36,18 +35,4 @@ public class FindbugsRulePriorityMapper implements RulePriorityMapper<String, St | |||
} | |||
throw new IllegalArgumentException("Priority not supported: " + priority); | |||
} | |||
public String to(RulePriority priority) { | |||
if (priority.equals(RulePriority.BLOCKER) || priority.equals(RulePriority.CRITICAL)) { | |||
return "1"; | |||
} | |||
if (priority.equals(RulePriority.MAJOR)) { | |||
return "2"; | |||
} | |||
if (priority.equals(RulePriority.INFO) || priority.equals(RulePriority.MINOR)) { | |||
return "3"; | |||
} | |||
throw new IllegalArgumentException("Priority not supported: " + priority); | |||
} | |||
} |
@@ -21,6 +21,7 @@ package org.sonar.plugins.findbugs; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.StringWriter; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.CoreProperties; | |||
@@ -37,11 +38,11 @@ import org.sonar.plugins.findbugs.xml.Match; | |||
public class FindbugsMavenPluginHandler implements MavenPluginHandler { | |||
private RulesProfile profile; | |||
private FindbugsRulesRepository findbugsRulesRepository; | |||
private FindbugsProfileExporter exporter; | |||
public FindbugsMavenPluginHandler(RulesProfile profile, FindbugsRulesRepository findbugsRulesRepository) { | |||
public FindbugsMavenPluginHandler(RulesProfile profile, FindbugsProfileExporter exporter) { | |||
this.profile = profile; | |||
this.findbugsRulesRepository = findbugsRulesRepository; | |||
this.exporter = exporter; | |||
} | |||
public String getGroupId() { | |||
@@ -121,8 +122,9 @@ public class FindbugsMavenPluginHandler implements MavenPluginHandler { | |||
} | |||
private File saveIncludeConfigXml(Project project) throws IOException { | |||
String configuration = findbugsRulesRepository.exportConfiguration(profile); | |||
return project.getFileSystem().writeToWorkingDirectory(configuration, "findbugs-include.xml"); | |||
StringWriter conf = new StringWriter(); | |||
exporter.exportProfile(profile, conf); | |||
return project.getFileSystem().writeToWorkingDirectory(conf.toString(), "findbugs-include.xml"); | |||
} | |||
private File saveExcludeConfigXml(Project project) throws IOException { |
@@ -19,11 +19,15 @@ | |||
*/ | |||
package org.sonar.plugins.findbugs; | |||
import org.sonar.api.*; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.Extension; | |||
import org.sonar.api.Plugin; | |||
import org.sonar.api.Properties; | |||
import org.sonar.api.Property; | |||
@Properties({ | |||
@Property( | |||
key = CoreProperties.FINDBUGS_EFFORT_PROPERTY, | |||
@@ -67,7 +71,10 @@ public class FindbugsPlugin implements Plugin { | |||
List<Class<? extends Extension>> list = new ArrayList<Class<? extends Extension>>(); | |||
list.add(FindbugsSensor.class); | |||
list.add(FindbugsMavenPluginHandler.class); | |||
list.add(FindbugsRulesRepository.class); | |||
list.add(FindbugsRuleRepository.class); | |||
list.add(FindbugsProfileExporter.class); | |||
list.add(FindbugsProfileImporter.class); | |||
list.add(SonarWayWithFindbugsProfile.class); | |||
return list; | |||
} | |||
} |
@@ -0,0 +1,67 @@ | |||
/* | |||
* Sonar, open source software quality management tool. | |||
* Copyright (C) 2009 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* Sonar 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 3 of the License, or (at your option) any later version. | |||
* | |||
* Sonar 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 Sonar; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.plugins.findbugs; | |||
import java.io.IOException; | |||
import java.io.Writer; | |||
import java.util.List; | |||
import org.sonar.api.profiles.ProfileExporter; | |||
import org.sonar.api.profiles.RulesProfile; | |||
import org.sonar.api.resources.Java; | |||
import org.sonar.api.rules.ActiveRule; | |||
import org.sonar.api.utils.SonarException; | |||
import org.sonar.plugins.findbugs.xml.Bug; | |||
import org.sonar.plugins.findbugs.xml.FindBugsFilter; | |||
import org.sonar.plugins.findbugs.xml.Match; | |||
import com.thoughtworks.xstream.XStream; | |||
public class FindbugsProfileExporter extends ProfileExporter { | |||
public FindbugsProfileExporter() { | |||
super(FindbugsConstants.REPOSITORY_KEY, FindbugsConstants.PLUGIN_NAME); | |||
setSupportedLanguages(Java.KEY); | |||
setMimeType("application/xml"); | |||
} | |||
@Override | |||
public void exportProfile(RulesProfile profile, Writer writer) { | |||
try { | |||
FindBugsFilter filter = buildFindbugsFilter(profile.getActiveRulesByRepository(FindbugsConstants.REPOSITORY_KEY)); | |||
XStream xstream = FindBugsFilter.createXStream(); | |||
writer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- Generated by Sonar -->\n".concat(xstream.toXML(filter))); | |||
} catch (IOException e) { | |||
throw new SonarException("Fail to export the Findbugs profile : " + profile, e); | |||
} | |||
} | |||
protected static FindBugsFilter buildFindbugsFilter(List<ActiveRule> activeRules) { | |||
FindBugsFilter root = new FindBugsFilter(); | |||
for (ActiveRule activeRule : activeRules) { | |||
if (FindbugsConstants.REPOSITORY_KEY.equals(activeRule.getRepositoryKey())) { | |||
Match child = new Match(); | |||
child.setBug(new Bug(activeRule.getConfigKey())); | |||
root.addMatch(child); | |||
} | |||
} | |||
return root; | |||
} | |||
} |
@@ -0,0 +1,112 @@ | |||
/* | |||
* Sonar, open source software quality management tool. | |||
* Copyright (C) 2009 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* Sonar 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 3 of the License, or (at your option) any later version. | |||
* | |||
* Sonar 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 Sonar; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.plugins.findbugs; | |||
import java.io.Reader; | |||
import java.util.Map; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.sonar.api.profiles.ProfileImporter; | |||
import org.sonar.api.profiles.RulesProfile; | |||
import org.sonar.api.resources.Java; | |||
import org.sonar.api.rules.Rule; | |||
import org.sonar.api.rules.RuleFinder; | |||
import org.sonar.api.rules.RulePriority; | |||
import org.sonar.api.rules.RuleQuery; | |||
import org.sonar.api.utils.ValidationMessages; | |||
import org.sonar.plugins.findbugs.xml.FindBugsFilter; | |||
import com.thoughtworks.xstream.XStream; | |||
public class FindbugsProfileImporter extends ProfileImporter { | |||
private final RuleFinder ruleFinder; | |||
private static Logger LOG = LoggerFactory.getLogger(FindbugsProfileImporter.class); | |||
public FindbugsProfileImporter(RuleFinder ruleFinder) { | |||
super(FindbugsConstants.REPOSITORY_KEY, FindbugsConstants.PLUGIN_NAME); | |||
setSupportedLanguages(Java.KEY); | |||
this.ruleFinder = ruleFinder; | |||
} | |||
@Override | |||
public RulesProfile importProfile(Reader findbugsConf, ValidationMessages messages) { | |||
RulesProfile profile = RulesProfile.create(); | |||
try { | |||
XStream xStream = FindBugsFilter.createXStream(); | |||
FindBugsFilter filter = (FindBugsFilter) xStream.fromXML(findbugsConf); | |||
activateRulesByCategory(profile, filter, messages); | |||
activateRulesByCode(profile, filter, messages); | |||
activateRulesByPattern(profile, filter, messages); | |||
return profile; | |||
} catch (Exception e) { | |||
String errorMessage = "The Findbugs configuration file is not valid"; | |||
messages.addErrorText(errorMessage + " : " + e.getMessage()); | |||
LOG.error(errorMessage, e); | |||
return profile; | |||
} | |||
} | |||
private void activateRulesByPattern(RulesProfile profile, FindBugsFilter filter, ValidationMessages messages) { | |||
for (Map.Entry<String, RulePriority> patternLevel : filter.getPatternLevels(new FindbugsLevelUtils()).entrySet()) { | |||
Rule rule = ruleFinder.findByKey(FindbugsConstants.REPOSITORY_KEY, patternLevel.getKey()); | |||
if (rule != null) { | |||
profile.activateRule(rule, patternLevel.getValue()); | |||
} else { | |||
messages.addWarningText("Unable to activate unknown rule : '" + patternLevel.getKey() + "'"); | |||
} | |||
} | |||
} | |||
private void activateRulesByCode(RulesProfile profile, FindBugsFilter filter, ValidationMessages messages) { | |||
for (Map.Entry<String, RulePriority> codeLevel : filter.getCodeLevels(new FindbugsLevelUtils()).entrySet()) { | |||
boolean someRulesHaveBeenActivated = false; | |||
for (Rule rule : ruleFinder.findAll(RuleQuery.create().withRepositoryKey(FindbugsConstants.REPOSITORY_KEY))) { | |||
if (rule.getKey().equals(codeLevel.getKey()) || StringUtils.startsWith(rule.getKey(), codeLevel.getKey() + "_")) { | |||
someRulesHaveBeenActivated = true; | |||
profile.activateRule(rule, codeLevel.getValue()); | |||
} | |||
} | |||
if ( !someRulesHaveBeenActivated) { | |||
messages.addWarningText("Unable to find any rules associated to code : '" + codeLevel.getKey() + "'"); | |||
} | |||
} | |||
} | |||
private void activateRulesByCategory(RulesProfile profile, FindBugsFilter filter, ValidationMessages messages) { | |||
for (Map.Entry<String, RulePriority> categoryLevel : filter.getCategoryLevels(new FindbugsLevelUtils()).entrySet()) { | |||
boolean someRulesHaveBeenActivated = false; | |||
String sonarCateg = FindbugsCategory.findbugsToSonar(categoryLevel.getKey()); | |||
for (Rule rule : ruleFinder.findAll(RuleQuery.create().withRepositoryKey(FindbugsConstants.REPOSITORY_KEY))) { | |||
if (sonarCateg != null && rule.getName().startsWith(sonarCateg)) { | |||
someRulesHaveBeenActivated = true; | |||
profile.activateRule(rule, categoryLevel.getValue()); | |||
} | |||
} | |||
if ( !someRulesHaveBeenActivated) { | |||
messages.addWarningText("Unable to find any rules associated to category : '" + categoryLevel.getKey() + "'"); | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,44 @@ | |||
/* | |||
* Sonar, open source software quality management tool. | |||
* Copyright (C) 2009 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* Sonar 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 3 of the License, or (at your option) any later version. | |||
* | |||
* Sonar 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 Sonar; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.plugins.findbugs; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import org.sonar.api.platform.ServerFileSystem; | |||
import org.sonar.api.resources.Java; | |||
import org.sonar.api.rules.Rule; | |||
import org.sonar.api.rules.RuleRepository; | |||
import org.sonar.api.rules.StandardRuleXmlFormat; | |||
public final class FindbugsRuleRepository extends RuleRepository { | |||
public FindbugsRuleRepository() { | |||
super(FindbugsConstants.REPOSITORY_KEY, Java.KEY); | |||
setName(FindbugsConstants.REPOSITORY_NAME); | |||
} | |||
@Override | |||
public List<Rule> createRules() { | |||
List<Rule> rules = new ArrayList<Rule>(); | |||
rules.addAll(StandardRuleXmlFormat.parseXml(getClass().getResourceAsStream("/org/sonar/plugins/findbugs/rules.xml"))); | |||
return rules; | |||
} | |||
} |
@@ -1,111 +0,0 @@ | |||
/* | |||
* Sonar, open source software quality management tool. | |||
* Copyright (C) 2009 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* Sonar 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 3 of the License, or (at your option) any later version. | |||
* | |||
* Sonar 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 Sonar; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.plugins.findbugs; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.profiles.RulesProfile; | |||
import org.sonar.api.resources.Java; | |||
import org.sonar.api.rules.*; | |||
import org.sonar.plugins.findbugs.xml.FindBugsFilter; | |||
import java.util.*; | |||
public class FindbugsRulesRepository extends AbstractRulesRepository<Java, FindbugsRulePriorityMapper> implements ConfigurationImportable, ConfigurationExportable { | |||
public FindbugsRulesRepository(Java language) { | |||
super(language, new FindbugsRulePriorityMapper()); | |||
} | |||
@Override | |||
public String getRepositoryResourcesBase() { | |||
return "org/sonar/plugins/findbugs"; | |||
} | |||
@Override | |||
public List<Rule> parseReferential(String fileContent) { | |||
return new StandardRulesXmlParser().parse(fileContent); | |||
} | |||
public List<RulesProfile> getProvidedProfiles() { | |||
RulesProfile profile = new RulesProfile(RulesProfile.SONAR_WAY_FINDBUGS_NAME, Java.KEY); | |||
List<Rule> rules = getInitialReferential(); | |||
ArrayList<ActiveRule> activeRules = new ArrayList<ActiveRule>(); | |||
for (Rule rule : rules) { | |||
activeRules.add(new ActiveRule(profile, rule, null)); | |||
} | |||
profile.setActiveRules(activeRules); | |||
return Arrays.asList(profile); | |||
} | |||
public String exportConfiguration(RulesProfile activeProfile) { | |||
FindBugsFilter filter = FindBugsFilter.fromActiveRules(activeProfile.getActiveRulesByPlugin(CoreProperties.FINDBUGS_PLUGIN)); | |||
return addHeaderToXml(filter.toXml()); | |||
} | |||
private static String addHeaderToXml(String xmlModules) { | |||
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- Generated by Sonar -->\n".concat(xmlModules); | |||
} | |||
public List<ActiveRule> importConfiguration(String xml, List<Rule> rules) { | |||
FindBugsFilter filter = FindBugsFilter.fromXml(xml); | |||
Set<ActiveRule> result = new HashSet<ActiveRule>(); | |||
for (Map.Entry<String, RulePriority> categoryLevel : filter.getCategoryLevels(getRulePriorityMapper()).entrySet()) { | |||
completeActiveRulesByCategory(result, rules, categoryLevel.getKey(), categoryLevel.getValue()); | |||
} | |||
for (Map.Entry<String, RulePriority> codeLevel : filter.getCodeLevels(getRulePriorityMapper()).entrySet()) { | |||
completeActiveRulesByCode(result, rules, codeLevel.getKey(), codeLevel.getValue()); | |||
} | |||
for (Map.Entry<String, RulePriority> patternLevel : filter.getPatternLevels(getRulePriorityMapper()).entrySet()) { | |||
completeActiveRulesByPattern(result, rules, patternLevel.getKey(), patternLevel.getValue()); | |||
} | |||
return new ArrayList<ActiveRule>(result); | |||
} | |||
private void completeActiveRulesByCategory(Set<ActiveRule> result, List<Rule> rules, String findbugsCategory, RulePriority priority) { | |||
for (Rule rule : rules) { | |||
String sonarCateg = Category.findbugsToSonar(findbugsCategory); | |||
if (sonarCateg != null && rule.getName().startsWith(sonarCateg)) { | |||
result.add(new ActiveRule(null, rule, priority)); | |||
} | |||
} | |||
} | |||
private void completeActiveRulesByCode(Set<ActiveRule> result, List<Rule> rules, String findbugsCode, RulePriority priority) { | |||
for (Rule rule : rules) { | |||
if (rule.getKey().equals(findbugsCode) || StringUtils.startsWith(rule.getKey(), findbugsCode + "_")) { | |||
result.add(new ActiveRule(null, rule, priority)); | |||
} | |||
} | |||
} | |||
private void completeActiveRulesByPattern(Set<ActiveRule> result, List<Rule> rules, String findbugsPattern, RulePriority priority) { | |||
for (Rule rule : rules) { | |||
if (rule.getKey().equals(findbugsPattern)) { | |||
result.add(new ActiveRule(null, rule, priority)); | |||
} | |||
} | |||
} | |||
} |
@@ -35,19 +35,19 @@ 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.RulesManager; | |||
import org.sonar.api.rules.RuleFinder; | |||
import org.sonar.api.rules.Violation; | |||
public class FindbugsSensor implements Sensor, DependsUponMavenPlugin, GeneratesViolations { | |||
private RulesProfile profile; | |||
private RulesManager rulesManager; | |||
private RuleFinder ruleFinder; | |||
private FindbugsMavenPluginHandler pluginHandler; | |||
private static Logger LOG = LoggerFactory.getLogger(FindbugsSensor.class); | |||
public FindbugsSensor(RulesProfile profile, RulesManager rulesManager, FindbugsMavenPluginHandler pluginHandler) { | |||
public FindbugsSensor(RulesProfile profile, RuleFinder ruleFinder, FindbugsMavenPluginHandler pluginHandler) { | |||
this.profile = profile; | |||
this.rulesManager = rulesManager; | |||
this.ruleFinder = ruleFinder; | |||
this.pluginHandler = pluginHandler; | |||
} | |||
@@ -57,12 +57,10 @@ public class FindbugsSensor implements Sensor, DependsUponMavenPlugin, Generates | |||
FindbugsXmlReportParser reportParser = new FindbugsXmlReportParser(report); | |||
List<FindbugsXmlReportParser.Violation> fbViolations = reportParser.getViolations(); | |||
for (FindbugsXmlReportParser.Violation fbViolation : fbViolations) { | |||
Rule rule = rulesManager.getPluginRule(CoreProperties.FINDBUGS_PLUGIN, fbViolation.getType()); | |||
Rule rule = ruleFinder.findByKey(FindbugsConstants.REPOSITORY_KEY, fbViolation.getType()); | |||
JavaFile resource = new JavaFile(fbViolation.getSonarJavaFileKey()); | |||
if (context.getResource(resource) != null) { | |||
Violation violation = new Violation(rule, resource) | |||
.setLineId(fbViolation.getStart()) | |||
.setMessage(fbViolation.getLongMessage()); | |||
Violation violation = new Violation(rule, resource).setLineId(fbViolation.getStart()).setMessage(fbViolation.getLongMessage()); | |||
context.saveViolation(violation); | |||
} | |||
} | |||
@@ -76,9 +74,9 @@ public class FindbugsSensor implements Sensor, DependsUponMavenPlugin, Generates | |||
} | |||
public boolean shouldExecuteOnProject(Project project) { | |||
return project.getFileSystem().hasJavaSourceFiles() && | |||
( !profile.getActiveRulesByPlugin(CoreProperties.FINDBUGS_PLUGIN).isEmpty() || project.getReuseExistingRulesConfig()) && | |||
project.getPom() != null && !StringUtils.equalsIgnoreCase(project.getPom().getPackaging(), "ear"); | |||
return project.getFileSystem().hasJavaSourceFiles() | |||
&& ( !profile.getActiveRulesByRepository(FindbugsConstants.REPOSITORY_KEY).isEmpty() || project.getReuseExistingRulesConfig()) | |||
&& project.getPom() != null && !StringUtils.equalsIgnoreCase(project.getPom().getPackaging(), "ear"); | |||
} | |||
public MavenPluginHandler getMavenPluginHandler(Project project) { |
@@ -0,0 +1,47 @@ | |||
/* | |||
* Sonar, open source software quality management tool. | |||
* Copyright (C) 2009 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* Sonar 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 3 of the License, or (at your option) any later version. | |||
* | |||
* Sonar 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 Sonar; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.plugins.findbugs; | |||
import java.io.InputStreamReader; | |||
import java.io.Reader; | |||
import org.sonar.api.profiles.ProfileDefinition; | |||
import org.sonar.api.profiles.RulesProfile; | |||
import org.sonar.api.resources.Java; | |||
import org.sonar.api.utils.ValidationMessages; | |||
public class SonarWayWithFindbugsProfile extends ProfileDefinition { | |||
private FindbugsProfileImporter importer; | |||
public SonarWayWithFindbugsProfile(FindbugsProfileImporter importer) { | |||
this.importer = importer; | |||
} | |||
@Override | |||
public RulesProfile createProfile(ValidationMessages messages) { | |||
Reader pmdSonarWayProfile = new InputStreamReader(this.getClass().getResourceAsStream( | |||
"/org/sonar/plugins/findbugs/profile-sonar-way-findbugs.xml")); | |||
RulesProfile profile = importer.importProfile(pmdSonarWayProfile, messages); | |||
profile.setLanguage(Java.KEY); | |||
profile.setName(RulesProfile.SONAR_WAY_FINDBUGS_NAME); | |||
return profile; | |||
} | |||
} |
@@ -29,6 +29,7 @@ import org.sonar.api.CoreProperties; | |||
import org.sonar.api.rules.ActiveRule; | |||
import org.sonar.api.rules.RulePriority; | |||
import org.sonar.api.rules.RulePriorityMapper; | |||
import org.sonar.plugins.findbugs.FindbugsLevelUtils; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
@@ -69,7 +70,7 @@ public class FindBugsFilter { | |||
matchs.add(child); | |||
} | |||
public Map<String, RulePriority> getPatternLevels(RulePriorityMapper priorityMapper) { | |||
public Map<String, RulePriority> getPatternLevels(FindbugsLevelUtils priorityMapper) { | |||
BugInfoSplitter splitter = new BugInfoSplitter() { | |||
public String getSeparator() { | |||
return PATTERN_SEPARATOR; | |||
@@ -82,7 +83,7 @@ public class FindBugsFilter { | |||
return processMatches(priorityMapper, splitter); | |||
} | |||
public Map<String, RulePriority> getCodeLevels(RulePriorityMapper priorityMapper) { | |||
public Map<String, RulePriority> getCodeLevels(FindbugsLevelUtils priorityMapper) { | |||
BugInfoSplitter splitter = new BugInfoSplitter() { | |||
public String getSeparator() { | |||
return CODE_SEPARATOR; | |||
@@ -95,7 +96,7 @@ public class FindBugsFilter { | |||
return processMatches(priorityMapper, splitter); | |||
} | |||
public Map<String, RulePriority> getCategoryLevels(RulePriorityMapper priorityMapper) { | |||
public Map<String, RulePriority> getCategoryLevels(FindbugsLevelUtils priorityMapper) { | |||
BugInfoSplitter splitter = new BugInfoSplitter() { | |||
public String getSeparator() { | |||
return CATEGORY_SEPARATOR; | |||
@@ -108,11 +109,11 @@ public class FindBugsFilter { | |||
return processMatches(priorityMapper, splitter); | |||
} | |||
private RulePriority getRulePriority(Priority priority, RulePriorityMapper priorityMapper) { | |||
private RulePriority getRulePriority(Priority priority, FindbugsLevelUtils priorityMapper) { | |||
return priority != null ? priorityMapper.from(priority.getValue()) : null; | |||
} | |||
private Map<String, RulePriority> processMatches(RulePriorityMapper priorityMapper, BugInfoSplitter splitter) { | |||
private Map<String, RulePriority> processMatches(FindbugsLevelUtils priorityMapper, BugInfoSplitter splitter) { | |||
Map<String, RulePriority> result = new HashMap<String, RulePriority>(); | |||
for (Match child : getChildren()) { | |||
if (child.getOrs() != null) { | |||
@@ -127,7 +128,7 @@ public class FindBugsFilter { | |||
return result; | |||
} | |||
private void completeLevels(Map<String, RulePriority> result, List<Bug> bugs, Priority priority, RulePriorityMapper priorityMapper, BugInfoSplitter splitter) { | |||
private void completeLevels(Map<String, RulePriority> result, List<Bug> bugs, Priority priority, FindbugsLevelUtils priorityMapper, BugInfoSplitter splitter) { | |||
if (bugs == null) { | |||
return; | |||
} | |||
@@ -174,33 +175,4 @@ public class FindBugsFilter { | |||
xstream.processAnnotations(OrFilter.class); | |||
return xstream; | |||
} | |||
public static FindBugsFilter fromXml(String xml) { | |||
try { | |||
XStream xStream = createXStream(); | |||
InputStream inputStream = IOUtils.toInputStream(xml, CharEncoding.UTF_8); | |||
return (FindBugsFilter) xStream.fromXML(inputStream); | |||
} catch (IOException e) { | |||
throw new RuntimeException("can't read configuration file", e); | |||
} | |||
} | |||
public static FindBugsFilter fromActiveRules(List<ActiveRule> activeRules) { | |||
FindBugsFilter root = new FindBugsFilter(); | |||
for (ActiveRule activeRule : activeRules) { | |||
if (CoreProperties.FINDBUGS_PLUGIN.equals(activeRule.getPluginName())) { | |||
Match child = createChild(activeRule); | |||
root.addMatch(child); | |||
} | |||
} | |||
return root; | |||
} | |||
private static Match createChild(ActiveRule activeRule) { | |||
Match child = new Match(); | |||
child.setBug(new Bug(activeRule.getConfigKey())); | |||
return child; | |||
} | |||
} |
@@ -52,7 +52,6 @@ public class FindbugsMavenPluginHandlerTest { | |||
private Project project; | |||
private ProjectFileSystem fs; | |||
private File fakeSonarConfig; | |||
private FindbugsRulesRepository repo; | |||
private MavenPlugin plugin; | |||
private FindbugsMavenPluginHandler handler; | |||
@@ -61,7 +60,6 @@ public class FindbugsMavenPluginHandlerTest { | |||
project = mock(Project.class); | |||
fs = mock(ProjectFileSystem.class); | |||
fakeSonarConfig = mock(File.class); | |||
repo = mock(FindbugsRulesRepository.class); | |||
plugin = mock(MavenPlugin.class); | |||
handler = createMavenPluginHandler(); | |||
} | |||
@@ -173,8 +171,7 @@ public class FindbugsMavenPluginHandlerTest { | |||
} | |||
private FindbugsMavenPluginHandler createMavenPluginHandler() { | |||
when(repo.exportConfiguration((RulesProfile) anyObject())).thenReturn("<test/>"); | |||
return new FindbugsMavenPluginHandler(new RulesProfile(), repo); | |||
return new FindbugsMavenPluginHandler(RulesProfile.create(), new FindbugsProfileExporter()); | |||
} | |||
private void mockProject(String effort) throws URISyntaxException, IOException { |
@@ -1,124 +1,131 @@ | |||
/* | |||
* Sonar, open source software quality management tool. | |||
* Copyright (C) 2009 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* Sonar 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 3 of the License, or (at your option) any later version. | |||
* | |||
* Sonar 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 Sonar; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.plugins.findbugs.xml; | |||
import org.apache.commons.io.IOUtils; | |||
import static org.hamcrest.CoreMatchers.is; | |||
import static org.junit.Assert.assertThat; | |||
import org.junit.Test; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.rules.ActiveRule; | |||
import org.sonar.api.rules.Rule; | |||
import org.sonar.api.rules.RulePriority; | |||
import org.sonar.plugins.findbugs.FindbugsRulePriorityMapper; | |||
import org.xml.sax.SAXException; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.util.Arrays; | |||
import java.util.Collections; | |||
import java.util.List; | |||
public class FindBugsFilterTest extends FindBugsXmlTests { | |||
@Test | |||
public void shouldBuilXmlFromModuleTree() throws IOException, SAXException { | |||
FindBugsFilter root = buildModuleTreeFixture(); | |||
String xml = root.toXml(); | |||
assertXmlAreSimilar(xml, "test_module_tree.xml"); | |||
} | |||
@Test | |||
public void shouldBuilModuleTreeFromXml() throws IOException { | |||
InputStream input = getClass().getResourceAsStream("/org/sonar/plugins/findbugs/test_module_tree.xml"); | |||
FindBugsFilter module = FindBugsFilter.fromXml(IOUtils.toString(input)); | |||
List<Match> matches = module.getMatchs(); | |||
assertThat(matches.size(), is(2)); | |||
assertChild(matches.get(0), "DLS_DEAD_LOCAL_STORE"); | |||
assertChild(matches.get(1), "URF_UNREAD_FIELD"); | |||
} | |||
private static FindBugsFilter buildModuleTreeFixture() { | |||
FindBugsFilter findBugsFilter = new FindBugsFilter(); | |||
findBugsFilter.addMatch(new Match(new Bug("DLS_DEAD_LOCAL_STORE"))); | |||
findBugsFilter.addMatch(new Match(new Bug("URF_UNREAD_FIELD"))); | |||
return findBugsFilter; | |||
} | |||
private static final String DLS_DEAD_LOCAL_STORE = "DLS_DEAD_LOCAL_STORE"; | |||
private static final String SS_SHOULD_BE_STATIC = "SS_SHOULD_BE_STATIC"; | |||
@Test | |||
public void shouldBuildModuleWithProperties() { | |||
ActiveRule activeRule = anActiveRule(DLS_DEAD_LOCAL_STORE); | |||
FindBugsFilter filter = FindBugsFilter.fromActiveRules(Arrays.asList(activeRule)); | |||
assertThat(filter.getMatchs().size(), is(1)); | |||
assertChild(filter.getMatchs().get(0), DLS_DEAD_LOCAL_STORE); | |||
} | |||
@Test | |||
public void shouldBuildOnlyOneModuleWhenNoActiveRules() { | |||
FindBugsFilter filter = FindBugsFilter.fromActiveRules(Collections.<ActiveRule>emptyList()); | |||
assertThat(filter.getMatchs().size(), is(0)); | |||
} | |||
@Test | |||
public void shouldBuildTwoModulesEvenIfSameTwoRulesActivated() { | |||
ActiveRule activeRule1 = anActiveRule(DLS_DEAD_LOCAL_STORE); | |||
ActiveRule activeRule2 = anActiveRule(SS_SHOULD_BE_STATIC); | |||
FindBugsFilter filter = FindBugsFilter.fromActiveRules(Arrays.asList(activeRule1, activeRule2)); | |||
List<Match> matches = filter.getMatchs(); | |||
assertThat(matches.size(), is(2)); | |||
assertChild(matches.get(0), DLS_DEAD_LOCAL_STORE); | |||
assertChild(matches.get(1), SS_SHOULD_BE_STATIC); | |||
} | |||
@Test | |||
public void shouldBuildOnlyOneModuleWhenNoFindbugsActiveRules() { | |||
ActiveRule activeRule1 = anActiveRuleFromAnotherPlugin(); | |||
ActiveRule activeRule2 = anActiveRuleFromAnotherPlugin(); | |||
FindBugsFilter filter = FindBugsFilter.fromActiveRules(Arrays.asList(activeRule1, activeRule2)); | |||
assertThat(filter.getMatchs().size(), is(0)); | |||
} | |||
private static ActiveRule anActiveRule(String configKey) { | |||
Rule rule = new Rule(); | |||
rule.setConfigKey(configKey); | |||
rule.setPluginName(CoreProperties.FINDBUGS_PLUGIN); | |||
ActiveRule activeRule = new ActiveRule(null, rule, RulePriority.CRITICAL); | |||
return activeRule; | |||
} | |||
private static ActiveRule anActiveRuleFromAnotherPlugin() { | |||
Rule rule1 = new Rule(); | |||
rule1.setPluginName("not-a-findbugs-plugin"); | |||
ActiveRule activeRule1 = new ActiveRule(null, rule1, RulePriority.CRITICAL); | |||
return activeRule1; | |||
} | |||
} | |||
/* | |||
* Sonar, open source software quality management tool. | |||
* Copyright (C) 2009 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* Sonar 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 3 of the License, or (at your option) any later version. | |||
* | |||
* Sonar 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 Sonar; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.plugins.findbugs; | |||
import static org.hamcrest.CoreMatchers.is; | |||
import static org.junit.Assert.assertThat; | |||
import java.io.IOException; | |||
import java.io.StringWriter; | |||
import java.util.Arrays; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import org.junit.Test; | |||
import org.sonar.api.profiles.RulesProfile; | |||
import org.sonar.api.rules.ActiveRule; | |||
import org.sonar.api.rules.Rule; | |||
import org.sonar.api.rules.RulePriority; | |||
import org.sonar.plugins.findbugs.xml.Bug; | |||
import org.sonar.plugins.findbugs.xml.FindBugsFilter; | |||
import org.sonar.plugins.findbugs.xml.Match; | |||
import org.xml.sax.SAXException; | |||
public class FindbugsProfileExporterTest extends FindbugsTests { | |||
private FindbugsProfileExporter exporter = new FindbugsProfileExporter(); | |||
@Test | |||
public void shouldAddHeaderToExportedXml() throws IOException, SAXException { | |||
RulesProfile profile = RulesProfile.create(); | |||
StringWriter xml = new StringWriter(); | |||
exporter.exportProfile(profile, xml); | |||
assertXmlAreSimilar(xml.toString(), "test_header.xml"); | |||
} | |||
@Test | |||
public void shouldExportConfiguration() throws IOException, SAXException { | |||
List<Rule> rules = buildRulesFixture(); | |||
List<ActiveRule> activeRulesExpected = buildActiveRulesFixture(rules); | |||
RulesProfile profile = RulesProfile.create(); | |||
profile.setActiveRules(activeRulesExpected); | |||
StringWriter xml = new StringWriter(); | |||
exporter.exportProfile(profile, xml); | |||
assertXmlAreSimilar(xml.toString(), "test_xml_complete.xml"); | |||
} | |||
@Test | |||
public void shouldBuildOnlyOneModuleWhenNoActiveRules() { | |||
FindBugsFilter filter = FindbugsProfileExporter.buildFindbugsFilter(Collections.<ActiveRule> emptyList()); | |||
assertThat(filter.getMatchs().size(), is(0)); | |||
} | |||
@Test | |||
public void shouldBuildTwoModulesEvenIfSameTwoRulesActivated() { | |||
ActiveRule activeRule1 = anActiveRule(DLS_DEAD_LOCAL_STORE); | |||
ActiveRule activeRule2 = anActiveRule(SS_SHOULD_BE_STATIC); | |||
FindBugsFilter filter = FindbugsProfileExporter.buildFindbugsFilter(Arrays.asList(activeRule1, activeRule2)); | |||
List<Match> matches = filter.getMatchs(); | |||
assertThat(matches.size(), is(2)); | |||
assertThat(matches.get(0).getBug().getPattern(), is("DLS_DEAD_LOCAL_STORE")); | |||
assertThat(matches.get(1).getBug().getPattern(), is("SS_SHOULD_BE_STATIC")); | |||
} | |||
@Test | |||
public void shouldBuildOnlyOneModuleWhenNoFindbugsActiveRules() { | |||
ActiveRule activeRule1 = anActiveRuleFromAnotherPlugin(); | |||
ActiveRule activeRule2 = anActiveRuleFromAnotherPlugin(); | |||
FindBugsFilter filter = FindbugsProfileExporter.buildFindbugsFilter(Arrays.asList(activeRule1, activeRule2)); | |||
assertThat(filter.getMatchs().size(), is(0)); | |||
} | |||
@Test | |||
public void shouldBuildModuleWithProperties() { | |||
ActiveRule activeRule = anActiveRule(DLS_DEAD_LOCAL_STORE); | |||
FindBugsFilter filter = FindbugsProfileExporter.buildFindbugsFilter(Arrays.asList(activeRule)); | |||
assertThat(filter.getMatchs().size(), is(1)); | |||
assertThat(filter.getMatchs().get(0).getBug().getPattern(), is("DLS_DEAD_LOCAL_STORE")); | |||
} | |||
@Test | |||
public void shouldBuilXmlFromModuleTree() throws IOException, SAXException { | |||
FindBugsFilter findBugsFilter = new FindBugsFilter(); | |||
findBugsFilter.addMatch(new Match(new Bug("DLS_DEAD_LOCAL_STORE"))); | |||
findBugsFilter.addMatch(new Match(new Bug("URF_UNREAD_FIELD"))); | |||
String xml = findBugsFilter.toXml(); | |||
assertXmlAreSimilar(xml, "test_module_tree.xml"); | |||
} | |||
private static final String DLS_DEAD_LOCAL_STORE = "DLS_DEAD_LOCAL_STORE"; | |||
private static final String SS_SHOULD_BE_STATIC = "SS_SHOULD_BE_STATIC"; | |||
private static ActiveRule anActiveRule(String configKey) { | |||
Rule rule = Rule.create(); | |||
rule.setConfigKey(configKey); | |||
rule.setRepositoryKey(FindbugsConstants.REPOSITORY_KEY); | |||
ActiveRule activeRule = RulesProfile.create().activateRule(rule, RulePriority.CRITICAL); | |||
return activeRule; | |||
} | |||
private static ActiveRule anActiveRuleFromAnotherPlugin() { | |||
Rule rule = Rule.create(); | |||
rule.setPluginName("not-a-findbugs-plugin"); | |||
ActiveRule activeRule = RulesProfile.create().activateRule(rule, RulePriority.CRITICAL); | |||
return activeRule; | |||
} | |||
} |
@@ -0,0 +1,144 @@ | |||
/* | |||
* Sonar, open source software quality management tool. | |||
* Copyright (C) 2009 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* Sonar 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 3 of the License, or (at your option) any later version. | |||
* | |||
* Sonar 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 Sonar; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.plugins.findbugs; | |||
import static org.hamcrest.CoreMatchers.is; | |||
import static org.hamcrest.CoreMatchers.notNullValue; | |||
import static org.junit.Assert.assertThat; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.InputStreamReader; | |||
import java.io.StringReader; | |||
import java.util.List; | |||
import org.apache.commons.io.IOUtils; | |||
import org.junit.Test; | |||
import org.sonar.api.profiles.RulesProfile; | |||
import org.sonar.api.rules.ActiveRule; | |||
import org.sonar.api.utils.ValidationMessages; | |||
import org.sonar.plugins.findbugs.xml.FindBugsFilter; | |||
import org.sonar.plugins.findbugs.xml.Match; | |||
import org.sonar.test.TestUtils; | |||
import com.thoughtworks.xstream.XStream; | |||
public class FindbugsProfileImporterTest { | |||
private FindbugsProfileImporter importer = new FindbugsProfileImporter(new FindbugsRuleFinder()); | |||
@Test | |||
public void shouldImportPatterns() throws IOException { | |||
String findbugsConf = TestUtils.getResourceContent("/org/sonar/plugins/findbugs/shouldImportPatterns.xml"); | |||
RulesProfile profile = importer.importProfile(new StringReader(findbugsConf), ValidationMessages.create()); | |||
assertThat(profile.getActiveRules().size(), is(2)); | |||
assertThat(profile.getActiveRule(FindbugsConstants.REPOSITORY_KEY, "NP_CLOSING_NULL"), is(notNullValue())); | |||
assertThat(profile.getActiveRule(FindbugsConstants.REPOSITORY_KEY, "RC_REF_COMPARISON_BAD_PRACTICE"), is(notNullValue())); | |||
} | |||
@Test | |||
public void shouldImportCodes() throws IOException { | |||
InputStream input = getClass().getResourceAsStream("/org/sonar/plugins/findbugs/shouldImportCodes.xml"); | |||
RulesProfile profile = importer.importProfile(new InputStreamReader(input), ValidationMessages.create()); | |||
List<ActiveRule> results = profile.getActiveRules(); | |||
assertThat(results.size(), is(18)); | |||
assertThat(profile.getActiveRule(FindbugsConstants.REPOSITORY_KEY, "EC_INCOMPATIBLE_ARRAY_COMPARE"), is(notNullValue())); | |||
assertThat(profile.getActiveRule(FindbugsConstants.REPOSITORY_KEY, "BC_IMPOSSIBLE_DOWNCAST_OF_TOARRAY"), is(notNullValue())); | |||
} | |||
@Test | |||
public void shouldImportCategories() throws IOException { | |||
InputStream input = getClass().getResourceAsStream("/org/sonar/plugins/findbugs/shouldImportCategories.xml"); | |||
RulesProfile profile = importer.importProfile(new InputStreamReader(input), ValidationMessages.create()); | |||
List<ActiveRule> results = profile.getActiveRules(); | |||
assertThat(results.size(), is(183)); | |||
assertThat(profile.getActiveRule(FindbugsConstants.REPOSITORY_KEY, "LG_LOST_LOGGER_DUE_TO_WEAK_REFERENCE"), is(notNullValue())); | |||
} | |||
@Test | |||
public void shouldImportConfigurationBugInclude() throws IOException { | |||
InputStream input = getClass().getResourceAsStream("/org/sonar/plugins/findbugs/findbugs-include.xml"); | |||
RulesProfile profile = importer.importProfile(new InputStreamReader(input), ValidationMessages.create()); | |||
List<ActiveRule> results = profile.getActiveRules(); | |||
assertThat(results.size(), is(11)); | |||
assertThat(profile.getActiveRule(FindbugsConstants.REPOSITORY_KEY, "RC_REF_COMPARISON_BAD_PRACTICE"), is(notNullValue())); | |||
} | |||
@Test | |||
public void shouldBuilModuleTreeFromXml() throws IOException { | |||
InputStream input = getClass().getResourceAsStream("/org/sonar/plugins/findbugs/test_module_tree.xml"); | |||
XStream xStream = FindBugsFilter.createXStream(); | |||
FindBugsFilter filter = (FindBugsFilter) xStream.fromXML(IOUtils.toString(input)); | |||
List<Match> matches = filter.getMatchs(); | |||
assertThat(matches.size(), is(2)); | |||
assertThat(matches.get(0).getBug().getPattern(), is("DLS_DEAD_LOCAL_STORE")); | |||
assertThat(matches.get(1).getBug().getPattern(), is("URF_UNREAD_FIELD")); | |||
} | |||
@Test | |||
public void testImportingUncorrectXmlFile() throws IOException { | |||
String uncorrectFindbugsXml = TestUtils.getResourceContent("/org/sonar/plugins/findbugs/uncorrectFindbugsXml.xml"); | |||
ValidationMessages messages = ValidationMessages.create(); | |||
RulesProfile profile = importer.importProfile(new StringReader(uncorrectFindbugsXml), messages); | |||
List<ActiveRule> results = profile.getActiveRules(); | |||
assertThat(results.size(), is(0)); | |||
assertThat(messages.getErrors().size(), is(1)); | |||
} | |||
@Test | |||
public void testImportingXmlFileWithUnknownRule() throws IOException { | |||
String uncorrectFindbugsXml = TestUtils.getResourceContent("/org/sonar/plugins/findbugs/findbugsXmlWithUnknownRule.xml"); | |||
ValidationMessages messages = ValidationMessages.create(); | |||
RulesProfile profile = importer.importProfile(new StringReader(uncorrectFindbugsXml), messages); | |||
List<ActiveRule> results = profile.getActiveRules(); | |||
assertThat(results.size(), is(1)); | |||
assertThat(messages.getWarnings().size(), is(1)); | |||
} | |||
@Test | |||
public void testImportingXmlFileWithUnknownCategory() throws IOException { | |||
String uncorrectFindbugsXml = TestUtils.getResourceContent("/org/sonar/plugins/findbugs/findbugsXmlWithUnknownCategory.xml"); | |||
ValidationMessages messages = ValidationMessages.create(); | |||
RulesProfile profile = importer.importProfile(new StringReader(uncorrectFindbugsXml), messages); | |||
List<ActiveRule> results = profile.getActiveRules(); | |||
assertThat(results.size(), is(142)); | |||
assertThat(messages.getWarnings().size(), is(1)); | |||
} | |||
@Test | |||
public void testImportingXmlFileWithUnknownCode() throws IOException { | |||
String uncorrectFindbugsXml = TestUtils.getResourceContent("/org/sonar/plugins/findbugs/findbugsXmlWithUnknownCode.xml"); | |||
ValidationMessages messages = ValidationMessages.create(); | |||
RulesProfile profile = importer.importProfile(new StringReader(uncorrectFindbugsXml), messages); | |||
List<ActiveRule> results = profile.getActiveRules(); | |||
assertThat(results.size(), is(9)); | |||
assertThat(messages.getWarnings().size(), is(1)); | |||
} | |||
} |
@@ -0,0 +1,57 @@ | |||
/* | |||
* Sonar, open source software quality management tool. | |||
* Copyright (C) 2009 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* Sonar 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 3 of the License, or (at your option) any later version. | |||
* | |||
* Sonar 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 Sonar; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.plugins.findbugs; | |||
import java.util.Collection; | |||
import java.util.List; | |||
import org.sonar.api.rules.Rule; | |||
import org.sonar.api.rules.RuleFinder; | |||
import org.sonar.api.rules.RuleQuery; | |||
public class FindbugsRuleFinder implements RuleFinder { | |||
private final List<Rule> findbugsRules; | |||
public FindbugsRuleFinder() { | |||
FindbugsRuleRepository repo = new FindbugsRuleRepository(); | |||
findbugsRules = repo.createRules(); | |||
for(Rule rule : findbugsRules){ | |||
rule.setRepositoryKey(FindbugsConstants.REPOSITORY_KEY); | |||
} | |||
} | |||
public Rule findByKey(String repositoryKey, String key) { | |||
for (Rule rule : findbugsRules) { | |||
if (rule.getKey().equals(key)) { | |||
return rule; | |||
} | |||
} | |||
return null; | |||
} | |||
public Rule find(RuleQuery query) { | |||
throw new UnsupportedOperationException(); | |||
} | |||
public Collection<Rule> findAll(RuleQuery query) { | |||
return findbugsRules; | |||
} | |||
} |
@@ -0,0 +1,45 @@ | |||
/* | |||
* Sonar, open source software quality management tool. | |||
* Copyright (C) 2009 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* Sonar 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 3 of the License, or (at your option) any later version. | |||
* | |||
* Sonar 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 Sonar; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.plugins.findbugs; | |||
import static org.hamcrest.Matchers.greaterThan; | |||
import static org.junit.Assert.assertNotNull; | |||
import static org.junit.Assert.assertThat; | |||
import java.util.List; | |||
import org.junit.Test; | |||
import org.sonar.api.rules.Rule; | |||
public class FindbugsRuleRepositoryTest { | |||
@Test | |||
public void testLoadRepositoryFromXml() { | |||
FindbugsRuleRepository repository = new FindbugsRuleRepository(); | |||
List<Rule> rules = repository.createRules(); | |||
assertThat(rules.size(), greaterThan(300)); | |||
for (Rule rule : rules) { | |||
assertNotNull(rule.getKey()); | |||
assertNotNull(rule.getDescription()); | |||
assertNotNull(rule.getConfigKey()); | |||
assertNotNull(rule.getName()); | |||
} | |||
} | |||
} |
@@ -1,186 +0,0 @@ | |||
/* | |||
* Sonar, open source software quality management tool. | |||
* Copyright (C) 2009 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* Sonar 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 3 of the License, or (at your option) any later version. | |||
* | |||
* Sonar 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 Sonar; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.plugins.findbugs; | |||
import org.apache.commons.io.IOUtils; | |||
import org.hamcrest.BaseMatcher; | |||
import static org.hamcrest.CoreMatchers.is; | |||
import org.hamcrest.Description; | |||
import static org.junit.Assert.*; | |||
import org.junit.Before; | |||
import org.junit.Ignore; | |||
import org.junit.Test; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.profiles.RulesProfile; | |||
import org.sonar.api.resources.Java; | |||
import org.sonar.api.rules.ActiveRule; | |||
import org.sonar.api.rules.Rule; | |||
import org.sonar.api.rules.RulePriority; | |||
import org.xml.sax.SAXException; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.util.Arrays; | |||
import java.util.Collections; | |||
import java.util.List; | |||
public class FindbugsRulesRepositoryTest extends FindbugsTests { | |||
private FindbugsRulesRepository repository; | |||
@Before | |||
public void setup() { | |||
repository = new FindbugsRulesRepository(new Java()); | |||
} | |||
@Test | |||
public void rulesAreDefinedWithTheDefaultSonarXmlFormat() { | |||
List<Rule> rules = repository.getInitialReferential(); | |||
assertTrue(rules.size() > 0); | |||
for (Rule rule : rules) { | |||
assertNotNull(rule.getKey()); | |||
assertNotNull(rule.getDescription()); | |||
assertNotNull(rule.getConfigKey()); | |||
assertNotNull(rule.getName()); | |||
} | |||
} | |||
@Test | |||
@Ignore | |||
public void shouldProvideProfiles() { | |||
List<RulesProfile> profiles = repository.getProvidedProfiles(); | |||
assertThat(profiles.size(), is(1)); | |||
RulesProfile profile1 = profiles.get(0); | |||
assertThat(profile1.getName(), is(RulesProfile.SONAR_WAY_FINDBUGS_NAME)); | |||
assertEquals(profile1.getActiveRules().size(), 344); | |||
} | |||
@Test | |||
public void shouldAddHeaderToExportedXml() throws IOException, SAXException { | |||
RulesProfile rulesProfile = mock(RulesProfile.class); | |||
when(rulesProfile.getActiveRulesByPlugin(CoreProperties.FINDBUGS_PLUGIN)).thenReturn(Collections.<ActiveRule>emptyList()); | |||
assertXmlAreSimilar(repository.exportConfiguration(rulesProfile), "test_header.xml"); | |||
} | |||
@Test | |||
public void shouldExportConfiguration() throws IOException, SAXException { | |||
List<Rule> rules = buildRulesFixture(); | |||
List<ActiveRule> activeRulesExpected = buildActiveRulesFixture(rules); | |||
RulesProfile activeProfile = new RulesProfile(); | |||
activeProfile.setActiveRules(activeRulesExpected); | |||
assertXmlAreSimilar(repository.exportConfiguration(activeProfile), "test_xml_complete.xml"); | |||
} | |||
@Test | |||
public void shouldImportPatterns() throws IOException { | |||
InputStream input = getClass().getResourceAsStream("/org/sonar/plugins/findbugs/FindbugsRulesRepositoryTest/shouldImportPatterns.xml"); | |||
List<ActiveRule> results = repository.importConfiguration(IOUtils.toString(input), buildRulesFixtureImport()); | |||
assertThat(results.size(), is(2)); | |||
assertThat(results, new ContainsActiveRule("FB1_IMPORT_TEST_1", RulePriority.MAJOR)); | |||
assertThat(results, new ContainsActiveRule("FB2_IMPORT_TEST_4", RulePriority.MAJOR)); | |||
} | |||
@Test | |||
public void shouldImportCodes() throws IOException { | |||
InputStream input = getClass().getResourceAsStream("/org/sonar/plugins/findbugs/FindbugsRulesRepositoryTest/shouldImportCodes.xml"); | |||
List<ActiveRule> results = repository.importConfiguration(IOUtils.toString(input), buildRulesFixtureImport()); | |||
assertThat(results.size(), is(4)); | |||
assertThat(results, new ContainsActiveRule("FB1_IMPORT_TEST_1", RulePriority.MAJOR)); | |||
assertThat(results, new ContainsActiveRule("FB1_IMPORT_TEST_2", RulePriority.MAJOR)); | |||
assertThat(results, new ContainsActiveRule("FB1_IMPORT_TEST_3", RulePriority.MAJOR)); | |||
assertThat(results, new ContainsActiveRule("FB3_IMPORT_TEST_5", RulePriority.MAJOR)); | |||
} | |||
@Test | |||
public void shouldImportCategories() throws IOException { | |||
InputStream input = getClass().getResourceAsStream("/org/sonar/plugins/findbugs/FindbugsRulesRepositoryTest/shouldImportCategories.xml"); | |||
List<ActiveRule> results = repository.importConfiguration(IOUtils.toString(input), buildRulesFixtureImport()); | |||
assertThat(results.size(), is(4)); | |||
assertThat(results, new ContainsActiveRule("FB1_IMPORT_TEST_1", RulePriority.INFO)); | |||
assertThat(results, new ContainsActiveRule("FB1_IMPORT_TEST_2", RulePriority.INFO)); | |||
assertThat(results, new ContainsActiveRule("FB1_IMPORT_TEST_3", RulePriority.INFO)); | |||
assertThat(results, new ContainsActiveRule("FB2_IMPORT_TEST_4", RulePriority.INFO)); | |||
} | |||
@Test | |||
public void shouldImportConfigurationBugInclude() throws IOException { | |||
InputStream input = getClass().getResourceAsStream("/org/sonar/plugins/findbugs/findbugs-include.xml"); | |||
List<ActiveRule> results = repository.importConfiguration(IOUtils.toString(input), buildRulesFixtureImport()); | |||
assertThat(results.size(), is(4)); | |||
assertThat(results, new ContainsActiveRule("FB1_IMPORT_TEST_1", null)); | |||
assertThat(results, new ContainsActiveRule("FB1_IMPORT_TEST_2", null)); | |||
assertThat(results, new ContainsActiveRule("FB1_IMPORT_TEST_3", null)); | |||
assertThat(results, new ContainsActiveRule("FB2_IMPORT_TEST_4", null)); | |||
} | |||
private static List<Rule> buildRulesFixtureImport() { | |||
Rule rule1 = new Rule("Correctness - Import test 1 group 1", "FB1_IMPORT_TEST_1", | |||
"FB1_IMPORT_TEST_1", null, CoreProperties.FINDBUGS_PLUGIN, null); | |||
Rule rule2 = new Rule("Multithreaded correctness - Import test 2 group 1", "FB1_IMPORT_TEST_2", | |||
"FB1_IMPORT_TEST_2", null, CoreProperties.FINDBUGS_PLUGIN, null); | |||
Rule rule3 = new Rule("Multithreaded correctness - Import test 3 group 1", "FB1_IMPORT_TEST_3", | |||
"FB1_IMPORT_TEST_3", null, CoreProperties.FINDBUGS_PLUGIN, null); | |||
Rule rule4 = new Rule("Multithreaded correctness - Import test 4 group 2", "FB2_IMPORT_TEST_4", | |||
"FB2_IMPORT_TEST_4", null, CoreProperties.FINDBUGS_PLUGIN, null); | |||
Rule rule5 = new Rule("Style - Import test 5 group 3", "FB3_IMPORT_TEST_5", | |||
"FB3_IMPORT_TEST_5", null, CoreProperties.FINDBUGS_PLUGIN, null); | |||
return Arrays.asList(rule1, rule2, rule3, rule4, rule5); | |||
} | |||
} | |||
class ContainsActiveRule extends BaseMatcher<List<ActiveRule>> { | |||
private String key; | |||
private RulePriority priority; | |||
ContainsActiveRule(String key, RulePriority priority) { | |||
this.key = key; | |||
this.priority = priority; | |||
} | |||
public boolean matches(Object o) { | |||
List<ActiveRule> rules = (List<ActiveRule>) o; | |||
for (ActiveRule rule : rules) { | |||
if (rule.getRule().getKey().equals(key)) { | |||
if (priority == null) { | |||
return true; | |||
} | |||
return rule.getPriority().equals(priority); | |||
} | |||
} | |||
return false; | |||
} | |||
public void describeTo(Description description) { | |||
} | |||
} |
@@ -38,6 +38,7 @@ import org.apache.maven.project.MavenProject; | |||
import org.junit.Test; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.batch.SensorContext; | |||
import org.sonar.api.profiles.RulesProfile; | |||
import org.sonar.api.resources.DefaultProjectFileSystem; | |||
import org.sonar.api.resources.JavaFile; | |||
import org.sonar.api.resources.Project; | |||
@@ -49,22 +50,21 @@ public class FindbugsSensorTest extends FindbugsTests { | |||
@Test | |||
public void shouldExecuteWhenSomeRulesAreActive() throws Exception { | |||
FindbugsSensor sensor = new FindbugsSensor(createRulesProfileWithActiveRules(), createRulesManager(), null); | |||
FindbugsSensor sensor = new FindbugsSensor(createRulesProfileWithActiveRules(), new FindbugsRuleFinder(), null); | |||
Project project = createProject(); | |||
assertTrue(sensor.shouldExecuteOnProject(project)); | |||
} | |||
@Test | |||
public void shouldNotExecuteWhenNoRulesAreActive() throws Exception { | |||
FindbugsSensor analyser = new FindbugsSensor(createRulesProfileWithoutActiveRules(), createRulesManager(), null); | |||
FindbugsSensor analyser = new FindbugsSensor(RulesProfile.create(), new FindbugsRuleFinder(), null); | |||
Project pom = createProject(); | |||
assertFalse(analyser.shouldExecuteOnProject(pom)); | |||
} | |||
@Test | |||
public void testGetMavenPluginHandlerWhenFindbugsReportPathExists() throws Exception { | |||
FindbugsSensor analyser = new FindbugsSensor(createRulesProfileWithoutActiveRules(), createRulesManager(), | |||
mock(FindbugsMavenPluginHandler.class)); | |||
FindbugsSensor analyser = new FindbugsSensor(RulesProfile.create(), new FindbugsRuleFinder(), mock(FindbugsMavenPluginHandler.class)); | |||
Project pom = createProject(); | |||
Configuration conf = mock(Configuration.class); | |||
when(conf.getString(CoreProperties.FINDBUGS_REPORT_PATH)).thenReturn("pathToFindbugsReport"); | |||
@@ -74,8 +74,7 @@ public class FindbugsSensorTest extends FindbugsTests { | |||
@Test | |||
public void testGetFindbugsReport() { | |||
FindbugsSensor analyser = new FindbugsSensor(createRulesProfileWithActiveRules(), createRulesManager(), | |||
null); | |||
FindbugsSensor analyser = new FindbugsSensor(createRulesProfileWithActiveRules(), new FindbugsRuleFinder(), null); | |||
Project pom = createProject(); | |||
Configuration conf = mock(Configuration.class); | |||
when(pom.getConfiguration()).thenReturn(conf); | |||
@@ -89,7 +88,7 @@ public class FindbugsSensorTest extends FindbugsTests { | |||
public void shouldNotExecuteOnEar() { | |||
Project project = createProject(); | |||
when(project.getPom().getPackaging()).thenReturn("ear"); | |||
FindbugsSensor analyser = new FindbugsSensor(createRulesProfileWithActiveRules(), createRulesManager(), null); | |||
FindbugsSensor analyser = new FindbugsSensor(createRulesProfileWithActiveRules(), new FindbugsRuleFinder(), null); | |||
assertFalse(analyser.shouldExecuteOnProject(project)); | |||
} | |||
@@ -104,21 +103,18 @@ public class FindbugsSensorTest extends FindbugsTests { | |||
when(project.getConfiguration()).thenReturn(conf); | |||
when(context.getResource(any(Resource.class))).thenReturn(new JavaFile("org.sonar.MyClass")); | |||
FindbugsSensor analyser = new FindbugsSensor(createRulesProfileWithoutActiveRules(), createRulesManager(), | |||
null); | |||
FindbugsSensor analyser = new FindbugsSensor(RulesProfile.create(), new FindbugsRuleFinder(), null); | |||
analyser.analyse(project, context); | |||
verify(context, times(3)).saveViolation(any(Violation.class)); | |||
Violation wanted = new Violation(null, new JavaFile("org.sonar.commons.ZipUtils")) | |||
.setMessage("Empty zip file entry created in org.sonar.commons.ZipUtils._zip(String, File, ZipOutputStream)") | |||
.setLineId(107); | |||
Violation wanted = new Violation(null, new JavaFile("org.sonar.commons.ZipUtils")).setMessage( | |||
"Empty zip file entry created in org.sonar.commons.ZipUtils._zip(String, File, ZipOutputStream)").setLineId(107); | |||
verify(context).saveViolation(argThat(new IsViolation(wanted))); | |||
wanted = new Violation(null, new JavaFile("org.sonar.commons.resources.MeasuresDao")) | |||
.setMessage("The class org.sonar.commons.resources.MeasuresDao$1 could be refactored into a named _static_ inner class") | |||
.setLineId(56); | |||
wanted = new Violation(null, new JavaFile("org.sonar.commons.resources.MeasuresDao")).setMessage( | |||
"The class org.sonar.commons.resources.MeasuresDao$1 could be refactored into a named _static_ inner class").setLineId(56); | |||
verify(context).saveViolation(argThat(new IsViolation(wanted))); | |||
} |
@@ -19,45 +19,44 @@ | |||
*/ | |||
package org.sonar.plugins.findbugs; | |||
import org.apache.commons.io.IOUtils; | |||
import static org.mockito.Matchers.anyString; | |||
import static org.mockito.Matchers.eq; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
import java.io.IOException; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.Collection; | |||
import java.util.List; | |||
import org.mockito.invocation.InvocationOnMock; | |||
import org.mockito.stubbing.Answer; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.profiles.RulesProfile; | |||
import org.sonar.api.resources.Java; | |||
import org.sonar.api.rules.ActiveRule; | |||
import org.sonar.api.rules.Rule; | |||
import org.sonar.api.rules.RulePriority; | |||
import org.sonar.api.rules.RuleQuery; | |||
import org.sonar.api.rules.RulesManager; | |||
import org.sonar.test.TestUtils; | |||
import org.xml.sax.SAXException; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.List; | |||
import static org.mockito.Matchers.anyString; | |||
import static org.mockito.Matchers.eq; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
public abstract class FindbugsTests { | |||
protected void assertXmlAreSimilar(String actualContent, String expectedFileName) throws IOException, SAXException { | |||
InputStream input = getClass().getResourceAsStream("/org/sonar/plugins/findbugs/" + expectedFileName); | |||
String expectedContent = IOUtils.toString(input); | |||
String expectedContent = TestUtils.getResourceContent("/org/sonar/plugins/findbugs/" + expectedFileName); | |||
TestUtils.assertSimilarXml(expectedContent, actualContent); | |||
} | |||
protected List<Rule> buildRulesFixture() { | |||
List<Rule> rules = new ArrayList<Rule>(); | |||
Rule rule1 = new Rule("DLS: Dead store to local variable", "DLS_DEAD_LOCAL_STORE", | |||
"DLS_DEAD_LOCAL_STORE", null, CoreProperties.FINDBUGS_PLUGIN, null); | |||
Rule rule1 = new Rule("DLS: Dead store to local variable", "DLS_DEAD_LOCAL_STORE", "DLS_DEAD_LOCAL_STORE", null, | |||
CoreProperties.FINDBUGS_PLUGIN, null); | |||
Rule rule2 = new Rule("UrF: Unread field", "URF_UNREAD_FIELD", | |||
"URF_UNREAD_FIELD", null, CoreProperties.FINDBUGS_PLUGIN, null); | |||
Rule rule2 = new Rule("UrF: Unread field", "URF_UNREAD_FIELD", "URF_UNREAD_FIELD", null, CoreProperties.FINDBUGS_PLUGIN, null); | |||
rules.add(rule1); | |||
rules.add(rule2); | |||
@@ -74,11 +73,11 @@ public abstract class FindbugsTests { | |||
return activeRules; | |||
} | |||
protected RulesManager createRulesManager() { | |||
RulesManager rulesManager = mock(RulesManager.class); | |||
when(rulesManager.getPluginRule(eq(CoreProperties.FINDBUGS_PLUGIN), anyString())).thenAnswer(new Answer<Rule>() { | |||
public Rule answer(InvocationOnMock invocationOnMock) throws Throwable { | |||
Object[] args = invocationOnMock.getArguments(); | |||
Rule rule = new Rule(); | |||
@@ -91,25 +90,13 @@ public abstract class FindbugsTests { | |||
} | |||
protected RulesProfile createRulesProfileWithActiveRules() { | |||
RulesProfile rulesProfile = mock(RulesProfile.class); | |||
when(rulesProfile.getActiveRule(eq(CoreProperties.FINDBUGS_PLUGIN), anyString())).thenAnswer(new Answer<ActiveRule>() { | |||
public ActiveRule answer(InvocationOnMock invocationOnMock) throws Throwable { | |||
Object[] args = invocationOnMock.getArguments(); | |||
ActiveRule activeRule = mock(ActiveRule.class); | |||
when(activeRule.getPluginName()).thenReturn((String) args[0]); | |||
when(activeRule.getRuleKey()).thenReturn((String) args[1]); | |||
when(activeRule.getPriority()).thenReturn(RulePriority.CRITICAL); | |||
return activeRule; | |||
} | |||
}); | |||
when(rulesProfile.getActiveRulesByPlugin(CoreProperties.FINDBUGS_PLUGIN)).thenReturn(Arrays.asList(new ActiveRule())); | |||
return rulesProfile; | |||
} | |||
protected RulesProfile createRulesProfileWithoutActiveRules() { | |||
RulesProfile rulesProfile = new RulesProfile(); | |||
List<ActiveRule> list = new ArrayList<ActiveRule>(); | |||
rulesProfile.setActiveRules(list); | |||
return rulesProfile; | |||
RulesProfile profile = RulesProfile.create(); | |||
profile.setName(RulesProfile.SONAR_WAY_FINDBUGS_NAME); | |||
profile.setLanguage(Java.KEY); | |||
for (Rule rule : new FindbugsRuleRepository().createRules()) { | |||
rule.setRepositoryKey(FindbugsConstants.REPOSITORY_KEY); | |||
profile.activateRule(rule, null); | |||
} | |||
return profile; | |||
} | |||
} |
@@ -0,0 +1,41 @@ | |||
/* | |||
* Sonar, open source software quality management tool. | |||
* Copyright (C) 2009 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* Sonar 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 3 of the License, or (at your option) any later version. | |||
* | |||
* Sonar 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 Sonar; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.plugins.findbugs; | |||
import static org.hamcrest.core.Is.is; | |||
import static org.hamcrest.number.OrderingComparisons.greaterThan; | |||
import static org.junit.Assert.assertThat; | |||
import org.junit.Test; | |||
import org.sonar.api.profiles.RulesProfile; | |||
import org.sonar.api.utils.ValidationMessages; | |||
public class SonarWayWithFindbugsProfileTest { | |||
@Test | |||
public void create() { | |||
FindbugsProfileImporter importer = new FindbugsProfileImporter(new FindbugsRuleFinder()); | |||
SonarWayWithFindbugsProfile sonarWayWithFindbugs = new SonarWayWithFindbugsProfile(importer); | |||
ValidationMessages validation = ValidationMessages.create(); | |||
RulesProfile profile = sonarWayWithFindbugs.createProfile(validation); | |||
assertThat(profile.getActiveRulesByRepository(FindbugsConstants.REPOSITORY_KEY).size(), greaterThan(300)); | |||
assertThat(validation.hasErrors(), is(false)); | |||
} | |||
} |
@@ -1,190 +0,0 @@ | |||
/* | |||
* Sonar, open source software quality management tool. | |||
* Copyright (C) 2009 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* Sonar 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 3 of the License, or (at your option) any later version. | |||
* | |||
* Sonar 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 Sonar; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.plugins.findbugs.tools; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.codehaus.plexus.util.IOUtil; | |||
import org.codehaus.staxmate.in.SMHierarchicCursor; | |||
import org.codehaus.staxmate.in.SMInputCursor; | |||
import org.sonar.api.rules.Rule; | |||
import org.sonar.api.rules.RulesCategory; | |||
import org.sonar.api.rules.StandardRulesXmlParser; | |||
import org.sonar.api.utils.StaxParser; | |||
import javax.xml.stream.XMLStreamException; | |||
import java.io.File; | |||
import java.io.FileOutputStream; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.net.MalformedURLException; | |||
import java.net.URL; | |||
import java.util.ArrayList; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
public class RulesGenerator { | |||
private static final String FOR_VERSION = "1.3.8"; | |||
private final static Map<String, String> BUG_CATEGS = new HashMap<String, String>(); | |||
static { | |||
BUG_CATEGS.put("STYLE", "Usability"); | |||
BUG_CATEGS.put("NOISE", "Reliability"); | |||
BUG_CATEGS.put("CORRECTNESS", "Reliability"); | |||
BUG_CATEGS.put("SECURITY", "Reliability"); | |||
BUG_CATEGS.put("BAD_PRACTICE", "Maintainability"); | |||
BUG_CATEGS.put("MT_CORRECTNESS", "Reliability"); | |||
BUG_CATEGS.put("PERFORMANCE", "Efficiency"); | |||
BUG_CATEGS.put("I18N", "Portability"); | |||
BUG_CATEGS.put("MALICIOUS_CODE", "Reliability"); | |||
} | |||
public static void main(String[] args) throws Exception { | |||
List<FindBugsBug> bugs = getBugsToImport(); | |||
String generatedXML = parseMessages(bugs); | |||
File out = new File(".", "rules.xml"); | |||
IOUtil.copy(generatedXML.getBytes(), new FileOutputStream(out)); | |||
System.out.println("Written to " + out.getPath()); | |||
} | |||
private static List<FindBugsBug> getBugsToImport() throws MalformedURLException, IOException, XMLStreamException { | |||
URL messages = new URL("http://findbugs.googlecode.com/svn/branches/" + FOR_VERSION + "/findbugs/etc/findbugs.xml"); | |||
InputStream in = messages.openStream(); | |||
final List<FindBugsBug> bugs = new ArrayList<FindBugsBug>(); | |||
StaxParser p = new StaxParser(new StaxParser.XmlStreamHandler() { | |||
public void stream(SMHierarchicCursor rootCursor) throws XMLStreamException { | |||
rootCursor.advance(); | |||
SMInputCursor bugPatterns = rootCursor.descendantElementCursor("BugPattern"); | |||
collectBugDefs(bugs, bugPatterns); | |||
} | |||
private void collectBugDefs(final List<FindBugsBug> bugs, SMInputCursor bugPatterns) throws XMLStreamException { | |||
while (bugPatterns.getNext() != null) { | |||
if (bugPatterns.asEvent().isEndElement()) continue; | |||
String experimental = bugPatterns.getAttrValue("experimental"); | |||
boolean isExperimental = (StringUtils.isNotEmpty(experimental) && Boolean.valueOf(experimental)) || bugPatterns.getAttrValue("category").equals("EXPERIMENTAL"); | |||
String deprecated = bugPatterns.getAttrValue("deprecated"); | |||
boolean isDeprecated = StringUtils.isNotEmpty(deprecated) && Boolean.valueOf(deprecated); | |||
if (!isExperimental && !isDeprecated) { | |||
bugs.add(new FindBugsBug(bugPatterns.getAttrValue("category"), bugPatterns.getAttrValue("type"))); | |||
} | |||
} | |||
} | |||
}); | |||
p.parse(in); | |||
in.close(); | |||
return bugs; | |||
} | |||
private static String parseMessages(final List<FindBugsBug> bugs) throws MalformedURLException, IOException, XMLStreamException { | |||
URL messages = new URL("http://findbugs.googlecode.com/svn/branches/" + FOR_VERSION + "/findbugs/etc/messages.xml"); | |||
InputStream in = messages.openStream(); | |||
final List<Rule> rules = new ArrayList<Rule>(); | |||
StaxParser p = new StaxParser(new StaxParser.XmlStreamHandler() { | |||
public void stream(SMHierarchicCursor rootCursor) throws XMLStreamException { | |||
rootCursor.advance(); | |||
Map<String, String> bugCategoriesDecr = new HashMap<String, String>(); | |||
SMInputCursor childrens = rootCursor.childElementCursor(); | |||
while (childrens.getNext() != null) { | |||
if (childrens.asEvent().isEndElement()) continue; | |||
if (childrens.getLocalName().equals("BugCategory")) { | |||
String bugCateg = childrens.getAttrValue("category"); | |||
bugCategoriesDecr.put(bugCateg, childrens.childElementCursor("Description").advance().collectDescendantText()); | |||
} else if (childrens.getLocalName().equals("BugPattern")) { | |||
String bugType = childrens.getAttrValue("type"); | |||
FindBugsBug bug = getFindBugsBugByType(bugType, bugs); | |||
if (bug == null) continue; | |||
rules.add(getRuleForBug(bugType, bug, bugCategoriesDecr, childrens)); | |||
} | |||
} | |||
} | |||
}); | |||
p.parse(in); | |||
in.close(); | |||
StandardRulesXmlParser parser = new StandardRulesXmlParser(); | |||
return parser.toXml(rules); | |||
} | |||
private static Rule getRuleForBug(String bugType, FindBugsBug bug, | |||
Map<String, String> bugCategoriesDecr, SMInputCursor childrens) throws XMLStreamException { | |||
Rule rule = new Rule(); | |||
rule.setKey(bugType); | |||
rule.setConfigKey(bugType); | |||
String rulesCateg = BUG_CATEGS.get(bug.getCategory()); | |||
if (StringUtils.isEmpty(rulesCateg)) { | |||
throw new RuntimeException("Rules cat not found " + bug.getCategory()); | |||
} | |||
rule.setRulesCategory(new RulesCategory(rulesCateg)); | |||
SMInputCursor descendents = childrens.childElementCursor(); | |||
while (descendents.getNext() != null) { | |||
if (descendents.asEvent().isStartElement()) { | |||
if (descendents.getLocalName().equals("ShortDescription")) { | |||
String categName = bugCategoriesDecr.get(bug.getCategory()); | |||
if (StringUtils.isEmpty(categName)) throw new RuntimeException("Cat not found " + bug.getCategory()); | |||
rule.setName(categName + " - " + descendents.collectDescendantText()); | |||
} else if (descendents.getLocalName().equals("Details")) { | |||
rule.setDescription(descendents.collectDescendantText()); | |||
} | |||
} | |||
} | |||
return rule; | |||
} | |||
private static FindBugsBug getFindBugsBugByType(String type, List<FindBugsBug> bugs) { | |||
for (FindBugsBug findBugsBug : bugs) { | |||
if (findBugsBug.getType().equals(type)) { | |||
return findBugsBug; | |||
} | |||
} | |||
return null; | |||
} | |||
private static class FindBugsBug { | |||
private String category; | |||
private String type; | |||
public FindBugsBug(String category, String type) { | |||
super(); | |||
this.category = category; | |||
this.type = type; | |||
} | |||
public String getCategory() { | |||
return category; | |||
} | |||
public String getType() { | |||
return type; | |||
} | |||
} | |||
} |
@@ -1,9 +0,0 @@ | |||
<FindBugsFilter> | |||
<Match> | |||
<Or> | |||
<Bug pattern="FB1_IMPORT_TEST_1"/> | |||
<Bug pattern="FB2_IMPORT_TEST_4"/> | |||
</Or> | |||
<Priority value="2"/> | |||
</Match> | |||
</FindBugsFilter> |
@@ -5,7 +5,7 @@ | |||
<Match> | |||
<Class name="com.foobar.ClassWithSomeBugsMatched" /> | |||
<Bug code="FB1" /> | |||
<Bug code="NP_CLOSING_NULL" /> | |||
<Priority value="2" /> | |||
</Match> | |||
@@ -13,7 +13,7 @@ | |||
<Class name="com.foobar.MyClass" /> | |||
<Method name="someMethod" /> | |||
<Local name="maxArgs" /> | |||
<Bug pattern="FB1_IMPORT_TEST_3" /> | |||
<Bug pattern="RC_REF_COMPARISON_BAD_PRACTICE" /> | |||
<Priority value="1" /> | |||
</Match> | |||
@@ -30,7 +30,7 @@ | |||
<Method name="frob" params="int,java.lang.String" returns="void" /> | |||
<Method name="blat" params="" returns="boolean" /> | |||
</Or> | |||
<Bug category="MT_CORRECTNESS" /> | |||
<Bug category="SECURITY" /> | |||
<Priority value="3" /> | |||
</Match> | |||
</FindBugsFilter> |
@@ -0,0 +1,6 @@ | |||
<FindBugsFilter> | |||
<Match> | |||
<Bug category="CORRECTNESS,MT_CORRECTN9876976" /> | |||
<Priority value="3"/> | |||
</Match> | |||
</FindBugsFilter> |
@@ -0,0 +1,6 @@ | |||
<FindBugsFilter> | |||
<Match> | |||
<Bug code="BC,EC87LK"/> | |||
<Priority value="2"/> | |||
</Match> | |||
</FindBugsFilter> |
@@ -0,0 +1,9 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<FindBugsFilter> | |||
<Match> | |||
<Bug pattern="DLS_DEAD_LOCAL_STORE" /> | |||
</Match> | |||
<Match> | |||
<Bug pattern="UNKNOWN" /> | |||
</Match> | |||
</FindBugsFilter> |
@@ -1,6 +1,6 @@ | |||
<FindBugsFilter> | |||
<Match> | |||
<Bug code="FB1,FB3"/> | |||
<Bug code="BC,EC"/> | |||
<Priority value="2"/> | |||
</Match> | |||
</FindBugsFilter> |
@@ -0,0 +1,9 @@ | |||
<FindBugsFilter> | |||
<Match> | |||
<Or> | |||
<Bug pattern="NP_CLOSING_NULL"/> | |||
<Bug pattern="RC_REF_COMPARISON_BAD_PRACTICE"/> | |||
</Or> | |||
<Priority value="2"/> | |||
</Match> | |||
</FindBugsFilter> |
@@ -0,0 +1,5 @@ | |||
<BugCollection timestamp='1282919233000' analysisTimestamp='1282919402891' sequence='0' release='' version='1.3.9'> | |||
<Project projectName=''> | |||
<Jar>/Users/freddy/Documents/sonar_projects/sonar/sonar-commons/target/classes</Jar> | |||
<AuxClasspathEntry>/Users/freddy/.m2/repository/org/apache/maven/reporting/maven-reporting-impl/2.0/maven-reporting-impl-2.0.jar</AuxClasspathEntry> | |||