se.bjurr.violations.git.ViolationsReporterApi Maven / Gradle / Ivy
The newest version!
package se.bjurr.violations.git;
import static se.bjurr.violations.git.ViolationsReporterDetailLevel.COMPACT;
import static se.bjurr.violations.git.ViolationsReporterDetailLevel.PER_FILE_COMPACT;
import static se.bjurr.violations.git.ViolationsReporterDetailLevel.VERBOSE;
import static se.bjurr.violations.lib.model.SEVERITY.ERROR;
import static se.bjurr.violations.lib.model.SEVERITY.INFO;
import static se.bjurr.violations.lib.model.SEVERITY.WARN;
import static se.bjurr.violations.lib.util.Utils.checkNotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import se.bjurr.violations.lib.model.SEVERITY;
import se.bjurr.violations.lib.model.Violation;
import se.bjurr.violations.table.ViolationsTable;
public class ViolationsReporterApi {
private Iterable violations;
private int maxReporterColumnWidth;
private int maxRuleColumnWidth = 10;
private int maxSeverityColumnWidth;
private int maxLineColumnWidth;
private int maxMessageColumnWidth = 50;
private ViolationsReporterApi() {}
public static ViolationsReporterApi violationsReporterApi() {
return new ViolationsReporterApi();
}
public String getReport(final ViolationsReporterDetailLevel level) {
checkNotNull(this.violations, "violations");
final StringBuilder sb = new StringBuilder();
if (level == COMPACT) {
sb.append(this.toCompact(this.violations, "Summary"));
} else if (level == PER_FILE_COMPACT) {
sb.append(this.toPerFile(this.violations));
sb.append(this.toCompact(this.violations, "Summary"));
} else if (level == VERBOSE) {
sb.append(this.toVerbose(this.violations));
sb.append(this.toCompact(this.violations, "Summary"));
}
return sb.toString();
}
private StringBuilder toVerbose(final Iterable violations) {
final StringBuilder sb = new StringBuilder();
final Map> perFile = this.getViolationsPerFile(violations);
for (final Entry> perFileEntry : perFile.entrySet()) {
final String file = perFileEntry.getKey();
final Set fileViolations = perFile.get(file);
sb.append(file + "\n");
sb.append(this.toDetailed(fileViolations, "Summary of " + file));
sb.append("\n");
}
return sb;
}
private StringBuilder toPerFile(final Iterable violations) {
final StringBuilder sb = new StringBuilder();
final Map> perFile = this.getViolationsPerFile(violations);
for (final Entry> fileEntry : perFile.entrySet()) {
final Set fileViolations = fileEntry.getValue();
final String fileName = fileEntry.getKey();
sb.append(this.toCompact(fileViolations, "Summary of " + fileName));
sb.append("\n");
}
return sb;
}
public ViolationsReporterApi withViolations(final Set violations) {
this.violations = violations;
return this;
}
/**
* Avoid wider column. Will add new lines if wider. A value of 0 or less will disable the feature.
*/
public ViolationsReporterApi withMaxMessageColumnWidth(final int maxMessageColumnWidth) {
this.maxMessageColumnWidth = maxMessageColumnWidth;
return this;
}
/**
* Avoid wider column. Will add new lines if wider. A value of 0 or less will disable the feature.
*/
public ViolationsReporterApi withMaxLineColumnWidth(final int maxLineColumnWidth) {
this.maxLineColumnWidth = maxLineColumnWidth;
return this;
}
/**
* Avoid wider column. Will add new lines if wider. A value of 0 or less will disable the feature.
*/
public ViolationsReporterApi withMaxReporterColumnWidth(final int maxReporterColumnWidth) {
this.maxReporterColumnWidth = maxReporterColumnWidth;
return this;
}
/**
* Avoid wider column. Will add new lines if wider. A value of 0 or less will disable the feature.
*/
public ViolationsReporterApi withMaxRuleColumnWidth(final int maxRuleColumnWidth) {
this.maxRuleColumnWidth = maxRuleColumnWidth;
return this;
}
/** Avoid wider column. Will add new lines if wider. */
public ViolationsReporterApi withMaxSeverityColumnWidth(final int maxSeverityColumnWidth) {
this.maxSeverityColumnWidth = maxSeverityColumnWidth;
return this;
}
private StringBuilder toDetailed(
final Iterable violations, final String summarySubject) {
final StringBuilder sb = new StringBuilder();
final List rows = new ArrayList<>();
for (final Violation violation : violations) {
final String message = this.nullToEmpty(violation.getMessage());
final String line = this.nullToEmpty(violation.getStartLine().toString());
final String severity = this.nullToEmpty(violation.getSeverity().name());
final String rule = this.nullToEmpty(violation.getRule());
final String reporter = this.nullToEmpty(violation.getReporter());
final String[] row = {reporter, rule, severity, line, message};
rows.add(row);
}
final String[] headers = {"Reporter", "Rule", "Severity", "Line", "Message"};
final String[][] data = rows.toArray(new String[][] {});
final int[] columnWidths = {
this.zeroToMax(this.maxReporterColumnWidth),
this.zeroToMax(this.maxRuleColumnWidth),
this.zeroToMax(this.maxSeverityColumnWidth),
this.zeroToMax(this.maxLineColumnWidth),
this.zeroToMax(this.maxMessageColumnWidth)
};
sb.append(ViolationsTable.of(headers, data, columnWidths));
sb.append("\n");
sb.append(this.toCompact(violations, summarySubject));
sb.append("\n");
return sb;
}
private int zeroToMax(final int i) {
return i == 0 ? Integer.MAX_VALUE : i;
}
private String nullToEmpty(final String message) {
if (message == null) {
return "";
}
return message.trim();
}
private StringBuilder toCompact(final Iterable violations, final String subject) {
final StringBuilder sb = new StringBuilder();
final Map> perReporter = this.getViolationsPerReporter(violations);
final List rows = new ArrayList<>();
Integer totNumInfo = 0;
Integer totNumWarn = 0;
Integer totNumError = 0;
Integer totNumTot = 0;
for (final Entry> reporterEntry : perReporter.entrySet()) {
final String reporter = reporterEntry.getKey();
final Set reporterViolations = reporterEntry.getValue();
final Map> perSeverity =
this.getViolationsPerSeverity(reporterViolations);
final Integer numInfo = perSeverity.get(INFO).size();
final Integer numWarn = perSeverity.get(WARN).size();
final Integer numError = perSeverity.get(ERROR).size();
final Integer numTot = numInfo + numWarn + numError;
final String[] row = {
reporter, numInfo.toString(), numWarn.toString(), numError.toString(), numTot.toString()
};
rows.add(row);
totNumInfo += numInfo;
totNumWarn += numWarn;
totNumError += numError;
totNumTot += numTot;
}
final String[] row = {
"", totNumInfo.toString(), totNumWarn.toString(), totNumError.toString(), totNumTot.toString()
};
rows.add(row);
final String[] headers = {"Reporter", INFO.name(), WARN.name(), ERROR.name(), "Total"};
final String[][] data = rows.toArray(new String[][] {});
sb.append(subject + "\n");
final int[] columnWidths = {};
sb.append(ViolationsTable.of(headers, data, columnWidths));
sb.append("\n");
return sb;
}
private Map> getViolationsPerSeverity(final Set violations) {
final Map> violationsPerSeverity = new TreeMap<>();
for (final SEVERITY severity : SEVERITY.values()) {
violationsPerSeverity.put(severity, new TreeSet());
}
for (final Violation violation : violations) {
final Set perReporter =
this.getOrCreate(violationsPerSeverity, violation.getSeverity());
perReporter.add(violation);
}
return violationsPerSeverity;
}
private Map> getViolationsPerFile(final Iterable violations) {
final Map> violationsPerFile = new TreeMap<>();
for (final Violation violation : violations) {
final Set perReporter = this.getOrCreate(violationsPerFile, violation.getFile());
perReporter.add(violation);
}
return violationsPerFile;
}
private Map> getViolationsPerReporter(
final Iterable violations) {
final Map> violationsPerReporter = new TreeMap<>();
for (final Violation violation : violations) {
final Set perReporter =
this.getOrCreate(violationsPerReporter, violation.getReporter());
perReporter.add(violation);
}
return violationsPerReporter;
}
private Set getOrCreate(final Map> container, final K key) {
if (container.containsKey(key)) {
return container.get(key);
} else {
final Set violationList = new TreeSet<>();
container.put(key, violationList);
return violationList;
}
}
}