diff --git a/.github/workflows/quality-monitor.yml b/.github/workflows/quality-monitor.yml index 65bede0ca..55e0652aa 100644 --- a/.github/workflows/quality-monitor.yml +++ b/.github/workflows/quality-monitor.yml @@ -54,12 +54,12 @@ jobs: { "id": "checkstyle", "name": "CheckStyle", - "pattern": "**/target/checkstyle-result.xml" + "pattern": "**/target/checkstyle-*/checkstyle-result.xml" }, { "id": "pmd", "name": "PMD", - "pattern": "**/target/pmd.xml" + "pattern": "**/target/pmd-*/pmd.xml" } ] }, diff --git a/pom.xml b/pom.xml index adf2101b5..67d0b150d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ edu.hm.hafner codingstyle-pom - 3.43.0 + 4.5.0 @@ -49,7 +49,7 @@ - https://www.cs.hm.edu/die_fakultaet/ansprechpartner/professoren/hafner/index.de.html + https://cs.hm.edu/~hafner HEAD diff --git a/src/main/java/edu/hm/hafner/analysis/FileReaderFactory.java b/src/main/java/edu/hm/hafner/analysis/FileReaderFactory.java index cfdd801db..585873d4a 100644 --- a/src/main/java/edu/hm/hafner/analysis/FileReaderFactory.java +++ b/src/main/java/edu/hm/hafner/analysis/FileReaderFactory.java @@ -59,6 +59,7 @@ public FileReaderFactory(final Path file) { this(file, null); } + @SuppressWarnings("PMD.CloseResource") @Override @MustBeClosed public Reader create() { try { diff --git a/src/main/java/edu/hm/hafner/analysis/FullTextFingerprint.java b/src/main/java/edu/hm/hafner/analysis/FullTextFingerprint.java index 2d929efa4..a0d8804d2 100644 --- a/src/main/java/edu/hm/hafner/analysis/FullTextFingerprint.java +++ b/src/main/java/edu/hm/hafner/analysis/FullTextFingerprint.java @@ -97,7 +97,7 @@ private String asHex(final byte[] bytes) { hexChars[j * 2] = HEX_CHARACTERS[v >>> 4]; hexChars[j * 2 + 1] = HEX_CHARACTERS[v & 0x0F]; } - return new String(hexChars); + return String.valueOf(hexChars); } @VisibleForTesting diff --git a/src/main/java/edu/hm/hafner/analysis/Issue.java b/src/main/java/edu/hm/hafner/analysis/Issue.java index 156308370..57809817d 100644 --- a/src/main/java/edu/hm/hafner/analysis/Issue.java +++ b/src/main/java/edu/hm/hafner/analysis/Issue.java @@ -60,7 +60,7 @@ public static String getPropertyValueAsString(final Issue issue, final String pr * @return the function that obtains the value */ public static Function getPropertyValueGetter(final String propertyName) { - return issue -> Issue.getPropertyValueAsString(issue, propertyName); + return issue -> getPropertyValueAsString(issue, propertyName); } /** diff --git a/src/main/java/edu/hm/hafner/analysis/IssueDifference.java b/src/main/java/edu/hm/hafner/analysis/IssueDifference.java index 69747f6c8..b3c1ba782 100644 --- a/src/main/java/edu/hm/hafner/analysis/IssueDifference.java +++ b/src/main/java/edu/hm/hafner/analysis/IssueDifference.java @@ -84,7 +84,7 @@ public IssueDifference(final Report currentIssues, final String referenceId, private void findIssuesInChangedCode(final Map includes) { for (Entry include : includes.entrySet()) { - newIssues.filter(issue -> filter(issue, include.getKey(), include.getValue())) + newIssues.filter(issue -> isInFileAtPosition(issue, include.getKey(), include.getValue())) .stream() .map(Issue::getId) .map(newIssues::remove) @@ -92,11 +92,8 @@ private void findIssuesInChangedCode(final Map includes) { } } - private boolean filter(final Issue issue, final String fileName, final int line) { - if (!issue.getFileName().endsWith(fileName)) { - return false; - } - return issue.affectsLine(line); + private boolean isInFileAtPosition(final Issue issue, final String fileName, final int line) { + return issue.getFileName().endsWith(fileName) && issue.affectsLine(line); } private List matchIssuesByEquals(final Report currentIssues) { diff --git a/src/main/java/edu/hm/hafner/analysis/IssuesInModifiedCodeMarker.java b/src/main/java/edu/hm/hafner/analysis/IssuesInModifiedCodeMarker.java index 1880f373f..8353f38df 100644 --- a/src/main/java/edu/hm/hafner/analysis/IssuesInModifiedCodeMarker.java +++ b/src/main/java/edu/hm/hafner/analysis/IssuesInModifiedCodeMarker.java @@ -35,9 +35,6 @@ public void markIssuesInModifiedCode(final Report report, final Map lines) { var normalizedPath = PATH_UTIL.getRelativePath(fileName); - if (!issue.getFileName().endsWith(normalizedPath)) { // check only the suffix - return false; - } - return lines.stream().anyMatch(issue::affectsLine); + return issue.getFileName().endsWith(normalizedPath) && lines.stream().anyMatch(issue::affectsLine); } } diff --git a/src/main/java/edu/hm/hafner/analysis/LookaheadParser.java b/src/main/java/edu/hm/hafner/analysis/LookaheadParser.java index e83181f50..98c40ccfd 100644 --- a/src/main/java/edu/hm/hafner/analysis/LookaheadParser.java +++ b/src/main/java/edu/hm/hafner/analysis/LookaheadParser.java @@ -1,7 +1,8 @@ package edu.hm.hafner.analysis; +import java.util.ArrayDeque; +import java.util.Deque; import java.util.Optional; -import java.util.Stack; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Stream; @@ -12,9 +13,9 @@ /** * Parses a report file line by line for issues using a pre-defined regular expression. If the regular expression - * matches then the abstract method {@link #createIssue(Matcher, LookaheadStream, IssueBuilder)} will be called. Sub - * classes need to provide an implementation that transforms the {@link Matcher} instance into a new issue. If required, - * sub classes may consume additional lines from the report file before control is handed back to the template method of + * matches then the abstract method {@link #createIssue(Matcher, LookaheadStream, IssueBuilder)} will be called. + * Subclasses need to provide an implementation that transforms the {@link Matcher} instance into a new issue. If required, + * subclasses may consume additional lines from the report file before control is handed back to the template method of * this parser. * * @author Ullrich Hafner @@ -38,7 +39,7 @@ public abstract class LookaheadParser extends IssueParser { private final Pattern pattern; - private final Stack recursiveDirectories; + private final Deque recursiveDirectories; /** * Creates a new instance of {@link LookaheadParser}. @@ -50,7 +51,7 @@ protected LookaheadParser(final String pattern) { super(); this.pattern = Pattern.compile(pattern); - this.recursiveDirectories = new Stack<>(); + this.recursiveDirectories = new ArrayDeque<>(); } @Override @@ -65,6 +66,7 @@ public Report parse(final ReaderFactory readerFactory) throws ParsingException, return postProcess(report); } + @SuppressWarnings("PMD.DoNotUseThreads") private void parse(final Report report, final LookaheadStream lookahead) { try (IssueBuilder builder = new IssueBuilder()) { while (lookahead.hasNext()) { @@ -107,7 +109,7 @@ protected void preprocessLine(final String line) { * @return The new directory to change to */ private String enterDirectory(final String line, final Report log) { - extractDirectory(line, ENTERING_DIRECTORY_PATH, log).map(recursiveDirectories::push); + extractDirectory(line, ENTERING_DIRECTORY_PATH, log).ifPresent(recursiveDirectories::push); return recursiveDirectories.isEmpty() ? NO_DIRECTORY : recursiveDirectories.peek(); } @@ -118,9 +120,9 @@ private String enterDirectory(final String line, final Report log) { * @return The last directory seen, or an empty String if we have returned to the beginning */ private String leaveDirectory() { - if (!recursiveDirectories.empty()) { + if (!recursiveDirectories.isEmpty()) { recursiveDirectories.pop(); - if (!recursiveDirectories.empty()) { + if (!recursiveDirectories.isEmpty()) { return recursiveDirectories.peek(); } } diff --git a/src/main/java/edu/hm/hafner/analysis/ModuleDetector.java b/src/main/java/edu/hm/hafner/analysis/ModuleDetector.java index 6149d672d..4d5cbc4be 100644 --- a/src/main/java/edu/hm/hafner/analysis/ModuleDetector.java +++ b/src/main/java/edu/hm/hafner/analysis/ModuleDetector.java @@ -108,7 +108,7 @@ public String guessModuleName(final String originalFileName) { * @return the found files (as absolute paths) */ private List find(final Path path) { - ArrayList absoluteFileNames = new ArrayList<>(); + List absoluteFileNames = new ArrayList<>(); for (AbstractModuleDetector moduleDetector : moduleDetectors) { String[] relativeFileNames = factory.find(path, moduleDetector.getPattern()); diff --git a/src/main/java/edu/hm/hafner/analysis/PackageNameResolver.java b/src/main/java/edu/hm/hafner/analysis/PackageNameResolver.java index 12003ece3..da2606cb9 100644 --- a/src/main/java/edu/hm/hafner/analysis/PackageNameResolver.java +++ b/src/main/java/edu/hm/hafner/analysis/PackageNameResolver.java @@ -3,13 +3,14 @@ import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import edu.hm.hafner.util.VisibleForTesting; -import static edu.hm.hafner.analysis.PackageDetectors.*; +import static edu.hm.hafner.analysis.PackageDetectors.*; import static java.util.function.Function.*; /** @@ -29,7 +30,7 @@ public PackageNameResolver() { @VisibleForTesting PackageNameResolver(final FileSystem fileSystem) { - ArrayList detectors = new ArrayList<>(Arrays.asList( + List detectors = new ArrayList<>(Arrays.asList( new JavaPackageDetector(fileSystem), new CSharpNamespaceDetector(fileSystem), new KotlinPackageDetector(fileSystem) diff --git a/src/main/java/edu/hm/hafner/analysis/Report.java b/src/main/java/edu/hm/hafner/analysis/Report.java index fa06acdeb..9ead7a909 100644 --- a/src/main/java/edu/hm/hafner/analysis/Report.java +++ b/src/main/java/edu/hm/hafner/analysis/Report.java @@ -358,10 +358,14 @@ public Report addAll(final Report... reports) { } private boolean contains(final Issue issue) { - if (elements.contains(issue)) { - return true; - } - return subReports.stream().map(r -> r.contains(issue)).reduce(Boolean::logicalOr).orElse(false); + return elements.contains(issue) || subReportsContains(issue); + } + + private Boolean subReportsContains(final Issue issue) { + return subReports.stream() + .map(r -> r.contains(issue)) + .reduce(Boolean::logicalOr) + .orElse(false); } @VisibleForTesting @@ -1089,6 +1093,8 @@ private void writeLongString(final ObjectOutputStream output, final String value } @SuppressWarnings("unchecked") + @SuppressFBWarnings(value = "MC_OVERRIDABLE_METHOD_CALL_IN_READ_OBJECT", + justification = "False positive, the overridden method is in already initialized objects") private void readObject(final ObjectInputStream input) throws IOException, ClassNotFoundException { elements = new LinkedHashSet<>(); readIssues(input, input.readInt()); @@ -1157,7 +1163,7 @@ private String readLongString(final ObjectInputStream input) throws IOException for (int j = 0; j < chars.length; j++) { chars[j] = input.readChar(); } - return new String(chars); + return String.valueOf(chars); } /** diff --git a/src/main/java/edu/hm/hafner/analysis/Severity.java b/src/main/java/edu/hm/hafner/analysis/Severity.java index a7a483298..64fb93019 100644 --- a/src/main/java/edu/hm/hafner/analysis/Severity.java +++ b/src/main/java/edu/hm/hafner/analysis/Severity.java @@ -96,18 +96,18 @@ public static Severity valueOf(@CheckForNull final String severity, final Severi */ public static Severity guessFromString(@CheckForNull final String severity) { if (StringUtils.containsAnyIgnoreCase(severity, "error", "severe", "critical", "fatal")) { - return Severity.ERROR; + return ERROR; } if (StringUtils.containsAnyIgnoreCase(severity, "info", "note", "low")) { - return Severity.WARNING_LOW; + return WARNING_LOW; } if (StringUtils.containsAnyIgnoreCase(severity, "warning", "medium")) { - return Severity.WARNING_NORMAL; + return WARNING_NORMAL; } if (StringUtils.containsIgnoreCase(severity, "high")) { - return Severity.WARNING_HIGH; + return WARNING_HIGH; } - return Severity.WARNING_LOW; + return WARNING_LOW; } /** @@ -120,7 +120,7 @@ public static Severity guessFromString(@CheckForNull final String severity) { */ public static Collection collectSeveritiesFrom(final Severity minimumSeverity) { List priorities = new ArrayList<>(); - priorities.add(Severity.ERROR); + priorities.add(ERROR); if (WARNING_HIGH.equals(minimumSeverity)) { priorities.add(WARNING_HIGH); } diff --git a/src/main/java/edu/hm/hafner/analysis/parser/AjcParser.java b/src/main/java/edu/hm/hafner/analysis/parser/AjcParser.java index a8f365bf8..a78543f2e 100644 --- a/src/main/java/edu/hm/hafner/analysis/parser/AjcParser.java +++ b/src/main/java/edu/hm/hafner/analysis/parser/AjcParser.java @@ -94,7 +94,7 @@ private void fillMessageAndCategory(final IssueBuilder builder, final String lin category = Categories.DEPRECATION; } else if (line.contains("adviceDidNotMatch")) { - category = AjcParser.ADVICE; + category = ADVICE; } else { category = ""; diff --git a/src/main/java/edu/hm/hafner/analysis/parser/DrMemoryParser.java b/src/main/java/edu/hm/hafner/analysis/parser/DrMemoryParser.java index c3b3500c3..227ed5e08 100644 --- a/src/main/java/edu/hm/hafner/analysis/parser/DrMemoryParser.java +++ b/src/main/java/edu/hm/hafner/analysis/parser/DrMemoryParser.java @@ -13,6 +13,7 @@ import edu.hm.hafner.analysis.ParsingException; import edu.hm.hafner.analysis.Severity; import edu.hm.hafner.util.LookaheadStream; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import static edu.hm.hafner.analysis.util.IntegerParser.*; @@ -40,7 +41,7 @@ public DrMemoryParser() { super(DR_MEMORY_WARNING_PATTERN); } - @Override + @Override @SuppressFBWarnings(value = "POTENTIAL_XML_INJECTION", justification = "Message is cleaned in UI") protected Optional createIssue(final Matcher matcher, final LookaheadStream lookahead, final IssueBuilder builder) throws ParsingException { diff --git a/src/main/java/edu/hm/hafner/analysis/parser/IarCstatParser.java b/src/main/java/edu/hm/hafner/analysis/parser/IarCstatParser.java index ea2e5144f..865422403 100644 --- a/src/main/java/edu/hm/hafner/analysis/parser/IarCstatParser.java +++ b/src/main/java/edu/hm/hafner/analysis/parser/IarCstatParser.java @@ -19,6 +19,8 @@ public class IarCstatParser extends LookaheadParser { private static final String IAR_WARNING_PATTERN = ANT_TASK + "(?:\"?(.*?)\"?[\\(,](\\d+)\\)?\\s+)?(Severity-(?:Low|Medium|High))\\[(\\S+)\\]:(.*)$"; + private static final String SEVERITY_LOW = "Severity-Low"; + private static final String SEVERITY_HIGH = "Severity-High"; /** * Creates a new instance of {@link IarCstatParser}. @@ -45,10 +47,10 @@ protected Optional createIssue(final Matcher matcher, final LookaheadStre private Severity mapSeverity(final String category) { Severity severity; - if ("Severity-Low".equals(category)) { + if (SEVERITY_LOW.equals(category)) { severity = Severity.WARNING_LOW; } - else if ("Severity-High".equals(category)) { + else if (SEVERITY_HIGH.equals(category)) { severity = Severity.WARNING_HIGH; } else { diff --git a/src/main/java/edu/hm/hafner/analysis/parser/IdeaInspectionParser.java b/src/main/java/edu/hm/hafner/analysis/parser/IdeaInspectionParser.java index 78188b6b5..a21ae115a 100644 --- a/src/main/java/edu/hm/hafner/analysis/parser/IdeaInspectionParser.java +++ b/src/main/java/edu/hm/hafner/analysis/parser/IdeaInspectionParser.java @@ -3,7 +3,6 @@ import java.util.List; import java.util.Optional; -import edu.hm.hafner.analysis.util.IntegerParser; import org.apache.commons.lang3.StringUtils; import org.apache.commons.text.StringEscapeUtils; import org.w3c.dom.Document; @@ -16,6 +15,7 @@ import edu.hm.hafner.analysis.ReaderFactory; import edu.hm.hafner.analysis.Report; import edu.hm.hafner.analysis.Severity; +import edu.hm.hafner.analysis.util.IntegerParser; import edu.hm.hafner.analysis.util.XmlElementUtil; /** @@ -26,6 +26,8 @@ public class IdeaInspectionParser extends IssueParser { private static final long serialVersionUID = 3307389086106375473L; private static final String PATH_PREFIX = "file://"; + private static final String WARNING = "WARNING"; + private static final String ERROR = "ERROR"; @Override public Report parse(final ReaderFactory readerFactory) throws ParsingException { @@ -58,10 +60,10 @@ private Report parseProblems(final List elements) { private Severity getPriority(final String severity) { Severity priority = Severity.WARNING_LOW; - if ("WARNING".equals(severity)) { + if (WARNING.equals(severity)) { priority = Severity.WARNING_NORMAL; } - else if ("ERROR".equals(severity)) { + else if (ERROR.equals(severity)) { priority = Severity.WARNING_HIGH; } return priority; diff --git a/src/main/java/edu/hm/hafner/analysis/parser/LintParser.java b/src/main/java/edu/hm/hafner/analysis/parser/LintParser.java index 22ec0f9e3..fad15d87b 100644 --- a/src/main/java/edu/hm/hafner/analysis/parser/LintParser.java +++ b/src/main/java/edu/hm/hafner/analysis/parser/LintParser.java @@ -19,6 +19,7 @@ */ public class LintParser extends IssueParser { private static final long serialVersionUID = 3341424685245834156L; + private static final String FILE = "file"; @Override public Report parse(final ReaderFactory readerFactory) throws ParsingException { @@ -56,7 +57,7 @@ public void startElement(final String namespaceURI, return; // Start element, good to skip } - if ("file".equals(key)) { + if (FILE.equals(key)) { fileName = atts.getValue("name"); return; } diff --git a/src/main/java/edu/hm/hafner/analysis/parser/MentorParser.java b/src/main/java/edu/hm/hafner/analysis/parser/MentorParser.java index 7c8a7b846..c730f53f1 100644 --- a/src/main/java/edu/hm/hafner/analysis/parser/MentorParser.java +++ b/src/main/java/edu/hm/hafner/analysis/parser/MentorParser.java @@ -8,6 +8,7 @@ import edu.hm.hafner.analysis.IssueBuilder; import edu.hm.hafner.analysis.LookaheadParser; import edu.hm.hafner.util.LookaheadStream; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; /** * Parser for Mentor Graphics Modelsim/Questa Simulator. @@ -125,6 +126,7 @@ private void parseVsimMessage(final LookaheadStream lookahead, final IssueBuilde builder.setMessage(parsedMessage); } + @SuppressFBWarnings(value = "POTENTIAL_XML_INJECTION", justification = "Message is cleaned in UI") private String parseSimTime(final LookaheadStream lookahead, final IssueBuilder builder) { StringBuilder description = new StringBuilder(); String timeLine = ""; diff --git a/src/main/java/edu/hm/hafner/analysis/parser/MsBuildParser.java b/src/main/java/edu/hm/hafner/analysis/parser/MsBuildParser.java index fd54043d1..0c0846a74 100644 --- a/src/main/java/edu/hm/hafner/analysis/parser/MsBuildParser.java +++ b/src/main/java/edu/hm/hafner/analysis/parser/MsBuildParser.java @@ -38,6 +38,8 @@ public class MsBuildParser extends LookaheadParser { private static final Pattern IGNORED_TOOLS_PATTERN = Pattern.compile("(?!.exe)(\\.[^.]+)$"); private static final Pattern LINKER_CAUSE = Pattern.compile(".*imported by '([A-Za-z0-9\\-_.]+)'.*"); + private static final String EXPECTED_CATEGORY = "Expected"; + private static final String MSBUILD = "MSBUILD"; /** * Creates a new instance of {@link MsBuildParser}. @@ -76,7 +78,7 @@ protected Optional createIssue(final Matcher matcher, final LookaheadStre } String category = matcher.group(9); - if ("Expected".equals(category)) { + if (EXPECTED_CATEGORY.equals(category)) { return Optional.empty(); } return builder.setLineStart(matcher.group(5)) @@ -124,7 +126,7 @@ else if (StringUtils.isNotBlank(matcher.group(7))) { if (canResolveRelativeFileName(fileName, projectDir)) { fileName = FilenameUtils.concat(projectDir, fileName); } - if ("MSBUILD".equals(fileName.trim())) { + if (MSBUILD.equals(fileName.trim())) { fileName = "-"; } return fileName; @@ -132,7 +134,7 @@ else if (StringUtils.isNotBlank(matcher.group(7))) { private boolean canResolveRelativeFileName(final String fileName, final String projectDir) { return StringUtils.isNotBlank(projectDir) && FilenameUtils.getPrefixLength(fileName) == 0 - && !"MSBUILD".equals(fileName.trim()); + && !MSBUILD.equals(fileName.trim()); } } diff --git a/src/main/java/edu/hm/hafner/analysis/parser/QtTranslationParser.java b/src/main/java/edu/hm/hafner/analysis/parser/QtTranslationParser.java index c82923f98..c3341f5c0 100644 --- a/src/main/java/edu/hm/hafner/analysis/parser/QtTranslationParser.java +++ b/src/main/java/edu/hm/hafner/analysis/parser/QtTranslationParser.java @@ -196,7 +196,7 @@ public void endElement(final String uri, final String localName, final String qN sourceValue = ""; } - @Override + @Override @SuppressWarnings("PMD.UnusedAssignment") // false positive in PMD 7.0.0 public void characters(final char[] ch, final int start, final int length) { lastColumnNumber = documentLocator.getColumnNumber(); if (CONTEXT_NAME.equals(elementTypeStack.getFirst())) { diff --git a/src/main/java/edu/hm/hafner/analysis/parser/RevApiParser.java b/src/main/java/edu/hm/hafner/analysis/parser/RevApiParser.java index f76edf247..f58e3e4f4 100644 --- a/src/main/java/edu/hm/hafner/analysis/parser/RevApiParser.java +++ b/src/main/java/edu/hm/hafner/analysis/parser/RevApiParser.java @@ -14,12 +14,14 @@ import edu.hm.hafner.analysis.Report; import edu.hm.hafner.analysis.RevApiInfoExtension; import edu.hm.hafner.analysis.Severity; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; /** * Parser for Revapi reports. */ public class RevApiParser extends JsonIssueParser { private static final long serialVersionUID = -2452699725595063377L; + private static final int CAPACITY = 1024; @Override protected void parseJsonArray(final Report report, final JSONArray jsonReport, final IssueBuilder issueBuilder) { @@ -101,8 +103,9 @@ private Severity toSeverity(final String level) { } } + @SuppressFBWarnings(value = "POTENTIAL_XML_INJECTION", justification = "Message is cleaned in UI") private String getDescription(final JSONObject jsonIssue) { - StringBuilder severityDescription = new StringBuilder(); + StringBuilder severityDescription = new StringBuilder(CAPACITY); for (Object severity : jsonIssue.getJSONArray("classification")) { if (severity instanceof JSONObject) { severityDescription.append("

