package pl.touk.sputnik.processor.pmd; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.sourceforge.pmd.Report; import net.sourceforge.pmd.RulePriority; import net.sourceforge.pmd.RuleViolation; import net.sourceforge.pmd.renderers.AbstractRenderer; import net.sourceforge.pmd.util.datasource.DataSource; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import pl.touk.sputnik.configuration.Configuration; import pl.touk.sputnik.configuration.ConfigurationBuilder; import pl.touk.sputnik.configuration.GeneralOption; import pl.touk.sputnik.review.ReviewResult; import pl.touk.sputnik.review.Severity; import pl.touk.sputnik.review.Violation; import java.io.IOException; import java.util.Properties; @Slf4j public class CollectorRenderer extends AbstractRenderer { private static final String SPUTNIK_PMD_COLLECT_RENDERER = "Sputnik PMD Collect Renderer"; private static final char LINE_SEPARATOR = '\n'; private final Configuration configuration; @Getter private final ReviewResult reviewResult = new ReviewResult(); public CollectorRenderer(Properties properties) { this(ConfigurationBuilder.initFromProperties(properties)); } public CollectorRenderer(Configuration configuration) { super(SPUTNIK_PMD_COLLECT_RENDERER, SPUTNIK_PMD_COLLECT_RENDERER); this.configuration = configuration; } @Override public String defaultFileExtension() { return null; } @Override public void startFileAnalysis(DataSource dataSource) { log.debug("PMD audit started for {}", dataSource); } @Override public void renderFileReport(Report report) throws IOException { boolean showDetails = Boolean.valueOf(configuration.getProperty(GeneralOption.PMD_SHOW_VIOLATION_DETAILS)); for (RuleViolation ruleViolation : report) { String violationDescription = showDetails ? renderViolationDetails(ruleViolation) :ruleViolation.getDescription(); reviewResult.add(new Violation(ruleViolation.getFilename(), ruleViolation.getBeginLine(), violationDescription, convert(ruleViolation.getRule().getPriority()))); } } private String renderViolationDetails(RuleViolation ruleViolation) { StringBuilder fullDescription = new StringBuilder(ruleViolation.getDescription()); String reason = ruleViolation.getRule().getDescription(); if (StringUtils.isNotEmpty(reason)) { fullDescription.append(LINE_SEPARATOR).append(reason); } String url = ruleViolation.getRule().getExternalInfoUrl(); if (StringUtils.isNotEmpty(url)) { fullDescription.append(LINE_SEPARATOR).append(url); } return fullDescription.toString(); } @Override public void start() throws IOException { log.info("PMD audit started"); } @Override public void end() throws IOException { log.info("PMD audit finished"); } @NotNull private Severity convert(@NotNull RulePriority rulePriority) { switch (rulePriority) { case HIGH: return Severity.ERROR; case MEDIUM_HIGH: return Severity.WARNING; case MEDIUM: return Severity.INFO; case MEDIUM_LOW: return Severity.INFO; case LOW: return Severity.IGNORE; default: throw new IllegalArgumentException("RulePriority " + rulePriority + " is not supported"); } } }