package pl.touk.sputnik.processor.findbugs;
import edu.umd.cs.findbugs.ClassScreener;
import edu.umd.cs.findbugs.DetectorFactoryCollection;
import edu.umd.cs.findbugs.FindBugs2;
import edu.umd.cs.findbugs.IClassScreener;
import edu.umd.cs.findbugs.Priorities;
import edu.umd.cs.findbugs.Project;
import edu.umd.cs.findbugs.config.UserPreferences;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import pl.touk.sputnik.configuration.Configuration;
import pl.touk.sputnik.configuration.GeneralOption;
import pl.touk.sputnik.review.Review;
import pl.touk.sputnik.review.ReviewException;
import pl.touk.sputnik.review.ReviewProcessor;
import pl.touk.sputnik.review.ReviewResult;
import pl.touk.sputnik.review.filter.JavaFilter;
import pl.touk.sputnik.review.locator.BuildDirLocatorFactory;
import pl.touk.sputnik.review.transformer.ClassNameTransformer;
@Slf4j
public class FindBugsProcessor implements ReviewProcessor {
private static final String SOURCE_NAME = "FindBugs";
private final CollectorBugReporter collectorBugReporter;
private final Configuration config;
public FindBugsProcessor(@NotNull Configuration configuration) {
collectorBugReporter = createBugReporter();
config = configuration;
}
@Nullable
@Override
public ReviewResult process(@NotNull Review review) {
FindBugs2 findBugs = createFindBugs2(review);
try {
findBugs.execute();
} catch (Exception e) {
log.error("FindBugs processing error", e);
throw new ReviewException("FindBugs processing error", e);
}
return collectorBugReporter.getReviewResult();
}
@NotNull
@Override
public String getName() {
return SOURCE_NAME;
}
public FindBugs2 createFindBugs2(Review review) {
FindBugs2 findBugs = new FindBugs2();
findBugs.setProject(createProject(review));
findBugs.setBugReporter(collectorBugReporter);
findBugs.setDetectorFactoryCollection(DetectorFactoryCollection.instance());
findBugs.setClassScreener(createClassScreener(review));
findBugs.setUserPreferences(createUserPreferences());
findBugs.setNoClassOk(true);
return findBugs;
}
private UserPreferences createUserPreferences() {
UserPreferences userPreferences = UserPreferences.createDefaultUserPreferences();
String includeFilterFilename = getIncludeFilterFilename();
if (StringUtils.isNotBlank(includeFilterFilename)) {
userPreferences.getIncludeFilterFiles().put(includeFilterFilename, true);
}
String excludeFilterFilename = getExcludeFilterFilename();
if (StringUtils.isNotBlank(excludeFilterFilename)) {
userPreferences.getExcludeFilterFiles().put(excludeFilterFilename, true);
}
return userPreferences;
}
@NotNull
public CollectorBugReporter createBugReporter() {
CollectorBugReporter collectorBugReporter = new CollectorBugReporter();
collectorBugReporter.setPriorityThreshold(Priorities.NORMAL_PRIORITY);
return collectorBugReporter;
}
@NotNull
private Project createProject(@NotNull Review review) {
Project project = new Project();
for (String buildDir : BuildDirLocatorFactory.create(config).getBuildDirs(review)) {
project.addFile(buildDir);
}
for (String sourceDir : review.getSourceDirs()) {
project.addSourceDir(sourceDir);
}
return project;
}
@NotNull
private IClassScreener createClassScreener(@NotNull Review review) {
ClassScreener classScreener = new ClassScreener();
for (String javaClassName : review.getFiles(new JavaFilter(), new ClassNameTransformer())) {
classScreener.addAllowedClass(javaClassName);
}
return classScreener;
}
@Nullable
private String getIncludeFilterFilename() {
String includeFilterFilename = config.getProperty(GeneralOption.FINDBUGS_INCLUDE_FILTER);
log.info("Using FindBugs include filter file {}", includeFilterFilename);
return includeFilterFilename;
}
@Nullable
private String getExcludeFilterFilename() {
String excludeFilterFilename = config.getProperty(GeneralOption.FINDBUGS_EXCLUDE_FILTER);
log.info("Using FindBugs exclude filter file {}", excludeFilterFilename);
return excludeFilterFilename;
}
}