Compatibility: ") diff --git a/src/main/java/edu/hm/hafner/analysis/parser/RfLintParser.java b/src/main/java/edu/hm/hafner/analysis/parser/RfLintParser.java index 9be1e2267..d83bc0091 100644 --- a/src/main/java/edu/hm/hafner/analysis/parser/RfLintParser.java +++ b/src/main/java/edu/hm/hafner/analysis/parser/RfLintParser.java @@ -165,6 +165,7 @@ public Report parse(final ReaderFactory readerFactory) { } } + @SuppressWarnings("PMD.DoNotUseThreads") private void parseLine(final IssueBuilder builder, final Report warnings, final String line) { Matcher fileMatcher = FILE_PATTERN.matcher(line); if (fileMatcher.find()) { diff --git a/src/main/java/edu/hm/hafner/analysis/parser/SbtScalacParser.java b/src/main/java/edu/hm/hafner/analysis/parser/SbtScalacParser.java index 5c1240388..8fed693ce 100644 --- a/src/main/java/edu/hm/hafner/analysis/parser/SbtScalacParser.java +++ b/src/main/java/edu/hm/hafner/analysis/parser/SbtScalacParser.java @@ -10,7 +10,8 @@ import edu.hm.hafner.util.LookaheadStream; /** - * A parser for the sbt scala compiler warnings. You should use -feature and -deprecation compiler opts. + * A parser for the sbt scala compiler warnings. You should use {@code -feature} and {@code -deprecation} compiler + * opts. * * @author Hochak Hung */ @@ -18,6 +19,7 @@ public class SbtScalacParser extends LookaheadParser { private static final long serialVersionUID = -4233964844965517977L; private static final String SBT_WARNING_PATTERN = "^(\\[warn\\]|\\[error\\](?!\\s+Total\\stime:))\\s*(.*?):(\\d+)(?::\\d+)?:\\s*(.*)$"; + private static final String ERROR = "[error]"; /** * Creates a new instance of {@link SbtScalacParser}. @@ -37,7 +39,7 @@ protected Optional createIssue(final Matcher matcher, final LookaheadStre } private Severity mapPriority(final Matcher matcher) { - if ("[error]".equals(matcher.group(1))) { + if (ERROR.equals(matcher.group(1))) { return Severity.WARNING_HIGH; } else { diff --git a/src/main/java/edu/hm/hafner/analysis/parser/XlcCompilerParser.java b/src/main/java/edu/hm/hafner/analysis/parser/XlcCompilerParser.java index a9a0f78aa..4e561677e 100644 --- a/src/main/java/edu/hm/hafner/analysis/parser/XlcCompilerParser.java +++ b/src/main/java/edu/hm/hafner/analysis/parser/XlcCompilerParser.java @@ -9,12 +9,14 @@ import edu.hm.hafner.analysis.LookaheadParser; import edu.hm.hafner.analysis.Severity; import edu.hm.hafner.util.LookaheadStream; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; /** * A parser for IBM xlC compiler warnings. * * @author Andrew Gvozdev */ +@SuppressFBWarnings("REDOS") public class XlcCompilerParser extends LookaheadParser { private static final long serialVersionUID = 5490211629355204910L; diff --git a/src/main/java/edu/hm/hafner/analysis/parser/XlcLinkerParser.java b/src/main/java/edu/hm/hafner/analysis/parser/XlcLinkerParser.java index 19fc154ec..5462875b6 100644 --- a/src/main/java/edu/hm/hafner/analysis/parser/XlcLinkerParser.java +++ b/src/main/java/edu/hm/hafner/analysis/parser/XlcLinkerParser.java @@ -9,12 +9,14 @@ import edu.hm.hafner.analysis.LookaheadParser; import edu.hm.hafner.analysis.Severity; import edu.hm.hafner.util.LookaheadStream; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; /** * A parser for IBM xlC linker warnings. * * @author Andrew Gvozdev */ +@SuppressFBWarnings("REDOS") public class XlcLinkerParser extends LookaheadParser { private static final long serialVersionUID = 211259620936831096L; private static final String XLC_LINKER_WARNING_PATTERN = ANT_TASK + "ld: ([0-9]+-[0-9]+)*\\s*(.*)$"; diff --git a/src/main/java/edu/hm/hafner/analysis/parser/ccm/CcmParser.java b/src/main/java/edu/hm/hafner/analysis/parser/ccm/CcmParser.java index e368149ff..f4a0363ec 100644 --- a/src/main/java/edu/hm/hafner/analysis/parser/ccm/CcmParser.java +++ b/src/main/java/edu/hm/hafner/analysis/parser/ccm/CcmParser.java @@ -106,9 +106,8 @@ private boolean isMetricHighPriority(final Metric metric) { private boolean isMetricModeratePriority(final Metric metric) { String metricClassification = metric.getClassification(); - if (StringUtils.contains(metricClassification, "moderate")) { - return true; - } - return "B".equals(metricClassification); + + return StringUtils.contains(metricClassification, "moderate") + || "B".equals(metricClassification); } } diff --git a/src/main/java/edu/hm/hafner/analysis/parser/findbugs/FindBugsParser.java b/src/main/java/edu/hm/hafner/analysis/parser/findbugs/FindBugsParser.java index 1a7564e58..84391c398 100644 --- a/src/main/java/edu/hm/hafner/analysis/parser/findbugs/FindBugsParser.java +++ b/src/main/java/edu/hm/hafner/analysis/parser/findbugs/FindBugsParser.java @@ -209,7 +209,7 @@ List preParse(final Reader file) throws SAXException, IOExceptio digester.addCallMethod(fileXPath, "setMessage", 0); digester.addSetNext(rootXPath, "add", Object.class.getName()); - ArrayList bugs = new ArrayList<>(); + List bugs = new ArrayList<>(); digester.push(bugs); digester.parse(file); @@ -230,6 +230,7 @@ private Severity getPriority(final BugInstance warning) { } } + @SuppressWarnings("PMD.DoNotUseThreads") private SortedBugCollection readXml(final Reader file) throws IOException, DocumentException { ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); try { diff --git a/src/main/java/edu/hm/hafner/analysis/parser/fxcop/FxCopParser.java b/src/main/java/edu/hm/hafner/analysis/parser/fxcop/FxCopParser.java index f2f52f0d1..99962a147 100644 --- a/src/main/java/edu/hm/hafner/analysis/parser/fxcop/FxCopParser.java +++ b/src/main/java/edu/hm/hafner/analysis/parser/fxcop/FxCopParser.java @@ -16,12 +16,11 @@ /** * Parses a fxcop xml report file. - * - *

Note that instances of this parser are not thread safe.

*/ @SuppressWarnings("unused") public class FxCopParser extends IssueParser { private static final long serialVersionUID = -7208558002331355408L; + private static final int CAPACITY = 1024; @Override public Report parse(final ReaderFactory readerFactory) throws ParsingException, ParsingCanceledException { @@ -164,7 +163,7 @@ private void parseIssue(final Element issue, final Element parent, final String String checkId = getString(parent, "CheckId"); String issueLevel = getString(issue, "Level"); - StringBuilder msgBuilder = new StringBuilder(); + StringBuilder msgBuilder = new StringBuilder(CAPACITY); FxCopRule rule = ruleSet.getRule(category, checkId); if (rule == null) { msgBuilder.append(typeName); diff --git a/src/main/java/edu/hm/hafner/analysis/parser/gendarme/GendarmeParser.java b/src/main/java/edu/hm/hafner/analysis/parser/gendarme/GendarmeParser.java index 98da1317a..e7ad48b96 100644 --- a/src/main/java/edu/hm/hafner/analysis/parser/gendarme/GendarmeParser.java +++ b/src/main/java/edu/hm/hafner/analysis/parser/gendarme/GendarmeParser.java @@ -32,6 +32,9 @@ public class GendarmeParser extends IssueParser { private static final long serialVersionUID = 1677715364464119907L; private static final Pattern FILE_PATTERN = Pattern.compile("^(.*)\\(.(\\d+)\\).*$"); + private static final String TYPE = "Type"; + private static final String METHOD = "Method"; + private static final String ASSEMBLY = "Assembly"; @Override public Report parse(final ReaderFactory factory) throws ParsingException { @@ -108,15 +111,19 @@ private Map parseRules(final List ruleElements) { rule.setName(ruleElement.getAttribute("Name")); rule.setTypeName(ruleElement.getTextContent()); - String typeString = ruleElement.getAttribute("Type"); - if ("Type".equals(typeString)) { - rule.setType(GendarmeRuleType.Type); - } - else if ("Method".equals(typeString)) { - rule.setType(GendarmeRuleType.Method); - } - else if ("Assembly".equals(typeString)) { - rule.setType(GendarmeRuleType.Assembly); + String typeString = ruleElement.getAttribute(TYPE); + switch (typeString) { + case TYPE: + rule.setType(GendarmeRuleType.Type); + break; + case METHOD: + rule.setType(GendarmeRuleType.Method); + break; + case ASSEMBLY: + rule.setType(GendarmeRuleType.Assembly); + break; + default: + // ignore the type } try { rule.setUrl(new URL(ruleElement.getAttribute("Uri"))); diff --git a/src/main/java/edu/hm/hafner/analysis/parser/pvsstudio/PVSStudioParser.java b/src/main/java/edu/hm/hafner/analysis/parser/pvsstudio/PVSStudioParser.java index 85ee62b12..0beb0a86e 100644 --- a/src/main/java/edu/hm/hafner/analysis/parser/pvsstudio/PVSStudioParser.java +++ b/src/main/java/edu/hm/hafner/analysis/parser/pvsstudio/PVSStudioParser.java @@ -17,15 +17,18 @@ */ public class PVSStudioParser extends IssueParser { private static final long serialVersionUID = -7777775729854832128L; + private static final String SEVERITY_HIGH = "1"; + private static final String SEVERITY_NORMAL = "2"; + private static final String SEVERITY_LOW = "3"; private static Severity getSeverity(final String level) { - if ("1".equals(level)) { + if (SEVERITY_HIGH.equals(level)) { return Severity.WARNING_HIGH; } - else if ("2".equals(level)) { + else if (SEVERITY_NORMAL.equals(level)) { return Severity.WARNING_NORMAL; } - else if ("3".equals(level)) { + else if (SEVERITY_LOW.equals(level)) { return Severity.WARNING_LOW; } else { diff --git a/src/main/java/edu/hm/hafner/analysis/parser/pylint/PyLintDescriptions.java b/src/main/java/edu/hm/hafner/analysis/parser/pylint/PyLintDescriptions.java index ea405b60e..778a73af0 100644 --- a/src/main/java/edu/hm/hafner/analysis/parser/pylint/PyLintDescriptions.java +++ b/src/main/java/edu/hm/hafner/analysis/parser/pylint/PyLintDescriptions.java @@ -22,6 +22,7 @@ public class PyLintDescriptions { /** * Loads the available rules into a map. */ + @SuppressWarnings("PMD.LooseCoupling") public PyLintDescriptions() { JSONParser parser = new JSONParser(JSONParser.MODE_JSON_SIMPLE); diff --git a/src/main/java/edu/hm/hafner/analysis/parser/violations/PitAdapter.java b/src/main/java/edu/hm/hafner/analysis/parser/violations/PitAdapter.java index cf6e5a832..53733893e 100644 --- a/src/main/java/edu/hm/hafner/analysis/parser/violations/PitAdapter.java +++ b/src/main/java/edu/hm/hafner/analysis/parser/violations/PitAdapter.java @@ -75,6 +75,6 @@ void extractAdditionalProperties(final IssueBuilder builder, final Violation vio } private String getMutationStatus(final Violation violation) { - return violation.getSpecifics().getOrDefault(PitAdapter.STATUS, KILLED); + return violation.getSpecifics().getOrDefault(STATUS, KILLED); } } diff --git a/src/main/java/edu/hm/hafner/analysis/registry/DryDescriptor.java b/src/main/java/edu/hm/hafner/analysis/registry/DryDescriptor.java index ba7000e0d..d32580231 100644 --- a/src/main/java/edu/hm/hafner/analysis/registry/DryDescriptor.java +++ b/src/main/java/edu/hm/hafner/analysis/registry/DryDescriptor.java @@ -51,7 +51,7 @@ private int convertThreshold(final String key, final int defaultValue, final Opt private String getDuplicateCode(@CheckForNull final Serializable properties) { if (properties instanceof DuplicationGroup) { - return pre().with(new UnescapedText(DryDescriptor.getCodeFragment((DuplicationGroup) properties))) + return pre().with(new UnescapedText(getCodeFragment((DuplicationGroup) properties))) .renderFormatted(); } else { diff --git a/src/test/java/edu/hm/hafner/analysis/AntModuleDetectorTest.java b/src/test/java/edu/hm/hafner/analysis/AntModuleDetectorTest.java index d36d670ee..c03256bba 100644 --- a/src/test/java/edu/hm/hafner/analysis/AntModuleDetectorTest.java +++ b/src/test/java/edu/hm/hafner/analysis/AntModuleDetectorTest.java @@ -37,9 +37,9 @@ void shouldIdentifyModuleByReadingAntProjectFile() { }); ModuleDetector detector = new ModuleDetector(ROOT, factory); - assertThat(detector.guessModuleName(PREFIX + (PATH_PREFIX_ANT + "something.txt"))) + assertThat(detector.guessModuleName(PREFIX + PATH_PREFIX_ANT + "something.txt")) .isEqualTo(EXPECTED_ANT_MODULE); - assertThat(detector.guessModuleName(PREFIX + (PATH_PREFIX_ANT + "in/between/something.txt"))) + assertThat(detector.guessModuleName(PREFIX + PATH_PREFIX_ANT + "in/between/something.txt")) .isEqualTo(EXPECTED_ANT_MODULE); assertThat(detector.guessModuleName(PREFIX + "path/to/something.txt")) .isEqualTo(StringUtils.EMPTY); diff --git a/src/test/java/edu/hm/hafner/analysis/GradleModuleDetectorTest.java b/src/test/java/edu/hm/hafner/analysis/GradleModuleDetectorTest.java index ee4e111fe..b5e059da3 100644 --- a/src/test/java/edu/hm/hafner/analysis/GradleModuleDetectorTest.java +++ b/src/test/java/edu/hm/hafner/analysis/GradleModuleDetectorTest.java @@ -39,7 +39,7 @@ void shouldIdentifyModuleByReadingGradlePath() { ModuleDetector detector = new ModuleDetector(ROOT, factory); - assertThat(detector.guessModuleName(PREFIX + (PATH_PREFIX_GRADLE + "build/reports/something.txt"))) + assertThat(detector.guessModuleName(PREFIX + PATH_PREFIX_GRADLE + "build/reports/something.txt")) .isEqualTo(EXPECTED_GRADLE_MODULE_ROOT_BY_PATH); assertThat(detector.guessModuleName(PREFIX + "build/reports/something.txt")) .isEqualTo(StringUtils.EMPTY); @@ -77,7 +77,7 @@ void shouldIdentifyModuleByReadingGradleKtsPath() { ModuleDetector detector = new ModuleDetector(ROOT, factory); - assertThat(detector.guessModuleName(PREFIX + (PATH_PREFIX_GRADLE + "build/reports/something.txt"))) + assertThat(detector.guessModuleName(PREFIX + PATH_PREFIX_GRADLE + "build/reports/something.txt")) .isEqualTo(EXPECTED_GRADLE_MODULE_ROOT_BY_PATH); assertThat(detector.guessModuleName(PREFIX + "build/reports/something.txt")) .isEqualTo(StringUtils.EMPTY); diff --git a/src/test/java/edu/hm/hafner/analysis/IssuesInModifiedCodeMarkerTest.java b/src/test/java/edu/hm/hafner/analysis/IssuesInModifiedCodeMarkerTest.java index c16332202..7454e64b7 100644 --- a/src/test/java/edu/hm/hafner/analysis/IssuesInModifiedCodeMarkerTest.java +++ b/src/test/java/edu/hm/hafner/analysis/IssuesInModifiedCodeMarkerTest.java @@ -22,7 +22,6 @@ void shouldNotMarkAnythingForEmptyMap() { var marker = new IssuesInModifiedCodeMarker(); marker.markIssuesInModifiedCode(report, Map.of()); - assertThatModifiedCodeMarkers(report).containsExactly(false, false); assertThatIssuesToString(report).containsExactly(TO_STRING_UNMODIFIED, TO_STRING_UNMODIFIED); } diff --git a/src/test/java/edu/hm/hafner/analysis/MavenModuleDetectorTest.java b/src/test/java/edu/hm/hafner/analysis/MavenModuleDetectorTest.java index f48595165..11c3b57b6 100644 --- a/src/test/java/edu/hm/hafner/analysis/MavenModuleDetectorTest.java +++ b/src/test/java/edu/hm/hafner/analysis/MavenModuleDetectorTest.java @@ -6,8 +6,7 @@ import edu.hm.hafner.analysis.ModuleDetector.FileSystem; import static org.assertj.core.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; class MavenModuleDetectorTest extends AbstractModuleDetectorTest { @@ -39,9 +38,9 @@ void shouldIdentifyModuleByReadingMavenPom() { ModuleDetector detector = new ModuleDetector(ROOT, factory); - assertThat(detector.guessModuleName(PREFIX + (PATH_PREFIX_MAVEN + "something.txt"))).isEqualTo( + assertThat(detector.guessModuleName(PREFIX + PATH_PREFIX_MAVEN + "something.txt")).isEqualTo( EXPECTED_MAVEN_MODULE); - assertThat(detector.guessModuleName(PREFIX + (PATH_PREFIX_MAVEN + "in/between/something.txt"))).isEqualTo( + assertThat(detector.guessModuleName(PREFIX + PATH_PREFIX_MAVEN + "in/between/something.txt")).isEqualTo( EXPECTED_MAVEN_MODULE); assertThat(detector.guessModuleName(PREFIX + "path/to/something.txt")).isEqualTo(StringUtils.EMPTY); } @@ -56,11 +55,11 @@ void shouldIdentifyModuleByReadingMavenPomWithoutName() { ModuleDetector detector = new ModuleDetector(ROOT, factory); String artifactId = "com.avaloq.adt.core"; - assertThat(detector.guessModuleName(PREFIX + (PATH_PREFIX_MAVEN + "something.txt"))) + assertThat(detector.guessModuleName(PREFIX + PATH_PREFIX_MAVEN + "something.txt")) .isEqualTo(artifactId); - assertThat(detector.guessModuleName(PREFIX + (PATH_PREFIX_MAVEN + "in/between/something.txt"))) + assertThat(detector.guessModuleName(PREFIX + PATH_PREFIX_MAVEN + "in/between/something.txt")) .isEqualTo(artifactId); assertThat(detector.guessModuleName(PREFIX + "path/to/something.txt")) .isEqualTo(StringUtils.EMPTY); } -} \ No newline at end of file +} diff --git a/src/test/java/edu/hm/hafner/analysis/ModuleDetectorTest.java b/src/test/java/edu/hm/hafner/analysis/ModuleDetectorTest.java index edbdb0af2..f64b46317 100644 --- a/src/test/java/edu/hm/hafner/analysis/ModuleDetectorTest.java +++ b/src/test/java/edu/hm/hafner/analysis/ModuleDetectorTest.java @@ -50,9 +50,9 @@ void shouldIdentifyModuleIfThereAreMoreEntries() { ModuleDetector detector = new ModuleDetector(ROOT, factory); - assertThat(detector.guessModuleName(PREFIX + (PATH_PREFIX_ANT + "something.txt"))) + assertThat(detector.guessModuleName(PREFIX + PATH_PREFIX_ANT + "something.txt")) .isEqualTo(EXPECTED_ANT_MODULE); - assertThat(detector.guessModuleName(PREFIX + (PATH_PREFIX_MAVEN + "something.txt"))) + assertThat(detector.guessModuleName(PREFIX + PATH_PREFIX_MAVEN + "something.txt")) .isEqualTo(EXPECTED_MAVEN_MODULE); } diff --git a/src/test/java/edu/hm/hafner/analysis/OsgiModuleDetectorTest.java b/src/test/java/edu/hm/hafner/analysis/OsgiModuleDetectorTest.java index 8c81c53e8..f9e8da95b 100644 --- a/src/test/java/edu/hm/hafner/analysis/OsgiModuleDetectorTest.java +++ b/src/test/java/edu/hm/hafner/analysis/OsgiModuleDetectorTest.java @@ -6,8 +6,7 @@ import edu.hm.hafner.analysis.ModuleDetector.FileSystem; import static org.assertj.core.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; /** @@ -41,9 +40,9 @@ void shouldIdentifyModuleByReadingOsgiBundle() { ModuleDetector detector = new ModuleDetector(ROOT, factory); - assertThat(detector.guessModuleName(PREFIX + (PATH_PREFIX_OSGI + "something.txt"))) + assertThat(detector.guessModuleName(PREFIX + PATH_PREFIX_OSGI + "something.txt")) .isEqualTo(EXPECTED_OSGI_MODULE); - assertThat(detector.guessModuleName(PREFIX + (PATH_PREFIX_OSGI + "in/between/something.txt"))) + assertThat(detector.guessModuleName(PREFIX + PATH_PREFIX_OSGI + "in/between/something.txt")) .isEqualTo(EXPECTED_OSGI_MODULE); assertThat(detector.guessModuleName(PREFIX + "path/to/something.txt")) .isEqualTo(StringUtils.EMPTY); @@ -59,9 +58,9 @@ void shouldIdentifyModuleByReadingOsgiBundleWithVendorInL10nProperties() { ModuleDetector detector = new ModuleDetector(ROOT, factory); String expectedName = "de.faktorlogik.prototyp (My Vendor)"; - assertThat(detector.guessModuleName(PREFIX + (PATH_PREFIX_OSGI + "something.txt"))) + assertThat(detector.guessModuleName(PREFIX + PATH_PREFIX_OSGI + "something.txt")) .isEqualTo(expectedName); - assertThat(detector.guessModuleName(PREFIX + (PATH_PREFIX_OSGI + "in/between/something.txt"))) + assertThat(detector.guessModuleName(PREFIX + PATH_PREFIX_OSGI + "in/between/something.txt")) .isEqualTo(expectedName); assertThat(detector.guessModuleName(PREFIX + "path/to/something.txt")) .isEqualTo(StringUtils.EMPTY); @@ -78,11 +77,11 @@ void shouldIdentifyModuleByReadingOsgiBundleWithManifestName() { ModuleDetector detector = new ModuleDetector(ROOT, fileSystem); String expectedName = "My Bundle"; - assertThat(detector.guessModuleName(PREFIX + (PATH_PREFIX_OSGI + "something.txt"))) + assertThat(detector.guessModuleName(PREFIX + PATH_PREFIX_OSGI + "something.txt")) .isEqualTo(expectedName); - assertThat(detector.guessModuleName(PREFIX + (PATH_PREFIX_OSGI + "in/between/something.txt"))) + assertThat(detector.guessModuleName(PREFIX + PATH_PREFIX_OSGI + "in/between/something.txt")) .isEqualTo(expectedName); assertThat(detector.guessModuleName(PREFIX + "path/to/something.txt")) .isEqualTo(StringUtils.EMPTY); } -} \ No newline at end of file +} diff --git a/src/test/java/edu/hm/hafner/analysis/ReportTest.java b/src/test/java/edu/hm/hafner/analysis/ReportTest.java index 28ee5acbb..484a341d5 100644 --- a/src/test/java/edu/hm/hafner/analysis/ReportTest.java +++ b/src/test/java/edu/hm/hafner/analysis/ReportTest.java @@ -848,7 +848,7 @@ void shouldWriteLongMessages() { private String createLongMessage() { char[] chars = new char[100_000]; - return new String(chars); + return String.valueOf(chars); } /** Verifies that equals checks all properties. */ diff --git a/src/test/java/edu/hm/hafner/analysis/registry/ParsersTest.java b/src/test/java/edu/hm/hafner/analysis/registry/ParsersTest.java index 426d63b40..f4e951182 100644 --- a/src/test/java/edu/hm/hafner/analysis/registry/ParsersTest.java +++ b/src/test/java/edu/hm/hafner/analysis/registry/ParsersTest.java @@ -14,7 +14,7 @@ import static edu.hm.hafner.analysis.assertions.Assertions.*; /** - * Integration tests of all parsers of the warnings plug-in in pipelines. + * Integration tests of all parsers. * * @author Ullrich Hafner */