From cb20e2c75ca5ed353f175704502d2881bd0ca270 Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Wed, 3 Jun 2026 09:27:40 +0200 Subject: [PATCH 01/16] #536: Resolve Sonar findings of June 2026 up to Linker.java --- .../openfasttrace/api/FilterSettings.java | 16 +++++++------- .../api/cli/DirectoryService.java | 2 +- .../api/core/DeepCoverageStatus.java | 8 +++---- .../openfasttrace/api/core/ItemStatus.java | 4 +++- .../openfasttrace/api/core/LinkStatus.java | 10 +++++---- .../api/core/LinkedSpecificationItem.java | 12 +++++------ .../api/exporter/ExporterFactory.java | 6 +++--- .../api/importer/ImportSettings.java | 7 ++++--- .../api/importer/ImporterContext.java | 2 +- .../tag/config/DescribedPathMatcher.java | 4 ++-- .../openfasttrace/core/ExportSettings.java | 4 ++-- .../openfasttrace/core/LinkedItemIndex.java | 8 +++---- .../itsallcode/openfasttrace/core/Linker.java | 11 +++++----- .../core/cli/ArgumentValidator.java | 2 +- .../openfasttrace/core/cli/CliArguments.java | 13 +++++++----- .../openfasttrace/core/cli/CliException.java | 2 +- .../core/cli/CommandLineInterpreter.java | 16 +++++++------- .../core/cli/commands/AbstractCommand.java | 6 +++--- .../core/cli/commands/ConvertCommand.java | 2 +- .../core/exporter/ExporterFactoryLoader.java | 12 +++++------ .../core/importer/ImporterServiceImpl.java | 2 +- .../common/IndentingXMLStreamWriter.java | 2 +- ...=> AbstractLightWeightMarkupImporter.java} | 8 +++---- .../ForwardingSpecificationItem.java | 18 ++++++++-------- .../importer/markdown/MarkdownImporter.java | 4 ++-- .../RestructuredTextImporter.java | 4 ++-- .../handler/FulfilledByHandlerBuilder.java | 4 ++-- .../importer/tag/ChecksumCalculator.java | 3 ++- .../importer/tag/DelegatingLineConsumer.java | 3 ++- .../importer/xmlparser/event/Attribute.java | 2 +- .../xmlparser/event/EndElementEvent.java | 2 +- .../tree/CallbackContentHandler.java | 8 +++---- .../report/aspec/ASpecReport.java | 11 ++++++---- .../openfasttrace/report/html/HtmlReport.java | 4 ++-- .../html/view/AbstractViewContainer.java | 7 ++++--- .../html/view/html/CharacterConstants.java | 10 ++++----- .../html/view/html/HtmlReportDetails.java | 2 +- .../html/view/html/HtmlSpecificationItem.java | 21 ++++++++++--------- .../html/view/html/HtmlTableOfContents.java | 2 +- .../html/view/html/HtmlTraceSummary.java | 2 +- .../html/view/html/HtmlViewFactory.java | 2 +- .../report/plaintext/AnsiSequence.java | 2 +- .../plaintext/ConsoleColorFormatter.java | 2 +- .../testutil/CompareAssertions.java | 5 +++-- .../testutil/core/ItemBuilderFactory.java | 2 +- .../xml/IndentingXMLStreamWriter.java | 4 ++-- 46 files changed, 150 insertions(+), 133 deletions(-) rename importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/{LightWeightMarkupImporter.java => AbstractLightWeightMarkupImporter.java} (96%) diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java b/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java index 8b50411a5..e9e17e50d 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java @@ -82,12 +82,12 @@ public boolean isAnyCriteriaSet() @Override public int hashCode() { - final int prime = 31; + final int PRIME = 31; int result = 1; - result = prime * result + result = PRIME * result + ((this.artifactTypes == null) ? 0 : this.artifactTypes.hashCode()); - result = prime * result + (this.withoutTags ? 1231 : 1237); - result = prime * result + ((this.tags == null) ? 0 : this.tags.hashCode()); + result = PRIME * result + (this.withoutTags ? 1231 : 1237); + result = PRIME * result + ((this.tags == null) ? 0 : this.tags.hashCode()); return result; } @@ -160,7 +160,7 @@ public static Builder builder() /** * Builder for {@link FilterSettings} */ - public static class Builder + public static final class Builder { private Set artifactTypes = Collections.emptySet(); private Set tags = Collections.emptySet(); @@ -180,7 +180,7 @@ private Builder() */ public Builder artifactTypes(final Set artifactTypes) { - this.artifactTypes = artifactTypes; + this.artifactTypes = Collections.unmodifiableSet(artifactTypes); return this; } @@ -193,7 +193,7 @@ public Builder artifactTypes(final Set artifactTypes) */ public Builder tags(final Set tags) { - this.tags = tags; + this.tags = Collections.unmodifiableSet(tags); return this; } @@ -220,4 +220,4 @@ public FilterSettings build() return new FilterSettings(this); } } -} \ No newline at end of file +} diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/cli/DirectoryService.java b/api/src/main/java/org/itsallcode/openfasttrace/api/cli/DirectoryService.java index 20ad9a879..589001711 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/cli/DirectoryService.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/cli/DirectoryService.java @@ -12,4 +12,4 @@ public interface DirectoryService * @return current directory */ String getCurrent(); -} \ No newline at end of file +} diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/core/DeepCoverageStatus.java b/api/src/main/java/org/itsallcode/openfasttrace/api/core/DeepCoverageStatus.java index 470c6dae7..818ed3c45 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/core/DeepCoverageStatus.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/core/DeepCoverageStatus.java @@ -21,23 +21,23 @@ public enum DeepCoverageStatus private final int badness; - private DeepCoverageStatus(final int badness) + DeepCoverageStatus(final int badness) { this.badness = badness; } /** - * Get the worse of two coverage status + * Get the worst of two coverage statuses * * @param a * left status to compare * @param b * right status to compare - * @return worse of both provided status + * @return worse of both provided statuses */ public static DeepCoverageStatus getWorst(final DeepCoverageStatus a, final DeepCoverageStatus b) { return (b.badness > a.badness) ? b : a; } -} \ No newline at end of file +} diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/core/ItemStatus.java b/api/src/main/java/org/itsallcode/openfasttrace/api/core/ItemStatus.java index 9ea98593c..9a0c73a91 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/core/ItemStatus.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/core/ItemStatus.java @@ -1,5 +1,7 @@ package org.itsallcode.openfasttrace.api.core; +import java.util.Locale; + /** * This enumeration represents the different statuses of an item. */ @@ -47,6 +49,6 @@ public static ItemStatus parseString(final String text) @Override public String toString() { - return this.name().toLowerCase(); + return this.name().toLowerCase(Locale.ENGLISH); } } diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/core/LinkStatus.java b/api/src/main/java/org/itsallcode/openfasttrace/api/core/LinkStatus.java index 669003859..25954eda0 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/core/LinkStatus.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/core/LinkStatus.java @@ -58,7 +58,7 @@ public enum LinkStatus private final String shortTag; private final String text; - private LinkStatus(final String shortTag, final String text) + LinkStatus(final String shortTag, final String text) { this.shortTag = shortTag; this.text = text; @@ -92,8 +92,10 @@ public boolean isOutgoing() */ public boolean isBadOutgoing() { - return (this == PREDATED) || (this == OUTDATED) || (this == AMBIGUOUS) || (this == UNWANTED) - || (this == ORPHANED); + return switch (this) { + case PREDATED, OUTDATED, AMBIGUOUS, UNWANTED, ORPHANED -> true; + default -> false; + }; } /** @@ -148,4 +150,4 @@ public String toString() { return this.text; } -} \ No newline at end of file +} diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/core/LinkedSpecificationItem.java b/api/src/main/java/org/itsallcode/openfasttrace/api/core/LinkedSpecificationItem.java index 23bb7ed5a..b163b6efb 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/core/LinkedSpecificationItem.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/core/LinkedSpecificationItem.java @@ -187,7 +187,7 @@ private void cacheOverCoveredArtifactType(final LinkedSpecificationItem overcove */ public Map> getLinks() { - return this.links; + return new EnumMap<>(this.links); } /** @@ -249,7 +249,7 @@ public List getNeedsArtifactTypes() */ public Set getCoveredArtifactTypes() { - return this.coveredArtifactTypes; + return Collections.unmodifiableSet(this.coveredArtifactTypes); } /** @@ -259,7 +259,7 @@ public Set getCoveredArtifactTypes() */ public Set getCoveredApprovedArtifactTypes() { - return this.coveredArtifactTypesFromApprovedItems; + return Collections.unmodifiableSet(this.coveredArtifactTypesFromApprovedItems); } /** @@ -270,7 +270,7 @@ public Set getCoveredApprovedArtifactTypes() public Set getOverCoveredArtifactTypes() { - return this.overCoveredArtifactTypes; + return Collections.unmodifiableSet(this.overCoveredArtifactTypes); } /** @@ -416,9 +416,9 @@ private List getIncomingItems() public boolean isDefect() { return hasDuplicates() // - || (getStatus() != ItemStatus.REJECTED) // + || ((getStatus() != ItemStatus.REJECTED) // && (hasBadLinks() - || (getDeepCoverageStatus() != DeepCoverageStatus.COVERED)); + || (getDeepCoverageStatus() != DeepCoverageStatus.COVERED))); } /** diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/exporter/ExporterFactory.java b/api/src/main/java/org/itsallcode/openfasttrace/api/exporter/ExporterFactory.java index 5abd2fee0..291500ddb 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/exporter/ExporterFactory.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/exporter/ExporterFactory.java @@ -102,12 +102,12 @@ private Writer createWriter(final Path file, final Charset charset) // Using System.out by intention @SuppressWarnings("squid:S106") - private PrintStream getStdOutStream() + private static PrintStream getStdOutStream() { return System.out; } - private Writer createFileWriter(final Path file, final Charset charset) + private static Writer createFileWriter(final Path file, final Charset charset) { try { @@ -132,4 +132,4 @@ private Writer createFileWriter(final Path file, final Charset charset) */ protected abstract Exporter createExporter(final Writer writer, Stream linkedSpecItemStream, final Newline newline); -} \ No newline at end of file +} diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImportSettings.java b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImportSettings.java index 1cad0704d..7c2ef1f71 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImportSettings.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImportSettings.java @@ -2,6 +2,7 @@ import java.nio.file.Path; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import org.itsallcode.openfasttrace.api.FilterSettings; @@ -30,7 +31,7 @@ private ImportSettings(final Builder builder) */ public List getInputs() { - return this.inputs; + return Collections.unmodifiableList(this.inputs); } /** @@ -138,7 +139,7 @@ public Builder filter(final FilterSettings filter) */ public Builder pathConfigs(final List pathConfigs) { - this.pathConfigs = pathConfigs; + this.pathConfigs = Collections.unmodifiableList(pathConfigs); return this; } @@ -152,4 +153,4 @@ public ImportSettings build() return new ImportSettings(this); } } -} \ No newline at end of file +} diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImporterContext.java b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImporterContext.java index 219432ccc..81fff548d 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImporterContext.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImporterContext.java @@ -52,4 +52,4 @@ public ImportSettings getImportSettings() { return this.settings; } -} \ No newline at end of file +} diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/tag/config/DescribedPathMatcher.java b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/tag/config/DescribedPathMatcher.java index 0e3d67800..b9c4f583a 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/tag/config/DescribedPathMatcher.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/tag/config/DescribedPathMatcher.java @@ -7,7 +7,7 @@ /** * A wrapper for {@link PathMatcher} providing a description. */ -public class DescribedPathMatcher +public final class DescribedPathMatcher { private static final String REGEX_PREFIX = "regex:"; private static final String GLOB_PREFIX = "glob:"; @@ -95,7 +95,7 @@ private static class ListBasedPathMatcher implements PathMatcher public ListBasedPathMatcher(final Set paths) { - this.paths = paths; + this.paths = Collections.unmodifiableSet(paths); } @Override diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/ExportSettings.java b/core/src/main/java/org/itsallcode/openfasttrace/core/ExportSettings.java index b8b9b7d8c..eb864916a 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/ExportSettings.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/ExportSettings.java @@ -7,7 +7,7 @@ * This class implements a parameter object to control the settings of OFT's * export mode. */ -public class ExportSettings +public final class ExportSettings { private final String outputFormat; private final Newline newline; @@ -61,7 +61,7 @@ public static Builder builder() /** * Builder for {@link ExportSettings} */ - public static class Builder + public static final class Builder { private String outputFormat = ExporterConstants.DEFAULT_OUTPUT_FORMAT; private Newline newline = Newline.UNIX; diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/LinkedItemIndex.java b/core/src/main/java/org/itsallcode/openfasttrace/core/LinkedItemIndex.java index c09918a2f..6927eaee6 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/LinkedItemIndex.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/LinkedItemIndex.java @@ -9,7 +9,7 @@ * An idex for {@link LinkedSpecificationItem} that allows retrieving items by * {@link SpecificationItemId}, optionally ignoring the revision. */ -public class LinkedItemIndex +public final class LinkedItemIndex { private final Map idIndex; private final Map> idIndexIgnoringVersion; @@ -143,11 +143,11 @@ public SpecificationItemIdWithoutVersion(final LinkedSpecificationItem linkedIte @Override public int hashCode() { - final int prime = 31; + final int PRIME = 31; int result = 1; - result = prime * result + result = PRIME * result + ((this.artifcatType == null) ? 0 : this.artifcatType.hashCode()); - result = prime * result + ((this.name == null) ? 0 : this.name.hashCode()); + result = PRIME * result + ((this.name == null) ? 0 : this.name.hashCode()); return result; } diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/Linker.java b/core/src/main/java/org/itsallcode/openfasttrace/core/Linker.java index 5660bd111..bf20bcc0a 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/Linker.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/Linker.java @@ -1,5 +1,6 @@ package org.itsallcode.openfasttrace.core; +import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -30,7 +31,7 @@ public Linker(final List items) this.staleIndex = new HashMap<>(); } - private List wrapItems(final List items) + private static List wrapItems(final List items) { return items.stream() // .map(LinkedSpecificationItem::new) // @@ -50,7 +51,7 @@ public List link() { linkItem(linkedItem); } - return this.linkedItems; + return Collections.unmodifiableList(this.linkedItems); } private void linkItem(final LinkedSpecificationItem item) @@ -78,7 +79,7 @@ private void linkItemToItemWithId(final LinkedSpecificationItem item, } } - private void linkMatchingRevision(final LinkedSpecificationItem covering, + private static void linkMatchingRevision(final LinkedSpecificationItem covering, final LinkedSpecificationItem covered) { final String coveringArtifactType = covering.getArtifactType(); @@ -126,7 +127,7 @@ private LinkedSpecificationItem findOrCreateStaleItem(final SpecificationItemId return this.staleIndex.get(id); } - private void linkToOutdatedOrPredated(final LinkedSpecificationItem item, + private static void linkToOutdatedOrPredated(final LinkedSpecificationItem item, final SpecificationItemId id, final List coveredLinkedItems) { @@ -152,4 +153,4 @@ else if (id.getRevision() > coveredItemRevision) } } } -} \ No newline at end of file +} diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/ArgumentValidator.java b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/ArgumentValidator.java index f80eb1cff..163a088e2 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/ArgumentValidator.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/ArgumentValidator.java @@ -101,7 +101,7 @@ private boolean validateConvertCommand() return ok; } - private String listCommands() + private static String listCommands() { return AVAILABLE_COMMANDS.stream().map(text -> "'" + text + "'") .collect(Collectors.joining(",")); diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CliArguments.java b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CliArguments.java index 3aa0c5bf1..e82e6f109 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CliArguments.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CliArguments.java @@ -24,6 +24,7 @@ public class CliArguments { /** Filter in command line arguments matching items with no tags. */ public static final String NO_TAGS_MARKER = "_"; + private static final String COMMA_SEPARATED_REGEX = ",(?U)\\s*"; // [impl->dsn~cli.default-newline-format~1] private Newline newline = Newline.fromRepresentation(System.lineSeparator()); private List unnamedValues; @@ -135,7 +136,9 @@ public List getInputs() */ public void setUnnamedValues(final List unnamedValues) { - this.unnamedValues = unnamedValues; + this.unnamedValues = unnamedValues == null + ? List.of() + : Collections.unmodifiableList(unnamedValues); } /** @@ -295,7 +298,7 @@ public void setH(final boolean helpSet) */ public Set getWantedArtifactTypes() { - return this.wantedArtifactTypes; + return Collections.unmodifiableSet(this.wantedArtifactTypes); } /** @@ -309,9 +312,9 @@ public void setWantedArtifactTypes(final String artifactTypes) this.wantedArtifactTypes = createSetFromCommaSeparatedString(artifactTypes); } - private HashSet createSetFromCommaSeparatedString(final String commaSeparatedString) + private static HashSet createSetFromCommaSeparatedString(final String commaSeparatedString) { - return new HashSet<>(Arrays.asList(commaSeparatedString.split(",\\s*"))); + return new HashSet<>(Arrays.asList(commaSeparatedString.split(COMMA_SEPARATED_REGEX))); } /** @@ -332,7 +335,7 @@ public void setA(final String artifactTypes) */ public Set getWantedTags() { - return this.wantedTags; + return Collections.unmodifiableSet(this.wantedTags); } /** diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CliException.java b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CliException.java index 69d3fd0fa..8ed80ce97 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CliException.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CliException.java @@ -5,7 +5,7 @@ */ public class CliException extends Exception { - private static final long serialVersionUID = 3126173961917546825L; + private static final long serialVersionUID = 1L; /** * Create a new {@link CliException} caused by another exception diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CommandLineInterpreter.java b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CommandLineInterpreter.java index 87760465a..8e80b29e8 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CommandLineInterpreter.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CommandLineInterpreter.java @@ -29,7 +29,7 @@ public class CommandLineInterpreter private static final String MULTIPLE_CHAR_ARG_PREFIX = "--"; private static final String SETTER_PREFIX = "set"; private final Object argumentsReceiver; - private final String[] arguments; + private final List arguments; private final Map setters; /** @@ -42,7 +42,7 @@ public class CommandLineInterpreter */ public CommandLineInterpreter(final String[] arguments, final Object argumentsReceiver) { - this.arguments = arguments; + this.arguments = List.of(arguments); this.argumentsReceiver = argumentsReceiver; this.setters = findAllSettersInArgumentsReceiver(argumentsReceiver); } @@ -64,7 +64,7 @@ private static String getSetterName(final Method method) { return method.getName() .substring(SETTER_PREFIX.length()) - .toLowerCase(); + .toLowerCase(Locale.ENGLISH); } /** @@ -76,7 +76,7 @@ private static String getSetterName(final Method method) public void parse() throws CliException { final List unnamedArguments = new ArrayList<>(); - final ListIterator iterator = asList(this.arguments).listIterator(); + final ListIterator iterator = this.arguments.listIterator(); while (iterator.hasNext()) { final String argument = iterator.next(); @@ -145,7 +145,7 @@ private static void handleUnnamedArgument(final List unnamedArguments, f unnamedArguments.add(argument); } - private void reportUnexpectedNamedArgument(final String argument) throws CliException + private static void reportUnexpectedNamedArgument(final String argument) throws CliException { throw new CliException("Unexpected parameter '" + argument + "' is not allowed"); } @@ -201,7 +201,7 @@ private T convertArgument(final String stringValue, final Class type) thr } @SuppressWarnings("unchecked") - private T convertEnum(final String stringValue, final Class type) throws CliException + private static T convertEnum(final String stringValue, final Class type) throws CliException { @SuppressWarnings("rawtypes") final Class enumType = type; @@ -219,13 +219,13 @@ private T convertEnum(final String stringValue, final Class type) throws } } - private void reportUnsupportedSetterArgumentCount(final Method setter) throws CliException + private static void reportUnsupportedSetterArgumentCount(final Method setter) throws CliException { throw new CliException("Unsupported argument count for setter '" + setter + "'. Only one argument is allowed."); } - private void reportMissingParameterValue(final String argumentName) throws CliException + private static void reportMissingParameterValue(final String argumentName) throws CliException { throw new CliException("No value for argument '" + argumentName + "'"); } diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/commands/AbstractCommand.java b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/commands/AbstractCommand.java index edd2dc555..2f3f3161e 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/commands/AbstractCommand.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/commands/AbstractCommand.java @@ -34,7 +34,7 @@ protected AbstractCommand(final CliArguments arguments) this.oft = Oft.create(); } - private List toPaths(final List inputs) + private static List toPaths(final List inputs) { final List inputsAsPaths = new ArrayList<>(); for (final String input : inputs) @@ -88,9 +88,9 @@ protected List importItems() { final ImportSettings importSettings = ImportSettings .builder() - .addInputs(this.toPaths(this.arguments.getInputs())) + .addInputs(toPaths(this.arguments.getInputs())) .filter(createFilterSettingsFromArguments()) .build(); return this.oft.importItems(importSettings); } -} \ No newline at end of file +} diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/commands/ConvertCommand.java b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/commands/ConvertCommand.java index 1c316b5ec..979f9d20a 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/commands/ConvertCommand.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/commands/ConvertCommand.java @@ -10,7 +10,7 @@ /** * Handler for specification item conversion CLI command. */ -public class ConvertCommand extends AbstractCommand implements Performable +public class ConvertCommand extends AbstractCommand { /** The command line action for running this command. */ public static final String COMMAND_NAME = "convert"; diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/exporter/ExporterFactoryLoader.java b/core/src/main/java/org/itsallcode/openfasttrace/core/exporter/ExporterFactoryLoader.java index d2edb904e..4ec7bc226 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/exporter/ExporterFactoryLoader.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/exporter/ExporterFactoryLoader.java @@ -47,17 +47,17 @@ public ExporterFactoryLoader(final ExporterContext context) public ExporterFactory getExporterFactory(final String outputFormat) { final List matchingExporters = getMatchingFactories(outputFormat); - switch (matchingExporters.size()) + return switch (matchingExporters.size()) { - case 0: + case 0 -> throw new ExporterException( "Found no matching exporter for output format '" + outputFormat + "'"); - case 1: - return matchingExporters.get(0); - default: + case 1 -> + matchingExporters.get(0); + default -> throw new ExporterException("Found more than one matching exporter for output format '" + outputFormat + "'"); - } + }; } private List getMatchingFactories(final String format) diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/importer/ImporterServiceImpl.java b/core/src/main/java/org/itsallcode/openfasttrace/core/importer/ImporterServiceImpl.java index 83b19012a..83fe1c23c 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/importer/ImporterServiceImpl.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/importer/ImporterServiceImpl.java @@ -50,4 +50,4 @@ public MultiFileImporter createImporter() return createImporter( SpecificationListBuilder.createWithFilter(this.settings.getFilters())); } -} \ No newline at end of file +} diff --git a/exporter/common/src/main/java/org/itsallcode/openfasttrace/exporter/common/IndentingXMLStreamWriter.java b/exporter/common/src/main/java/org/itsallcode/openfasttrace/exporter/common/IndentingXMLStreamWriter.java index fd897fc0b..c112ddce3 100644 --- a/exporter/common/src/main/java/org/itsallcode/openfasttrace/exporter/common/IndentingXMLStreamWriter.java +++ b/exporter/common/src/main/java/org/itsallcode/openfasttrace/exporter/common/IndentingXMLStreamWriter.java @@ -22,7 +22,7 @@ private enum State private State state = State.SEEN_NOTHING; - private int depth = 0; + private int depth; /** * Create an new instance wrapping a delegate. diff --git a/importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/LightWeightMarkupImporter.java b/importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/AbstractLightWeightMarkupImporter.java similarity index 96% rename from importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/LightWeightMarkupImporter.java rename to importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/AbstractLightWeightMarkupImporter.java index 41bc69674..400ae7647 100644 --- a/importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/LightWeightMarkupImporter.java +++ b/importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/AbstractLightWeightMarkupImporter.java @@ -11,7 +11,7 @@ /** * Base class for importers of lightweight markup text. */ -public abstract class LightWeightMarkupImporter implements Importer, LineReaderCallback +public abstract class AbstractLightWeightMarkupImporter implements Importer, LineReaderCallback { /** File to be imported */ protected final InputFile file; @@ -24,7 +24,7 @@ public abstract class LightWeightMarkupImporter implements Importer, LineReaderC private LineContext currentContext; /** - * Create a new {@link LightWeightMarkupImporter}. + * Create a new {@link AbstractLightWeightMarkupImporter}. * * @param file * input file @@ -34,7 +34,7 @@ public abstract class LightWeightMarkupImporter implements Importer, LineReaderC // Possible 'this' escape before subclass is fully initialized: // LineParserStateMachine constructor does not use 'this'. @SuppressWarnings("this-escape") - protected LightWeightMarkupImporter(final InputFile file, final ImportEventListener listener) + protected AbstractLightWeightMarkupImporter(final InputFile file, final ImportEventListener listener) { this.file = file; this.listener = listener; @@ -131,7 +131,7 @@ protected void informListenerAboutNewItem() * End a specification item gracefully. *

* As opposed to forcing an end at clean-up (see - * {@link LightWeightMarkupImporter#cleanUpLastItem()}. + * {@link AbstractLightWeightMarkupImporter#cleanUpLastItem()}. *

*/ protected void endItem() diff --git a/importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/ForwardingSpecificationItem.java b/importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/ForwardingSpecificationItem.java index eb9306ce6..28f2e093e 100644 --- a/importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/ForwardingSpecificationItem.java +++ b/importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/ForwardingSpecificationItem.java @@ -1,6 +1,5 @@ package org.itsallcode.openfasttrace.importer.lightweightmarkup; -import java.util.Arrays; import java.util.List; import org.itsallcode.openfasttrace.api.core.SpecificationItemId; @@ -18,6 +17,7 @@ public class ForwardingSpecificationItem public static final String ORIGINAL_MARKER = ":"; /** Marker after which the artifact types are listed to which we forward. */ public static final String FORWARD_MARKER = "-->"; + private static final String COMMA_SEPARATED_REGEX = "(?U),\\s*"; private final String skippedArtifactType; private final SpecificationItemId originalId; private final SpecificationItemId skippedId; @@ -34,19 +34,19 @@ public ForwardingSpecificationItem(final String forward) final int posForwardMarker = forward.indexOf(FORWARD_MARKER); final int posOriginalMarker = forward.indexOf(ORIGINAL_MARKER); this.skippedArtifactType = forward.substring(0, posForwardMarker).trim(); - this.targetArtifactTypes = Arrays.asList(forward // - .substring(posForwardMarker + FORWARD_MARKER.length(), posOriginalMarker) // - .trim() // - .split(",\\s*")); - this.originalId = SpecificationItemId.parseId(forward // - .substring(posOriginalMarker + ORIGINAL_MARKER.length()) // + this.targetArtifactTypes = List.of(forward + .substring(posForwardMarker + FORWARD_MARKER.length(), posOriginalMarker) + .trim() + .split(COMMA_SEPARATED_REGEX)); + this.originalId = SpecificationItemId.parseId(forward + .substring(posOriginalMarker + ORIGINAL_MARKER.length()) .trim()); this.skippedId = SpecificationItemId.createId(this.skippedArtifactType, this.originalId.getName(), this.originalId.getRevision()); } /** - * The artifact type which forwards the needed coverage (in effect the one + * The artifact type that forwards the needed coverage (in effect the one * that is "skipped" during authoring) * * @return the "skipped" artifact type @@ -86,4 +86,4 @@ public List getTargetArtifactTypes() { return this.targetArtifactTypes; } -} \ No newline at end of file +} diff --git a/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MarkdownImporter.java b/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MarkdownImporter.java index 85374d103..f5843de6c 100644 --- a/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MarkdownImporter.java +++ b/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MarkdownImporter.java @@ -4,7 +4,7 @@ import org.itsallcode.openfasttrace.api.importer.ImportEventListener; import org.itsallcode.openfasttrace.api.importer.input.InputFile; -import org.itsallcode.openfasttrace.importer.lightweightmarkup.LightWeightMarkupImporter; +import org.itsallcode.openfasttrace.importer.lightweightmarkup.AbstractLightWeightMarkupImporter; import org.itsallcode.openfasttrace.importer.lightweightmarkup.statemachine.*; /** @@ -18,7 +18,7 @@ * explicitly not the purpose of the importer. *

*/ -class MarkdownImporter extends LightWeightMarkupImporter +class MarkdownImporter extends AbstractLightWeightMarkupImporter { private static final LinePattern SECTION_TITLE = new MdSectionTitlePattern(); diff --git a/importer/restructuredtext/src/main/java/org/itsallcode/openfasttrace/importer/restructuredtext/RestructuredTextImporter.java b/importer/restructuredtext/src/main/java/org/itsallcode/openfasttrace/importer/restructuredtext/RestructuredTextImporter.java index 979ca6a3a..4a7402b94 100644 --- a/importer/restructuredtext/src/main/java/org/itsallcode/openfasttrace/importer/restructuredtext/RestructuredTextImporter.java +++ b/importer/restructuredtext/src/main/java/org/itsallcode/openfasttrace/importer/restructuredtext/RestructuredTextImporter.java @@ -4,7 +4,7 @@ import org.itsallcode.openfasttrace.api.importer.ImportEventListener; import org.itsallcode.openfasttrace.api.importer.input.InputFile; -import org.itsallcode.openfasttrace.importer.lightweightmarkup.LightWeightMarkupImporter; +import org.itsallcode.openfasttrace.importer.lightweightmarkup.AbstractLightWeightMarkupImporter; import org.itsallcode.openfasttrace.importer.lightweightmarkup.statemachine.*; /** @@ -18,7 +18,7 @@ * is explicitly not the purpose of the importer. *

*/ -public class RestructuredTextImporter extends LightWeightMarkupImporter +public class RestructuredTextImporter extends AbstractLightWeightMarkupImporter { private static final LinePattern SECTION_TITLE = new RstSectionTitlePattern(); diff --git a/importer/specobject/src/main/java/org/itsallcode/openfasttrace/importer/specobject/handler/FulfilledByHandlerBuilder.java b/importer/specobject/src/main/java/org/itsallcode/openfasttrace/importer/specobject/handler/FulfilledByHandlerBuilder.java index 3a24d0433..7744c642c 100644 --- a/importer/specobject/src/main/java/org/itsallcode/openfasttrace/importer/specobject/handler/FulfilledByHandlerBuilder.java +++ b/importer/specobject/src/main/java/org/itsallcode/openfasttrace/importer/specobject/handler/FulfilledByHandlerBuilder.java @@ -14,11 +14,11 @@ class FulfilledByHandlerBuilder TreeContentHandler build() { - this.handler.addSubTreeHandler("ffbObj", this::createFulfillByObjectHandler); + this.handler.addSubTreeHandler("ffbObj", FulfilledByHandlerBuilder::createFulfillByObjectHandler); return this.handler; } - private CallbackContentHandler createFulfillByObjectHandler() + private static CallbackContentHandler createFulfillByObjectHandler() { return new CallbackContentHandler() .addCharacterDataListener("ffbId", data -> {}) diff --git a/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/ChecksumCalculator.java b/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/ChecksumCalculator.java index 127ffc3bc..b9619019c 100644 --- a/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/ChecksumCalculator.java +++ b/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/ChecksumCalculator.java @@ -3,10 +3,11 @@ import java.nio.charset.StandardCharsets; import java.util.zip.CRC32; -class ChecksumCalculator +final class ChecksumCalculator { private ChecksumCalculator() { + // Prevent instantiation. } static long calculateCrc32(final String value) diff --git a/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/DelegatingLineConsumer.java b/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/DelegatingLineConsumer.java index 47eb35019..da7a2ed1b 100644 --- a/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/DelegatingLineConsumer.java +++ b/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/DelegatingLineConsumer.java @@ -1,4 +1,5 @@ package org.itsallcode.openfasttrace.importer.tag; +import java.util.Collections; import java.util.List; import org.itsallcode.openfasttrace.importer.tag.LineReader.LineConsumer; @@ -9,7 +10,7 @@ class DelegatingLineConsumer implements LineConsumer DelegatingLineConsumer(final List delegates) { - this.delegates = delegates; + this.delegates = Collections.unmodifiableList(delegates); } @Override diff --git a/importer/xmlparser/src/main/java/org/itsallcode/openfasttrace/importer/xmlparser/event/Attribute.java b/importer/xmlparser/src/main/java/org/itsallcode/openfasttrace/importer/xmlparser/event/Attribute.java index 9bb442f8c..bf9e97f16 100644 --- a/importer/xmlparser/src/main/java/org/itsallcode/openfasttrace/importer/xmlparser/event/Attribute.java +++ b/importer/xmlparser/src/main/java/org/itsallcode/openfasttrace/importer/xmlparser/event/Attribute.java @@ -8,7 +8,7 @@ /** * A simplified wrapper for SAX {@link Attributes}. */ -public class Attribute +public final class Attribute { private final String qName; private final String value; diff --git a/importer/xmlparser/src/main/java/org/itsallcode/openfasttrace/importer/xmlparser/event/EndElementEvent.java b/importer/xmlparser/src/main/java/org/itsallcode/openfasttrace/importer/xmlparser/event/EndElementEvent.java index 7ff03d5b0..d8a5824f1 100644 --- a/importer/xmlparser/src/main/java/org/itsallcode/openfasttrace/importer/xmlparser/event/EndElementEvent.java +++ b/importer/xmlparser/src/main/java/org/itsallcode/openfasttrace/importer/xmlparser/event/EndElementEvent.java @@ -9,7 +9,7 @@ * * @see org.xml.sax.ContentHandler#endElement(String, String, String) */ -public class EndElementEvent +public final class EndElementEvent { private final QName qName; private final Location location; diff --git a/importer/xmlparser/src/main/java/org/itsallcode/openfasttrace/importer/xmlparser/tree/CallbackContentHandler.java b/importer/xmlparser/src/main/java/org/itsallcode/openfasttrace/importer/xmlparser/tree/CallbackContentHandler.java index bc4aee81f..da64563da 100644 --- a/importer/xmlparser/src/main/java/org/itsallcode/openfasttrace/importer/xmlparser/tree/CallbackContentHandler.java +++ b/importer/xmlparser/src/main/java/org/itsallcode/openfasttrace/importer/xmlparser/tree/CallbackContentHandler.java @@ -138,14 +138,14 @@ public void startElement(final TreeElement treeElement) { consumer.accept(treeElement); } - catch (final Exception e) + catch (final Exception exception) { throw new XmlParserException("Error handling " + treeElement + " with consumer " - + consumer + ": " + e.getMessage(), e); + + consumer + ": " + exception.getMessage(), exception); } } - private boolean isCustomXMLNamespace(final String namespaceURI) + private static boolean isCustomXMLNamespace(final String namespaceURI) { return !"".equals(namespaceURI) && !OPENFASTTRACE_XML_NAMESPACE.equals(namespaceURI); } @@ -201,7 +201,7 @@ public CallbackContentHandler addIntDataListener(final String elementName, return this; } - private int parseInt(final String elementName, final String data) + private static int parseInt(final String elementName, final String data) { try { diff --git a/reporter/aspec/src/main/java/org/itsallcode/openfasttrace/report/aspec/ASpecReport.java b/reporter/aspec/src/main/java/org/itsallcode/openfasttrace/report/aspec/ASpecReport.java index 47306d1e8..b4db64591 100644 --- a/reporter/aspec/src/main/java/org/itsallcode/openfasttrace/report/aspec/ASpecReport.java +++ b/reporter/aspec/src/main/java/org/itsallcode/openfasttrace/report/aspec/ASpecReport.java @@ -103,7 +103,7 @@ private void writeSpecDocument(XMLStreamWriter writer) writer.writeEndElement(); } - private Map> groupItemsByAttributeType( + private static Map> groupItemsByAttributeType( final List items) { return items.stream().collect( @@ -251,6 +251,10 @@ else if (linkStatus == LinkStatus.AMBIGUOUS || linkStatus == LinkStatus.COVERED_ { writeElement(writer, ELEMENT_COVERING_STATUS, CoveringStatus.UNEXPECTED.getLabel()); } + else + { + throw new IllegalStateException("Unknown link status found trying to write ASpec report: " + linkStatus); + } } private void writeDependsOnIds(final XMLStreamWriter writer, final List dependOnIds) @@ -349,7 +353,7 @@ private void writeElementIfPresent(final XMLStreamWriter writer, final String el } } - private void writeElement(final XMLStreamWriter writer, final String elementName, final String content) + private static void writeElement(final XMLStreamWriter writer, final String elementName, final String content) throws XMLStreamException { writer.writeStartElement(elementName); @@ -382,5 +386,4 @@ public String getLabel() return label; } } - -} \ No newline at end of file +} diff --git a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/HtmlReport.java b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/HtmlReport.java index 3b09e55cd..e7a71b821 100644 --- a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/HtmlReport.java +++ b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/HtmlReport.java @@ -18,8 +18,8 @@ */ public class HtmlReport implements Reportable { - private final Trace trace; private static final String REPORT_CSS_FILE = "/css/report.css"; + private final Trace trace; private final ReportSettings settings; /** @@ -77,7 +77,7 @@ private List getSortedItems() .toList(); } - private void addSectionedItems(final ViewFactory factory, final ViewableContainer view, + private static void addSectionedItems(final ViewFactory factory, final ViewableContainer view, final List items) { String artifactType = "\0"; diff --git a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/AbstractViewContainer.java b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/AbstractViewContainer.java index fed194bb8..1c92104f2 100644 --- a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/AbstractViewContainer.java +++ b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/AbstractViewContainer.java @@ -1,6 +1,7 @@ package org.itsallcode.openfasttrace.report.html.view; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -62,7 +63,7 @@ public void render(final int level) } /** - * Render a the part of the view that comes before the children. + * Render the part of the view that comes before the children. * * @param level * indentation level @@ -70,7 +71,7 @@ public void render(final int level) protected abstract void renderBeforeChildren(final int level); /** - * Render a the children of this sub(view). + * Render the children of this sub(view). * * @param level * indentation level @@ -106,6 +107,6 @@ public void add(final Viewable child) @Override public List getChildren() { - return this.children; + return Collections.unmodifiableList(this.children); } } diff --git a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/CharacterConstants.java b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/CharacterConstants.java index c5606c232..50ddef002 100644 --- a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/CharacterConstants.java +++ b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/CharacterConstants.java @@ -1,12 +1,12 @@ package org.itsallcode.openfasttrace.report.html.view.html; -class CharacterConstants +final class CharacterConstants { + public static final String CHECK_MARK = ""; + public static final String CROSS_MARK = ""; + private CharacterConstants() { // prevent instantiation } - - public static final String CHECK_MARK = ""; - public static final String CROSS_MARK = ""; -} \ No newline at end of file +} diff --git a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlReportDetails.java b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlReportDetails.java index 2a858cb5d..b0ced2d41 100644 --- a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlReportDetails.java +++ b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlReportDetails.java @@ -24,4 +24,4 @@ protected void renderAfterChildren(final int level) renderIndentation(level); this.stream.println(""); } -} \ No newline at end of file +} diff --git a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlSpecificationItem.java b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlSpecificationItem.java index 52cb4f85d..204087333 100644 --- a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlSpecificationItem.java +++ b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlSpecificationItem.java @@ -6,6 +6,7 @@ import java.io.PrintStream; import java.util.Comparator; import java.util.List; +import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -16,6 +17,7 @@ class HtmlSpecificationItem implements Viewable { + public static final Pattern INSERT_DELETE_PATTERN = Pattern.compile("<(?:ins|del)>"); private final LinkedSpecificationItem item; private final PrintStream stream; private final MarkdownConverter converter = new MarkdownConverter(); @@ -145,20 +147,19 @@ private void renderNeeds(final String indentation) } } - private String translateArtifactTypeCoverage(final LinkedSpecificationItem item) + private static String translateArtifactTypeCoverage(final LinkedSpecificationItem item) { - final Comparator byTypeName = Comparator.comparing(a -> a.replaceFirst("<(?:ins|del)>", "")); + final Comparator byTypeName = Comparator + .comparing(a -> INSERT_DELETE_PATTERN.matcher(a).replaceFirst("")); final Stream uncoveredStream = item.getUncoveredArtifactTypes().stream() .map(x -> "" + x + ""); - return Stream.concat( // - Stream.concat( // - uncoveredStream, // - item.getCoveredArtifactTypes().stream() // - ), // - item.getOverCoveredArtifactTypes().stream().map(x -> "" + x + "") // - ) // - .sorted(byTypeName) // + return Stream.concat( + Stream.concat( + uncoveredStream, + item.getCoveredArtifactTypes().stream()), + item.getOverCoveredArtifactTypes().stream().map(x -> "" + x + "")) + .sorted(byTypeName) .collect(Collectors.joining(", ")); } diff --git a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlTableOfContents.java b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlTableOfContents.java index 5560f7725..a2e4fe236 100644 --- a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlTableOfContents.java +++ b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlTableOfContents.java @@ -59,4 +59,4 @@ protected void renderLinkWithText(final ViewableContainer container) this.stream.print(container.getTitle()); this.stream.print(""); } -} \ No newline at end of file +} diff --git a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlTraceSummary.java b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlTraceSummary.java index 23a95eae8..7bb289955 100644 --- a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlTraceSummary.java +++ b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlTraceSummary.java @@ -86,4 +86,4 @@ protected void renderEnd() { // intentionally left empty } -} \ No newline at end of file +} diff --git a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlViewFactory.java b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlViewFactory.java index 7b6cf606a..232e03076 100644 --- a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlViewFactory.java +++ b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlViewFactory.java @@ -15,7 +15,7 @@ * Factory that creates an HTML OFT view (e.g. for reports) and provides an * output stream. */ -public class HtmlViewFactory extends AbstractViewFactory +public final class HtmlViewFactory extends AbstractViewFactory { private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; private final URL cssUrl; diff --git a/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/AnsiSequence.java b/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/AnsiSequence.java index 682a613e4..ed6678acf 100644 --- a/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/AnsiSequence.java +++ b/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/AnsiSequence.java @@ -39,7 +39,7 @@ enum AnsiSequence { public static final String SUFFIX = "m"; private final int id; - private AnsiSequence(final int id) { + AnsiSequence(final int id) { this.id = id; } diff --git a/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/ConsoleColorFormatter.java b/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/ConsoleColorFormatter.java index f3b8ca41b..2e8106c1c 100644 --- a/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/ConsoleColorFormatter.java +++ b/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/ConsoleColorFormatter.java @@ -28,4 +28,4 @@ public String formatNotOk(final String text) { public String formatStrong(final String text) { return AnsiSequence.combine(BOLD, CYAN) + text + RESET; } -} \ No newline at end of file +} diff --git a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/CompareAssertions.java b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/CompareAssertions.java index f712b1feb..c070703d7 100644 --- a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/CompareAssertions.java +++ b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/CompareAssertions.java @@ -10,7 +10,7 @@ * Provides static assertion methods that verify implementations of * {@link Comparator} and {@link Comparable} are consistent with the contract. */ -public class CompareAssertions +public final class CompareAssertions { private CompareAssertions() { @@ -73,6 +73,7 @@ public static void testComparator(Comparator comparator, T o, T s assertNullValue(comparator, o, nullValueSupported); } + @SuppressWarnings({"java:S1696", "java:S1166"}) // NullPointerExceptions are expected. private static void assertNullValue(Comparator comparator, T o, boolean nullValueSupported) { @@ -81,7 +82,7 @@ private static void assertNullValue(Comparator comparator, T o, comparator.compare(o, null); assertTrue(nullValueSupported, "No NullPointerException but null value not supported!"); } - catch (final NullPointerException ex) + catch (final NullPointerException exception) { assertFalse(nullValueSupported, "NullPointerException thrown but null value supported!!"); diff --git a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/core/ItemBuilderFactory.java b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/core/ItemBuilderFactory.java index f7055e84c..685773bac 100644 --- a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/core/ItemBuilderFactory.java +++ b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/core/ItemBuilderFactory.java @@ -6,7 +6,7 @@ /** * The {@link ItemBuilderFactory} class provides convenience methods for creating instances of {@link SpecificationItem}. */ -public class ItemBuilderFactory { +public final class ItemBuilderFactory { private ItemBuilderFactory() { // prevent instantiation. } diff --git a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/xml/IndentingXMLStreamWriter.java b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/xml/IndentingXMLStreamWriter.java index f3594a8e6..4142075f2 100644 --- a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/xml/IndentingXMLStreamWriter.java +++ b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/xml/IndentingXMLStreamWriter.java @@ -13,11 +13,11 @@ public class IndentingXMLStreamWriter extends StreamWriterDelegate private final String indent; private final String newLine; /** How deeply nested the current scope is. The root element is depth 1. */ - private int depth = 0; // document scope + private int depth; // document scope /** stack[depth] indicates what's been written into the current scope. */ private int[] stack = new int[] { 0, 0, 0, 0 }; // nothing written yet /** Prefix that defines how deeply a line is indented. */ - private char[] linePrefix = null; + private char[] linePrefix; /** * Create a new instance of the {@link IndentingXMLStreamWriter}. From 73734c9eb93cffc0dba9a180c27072b7ddd21306 Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Wed, 3 Jun 2026 15:01:46 +0200 Subject: [PATCH 02/16] #536: Resolve Sonar findings of June 2026 up to TestSpecificationItemIdMatcher.java --- .../openfasttrace/api/core/Location.java | 17 +++++++---------- .../api/importer/tag/config/PathConfig.java | 4 ++-- .../org/itsallcode/openfasttrace/core/Oft.java | 2 +- .../matcher/TestSpecificationItemIdMatcher.java | 4 ++-- .../importer/markdown/MarkdownImporter.java | 1 + .../tag/LongTagImportingLineConsumer.java | 11 +++-------- .../html/view/html/MarkdownConverter.java | 2 +- .../html/view/html/MarkdownLineState.java | 6 +++--- .../html/view/html/MarkdownSpanConverter.java | 2 +- .../html/view/html/OriginLinkFormatter.java | 3 ++- .../report/plaintext/NullTextFormatter.java | 2 +- .../openfasttrace/testutil/OsDetector.java | 2 +- ...erTestBase.java => AbstractMatcherTest.java} | 4 ++-- .../testutil/matcher/MatcherTestBaseTest.java | 2 +- 14 files changed, 28 insertions(+), 34 deletions(-) rename testutil/src/main/java/org/itsallcode/openfasttrace/testutil/matcher/{MatcherTestBase.java => AbstractMatcherTest.java} (96%) diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/core/Location.java b/api/src/main/java/org/itsallcode/openfasttrace/api/core/Location.java index 5aa697ce0..3549030ba 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/core/Location.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/core/Location.java @@ -1,5 +1,7 @@ package org.itsallcode.openfasttrace.api.core; +import java.util.Objects; + /** * The location of a coverage item. */ @@ -112,12 +114,7 @@ public int getColumn() @Override public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + this.column; - result = prime * result + this.line; - result = prime * result + ((this.path == null) ? 0 : this.path.hashCode()); - return result; + return Objects.hash(this.column, this.line, this.path); } @Override @@ -162,8 +159,8 @@ else if (!this.path.equals(other.path)) public String toString() { return this.path // - + (this.line != NO_LINE ? ":" + this.line : "") // - + (this.column != NO_COLUMN ? ":" + this.column : ""); + + ((this.line != NO_LINE) ? (":" + this.line) : "") // + + ((this.column != NO_COLUMN) ? (":" + this.column) : ""); } /** @@ -180,7 +177,7 @@ public static Builder builder() * A builder for {@link Location}. Use {@link Location#builder()} to create * a new builder and call {@link #build()} to build a {@link Location}. */ - public static class Builder + public static final class Builder { private String path; private int line = NO_LINE; @@ -250,4 +247,4 @@ public boolean isCompleteEnough() return this.path != null && !this.path.isEmpty(); } } -} \ No newline at end of file +} diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/tag/config/PathConfig.java b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/tag/config/PathConfig.java index bac6aaa48..24c4158d7 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/tag/config/PathConfig.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/tag/config/PathConfig.java @@ -13,7 +13,7 @@ * The configuration of a single path that is imported by the tag importer Use * {@link #builder()} to create a new instance. */ -public class PathConfig +public final class PathConfig { private static final Logger LOG = Logger.getLogger(PathConfig.class.getName()); @@ -109,7 +109,7 @@ public static Builder builder() /** * Builder for {@link PathConfig} objects. */ - public static class Builder + public static final class Builder { private DescribedPathMatcher pathMatcher; private String coveredItemNamePrefix; diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/Oft.java b/core/src/main/java/org/itsallcode/openfasttrace/core/Oft.java index 6f508b874..a2ca887ec 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/Oft.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/Oft.java @@ -125,4 +125,4 @@ static Oft create() { return new OftRunner(); } -} \ No newline at end of file +} diff --git a/core/src/test/java/org/itsallcode/openfasttrace/core/matcher/TestSpecificationItemIdMatcher.java b/core/src/test/java/org/itsallcode/openfasttrace/core/matcher/TestSpecificationItemIdMatcher.java index aad3a978f..c2dbc6454 100644 --- a/core/src/test/java/org/itsallcode/openfasttrace/core/matcher/TestSpecificationItemIdMatcher.java +++ b/core/src/test/java/org/itsallcode/openfasttrace/core/matcher/TestSpecificationItemIdMatcher.java @@ -2,13 +2,13 @@ import org.hamcrest.Matcher; import org.itsallcode.openfasttrace.api.core.SpecificationItemId; -import org.itsallcode.openfasttrace.testutil.matcher.MatcherTestBase; +import org.itsallcode.openfasttrace.testutil.matcher.AbstractMatcherTest; import org.junit.jupiter.api.Test; /** * Unit test for {@link SpecificationItemIdMatcher} */ -class TestSpecificationItemIdMatcher extends MatcherTestBase +class TestSpecificationItemIdMatcher extends AbstractMatcherTest { @Test void testMatches() diff --git a/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MarkdownImporter.java b/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MarkdownImporter.java index f5843de6c..41237536c 100644 --- a/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MarkdownImporter.java +++ b/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MarkdownImporter.java @@ -35,6 +35,7 @@ class MarkdownImporter extends AbstractLightWeightMarkupImporter super(fileName, listener); } + @SuppressWarnings("squid:S1386") // Transition table is OK be larger than 75 lines. protected Transition[] configureTransitions() { // @formatter:off diff --git a/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/LongTagImportingLineConsumer.java b/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/LongTagImportingLineConsumer.java index 17853ce2a..cf59a4aa8 100644 --- a/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/LongTagImportingLineConsumer.java +++ b/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/LongTagImportingLineConsumer.java @@ -64,7 +64,7 @@ public void processMatch(final Matcher matcher, final int lineNumber, final int this.listener.endSpecificationItem(); } - private List parseCommaSeparatedList(final String input) + private static List parseCommaSeparatedList(final String input) { if (input == null) { @@ -104,7 +104,7 @@ private void logItem(final int lineNumber, final SpecificationItemId coveredId, } } - private int parseRevision(final String revision) + private static int parseRevision(final String revision) { return Optional.ofNullable(revision) .map(Integer::parseInt) @@ -125,12 +125,7 @@ private String getItemName(final int lineNumber, final int lineMatchCount, final private String generateUniqueName(final SpecificationItemId coveredId, final int lineNumber, final int counter) { - final String uniqueName = new StringBuilder() // - .append(this.file.getPath()) // - .append(lineNumber) // - .append(counter) // - .append(coveredId) // - .toString(); + final String uniqueName = this.file.getPath() + lineNumber + counter + coveredId; final String checksum = Long.toString(ChecksumCalculator.calculateCrc32(uniqueName)); return coveredId.getName() + "-" + checksum; } diff --git a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/MarkdownConverter.java b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/MarkdownConverter.java index fdc9242ca..ebf645710 100644 --- a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/MarkdownConverter.java +++ b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/MarkdownConverter.java @@ -8,4 +8,4 @@ String convert(final String input) { return this.machine.run(input); } -} \ No newline at end of file +} diff --git a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/MarkdownLineState.java b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/MarkdownLineState.java index 10c61cd4b..457eb8355 100644 --- a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/MarkdownLineState.java +++ b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/MarkdownLineState.java @@ -1,8 +1,8 @@ package org.itsallcode.openfasttrace.report.html.view.html; /** - * The MarkdownLineState represents the Markdown states that can be - * switched by newlines and the way the next line starts. + * The MarkdownLineState represents the Markdown states that newlines can + * switch and the way the next line starts. */ enum MarkdownLineState { @@ -14,4 +14,4 @@ enum MarkdownLineState ORDERED_LIST_CONTINUED, // PREFORMATTED, // TERMINATOR -} \ No newline at end of file +} diff --git a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/MarkdownSpanConverter.java b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/MarkdownSpanConverter.java index 10975bf83..6836cc7ba 100644 --- a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/MarkdownSpanConverter.java +++ b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/MarkdownSpanConverter.java @@ -40,7 +40,7 @@ static String escapeHtml(String text) return text; } - private static class RegexReplacement + private static final class RegexReplacement { private final Pattern pattern; private final String replacement; diff --git a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/OriginLinkFormatter.java b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/OriginLinkFormatter.java index 818ad0345..f6a1ef1ff 100644 --- a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/OriginLinkFormatter.java +++ b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/OriginLinkFormatter.java @@ -90,13 +90,14 @@ private static boolean checkPathHasProtocol(final String path) return PROTOCOL_PREFIX_PATTERN.matcher(path).matches(); } + @SuppressWarnings("java:S1166") // No need to log the IllegalArgumentException. private static URI convertPathWithProtocolToUri(final String path) { try { return URI.create(path); } - catch (final IllegalArgumentException e) + catch (final IllegalArgumentException exception) { return null; } diff --git a/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/NullTextFormatter.java b/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/NullTextFormatter.java index c841c1f0f..424dbe006 100644 --- a/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/NullTextFormatter.java +++ b/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/NullTextFormatter.java @@ -28,4 +28,4 @@ public String formatNotOk(final String text) { public String formatStrong(final String text) { return text; } -} \ No newline at end of file +} diff --git a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/OsDetector.java b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/OsDetector.java index e816d56f0..85686366c 100644 --- a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/OsDetector.java +++ b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/OsDetector.java @@ -9,7 +9,7 @@ * Helper class to detect the operating system. Contains assumption methods for * JUnit. */ -public class OsDetector +public final class OsDetector { private static final OsCheck OS_CHECK = new OsCheck(); diff --git a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/matcher/MatcherTestBase.java b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/matcher/AbstractMatcherTest.java similarity index 96% rename from testutil/src/main/java/org/itsallcode/openfasttrace/testutil/matcher/MatcherTestBase.java rename to testutil/src/main/java/org/itsallcode/openfasttrace/testutil/matcher/AbstractMatcherTest.java index 907a96a80..f02e8933f 100644 --- a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/matcher/MatcherTestBase.java +++ b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/matcher/AbstractMatcherTest.java @@ -15,12 +15,12 @@ * type compared by the {@link TypeSafeDiagnosingMatcher} under * test. */ -public abstract class MatcherTestBase +public abstract class AbstractMatcherTest { /** * Creates a new instance of the test base. */ - protected MatcherTestBase() + protected AbstractMatcherTest() { // Default constructor to fix compiler warning "missing-explicit-ctor" } diff --git a/testutil/src/test/java/org/itsallcode/openfasttrace/testutil/matcher/MatcherTestBaseTest.java b/testutil/src/test/java/org/itsallcode/openfasttrace/testutil/matcher/MatcherTestBaseTest.java index f154df1a8..d672c42e0 100644 --- a/testutil/src/test/java/org/itsallcode/openfasttrace/testutil/matcher/MatcherTestBaseTest.java +++ b/testutil/src/test/java/org/itsallcode/openfasttrace/testutil/matcher/MatcherTestBaseTest.java @@ -14,7 +14,7 @@ void testConstructor() assertThat(new DummyMatcher(), notNullValue()); } - private static class DummyMatcher extends MatcherTestBase + private static class DummyMatcher extends AbstractMatcherTest { @Override protected Matcher createMatcher(final String object) From 2e8ec57e4b445559c430704014762e79912ec3f6 Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Wed, 3 Jun 2026 15:27:13 +0200 Subject: [PATCH 03/16] #536: Resolve Sonar findings of June 2026 up to TestSpecificationItemIdMatcher.java --- .../openfasttrace/api/core/Newline.java | 18 +++++++--------- .../core/cli/commands/AbstractCommand.java | 17 +++++++-------- .../view/html/MarkdownLineStateMachine.java | 21 +++++++++++-------- .../matcher/MultilineTextMatcher.java | 4 ++-- 4 files changed, 28 insertions(+), 32 deletions(-) diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/core/Newline.java b/api/src/main/java/org/itsallcode/openfasttrace/api/core/Newline.java index e08d45195..51139011e 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/core/Newline.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/core/Newline.java @@ -18,7 +18,7 @@ public enum Newline private static final Pattern ANY_NEWLINE_PATTERN = Pattern.compile(ANY_NEWLINE_REG_EX); private final String representation; - private Newline(final String representation) + Newline(final String representation) { this.representation = representation; } @@ -38,18 +38,14 @@ public String toString() */ public static Newline fromRepresentation(final String representation) { - switch (representation) + return switch (representation) { - case "\n": - return UNIX; - case "\r\n": - return WINDOWS; - case "\r": - return OLDMAC; - default: - throw new IllegalArgumentException( + case "\n" -> UNIX; + case "\r\n" -> WINDOWS; + case "\r" -> OLDMAC; + default -> throw new IllegalArgumentException( "Line separator not supported: '" + representation + "'"); - } + }; } /** diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/commands/AbstractCommand.java b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/commands/AbstractCommand.java index 2f3f3161e..be1d7bd41 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/commands/AbstractCommand.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/commands/AbstractCommand.java @@ -4,6 +4,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; +import java.util.stream.Collectors; import org.itsallcode.openfasttrace.api.FilterSettings; import org.itsallcode.openfasttrace.api.core.SpecificationItem; @@ -66,16 +67,12 @@ private void setTagFilter(final FilterSettings.Builder builder) final Set wantedTags = this.arguments.getWantedTags(); if (wantedTags != null && !wantedTags.isEmpty()) { - if (wantedTags.contains(CliArguments.NO_TAGS_MARKER)) - { - builder.withoutTags(true); - wantedTags.remove(CliArguments.NO_TAGS_MARKER); - } - else - { - builder.withoutTags(false); - } - builder.tags(wantedTags); + final boolean withoutTags = wantedTags.contains(CliArguments.NO_TAGS_MARKER); + builder.withoutTags(withoutTags); + final Set filteredTags = wantedTags.stream() + .filter(tag -> !CliArguments.NO_TAGS_MARKER.equals(tag)) + .collect(Collectors.toSet()); + builder.tags(filteredTags); } } diff --git a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/MarkdownLineStateMachine.java b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/MarkdownLineStateMachine.java index 8ec0ecde2..626920730 100644 --- a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/MarkdownLineStateMachine.java +++ b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/MarkdownLineStateMachine.java @@ -5,9 +5,10 @@ import java.util.ArrayList; import java.util.List; import java.util.function.UnaryOperator; +import java.util.regex.Pattern; /** - * A state machine for converting markdown to HTML. + * A state machine for converting Markdown to HTML. */ public final class MarkdownLineStateMachine { @@ -18,6 +19,8 @@ public final class MarkdownLineStateMachine private static final String P_PRE = "^ .*"; private static final String P_LIST_CONT = ".+"; private static final String P_TERM = "^$"; + private static final Pattern ANY_NEWLINE = Pattern.compile("\n\r?|\r"); + private static final Pattern BULLET_POINT_PREFIX = Pattern.compile("^ {0,3}[-+*]"); private final List transitions = new ArrayList<>(); MarkdownLineStateMachine() @@ -25,7 +28,7 @@ public final class MarkdownLineStateMachine initializeTransitions(); } - // Duplicate strings help making this easier to understand. + // Duplicate strings help make this easier to understand. @SuppressWarnings("squid:S1192") private void initializeTransitions() { @@ -76,7 +79,7 @@ String run(final String input) { final StringBuilder builder = new StringBuilder(); MarkdownLineState state = START; - for (final String line : input.split("(?:\n\r?|\r)", INCLUDE_EMPTY_STRINGS)) + for (final String line : ANY_NEWLINE.split(input, INCLUDE_EMPTY_STRINGS)) { for (final MarkdownLineTransition transition : this.transitions) { @@ -96,7 +99,7 @@ String run(final String input) return builder.toString(); } - private void closeLastLineState(final StringBuilder builder, final MarkdownLineState state) + private static void closeLastLineState(final StringBuilder builder, final MarkdownLineState state) { switch (state) { @@ -120,23 +123,23 @@ private void closeLastLineState(final StringBuilder builder, final MarkdownLineS } } - private UnaryOperator empty() + private static UnaryOperator empty() { return s -> ""; } - private UnaryOperator trimEnum() + private static UnaryOperator trimEnum() { return s -> s.substring(s.indexOf('.') + 1).trim(); } - private UnaryOperator trimPre() + private static UnaryOperator trimPre() { return s -> s.substring(4); } - private UnaryOperator trimBullet() + private static UnaryOperator trimBullet() { - return s -> s.replaceFirst("^ {0,3}[-+*]", "").trim(); + return s -> BULLET_POINT_PREFIX.matcher(s).replaceFirst("").trim(); } } diff --git a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/matcher/MultilineTextMatcher.java b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/matcher/MultilineTextMatcher.java index 1ad593503..baeb7cc4d 100644 --- a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/matcher/MultilineTextMatcher.java +++ b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/matcher/MultilineTextMatcher.java @@ -73,7 +73,7 @@ else if (line.equals(originalLines.get(i))) } } - private String describeLineCount(final int lineCount) + private static String describeLineCount(final int lineCount) { return "(" + lineCount + " lines)" + System.lineSeparator(); } @@ -105,7 +105,7 @@ public static MultilineTextMatcher matchesAllLines(final String... lines) return new MultilineTextMatcher(String.join(System.lineSeparator(), lines)); } - private List splitPreservingNewLines(final String text) + private static List splitPreservingNewLines(final String text) { final String lineSplittingRegEx = "(?<=" + LINE_ENDING + ")"; From b8cf02f7d921f7df3fd93800704b41d3acabb28a Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Wed, 3 Jun 2026 15:46:20 +0200 Subject: [PATCH 04/16] #536: Resolve Sonar findings of June 2026 up to ExporterFactory.java --- .../api/exporter/ExporterFactory.java | 2 +- .../openfasttrace/core/cli/CliArguments.java | 7 +++--- .../core/cli/CommandLineInterpreter.java | 10 +++++--- .../report/aspec/ASpecReport.java | 25 +++++++++++-------- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/exporter/ExporterFactory.java b/api/src/main/java/org/itsallcode/openfasttrace/api/exporter/ExporterFactory.java index 291500ddb..a51dcd904 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/exporter/ExporterFactory.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/exporter/ExporterFactory.java @@ -89,7 +89,7 @@ public Exporter createExporter(final Path file, final String format, final Chars return createExporter(writer, itemStream, newline); } - private Writer createWriter(final Path file, final Charset charset) + private static Writer createWriter(final Path file, final Charset charset) { if (file == null) { diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CliArguments.java b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CliArguments.java index e82e6f109..d6a223585 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CliArguments.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CliArguments.java @@ -3,6 +3,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; +import java.util.regex.Pattern; import org.itsallcode.openfasttrace.api.ColorScheme; import org.itsallcode.openfasttrace.api.DetailsSectionDisplay; @@ -24,7 +25,7 @@ public class CliArguments { /** Filter in command line arguments matching items with no tags. */ public static final String NO_TAGS_MARKER = "_"; - private static final String COMMA_SEPARATED_REGEX = ",(?U)\\s*"; + private static final Pattern COMMA_SEPARATED_PATTERN = Pattern.compile(",(?U)\\s*"); // [impl->dsn~cli.default-newline-format~1] private Newline newline = Newline.fromRepresentation(System.lineSeparator()); private List unnamedValues; @@ -312,9 +313,9 @@ public void setWantedArtifactTypes(final String artifactTypes) this.wantedArtifactTypes = createSetFromCommaSeparatedString(artifactTypes); } - private static HashSet createSetFromCommaSeparatedString(final String commaSeparatedString) + private static Set createSetFromCommaSeparatedString(final String commaSeparatedString) { - return new HashSet<>(Arrays.asList(commaSeparatedString.split(COMMA_SEPARATED_REGEX))); + return Set.of(COMMA_SEPARATED_PATTERN.split(commaSeparatedString)); } /** diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CommandLineInterpreter.java b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CommandLineInterpreter.java index 8e80b29e8..446cd481a 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CommandLineInterpreter.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CommandLineInterpreter.java @@ -8,6 +8,7 @@ import java.util.*; import java.util.function.Function; import java.util.logging.Logger; +import java.util.regex.Pattern; import java.util.stream.Stream; /** @@ -15,7 +16,8 @@ *

* Users of this class must create a POJO that contains a setter method for each * command line argument that they want to use. - *

+ *

+ *

* Additionally, they can add a setter called setUnnamedValues that * will receive all argument values that are unnamed. *

@@ -26,6 +28,7 @@ public class CommandLineInterpreter private static final String UNNAMED_ARGUMENTS_SUFFIX = "unnamedvalues"; private static final String SINGLE_CHAR_ARG_PREFIX = "-"; + private static final Pattern SINGLE_CHAR_ARG_PREFIX_PATTERN = Pattern.compile(SINGLE_CHAR_ARG_PREFIX); private static final String MULTIPLE_CHAR_ARG_PREFIX = "--"; private static final String SETTER_PREFIX = "set"; private final Object argumentsReceiver; @@ -102,7 +105,8 @@ else if (argument.startsWith(SINGLE_CHAR_ARG_PREFIX)) private void handleChainedSingleCharacterArguments(final ListIterator iterator, final String argument) throws CliException { - final String characters = argument.replaceFirst(SINGLE_CHAR_ARG_PREFIX, "").toLowerCase(Locale.ENGLISH); + final String characters = SINGLE_CHAR_ARG_PREFIX_PATTERN.matcher(argument).replaceFirst("") + .toLowerCase(Locale.ENGLISH); final int lastPosition = characters.length() - 1; for (int position = 0; position <= lastPosition; ++position) @@ -186,7 +190,7 @@ private void handleExpectedNamedArgument(final ListIterator iterator, } } - private T convertArgument(final String stringValue, final Class type) throws CliException + private static T convertArgument(final String stringValue, final Class type) throws CliException { if (type.equals(String.class)) { diff --git a/reporter/aspec/src/main/java/org/itsallcode/openfasttrace/report/aspec/ASpecReport.java b/reporter/aspec/src/main/java/org/itsallcode/openfasttrace/report/aspec/ASpecReport.java index b4db64591..e329a6951 100644 --- a/reporter/aspec/src/main/java/org/itsallcode/openfasttrace/report/aspec/ASpecReport.java +++ b/reporter/aspec/src/main/java/org/itsallcode/openfasttrace/report/aspec/ASpecReport.java @@ -166,7 +166,7 @@ private String unifyNewlines(final String text) return matcher.replaceAll(this.newline.toString()); } - private void writeTags(final XMLStreamWriter writer, final List tags) throws XMLStreamException + private static void writeTags(final XMLStreamWriter writer, final List tags) throws XMLStreamException { if (tags.isEmpty()) { @@ -211,7 +211,7 @@ private void writeCoveringSpecObjects(XMLStreamWriter writer, LinkedSpecificatio writer.writeEndElement(); } - private void writeCoveringSpecObject(final XMLStreamWriter writer, final LinkStatus linkStatus, + private static void writeCoveringSpecObject(final XMLStreamWriter writer, final LinkStatus linkStatus, final LinkedSpecificationItem item) throws XMLStreamException { writer.writeStartElement("coveringSpecObject"); @@ -231,7 +231,7 @@ private void writeCoveringSpecObject(final XMLStreamWriter writer, final LinkSta writer.writeEndElement(); } - private void writeCoveringStatus(XMLStreamWriter writer, LinkStatus linkStatus, + private static void writeCoveringStatus(XMLStreamWriter writer, LinkStatus linkStatus, DeepCoverageStatus deepCoverageStatus) throws XMLStreamException { @@ -257,7 +257,7 @@ else if (linkStatus == LinkStatus.AMBIGUOUS || linkStatus == LinkStatus.COVERED_ } } - private void writeDependsOnIds(final XMLStreamWriter writer, final List dependOnIds) + private static void writeDependsOnIds(final XMLStreamWriter writer, final List dependOnIds) throws XMLStreamException { if (dependOnIds.isEmpty()) @@ -276,7 +276,7 @@ private void writeDependsOnIds(final XMLStreamWriter writer, final List coveredIds) + private static void writeCoveredIds(final XMLStreamWriter writer, final List coveredIds) throws XMLStreamException { if (coveredIds.isEmpty()) @@ -295,7 +295,7 @@ private void writeCoveredIds(final XMLStreamWriter writer, final List needsArtifactTypes) + private static void writeNeedsArtifactTypes(final XMLStreamWriter writer, final List needsArtifactTypes) throws XMLStreamException { if (needsArtifactTypes.isEmpty()) @@ -310,7 +310,8 @@ private void writeNeedsArtifactTypes(final XMLStreamWriter writer, final List types) throws XMLStreamException + private static void writeCoveredTypes(final XMLStreamWriter writer, final Set types) + throws XMLStreamException { if (types.isEmpty()) { @@ -324,7 +325,8 @@ private void writeCoveredTypes(final XMLStreamWriter writer, final Set t writer.writeEndElement(); } - private void writeUncoveredTypes(final XMLStreamWriter writer, final List types) throws XMLStreamException + private static void writeUncoveredTypes(final XMLStreamWriter writer, final List types) + throws XMLStreamException { if (types.isEmpty()) { @@ -338,13 +340,14 @@ private void writeUncoveredTypes(final XMLStreamWriter writer, final List Date: Wed, 3 Jun 2026 19:35:34 +0200 Subject: [PATCH 05/16] #536: Resolve Sonar findings of June 2026 up to MultiFileImporterImpl.java --- .../openfasttrace/api/FilterSettings.java | 13 ++++--------- .../openfasttrace/api/importer/ImportSettings.java | 6 +++--- .../core/importer/MultiFileImporterImpl.java | 2 +- .../core/serviceloader/ChildFirstClassLoader.java | 6 ++++++ .../importer/markdown/MarkdownImporter.java | 2 +- .../openfasttrace/report/aspec/ASpecReport.java | 2 +- .../testutil/core/ItemBuilderFactory.java | 6 +++--- 7 files changed, 19 insertions(+), 18 deletions(-) diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java b/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java index e9e17e50d..bd665db09 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java @@ -1,6 +1,7 @@ package org.itsallcode.openfasttrace.api; import java.util.Collections; +import java.util.Objects; import java.util.Set; /** @@ -26,7 +27,7 @@ private FilterSettings(final Builder builder) */ public Set getArtifactTypes() { - return this.artifactTypes; + return Collections.unmodifiableSet(this.artifactTypes); } /** @@ -36,7 +37,7 @@ public Set getArtifactTypes() */ public Set getTags() { - return this.tags; + return Collections.unmodifiableSet(this.tags); } /** @@ -82,13 +83,7 @@ public boolean isAnyCriteriaSet() @Override public int hashCode() { - final int PRIME = 31; - int result = 1; - result = PRIME * result - + ((this.artifactTypes == null) ? 0 : this.artifactTypes.hashCode()); - result = PRIME * result + (this.withoutTags ? 1231 : 1237); - result = PRIME * result + ((this.tags == null) ? 0 : this.tags.hashCode()); - return result; + return Objects.hash(this.artifactTypes, this.tags, this.withoutTags); } @Override diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImportSettings.java b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImportSettings.java index 7c2ef1f71..2d57963e9 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImportSettings.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImportSettings.java @@ -11,7 +11,7 @@ /** * Configuration for an {@link Importer}. */ -public class ImportSettings +public final class ImportSettings { private final List inputs; private final FilterSettings filter; @@ -52,7 +52,7 @@ public FilterSettings getFilters() */ public List getPathConfigs() { - return this.pathConfigs; + return Collections.unmodifiableSet(this.pathConfigs); } /** @@ -78,7 +78,7 @@ public static Builder builder() /** * Builder for {@link ImportSettings} */ - public static class Builder + public static final class Builder { private final List inputs = new ArrayList<>(); private FilterSettings filter = FilterSettings.createAllowingEverything(); diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/importer/MultiFileImporterImpl.java b/core/src/main/java/org/itsallcode/openfasttrace/core/importer/MultiFileImporterImpl.java index 6e53a5cca..d8348b9f6 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/importer/MultiFileImporterImpl.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/importer/MultiFileImporterImpl.java @@ -117,7 +117,7 @@ private Optional createImporterIfPossible(final InputFile file, final .map(factory -> factory.createImporter(file, builder)); LOG.finest( - () -> (importer.isPresent() ? "Created importer of type '" + importer.get().getClass().getSimpleName() + () -> (importer.isPresent() ? ("Created importer of type '" + importer.get().getClass().getSimpleName()) : "No import") + "' for file '" + file + "'"); return importer; diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/serviceloader/ChildFirstClassLoader.java b/core/src/main/java/org/itsallcode/openfasttrace/core/serviceloader/ChildFirstClassLoader.java index 77f82e29f..9e5cf0437 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/serviceloader/ChildFirstClassLoader.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/serviceloader/ChildFirstClassLoader.java @@ -2,6 +2,8 @@ import java.net.URL; import java.net.URLClassLoader; +import java.util.logging.Level; +import java.util.logging.Logger; /** * This class loader will first try to load the class from the given URLs and @@ -17,6 +19,8 @@ */ class ChildFirstClassLoader extends URLClassLoader { + private static final Logger LOGGER = Logger.getLogger(ChildFirstClassLoader.class); + ChildFirstClassLoader(final String name, final URL[] urls, final ClassLoader parent) { super(name, urls, parent); @@ -53,6 +57,8 @@ private Class loadClassInternally(final String name, final boolean resolve) t } catch (final ClassNotFoundException ignore) { + LOGGER.log(Level.FINEST, () -> "Unable to find class " + name + " with child logger." + + "Falling back to parent logger"); // Class does not exist in the given URLs. // Let's try finding it in our parent classloader. // This will throw ClassNotFoundException on failure. diff --git a/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MarkdownImporter.java b/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MarkdownImporter.java index 41237536c..5aa0322e9 100644 --- a/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MarkdownImporter.java +++ b/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MarkdownImporter.java @@ -35,7 +35,7 @@ class MarkdownImporter extends AbstractLightWeightMarkupImporter super(fileName, listener); } - @SuppressWarnings("squid:S1386") // Transition table is OK be larger than 75 lines. + @SuppressWarnings("squid:S138") // Transition table is OK be larger than 75 lines. protected Transition[] configureTransitions() { // @formatter:off diff --git a/reporter/aspec/src/main/java/org/itsallcode/openfasttrace/report/aspec/ASpecReport.java b/reporter/aspec/src/main/java/org/itsallcode/openfasttrace/report/aspec/ASpecReport.java index e329a6951..3b48037ae 100644 --- a/reporter/aspec/src/main/java/org/itsallcode/openfasttrace/report/aspec/ASpecReport.java +++ b/reporter/aspec/src/main/java/org/itsallcode/openfasttrace/report/aspec/ASpecReport.java @@ -195,7 +195,7 @@ private void writeItemCoverage(XMLStreamWriter writer, LinkedSpecificationItem i writer.writeEndElement(); } - private void writeCoveringSpecObjects(XMLStreamWriter writer, LinkedSpecificationItem item) + private static void writeCoveringSpecObjects(XMLStreamWriter writer, LinkedSpecificationItem item) throws XMLStreamException { writer.writeStartElement("coveringSpecObjects"); diff --git a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/core/ItemBuilderFactory.java b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/core/ItemBuilderFactory.java index 685773bac..800638910 100644 --- a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/core/ItemBuilderFactory.java +++ b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/core/ItemBuilderFactory.java @@ -16,7 +16,7 @@ private ItemBuilderFactory() { * * @return a new instance of {@link SpecificationItem.Builder} */ - public static final SpecificationItem.Builder item() { + public static SpecificationItem.Builder item() { return SpecificationItem.builder(); } @@ -27,7 +27,7 @@ public static final SpecificationItem.Builder item() { * * @return a new instance of {@link SpecificationItem.Builder} with the specified ID */ - public static final SpecificationItem.Builder itemWithId(SpecificationItemId id) { + public static SpecificationItem.Builder itemWithId(SpecificationItemId id) { return SpecificationItem.builder().id(id); } @@ -38,7 +38,7 @@ public static final SpecificationItem.Builder itemWithId(SpecificationItemId id) * * @return a new instance of {@link SpecificationItem.Builder} with the default filename and the specified line */ - public static final SpecificationItem.Builder itemWithDefaultFilenameInLine(final int line) { + public static SpecificationItem.Builder itemWithDefaultFilenameInLine(final int line) { return SpecificationItem.builder().location("file", line); } } From f8fb51e398d9299c7c674642927efa0314e60e4d Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Thu, 4 Jun 2026 17:21:01 +0200 Subject: [PATCH 06/16] #536: Resolve Sonar findings of June 2026 up to SpecificationItemId.java --- .../openfasttrace/api/FilterSettings.java | 45 +---- .../openfasttrace/api/ReportSettings.java | 6 +- .../openfasttrace/api/core/Location.java | 37 +--- .../api/core/SpecificationItem.java | 176 ++---------------- .../api/importer/ImportSettings.java | 2 +- .../api/importer/input/RealFileInput.java | 2 +- .../openfasttrace/core/LinkedItemIndex.java | 56 ++---- .../core/report/ReportService.java | 6 +- .../core/report/ReporterFactoryLoader.java | 13 +- .../serviceloader/ChildFirstClassLoader.java | 2 +- .../core/TestLinkedItemIndex.java | 20 ++ .../ForwardingSpecificationItem.java | 9 +- .../SingleSpecObjectsHandlerBuilder.java | 2 +- .../handler/SpecDocumentHandlerBuilder.java | 5 +- ...er.java => AbstractRegexLineConsumer.java} | 6 +- .../tag/LongTagImportingLineConsumer.java | 2 +- .../tag/ShortTagImportingLineConsumer.java | 4 +- .../xmlparser/event/QNameFactory.java | 2 +- .../report/aspec/ASpecReport.java | 2 +- .../html/view/html/HtmlSpecificationItem.java | 24 ++- .../report/plaintext/PlainTextReport.java | 17 +- .../openfasttrace/testutil/OsCheck.java | 4 +- .../testutil/core/SampleArtifactTypes.java | 12 +- 23 files changed, 125 insertions(+), 329 deletions(-) rename importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/{RegexLineConsumer.java => AbstractRegexLineConsumer.java} (86%) diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java b/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java index bd665db09..14312c58d 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java @@ -87,48 +87,11 @@ public int hashCode() } @Override - public boolean equals(final Object obj) - { - if (this == obj) - { - return true; - } - if (obj == null) - { + public boolean equals(final Object other) { + if (!(other instanceof final FilterSettings that)) return false; - } - if (!(obj instanceof FilterSettings)) - { - return false; - } - final FilterSettings other = (FilterSettings) obj; - if (this.artifactTypes == null) - { - if (other.artifactTypes != null) - { - return false; - } - } - else if (!this.artifactTypes.equals(other.artifactTypes)) - { - return false; - } - if (this.withoutTags != other.withoutTags) - { - return false; - } - if (this.tags == null) - { - if (other.tags != null) - { - return false; - } - } - else if (!this.tags.equals(other.tags)) - { - return false; - } - return true; + return withoutTags == that.withoutTags && Objects.equals(artifactTypes, that.artifactTypes) + && Objects.equals(tags, that.tags); } /** diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/ReportSettings.java b/api/src/main/java/org/itsallcode/openfasttrace/api/ReportSettings.java index b8af61b71..3fa87ab2b 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/ReportSettings.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/ReportSettings.java @@ -10,7 +10,7 @@ * This class implements a parameter object to control the settings of OFT's * report mode. */ -public class ReportSettings +public final class ReportSettings { private final ReportVerbosity verbosity; private final boolean showOrigin; @@ -112,12 +112,12 @@ public static Builder builder() /** * Builder for {@link ReportSettings} */ - public static class Builder + public static final class Builder { private DetailsSectionDisplay detailsSectionDisplay = DetailsSectionDisplay.COLLAPSE; private Newline newline = Newline.UNIX; private String outputFormat = ReportConstants.DEFAULT_REPORT_FORMAT; - private boolean showOrigin = false; + private boolean showOrigin; private ReportVerbosity verbosity = ReportVerbosity.FAILURE_DETAILS; private ColorScheme colorScheme = ColorScheme.BLACK_AND_WHITE; diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/core/Location.java b/api/src/main/java/org/itsallcode/openfasttrace/api/core/Location.java index 3549030ba..8b56b3a7d 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/core/Location.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/core/Location.java @@ -118,41 +118,10 @@ public int hashCode() } @Override - public boolean equals(final Object obj) - { - if (this == obj) - { - return true; - } - if (obj == null) - { - return false; - } - if (getClass() != obj.getClass()) - { - return false; - } - final Location other = (Location) obj; - if (this.column != other.column) - { + public boolean equals(final Object other) { + if (!(other instanceof final Location location)) return false; - } - if (this.line != other.line) - { - return false; - } - if (this.path == null) - { - if (other.path != null) - { - return false; - } - } - else if (!this.path.equals(other.path)) - { - return false; - } - return true; + return line == location.line && column == location.column && Objects.equals(path, location.path); } @Override diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/core/SpecificationItem.java b/api/src/main/java/org/itsallcode/openfasttrace/api/core/SpecificationItem.java index 92ca7a774..f2612d44e 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/core/SpecificationItem.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/core/SpecificationItem.java @@ -7,7 +7,7 @@ * coverage for other items. */ // [impl->dsn~specification-item~3] -public class SpecificationItem +public final class SpecificationItem { private final SpecificationItemId id; private final String title; @@ -141,7 +141,7 @@ public List getCoveredIds() */ public List getDependOnIds() { - return this.dependOnIds; + return Collections.unmodifiableList(this.dependOnIds); } /** @@ -152,7 +152,7 @@ public List getDependOnIds() */ public List getNeedsArtifactTypes() { - return this.needsArtifactTypes; + return Collections.unmodifiableList(this.needsArtifactTypes); } /** @@ -206,7 +206,7 @@ public ItemStatus getStatus() */ public List getTags() { - return this.tags; + return Collections.unmodifiableList(this.tags); } /** @@ -220,161 +220,21 @@ public boolean isForwarding() } @Override - public final int hashCode() - { - final int prime = 31; - int result = 1; - result = prime * result + ((this.comment == null) ? 0 : this.comment.hashCode()); - result = prime * result + ((this.coveredIds == null) ? 0 : this.coveredIds.hashCode()); - result = prime * result + ((this.dependOnIds == null) ? 0 : this.dependOnIds.hashCode()); - result = prime * result + ((this.description == null) ? 0 : this.description.hashCode()); - result = prime * result + (this.forwards ? 1231 : 1237); - result = prime * result + ((this.id == null) ? 0 : this.id.hashCode()); - result = prime * result + ((this.location == null) ? 0 : this.location.hashCode()); - result = prime * result - + ((this.needsArtifactTypes == null) ? 0 : this.needsArtifactTypes.hashCode()); - result = prime * result + ((this.rationale == null) ? 0 : this.rationale.hashCode()); - result = prime * result + ((this.status == null) ? 0 : this.status.hashCode()); - result = prime * result + ((this.tags == null) ? 0 : this.tags.hashCode()); - result = prime * result + ((this.title == null) ? 0 : this.title.hashCode()); - return result; + public boolean equals(final Object other) { + if (!(other instanceof final SpecificationItem that)) + return false; + return forwards == that.forwards && Objects.equals(id, that.id) && Objects.equals(title, that.title) + && Objects.equals(description, that.description) && Objects.equals(rationale, that.rationale) + && Objects.equals(comment, that.comment) && Objects.equals(location, that.location) + && status == that.status && Objects.equals(coveredIds, that.coveredIds) + && Objects.equals(dependOnIds, that.dependOnIds) + && Objects.equals(needsArtifactTypes, that.needsArtifactTypes) && Objects.equals(tags, that.tags); } @Override - public final boolean equals(final Object obj) - { - if (this == obj) - { - return true; - } - if (obj == null) - { - return false; - } - if (!(obj instanceof SpecificationItem)) - { - return false; - } - final SpecificationItem other = (SpecificationItem) obj; - if (this.comment == null) - { - if (other.comment != null) - { - return false; - } - } - else if (!this.comment.equals(other.comment)) - { - return false; - } - if (this.coveredIds == null) - { - if (other.coveredIds != null) - { - return false; - } - } - else if (!this.coveredIds.equals(other.coveredIds)) - { - return false; - } - if (this.dependOnIds == null) - { - if (other.dependOnIds != null) - { - return false; - } - } - else if (!this.dependOnIds.equals(other.dependOnIds)) - { - return false; - } - if (this.description == null) - { - if (other.description != null) - { - return false; - } - } - else if (!this.description.equals(other.description)) - { - return false; - } - if (this.forwards != other.forwards) - { - return false; - } - if (this.id == null) - { - if (other.id != null) - { - return false; - } - } - else if (!this.id.equals(other.id)) - { - return false; - } - if (this.location == null) - { - if (other.location != null) - { - return false; - } - } - else if (!this.location.equals(other.location)) - { - return false; - } - if (this.needsArtifactTypes == null) - { - if (other.needsArtifactTypes != null) - { - return false; - } - } - else if (!this.needsArtifactTypes.equals(other.needsArtifactTypes)) - { - return false; - } - if (this.rationale == null) - { - if (other.rationale != null) - { - return false; - } - } - else if (!this.rationale.equals(other.rationale)) - { - return false; - } - if (this.status != other.status) - { - return false; - } - if (this.tags == null) - { - if (other.tags != null) - { - return false; - } - } - else if (!this.tags.equals(other.tags)) - { - return false; - } - if (this.title == null) - { - if (other.title != null) - { - return false; - } - } - else if (!this.title.equals(other.title)) - { - return false; - } - return true; + public int hashCode() { + return Objects.hash(id, title, description, rationale, comment, location, status, coveredIds, dependOnIds, + needsArtifactTypes, tags, forwards); } /** @@ -390,7 +250,7 @@ public static Builder builder() /** * Builder for objects of type {@link SpecificationItem} */ - public static class Builder + public static final class Builder { private SpecificationItemId id; private String title; @@ -671,4 +531,4 @@ public Builder forwards(final boolean forwards) return this; } } -} \ No newline at end of file +} diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImportSettings.java b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImportSettings.java index 2d57963e9..91cf107fa 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImportSettings.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImportSettings.java @@ -52,7 +52,7 @@ public FilterSettings getFilters() */ public List getPathConfigs() { - return Collections.unmodifiableSet(this.pathConfigs); + return Collections.unmodifiableList(this.pathConfigs); } /** diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/input/RealFileInput.java b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/input/RealFileInput.java index f8c5d219e..ac6df29f3 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/input/RealFileInput.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/input/RealFileInput.java @@ -9,7 +9,7 @@ /** * An {@link InputFile} for a file on disk, represented by a {@link Path}. */ -public class RealFileInput implements InputFile +public final class RealFileInput implements InputFile { private final Path path; private final Charset charset; diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/LinkedItemIndex.java b/core/src/main/java/org/itsallcode/openfasttrace/core/LinkedItemIndex.java index 6927eaee6..c204eb065 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/LinkedItemIndex.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/LinkedItemIndex.java @@ -124,7 +124,7 @@ public List getByIdIgnoringVersion(final SpecificationI return items == null ? Collections.emptyList() : items; } - static final class SpecificationItemIdWithoutVersion + static final class SpecificationItemIdWithoutVersion implements Comparable { private final String name; private final String artifcatType; @@ -143,53 +143,21 @@ public SpecificationItemIdWithoutVersion(final LinkedSpecificationItem linkedIte @Override public int hashCode() { - final int PRIME = 31; - int result = 1; - result = PRIME * result - + ((this.artifcatType == null) ? 0 : this.artifcatType.hashCode()); - result = PRIME * result + ((this.name == null) ? 0 : this.name.hashCode()); - return result; + return Objects.hash(this.artifcatType, this.name); } @Override - public boolean equals(final Object obj) - { - if (this == obj) - { - return true; - } - if (obj == null) - { - return false; - } - if (getClass() != obj.getClass()) - { - return false; - } - final SpecificationItemIdWithoutVersion other = (SpecificationItemIdWithoutVersion) obj; - if (this.artifcatType == null) - { - if (other.artifcatType != null) - { - return false; - } - } - else if (!this.artifcatType.equals(other.artifcatType)) - { - return false; - } - if (this.name == null) - { - if (other.name != null) - { - return false; - } - } - else if (!this.name.equals(other.name)) - { + public boolean equals(final Object other) { + if (!(other instanceof final SpecificationItemIdWithoutVersion that)) return false; - } - return true; + return Objects.equals(name, that.name) && Objects.equals(artifcatType, that.artifcatType); + } + + @Override + public int compareTo(final SpecificationItemIdWithoutVersion specificationItemIdWithoutVersion) { + return (specificationItemIdWithoutVersion.artifcatType.compareTo(this.artifcatType) == 0) + ? specificationItemIdWithoutVersion.name.compareTo(this.name) + : specificationItemIdWithoutVersion.artifcatType.compareTo(this.artifcatType); } } } diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/report/ReportService.java b/core/src/main/java/org/itsallcode/openfasttrace/core/report/ReportService.java index 3ba64e542..6ac089164 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/report/ReportService.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/report/ReportService.java @@ -4,6 +4,8 @@ import java.io.PrintStream; import java.nio.file.Files; import java.nio.file.Path; +import java.util.logging.Level; +import java.util.logging.Logger; import org.itsallcode.openfasttrace.api.core.Trace; import org.itsallcode.openfasttrace.api.report.ReportException; @@ -16,6 +18,7 @@ */ public class ReportService { + private static final Logger LOGGER = Logger.getLogger(ReportService.class.getName()); private final ReporterFactoryLoader reporterFactoryLoader; /** @@ -73,7 +76,7 @@ public void reportTraceToStdOut(final Trace trace, final String outputFormat) // Using System.out by intention @SuppressWarnings("squid:S106") - private PrintStream getStdOutStream() + private static PrintStream getStdOutStream() { return System.out; } @@ -89,6 +92,7 @@ private void reportTraceToStream(final Trace trace, final OutputStream outputStr } catch (final IOException exception) { + LOGGER.log(Level.SEVERE, "Failed to flush report output stream", exception); throw new ReportException(exception.getMessage()); } } diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/report/ReporterFactoryLoader.java b/core/src/main/java/org/itsallcode/openfasttrace/core/report/ReporterFactoryLoader.java index ac9d22ccc..41a328996 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/report/ReporterFactoryLoader.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/report/ReporterFactoryLoader.java @@ -48,17 +48,14 @@ private ReporterFactoryLoader(final Loader serviceLoader) public ReporterFactory getReporterFactory(final String outputFormat) { final List matchingReporters = getMatchingFactories(outputFormat); - switch (matchingReporters.size()) + return switch (matchingReporters.size()) { - case 0: - throw new ExporterException( + case 0 -> throw new ExporterException( "Found no matching reporter for output format '" + outputFormat + "'"); - case 1: - return matchingReporters.get(0); - default: - throw new ReportException("Found more than one matching reporter for output format '" + case 1 -> matchingReporters.get(0); + default -> throw new ReportException("Found more than one matching reporter for output format '" + outputFormat + "'"); - } + }; } private List getMatchingFactories(final String format) diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/serviceloader/ChildFirstClassLoader.java b/core/src/main/java/org/itsallcode/openfasttrace/core/serviceloader/ChildFirstClassLoader.java index 9e5cf0437..5ae3ed4cc 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/serviceloader/ChildFirstClassLoader.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/serviceloader/ChildFirstClassLoader.java @@ -19,7 +19,7 @@ */ class ChildFirstClassLoader extends URLClassLoader { - private static final Logger LOGGER = Logger.getLogger(ChildFirstClassLoader.class); + private static final Logger LOGGER = Logger.getLogger(ChildFirstClassLoader.class.getName()); ChildFirstClassLoader(final String name, final URL[] urls, final ClassLoader parent) { diff --git a/core/src/test/java/org/itsallcode/openfasttrace/core/TestLinkedItemIndex.java b/core/src/test/java/org/itsallcode/openfasttrace/core/TestLinkedItemIndex.java index 7a19ef239..dda6b1c51 100644 --- a/core/src/test/java/org/itsallcode/openfasttrace/core/TestLinkedItemIndex.java +++ b/core/src/test/java/org/itsallcode/openfasttrace/core/TestLinkedItemIndex.java @@ -10,6 +10,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -100,4 +102,22 @@ void testDuplicateVersionId() LinkedItemInstanceMatcher .sameItemInstance(this.duplicateIdIgnoringVersionItemMock)))); } + + @CsvSource({ + "a, b, a, b, 1", + "a, b, b, a, 1", + "a, a, a, a, 0", + "b, a, a, b, -1", + "a, a, b, a, -1" + }) + @ParameterizedTest + void testCompareSpecificationItemIdWithoutVersion(final String artifactTypeLeft, final String artifactTypeRight, + final String nameLeft, final String nameRight, final int expected) + { + final SpecificationItemIdWithoutVersion left = new SpecificationItemIdWithoutVersion( + SpecificationItemId.createId(artifactTypeLeft, nameLeft, 0)); + final SpecificationItemIdWithoutVersion right = new SpecificationItemIdWithoutVersion( + SpecificationItemId.createId(artifactTypeRight, nameRight, 0)); + assertThat(left.compareTo(right), equalTo(expected)); + } } diff --git a/importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/ForwardingSpecificationItem.java b/importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/ForwardingSpecificationItem.java index 28f2e093e..cc99a7304 100644 --- a/importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/ForwardingSpecificationItem.java +++ b/importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/ForwardingSpecificationItem.java @@ -1,6 +1,7 @@ package org.itsallcode.openfasttrace.importer.lightweightmarkup; import java.util.List; +import java.util.regex.Pattern; import org.itsallcode.openfasttrace.api.core.SpecificationItemId; @@ -17,7 +18,7 @@ public class ForwardingSpecificationItem public static final String ORIGINAL_MARKER = ":"; /** Marker after which the artifact types are listed to which we forward. */ public static final String FORWARD_MARKER = "-->"; - private static final String COMMA_SEPARATED_REGEX = "(?U),\\s*"; + private static final Pattern COMMA_SEPARATED_PATTERN = Pattern.compile("(?U),\\s*"); private final String skippedArtifactType; private final SpecificationItemId originalId; private final SpecificationItemId skippedId; @@ -34,10 +35,10 @@ public ForwardingSpecificationItem(final String forward) final int posForwardMarker = forward.indexOf(FORWARD_MARKER); final int posOriginalMarker = forward.indexOf(ORIGINAL_MARKER); this.skippedArtifactType = forward.substring(0, posForwardMarker).trim(); - this.targetArtifactTypes = List.of(forward + final String commaSeparatedTargetArtifactTypes = forward .substring(posForwardMarker + FORWARD_MARKER.length(), posOriginalMarker) - .trim() - .split(COMMA_SEPARATED_REGEX)); + .trim(); + this.targetArtifactTypes = List.of(COMMA_SEPARATED_PATTERN.split(commaSeparatedTargetArtifactTypes)); this.originalId = SpecificationItemId.parseId(forward .substring(posOriginalMarker + ORIGINAL_MARKER.length()) .trim()); diff --git a/importer/specobject/src/main/java/org/itsallcode/openfasttrace/importer/specobject/handler/SingleSpecObjectsHandlerBuilder.java b/importer/specobject/src/main/java/org/itsallcode/openfasttrace/importer/specobject/handler/SingleSpecObjectsHandlerBuilder.java index 554710997..cfa0570d1 100644 --- a/importer/specobject/src/main/java/org/itsallcode/openfasttrace/importer/specobject/handler/SingleSpecObjectsHandlerBuilder.java +++ b/importer/specobject/src/main/java/org/itsallcode/openfasttrace/importer/specobject/handler/SingleSpecObjectsHandlerBuilder.java @@ -10,7 +10,7 @@ class SingleSpecObjectsHandlerBuilder private final ImportEventListener listener; private final SpecificationItemId.Builder idBuilder; private final Location.Builder locationBuilder; - private String containedFileName = null; + private String containedFileName ; private int containedLine = -1; SingleSpecObjectsHandlerBuilder(final ImportEventListener listener, diff --git a/importer/specobject/src/main/java/org/itsallcode/openfasttrace/importer/specobject/handler/SpecDocumentHandlerBuilder.java b/importer/specobject/src/main/java/org/itsallcode/openfasttrace/importer/specobject/handler/SpecDocumentHandlerBuilder.java index 4c2db4c34..5e529db6f 100644 --- a/importer/specobject/src/main/java/org/itsallcode/openfasttrace/importer/specobject/handler/SpecDocumentHandlerBuilder.java +++ b/importer/specobject/src/main/java/org/itsallcode/openfasttrace/importer/specobject/handler/SpecDocumentHandlerBuilder.java @@ -51,7 +51,6 @@ public TreeContentHandler build() } LOG.warning(() -> "Found unknown element " + startElement); }); - this.handler.addElementListener("specdocument", elem -> { LOG.finest(() -> "Found specdocument element " + elem); if (!elem.isRootElement()) @@ -66,10 +65,8 @@ public TreeContentHandler build() throw new ImporterException("Element " + elem + " does not have an attribute '" + DOCTYPE_ATTRIBUTE_NAME + "' at " + elem.getLocation()); } - final String defaultDoctype = doctypeAttribute.getValue(); - this.handler.pushDelegate( - new SpecObjectsHandlerBuilder(this.file, defaultDoctype, this.listener) + this.handler.pushDelegate(new SpecObjectsHandlerBuilder(this.file, defaultDoctype, this.listener) .build()); }); diff --git a/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/RegexLineConsumer.java b/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/AbstractRegexLineConsumer.java similarity index 86% rename from importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/RegexLineConsumer.java rename to importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/AbstractRegexLineConsumer.java index b3231bb6d..1d2f4c9ce 100644 --- a/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/RegexLineConsumer.java +++ b/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/AbstractRegexLineConsumer.java @@ -4,16 +4,16 @@ import org.itsallcode.openfasttrace.importer.tag.LineReader.LineConsumer; -abstract class RegexLineConsumer implements LineConsumer +abstract class AbstractRegexLineConsumer implements LineConsumer { private final Pattern pattern; - RegexLineConsumer(final String patternRegex) + AbstractRegexLineConsumer(final String patternRegex) { this(Pattern.compile(patternRegex)); } - private RegexLineConsumer(final Pattern pattern) + private AbstractRegexLineConsumer(final Pattern pattern) { this.pattern = pattern; } diff --git a/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/LongTagImportingLineConsumer.java b/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/LongTagImportingLineConsumer.java index cf59a4aa8..12ba0865c 100644 --- a/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/LongTagImportingLineConsumer.java +++ b/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/LongTagImportingLineConsumer.java @@ -13,7 +13,7 @@ // [impl->dsn~import.full-coverage-tag~1] // [impl->dsn~import.full-coverage-tag-with-needed-coverage~1] -class LongTagImportingLineConsumer extends RegexLineConsumer +class LongTagImportingLineConsumer extends AbstractRegexLineConsumer { private static final Logger LOG = Logger .getLogger(LongTagImportingLineConsumer.class.getName()); diff --git a/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/ShortTagImportingLineConsumer.java b/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/ShortTagImportingLineConsumer.java index 4747da0d7..428ab7dae 100644 --- a/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/ShortTagImportingLineConsumer.java +++ b/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/ShortTagImportingLineConsumer.java @@ -10,7 +10,7 @@ import org.itsallcode.openfasttrace.api.importer.tag.config.PathConfig; // [impl->dsn~import.short-coverage-tag~1] -class ShortTagImportingLineConsumer extends RegexLineConsumer +class ShortTagImportingLineConsumer extends AbstractRegexLineConsumer { private static final Logger LOG = Logger.getLogger(ShortTagImportingLineConsumer.class.getName()); @@ -71,7 +71,7 @@ private SpecificationItemId createCoveredItem(final String name, final String re nameWithPrefix, parsedRevision); } - private int parseRevision(final String name, final String revision) + private static int parseRevision(final String name, final String revision) { try { diff --git a/importer/xmlparser/src/main/java/org/itsallcode/openfasttrace/importer/xmlparser/event/QNameFactory.java b/importer/xmlparser/src/main/java/org/itsallcode/openfasttrace/importer/xmlparser/event/QNameFactory.java index bc3d98c77..dad1142fc 100644 --- a/importer/xmlparser/src/main/java/org/itsallcode/openfasttrace/importer/xmlparser/event/QNameFactory.java +++ b/importer/xmlparser/src/main/java/org/itsallcode/openfasttrace/importer/xmlparser/event/QNameFactory.java @@ -7,7 +7,7 @@ /** * Factory for creating {@link QName} objects. */ -class QNameFactory +final class QNameFactory { private QNameFactory() { diff --git a/reporter/aspec/src/main/java/org/itsallcode/openfasttrace/report/aspec/ASpecReport.java b/reporter/aspec/src/main/java/org/itsallcode/openfasttrace/report/aspec/ASpecReport.java index 3b48037ae..758e630bb 100644 --- a/reporter/aspec/src/main/java/org/itsallcode/openfasttrace/report/aspec/ASpecReport.java +++ b/reporter/aspec/src/main/java/org/itsallcode/openfasttrace/report/aspec/ASpecReport.java @@ -180,7 +180,7 @@ private static void writeTags(final XMLStreamWriter writer, final List t writer.writeEndElement(); } - private void writeItemCoverage(XMLStreamWriter writer, LinkedSpecificationItem item) throws XMLStreamException + private static void writeItemCoverage(XMLStreamWriter writer, LinkedSpecificationItem item) throws XMLStreamException { writer.writeStartElement("coverage"); writeNeedsArtifactTypes(writer, item.getNeedsArtifactTypes()); diff --git a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlSpecificationItem.java b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlSpecificationItem.java index 204087333..865508ae5 100644 --- a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlSpecificationItem.java +++ b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/html/HtmlSpecificationItem.java @@ -133,12 +133,9 @@ private void renderComment(final String indentation) private void renderNeeds(final String indentation) { - if ((this.item.getNeedsArtifactTypes() != null - && !this.item.getNeedsArtifactTypes().isEmpty()) - || (this.item.getUncoveredArtifactTypes() != null - && !this.item.getUncoveredArtifactTypes().isEmpty()) - || (this.item.getOverCoveredArtifactTypes() != null - && !this.item.getOverCoveredArtifactTypes().isEmpty())) + if (atLeastOneNeededArtifactTypeCovered() + || hasUncoveredArtifactTypes() + || hasOvercoveredArtifactTypes()) { this.stream.print(indentation); this.stream.print("
Needs: "); @@ -147,6 +144,21 @@ private void renderNeeds(final String indentation) } } + private boolean atLeastOneNeededArtifactTypeCovered() { + return this.item.getNeedsArtifactTypes() != null + && !this.item.getNeedsArtifactTypes().isEmpty(); + } + + private boolean hasUncoveredArtifactTypes() { + return this.item.getUncoveredArtifactTypes() != null + && !this.item.getUncoveredArtifactTypes().isEmpty(); + } + + private boolean hasOvercoveredArtifactTypes() { + return this.item.getOverCoveredArtifactTypes() != null + && !this.item.getOverCoveredArtifactTypes().isEmpty(); + } + private static String translateArtifactTypeCoverage(final LinkedSpecificationItem item) { final Comparator byTypeName = Comparator diff --git a/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/PlainTextReport.java b/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/PlainTextReport.java index 16250bc5d..17b6b1d1a 100644 --- a/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/PlainTextReport.java +++ b/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/PlainTextReport.java @@ -7,6 +7,8 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Locale; +import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -20,10 +22,11 @@ */ public class PlainTextReport implements Reportable { - private final Trace trace; + public static final Pattern PLUS_MINUS_PATTERN = Pattern.compile("[-+]"); private static final Comparator LINKED_ITEM_BY_ID = Comparator .comparing(LinkedSpecificationItem::getId); - private int nonEmptySections = 0; + private final Trace trace; + private int nonEmptySections; private final ReportSettings settings; private final TextFormatter formatter; @@ -156,7 +159,7 @@ private void renderItemSummary(final PrintStream report, final LinkedSpecificati private String translateArtifactTypeCoverage(final LinkedSpecificationItem item) { - final Comparator byTypeName = Comparator.comparing(a -> a.replaceFirst("[-+]", "")); + final Comparator byTypeName = Comparator.comparing(a -> PLUS_MINUS_PATTERN.matcher(a).replaceFirst("")); final Stream uncoveredStream = item.getUncoveredArtifactTypes().stream() .map(x -> this.formatter.formatNotOk("-" + x)); @@ -205,7 +208,7 @@ private String formatCountXofY(final int countGood, final int count) { } } - private void renderMaturity(final PrintStream report, final LinkedSpecificationItem item) + private static void renderMaturity(final PrintStream report, final LinkedSpecificationItem item) { final ItemStatus status = item.getStatus(); if (status != ItemStatus.APPROVED) @@ -244,7 +247,7 @@ private void renderItemDetails(final PrintStream report, final LinkedSpecificati renderItemDetailsEnd(report); } - private void renderOrigin(final PrintStream report, final Location location) + private static void renderOrigin(final PrintStream report, final Location location) { report.print("("); report.print(location.getPath()); @@ -322,7 +325,7 @@ private void renderLink(final PrintStream report, final TracedLink link, } private static String padStatus(final LinkStatus status) { - return String.format("%-17s", status.toString().toLowerCase()); + return String.format("%-17s", status.toString().toLowerCase(Locale.ENGLISH)); } private void renderTags(final PrintStream report, final LinkedSpecificationItem item) @@ -360,4 +363,4 @@ private void renderItemDetailsEnd(final PrintStream report) renderEmptyItemDetailsLine(report); } } -} \ No newline at end of file +} diff --git a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/OsCheck.java b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/OsCheck.java index b8f412711..e2712dd31 100644 --- a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/OsCheck.java +++ b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/OsCheck.java @@ -69,6 +69,8 @@ else if (os.contains("linux")) { return OSType.LINUX; } - return OSType.OTHER; + else { + return OSType.OTHER; + } } } diff --git a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/core/SampleArtifactTypes.java b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/core/SampleArtifactTypes.java index 789eeb22e..6cc937adc 100644 --- a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/core/SampleArtifactTypes.java +++ b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/core/SampleArtifactTypes.java @@ -3,13 +3,8 @@ /** * Constants for sample artifact types used in tests. */ -public class SampleArtifactTypes +public final class SampleArtifactTypes { - private SampleArtifactTypes() - { - // Not instantiable - } - /** Architecture artifact type. */ public static final String ARCH = "arch"; /** Design artifact type. */ @@ -26,4 +21,9 @@ private SampleArtifactTypes() public static final String UTEST = "utest"; /** User manual artifact type. */ public static final String UMAN = "uman"; + + private SampleArtifactTypes() + { + // Not instantiable + } } From b125ad5ae2000c3875128fb1bbf4a9f533606f1c Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Thu, 4 Jun 2026 17:25:39 +0200 Subject: [PATCH 07/16] #536: Maded pattern private in PlainTextReport. --- .../openfasttrace/report/plaintext/PlainTextReport.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/PlainTextReport.java b/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/PlainTextReport.java index 17b6b1d1a..8435b80af 100644 --- a/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/PlainTextReport.java +++ b/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/PlainTextReport.java @@ -22,7 +22,7 @@ */ public class PlainTextReport implements Reportable { - public static final Pattern PLUS_MINUS_PATTERN = Pattern.compile("[-+]"); + private static final Pattern PLUS_MINUS_PATTERN = Pattern.compile("[-+]"); private static final Comparator LINKED_ITEM_BY_ID = Comparator .comparing(LinkedSpecificationItem::getId); private final Trace trace; From 08b616a1ccc4d2b3b804b327c3dd539ffb8d41df Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Thu, 4 Jun 2026 18:07:18 +0200 Subject: [PATCH 08/16] #536: Up to TextFormatterFactory. --- .../api/core/SpecificationItem.java | 3 +- .../api/core/SpecificationItemId.java | 90 ++++--------------- .../openfasttrace/api/core/Trace.java | 15 ++-- .../importer/SpecificationListBuilder.java | 10 +-- .../openfasttrace/core/LinkedItemIndex.java | 19 ++-- .../core/cli/StandardDirectoryService.java | 2 +- .../core/TestLinkedItemIndex.java | 8 +- .../core/importer/TestImporterService.java | 5 +- .../specobject/SpecobjectExporter.java | 2 +- .../ForwardingSpecificationItem.java | 4 +- .../specobject/SpecobjectImporterFactory.java | 4 +- .../xmlparser/event/StartElementEvent.java | 2 +- .../report/plaintext/TextFormatter.java | 8 +- .../plaintext/TextFormatterFactory.java | 22 ++--- .../testutil/importer/input/StreamInput.java | 2 +- 15 files changed, 72 insertions(+), 124 deletions(-) diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/core/SpecificationItem.java b/api/src/main/java/org/itsallcode/openfasttrace/api/core/SpecificationItem.java index f2612d44e..42c66cc0e 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/core/SpecificationItem.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/core/SpecificationItem.java @@ -221,8 +221,9 @@ public boolean isForwarding() @Override public boolean equals(final Object other) { - if (!(other instanceof final SpecificationItem that)) + if (!(other instanceof final SpecificationItem that)) { return false; + } return forwards == that.forwards && Objects.equals(id, that.id) && Objects.equals(title, that.title) && Objects.equals(description, that.description) && Objects.equals(rationale, that.rationale) && Objects.equals(comment, that.comment) && Objects.equals(location, that.location) diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/core/SpecificationItemId.java b/api/src/main/java/org/itsallcode/openfasttrace/api/core/SpecificationItemId.java index 54a0c34d1..1b45ff2d7 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/core/SpecificationItemId.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/core/SpecificationItemId.java @@ -1,16 +1,19 @@ package org.itsallcode.openfasttrace.api.core; +import java.util.Comparator; +import java.util.Objects; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Specification item ID - * + *

* Consists of an artifact type (e.g. "test"), a name and a revision number. + *

*/ // [impl->dsn~specification-item-id~1] -public class SpecificationItemId implements Comparable +public final class SpecificationItemId implements Comparable { private static final Logger LOG = Logger.getLogger(SpecificationItemId.class.getName()); @@ -89,67 +92,23 @@ public String getArtifactType() } @Override - public final int hashCode() - { - final int prime = 31; - int result = 1; - result = prime * result + ((this.artifactType == null) ? 0 : this.artifactType.hashCode()); - result = prime * result + ((this.name == null) ? 0 : this.name.hashCode()); - result = prime * result + this.revision; - return result; + public boolean equals(final Object o) { + if (!(o instanceof final SpecificationItemId that)) { + return false; + } + return revision == that.revision && Objects.equals(name, that.name) + && Objects.equals(artifactType, that.artifactType); } @Override - public final boolean equals(final Object obj) - { - if (this == obj) - { - return true; - } - if (obj == null) - { - return false; - } - if (!(obj instanceof SpecificationItemId)) - { - return false; - } - final SpecificationItemId other = (SpecificationItemId) obj; - if (this.artifactType == null) - { - if (other.artifactType != null) - { - return false; - } - } - else if (!this.artifactType.equals(other.artifactType)) - { - return false; - } - if (this.name == null) - { - if (other.name != null) - { - return false; - } - } - else if (!this.name.equals(other.name)) - { - return false; - } - return (other.revision == REVISION_WILDCARD) || (this.revision == other.revision); + public int hashCode() { + return Objects.hash(name, revision, artifactType); } @Override public String toString() { - final StringBuilder builder = new StringBuilder() // - .append(this.artifactType) // - .append(ARTIFACT_TYPE_SEPARATOR) // - .append(this.name) // - .append(REVISION_SEPARATOR) // - .append(this.revision); - return builder.toString(); + return this.artifactType + ARTIFACT_TYPE_SEPARATOR + this.name + REVISION_SEPARATOR + this.revision; } /** @@ -401,22 +360,9 @@ private void parseRevision(final String text) @Override public int compareTo(final SpecificationItemId other) { - int compared = this.getArtifactType().compareTo(other.getArtifactType()); - if (compared == 0) - { - compared = this.getName().compareTo(other.getName()); - if (compared == 0) - { - if (this.getRevision() > other.getRevision()) - { - compared = 1; - } - else if (this.getRevision() < other.getRevision()) - { - compared = -1; - } - } - } - return compared; + return Comparator.comparing(SpecificationItemId::getArtifactType) + .thenComparing(SpecificationItemId::getName) + .thenComparingInt(SpecificationItemId::getRevision) + .compare(this, other); } } diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/core/Trace.java b/api/src/main/java/org/itsallcode/openfasttrace/api/core/Trace.java index 71a8ecceb..4f70e3a74 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/core/Trace.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/core/Trace.java @@ -1,11 +1,12 @@ package org.itsallcode.openfasttrace.api.core; +import java.util.Collections; import java.util.List; /** * The result of tracing requirements. */ -public class Trace +public final class Trace { private final List items; private final List defectItems; @@ -35,7 +36,7 @@ public boolean hasNoDefects() */ public List getDefectItems() { - return this.defectItems; + return Collections.unmodifiableList(this.defectItems); } /** @@ -45,7 +46,7 @@ public List getDefectItems() */ public List getItems() { - return this.items; + return Collections.unmodifiableList(this.items); } /** @@ -94,7 +95,7 @@ public static Builder builder() * A builder for {@link Trace}. Use {@link Trace#builder()} to create a new * builder and call {@link #build()} to build a {@link Trace}. */ - public static class Builder + public static final class Builder { private List items; private List defectItems; @@ -112,7 +113,7 @@ private Builder() */ public Builder items(final List items) { - this.items = items; + this.items = Collections.unmodifiableList(items); return this; } @@ -125,7 +126,7 @@ public Builder items(final List items) */ public Builder defectItems(final List defectItems) { - this.defectItems = defectItems; + this.defectItems = Collections.unmodifiableList(defectItems); return this; } @@ -139,4 +140,4 @@ public Trace build() return new Trace(this.items, this.defectItems); } } -} \ No newline at end of file +} diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/SpecificationListBuilder.java b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/SpecificationListBuilder.java index da9c717b7..8136fe67d 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/SpecificationListBuilder.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/SpecificationListBuilder.java @@ -10,12 +10,12 @@ * map of specification items from them. The key to the map is the specification * item ID. */ -public class SpecificationListBuilder implements ImportEventListener +public final class SpecificationListBuilder implements ImportEventListener { private final FilterSettings filterSettings; private final List items = new LinkedList<>(); - private SpecificationItem.Builder itemBuilder = null; - private SpecificationItemId id = null; + private SpecificationItem.Builder itemBuilder; + private SpecificationItemId id; private StringBuilder description = new StringBuilder(); private StringBuilder rationale = new StringBuilder(); private StringBuilder comment = new StringBuilder(); @@ -139,7 +139,7 @@ public void addTag(final String tag) public List build() { this.endSpecificationItem(); - return this.items; + return Collections.unmodifiableList(this.items) ; } /** @@ -228,4 +228,4 @@ public void setForwards(final boolean forwards) { this.itemBuilder.forwards(forwards); } -} \ No newline at end of file +} diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/LinkedItemIndex.java b/core/src/main/java/org/itsallcode/openfasttrace/core/LinkedItemIndex.java index c204eb065..25e519ab2 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/LinkedItemIndex.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/LinkedItemIndex.java @@ -140,6 +140,14 @@ public SpecificationItemIdWithoutVersion(final LinkedSpecificationItem linkedIte this(linkedItem.getId()); } + public String getName() { + return this.name; + } + + public String getArtifcatType() { + return this.artifcatType; + } + @Override public int hashCode() { @@ -148,16 +156,17 @@ public int hashCode() @Override public boolean equals(final Object other) { - if (!(other instanceof final SpecificationItemIdWithoutVersion that)) + if (!(other instanceof final SpecificationItemIdWithoutVersion that)) { return false; + } return Objects.equals(name, that.name) && Objects.equals(artifcatType, that.artifcatType); } @Override - public int compareTo(final SpecificationItemIdWithoutVersion specificationItemIdWithoutVersion) { - return (specificationItemIdWithoutVersion.artifcatType.compareTo(this.artifcatType) == 0) - ? specificationItemIdWithoutVersion.name.compareTo(this.name) - : specificationItemIdWithoutVersion.artifcatType.compareTo(this.artifcatType); + public int compareTo(final SpecificationItemIdWithoutVersion other) { + return Comparator.comparing(SpecificationItemIdWithoutVersion::getArtifcatType) + .thenComparing(SpecificationItemIdWithoutVersion::getName) + .compare(this, other); } } } diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/StandardDirectoryService.java b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/StandardDirectoryService.java index 57f5c7b84..6d1a4026f 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/StandardDirectoryService.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/StandardDirectoryService.java @@ -20,4 +20,4 @@ public String getCurrent() { return System.getProperty("user.dir"); } -} \ No newline at end of file +} diff --git a/core/src/test/java/org/itsallcode/openfasttrace/core/TestLinkedItemIndex.java b/core/src/test/java/org/itsallcode/openfasttrace/core/TestLinkedItemIndex.java index dda6b1c51..a378654c0 100644 --- a/core/src/test/java/org/itsallcode/openfasttrace/core/TestLinkedItemIndex.java +++ b/core/src/test/java/org/itsallcode/openfasttrace/core/TestLinkedItemIndex.java @@ -104,11 +104,11 @@ void testDuplicateVersionId() } @CsvSource({ - "a, b, a, b, 1", - "a, b, b, a, 1", + "a, b, a, b, -1", + "a, b, b, a, -1", "a, a, a, a, 0", - "b, a, a, b, -1", - "a, a, b, a, -1" + "b, a, a, b, 1", + "a, a, b, a, 1" }) @ParameterizedTest void testCompareSpecificationItemIdWithoutVersion(final String artifactTypeLeft, final String artifactTypeRight, diff --git a/core/src/test/java/org/itsallcode/openfasttrace/core/importer/TestImporterService.java b/core/src/test/java/org/itsallcode/openfasttrace/core/importer/TestImporterService.java index 60d977629..4e5fe027a 100644 --- a/core/src/test/java/org/itsallcode/openfasttrace/core/importer/TestImporterService.java +++ b/core/src/test/java/org/itsallcode/openfasttrace/core/importer/TestImporterService.java @@ -3,7 +3,6 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.sameInstance; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -37,8 +36,6 @@ class TestImporterService private ImporterFactory importerFactoryMock; @Mock private Importer importerMock; - @Mock - private ImporterContext contextMock; @Captor private ArgumentCaptor builderArg; @@ -86,6 +83,6 @@ private void runImporter() this.builderArg.capture()); final SpecificationListBuilder builder = this.builderArg.getValue(); - assertThat(result, sameInstance(builder.build())); + assertThat(result, equalTo(builder.build())); } } diff --git a/exporter/specobject/src/main/java/org/itsallcode/openfasttrace/exporter/specobject/SpecobjectExporter.java b/exporter/specobject/src/main/java/org/itsallcode/openfasttrace/exporter/specobject/SpecobjectExporter.java index d772ef3a2..50b78953f 100644 --- a/exporter/specobject/src/main/java/org/itsallcode/openfasttrace/exporter/specobject/SpecobjectExporter.java +++ b/exporter/specobject/src/main/java/org/itsallcode/openfasttrace/exporter/specobject/SpecobjectExporter.java @@ -41,7 +41,7 @@ public SpecobjectExporter(final Stream itemStream, this.originalWriter = originalWriter; } - private Map> groupByDoctype( + private static Map> groupByDoctype( final Stream itemStream) { return itemStream.collect( diff --git a/importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/ForwardingSpecificationItem.java b/importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/ForwardingSpecificationItem.java index cc99a7304..795801742 100644 --- a/importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/ForwardingSpecificationItem.java +++ b/importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/ForwardingSpecificationItem.java @@ -18,7 +18,7 @@ public class ForwardingSpecificationItem public static final String ORIGINAL_MARKER = ":"; /** Marker after which the artifact types are listed to which we forward. */ public static final String FORWARD_MARKER = "-->"; - private static final Pattern COMMA_SEPARATED_PATTERN = Pattern.compile("(?U),\\s*"); + private static final Pattern COMMA_SEPARATED_REGEX = Pattern.compile("(?U),\\s*"); private final String skippedArtifactType; private final SpecificationItemId originalId; private final SpecificationItemId skippedId; @@ -38,7 +38,7 @@ public ForwardingSpecificationItem(final String forward) final String commaSeparatedTargetArtifactTypes = forward .substring(posForwardMarker + FORWARD_MARKER.length(), posOriginalMarker) .trim(); - this.targetArtifactTypes = List.of(COMMA_SEPARATED_PATTERN.split(commaSeparatedTargetArtifactTypes)); + this.targetArtifactTypes = List.of(COMMA_SEPARATED_REGEX.split(commaSeparatedTargetArtifactTypes)); this.originalId = SpecificationItemId.parseId(forward .substring(posOriginalMarker + ORIGINAL_MARKER.length()) .trim()); diff --git a/importer/specobject/src/main/java/org/itsallcode/openfasttrace/importer/specobject/SpecobjectImporterFactory.java b/importer/specobject/src/main/java/org/itsallcode/openfasttrace/importer/specobject/SpecobjectImporterFactory.java index d4137d163..8e7761e5d 100644 --- a/importer/specobject/src/main/java/org/itsallcode/openfasttrace/importer/specobject/SpecobjectImporterFactory.java +++ b/importer/specobject/src/main/java/org/itsallcode/openfasttrace/importer/specobject/SpecobjectImporterFactory.java @@ -66,7 +66,9 @@ private static boolean doesFileContainOreqmHeader(final InputFile file, final St } catch (final IOException exception) { - LOG.fine(() -> "Unable to peek XML file '" + path + "' trying to determine if it contains ReqM2 format: " + exception.getMessage()); + LOG.fine(() -> "Unable to peek XML file '" + path + + "' trying to determine if it contains ReqM2 format: " + + exception.getMessage()); return false; } } diff --git a/importer/xmlparser/src/main/java/org/itsallcode/openfasttrace/importer/xmlparser/event/StartElementEvent.java b/importer/xmlparser/src/main/java/org/itsallcode/openfasttrace/importer/xmlparser/event/StartElementEvent.java index 872e0efbd..b8c7e88a3 100644 --- a/importer/xmlparser/src/main/java/org/itsallcode/openfasttrace/importer/xmlparser/event/StartElementEvent.java +++ b/importer/xmlparser/src/main/java/org/itsallcode/openfasttrace/importer/xmlparser/event/StartElementEvent.java @@ -12,7 +12,7 @@ * * @see org.xml.sax.ContentHandler#endElement(String, String, String) */ -public class StartElementEvent +public final class StartElementEvent { private final QName qName; private final Location location; diff --git a/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/TextFormatter.java b/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/TextFormatter.java index e717b5239..257de0695 100644 --- a/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/TextFormatter.java +++ b/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/TextFormatter.java @@ -9,7 +9,7 @@ interface TextFormatter { * @param text text span to be formatted * @return formatted text */ - public String formatOk(final String text); + String formatOk(final String text); /** * Format a text span that represents a bad result. @@ -17,7 +17,7 @@ interface TextFormatter { * @param text text span to be formatted * @return formatted text */ - public String formatNotOk(final String text); + String formatNotOk(final String text); /** * Format a text span that represents a strongly emphasized text. @@ -25,5 +25,5 @@ interface TextFormatter { * @param text text span to be formatted * @return formatted text */ - public String formatStrong(final String text); -} \ No newline at end of file + String formatStrong(final String text); +} diff --git a/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/TextFormatterFactory.java b/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/TextFormatterFactory.java index 8e93d8815..0a0fee69d 100644 --- a/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/TextFormatterFactory.java +++ b/reporter/plaintext/src/main/java/org/itsallcode/openfasttrace/report/plaintext/TextFormatterFactory.java @@ -16,20 +16,12 @@ private TextFormatterFactory() { * @return text formatter */ public static TextFormatter createFormatter(ColorScheme colorScheme) { - if(colorScheme == null) - { - return new NullTextFormatter(); - } - switch (colorScheme) { - case BLACK_AND_WHITE: - return new NullTextFormatter(); - case MONOCHROME: - return new MonochromeTextFormatter(); - case COLOR: - return new ConsoleColorFormatter(); - default: - throw new IllegalArgumentException("Unable to create text formatter for unknown color scheme '" - + colorScheme + "'."); - } + return (colorScheme == null) + ? new NullTextFormatter() + : (switch (colorScheme) { + case BLACK_AND_WHITE -> new NullTextFormatter(); + case MONOCHROME -> new MonochromeTextFormatter(); + case COLOR -> new ConsoleColorFormatter(); + }); } } diff --git a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/importer/input/StreamInput.java b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/importer/input/StreamInput.java index 963e6e2a3..c89d28171 100644 --- a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/importer/input/StreamInput.java +++ b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/importer/input/StreamInput.java @@ -10,7 +10,7 @@ * An implementation of {@link InputFile} that reads from a * {@link BufferedReader}. This is useful for tests to avoid using real files. */ -public class StreamInput implements InputFile +public final class StreamInput implements InputFile { private final Path path; private final BufferedReader reader; From ed28a944786deb8e81a708e12d88f23173532d60 Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Thu, 4 Jun 2026 18:13:32 +0200 Subject: [PATCH 09/16] #536: Up to ZipFileImporter. --- .../openfasttrace/api/core/TracedLink.java | 43 ++++--------------- .../importer/zip/ZipFileImporter.java | 2 +- .../importer/zip/input/ZipEntryInput.java | 2 +- .../report/html/view/ViewableContainer.java | 2 +- 4 files changed, 12 insertions(+), 37 deletions(-) diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/core/TracedLink.java b/api/src/main/java/org/itsallcode/openfasttrace/api/core/TracedLink.java index 2b770ee83..9745e3f64 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/core/TracedLink.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/core/TracedLink.java @@ -1,5 +1,7 @@ package org.itsallcode.openfasttrace.api.core; +import java.util.Objects; + /** * This class represents a link that had its status evaluated during a trace * run. @@ -64,42 +66,15 @@ public boolean isOutgoing() } @Override - public int hashCode() - { - final int prime = 31; - int result = 1; - result = prime * result + ((this.otherLinkEnd == null) ? 0 : this.otherLinkEnd.hashCode()); - result = prime * result + ((this.status == null) ? 0 : this.status.hashCode()); - return result; + public boolean equals(final Object o) { + if (!(o instanceof final TracedLink that)) { + return false; + } + return Objects.equals(otherLinkEnd, that.otherLinkEnd) && status == that.status; } @Override - public boolean equals(final Object obj) - { - if (this == obj) - { - return true; - } - if (obj == null) - { - return false; - } - if (!(obj instanceof TracedLink)) - { - return false; - } - final TracedLink other = (TracedLink) obj; - if (this.otherLinkEnd == null) - { - if (other.otherLinkEnd != null) - { - return false; - } - } - else if (!this.otherLinkEnd.equals(other.otherLinkEnd)) - { - return false; - } - return this.status == other.status; + public int hashCode() { + return Objects.hash(otherLinkEnd, status); } } diff --git a/importer/zip/src/main/java/org/itsallcode/openfasttrace/importer/zip/ZipFileImporter.java b/importer/zip/src/main/java/org/itsallcode/openfasttrace/importer/zip/ZipFileImporter.java index 3b9a93710..730c8ab25 100644 --- a/importer/zip/src/main/java/org/itsallcode/openfasttrace/importer/zip/ZipFileImporter.java +++ b/importer/zip/src/main/java/org/itsallcode/openfasttrace/importer/zip/ZipFileImporter.java @@ -51,7 +51,7 @@ public void runImport() } } - private InputFile createInput(final ZipFile zip, final ZipEntry entry) + private static InputFile createInput(final ZipFile zip, final ZipEntry entry) { return ZipEntryInput.forZipEntry(zip, entry); } diff --git a/importer/zip/src/main/java/org/itsallcode/openfasttrace/importer/zip/input/ZipEntryInput.java b/importer/zip/src/main/java/org/itsallcode/openfasttrace/importer/zip/input/ZipEntryInput.java index 83359808f..c283283f0 100644 --- a/importer/zip/src/main/java/org/itsallcode/openfasttrace/importer/zip/input/ZipEntryInput.java +++ b/importer/zip/src/main/java/org/itsallcode/openfasttrace/importer/zip/input/ZipEntryInput.java @@ -12,7 +12,7 @@ /** * An {@link InputFile} for {@link ZipEntry} of a {@link ZipFile}. */ -public class ZipEntryInput implements InputFile +public final class ZipEntryInput implements InputFile { private final ZipFile zip; private final ZipEntry entry; diff --git a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/ViewableContainer.java b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/ViewableContainer.java index 4fac784b6..af709c650 100644 --- a/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/ViewableContainer.java +++ b/reporter/html/src/main/java/org/itsallcode/openfasttrace/report/html/view/ViewableContainer.java @@ -42,4 +42,4 @@ public interface ViewableContainer extends Viewable * @return list of children */ List getChildren(); -} \ No newline at end of file +} From af6f33e7068540dccf4c08b235b26866eb2b2721 Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Thu, 4 Jun 2026 18:41:07 +0200 Subject: [PATCH 10/16] #536: Wrapped overlong line. --- .../org/itsallcode/openfasttrace/report/aspec/ASpecReport.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/reporter/aspec/src/main/java/org/itsallcode/openfasttrace/report/aspec/ASpecReport.java b/reporter/aspec/src/main/java/org/itsallcode/openfasttrace/report/aspec/ASpecReport.java index 758e630bb..62325676a 100644 --- a/reporter/aspec/src/main/java/org/itsallcode/openfasttrace/report/aspec/ASpecReport.java +++ b/reporter/aspec/src/main/java/org/itsallcode/openfasttrace/report/aspec/ASpecReport.java @@ -180,7 +180,8 @@ private static void writeTags(final XMLStreamWriter writer, final List t writer.writeEndElement(); } - private static void writeItemCoverage(XMLStreamWriter writer, LinkedSpecificationItem item) throws XMLStreamException + private static void writeItemCoverage(XMLStreamWriter writer, LinkedSpecificationItem item) + throws XMLStreamException { writer.writeStartElement("coverage"); writeNeedsArtifactTypes(writer, item.getNeedsArtifactTypes()); From 710fd9939c1e9c50798760b01e08e179f38a7ac2 Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Thu, 4 Jun 2026 18:41:20 +0200 Subject: [PATCH 11/16] #536: Added missing curly braces. --- .../java/org/itsallcode/openfasttrace/api/FilterSettings.java | 3 ++- .../java/org/itsallcode/openfasttrace/api/core/Location.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java b/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java index 14312c58d..78c9812f0 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java @@ -88,8 +88,9 @@ public int hashCode() @Override public boolean equals(final Object other) { - if (!(other instanceof final FilterSettings that)) + if (!(other instanceof final FilterSettings that)) { return false; + } return withoutTags == that.withoutTags && Objects.equals(artifactTypes, that.artifactTypes) && Objects.equals(tags, that.tags); } diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/core/Location.java b/api/src/main/java/org/itsallcode/openfasttrace/api/core/Location.java index 8b56b3a7d..3103c1e70 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/core/Location.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/core/Location.java @@ -119,8 +119,9 @@ public int hashCode() @Override public boolean equals(final Object other) { - if (!(other instanceof final Location location)) + if (!(other instanceof final Location location)) { return false; + } return line == location.line && column == location.column && Objects.equals(path, location.path); } From 07636a5ef68f3daf722d8815b6779b5fda107991 Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Thu, 4 Jun 2026 19:45:54 +0200 Subject: [PATCH 12/16] #536: Fixed some more Sonar findings. --- .../org/itsallcode/openfasttrace/core/cli/CliArguments.java | 2 +- .../openfasttrace/core/cli/commands/TraceCommand.java | 2 +- .../itsallcode/openfasttrace/core/cli/TestCliArguments.java | 6 +++--- .../itsallcode/openfasttrace/importer/tag/LineReader.java | 3 ++- .../openfasttrace/testutil/xml/StreamWriterDelegate.java | 6 +++--- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CliArguments.java b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CliArguments.java index d6a223585..c07678b76 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CliArguments.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/CliArguments.java @@ -401,7 +401,7 @@ public void setT(final String tags) * * @return {@code true} if origin information should be shown in reports. */ - public boolean getShowOrigin() + public boolean isShowOrigin() { return this.showOrigin; } diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/commands/TraceCommand.java b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/commands/TraceCommand.java index 2d3b91dd1..a137b831c 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/cli/commands/TraceCommand.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/cli/commands/TraceCommand.java @@ -68,7 +68,7 @@ private ReportSettings convertCommandLineArgumentsToReportSettings() .outputFormat(this.arguments.getOutputFormat()) // .verbosity(this.arguments.getReportVerbosity()) // .newline(this.arguments.getNewline()) // - .showOrigin(this.arguments.getShowOrigin()) // + .showOrigin(this.arguments.isShowOrigin()) // .colorScheme(this.arguments.getColorScheme()) // .detailsSectionDisplay(this.arguments.getDetailsSectionDisplay()) // .build(); diff --git a/core/src/test/java/org/itsallcode/openfasttrace/core/cli/TestCliArguments.java b/core/src/test/java/org/itsallcode/openfasttrace/core/cli/TestCliArguments.java index 143b18475..c538bf67f 100644 --- a/core/src/test/java/org/itsallcode/openfasttrace/core/cli/TestCliArguments.java +++ b/core/src/test/java/org/itsallcode/openfasttrace/core/cli/TestCliArguments.java @@ -210,7 +210,7 @@ void testSetWantedTagsIncludingNone() @Test void testShowOriginDisabledByDefault() { - assertThat(this.arguments.getShowOrigin(), is(false)); + assertThat(this.arguments.isShowOrigin(), is(false)); } // [utest->dsn~reporting.plain-text.specification-item-origin~1]] @@ -221,7 +221,7 @@ void testShowOriginDisabledByDefault() void testSetShowOrigin() { this.arguments.setShowOrigin(true); - assertThat(this.arguments.getShowOrigin(), is(true)); + assertThat(this.arguments.isShowOrigin(), is(true)); } // [utest->dsn~reporting.plain-text.specification-item-origin~1]] @@ -232,7 +232,7 @@ void testSetShowOrigin() void testSetS() { this.arguments.setS(true); - assertThat(this.arguments.getShowOrigin(), is(true)); + assertThat(this.arguments.isShowOrigin(), is(true)); } // [utest->dsn~reporting.plain-text.ansi-color~1] diff --git a/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/LineReader.java b/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/LineReader.java index a8d101605..535268f05 100644 --- a/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/LineReader.java +++ b/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/LineReader.java @@ -39,6 +39,7 @@ void readLines(final LineConsumer consumer) } } + @SuppressWarnings("java:S2221") // Catching Exception is intentional. private void processLine(final LineConsumer consumer, final int currentLineNumber, final String line) { @@ -49,7 +50,7 @@ private void processLine(final LineConsumer consumer, final int currentLineNumbe catch (final Exception exception) { throw new ImporterException("Error processing line " + this.file.getPath() + ":" - + currentLineNumber + " '" + line + "': " + exception.toString(), exception); + + currentLineNumber + " '" + line + "': " + exception, exception); } } diff --git a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/xml/StreamWriterDelegate.java b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/xml/StreamWriterDelegate.java index c1f7da2ee..edb878c12 100644 --- a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/xml/StreamWriterDelegate.java +++ b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/xml/StreamWriterDelegate.java @@ -10,6 +10,9 @@ */ public abstract class StreamWriterDelegate implements XMLStreamWriter { + /** Stream writer to delegate to. */ + protected XMLStreamWriter out; + /** * Creates a new instance of the delegate. * @@ -21,9 +24,6 @@ protected StreamWriterDelegate(final XMLStreamWriter out) this.out = out; } - /** Stream writer to delegate to. */ - protected XMLStreamWriter out; - @Override public Object getProperty(final String name) { From 22ef28e9feb8a50e57ad857036e5901658a5cfd4 Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Fri, 5 Jun 2026 17:28:30 +0200 Subject: [PATCH 13/16] #536: Added suppression for S4968 when Hamcrest Matcher requires generic wildcard parameter in AbstractLightWeightMarkupImporterTest. --- .../AbstractLightWeightMarkupImporterTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/importer/lightweightmarkup/AbstractLightWeightMarkupImporterTest.java b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/importer/lightweightmarkup/AbstractLightWeightMarkupImporterTest.java index f5faf8aee..2a3ef50c5 100644 --- a/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/importer/lightweightmarkup/AbstractLightWeightMarkupImporterTest.java +++ b/testutil/src/main/java/org/itsallcode/openfasttrace/testutil/importer/lightweightmarkup/AbstractLightWeightMarkupImporterTest.java @@ -79,6 +79,7 @@ void testRequirementIdDetected(final String markdownId, final String expectedArt * @param matcher * matcher to verify the imported specification items */ + @SuppressWarnings("java:S4968") // Match type definition comes from Hamcrest. Cannot change. protected void assertImport(final String path, final String input, final Matcher> matcher) { @@ -95,6 +96,7 @@ protected void assertImport(final String path, final String input, * @param matcher * matcher to verify the imported specification items */ + @SuppressWarnings("java:S4968") // Match type definition comes from Hamcrest. Cannot change. protected void assertImport(final Path path, final String input, final Matcher> matcher) { From c486d37134b4e6f58261c48497916a901498a5a3 Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Fri, 5 Jun 2026 20:42:42 +0200 Subject: [PATCH 14/16] #536: Removed redundant unmodifiable wrappers for collections. The builders do it already. --- .../openfasttrace/api/FilterSettings.java | 4 ++-- .../openfasttrace/api/core/SpecificationItem.java | 14 +++++++------- .../itsallcode/openfasttrace/api/core/Trace.java | 4 ++-- .../openfasttrace/api/importer/ImportSettings.java | 8 +++----- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java b/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java index 78c9812f0..b282ac9e2 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java @@ -27,7 +27,7 @@ private FilterSettings(final Builder builder) */ public Set getArtifactTypes() { - return Collections.unmodifiableSet(this.artifactTypes); + return this.artifactTypes; } /** @@ -37,7 +37,7 @@ public Set getArtifactTypes() */ public Set getTags() { - return Collections.unmodifiableSet(this.tags); + return this.tags; } /** diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/core/SpecificationItem.java b/api/src/main/java/org/itsallcode/openfasttrace/api/core/SpecificationItem.java index 42c66cc0e..9561bb78a 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/core/SpecificationItem.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/core/SpecificationItem.java @@ -31,10 +31,10 @@ private SpecificationItem(final Builder builder) this.comment = builder.comment; this.location = builder.location; this.status = builder.status; - this.coveredIds = builder.coveredIds; - this.dependOnIds = builder.dependOnIds; - this.needsArtifactTypes = builder.neededArtifactTypes; - this.tags = builder.tags; + this.coveredIds = Collections.unmodifiableList(builder.coveredIds); + this.dependOnIds = Collections.unmodifiableList(builder.dependOnIds); + this.needsArtifactTypes = Collections.unmodifiableList(builder.neededArtifactTypes); + this.tags = Collections.unmodifiableList(builder.tags); this.forwards = builder.forwards; } @@ -141,7 +141,7 @@ public List getCoveredIds() */ public List getDependOnIds() { - return Collections.unmodifiableList(this.dependOnIds); + return this.dependOnIds; } /** @@ -152,7 +152,7 @@ public List getDependOnIds() */ public List getNeedsArtifactTypes() { - return Collections.unmodifiableList(this.needsArtifactTypes); + return this.needsArtifactTypes; } /** @@ -206,7 +206,7 @@ public ItemStatus getStatus() */ public List getTags() { - return Collections.unmodifiableList(this.tags); + return this.tags; } /** diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/core/Trace.java b/api/src/main/java/org/itsallcode/openfasttrace/api/core/Trace.java index 4f70e3a74..e8928d082 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/core/Trace.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/core/Trace.java @@ -36,7 +36,7 @@ public boolean hasNoDefects() */ public List getDefectItems() { - return Collections.unmodifiableList(this.defectItems); + return this.defectItems; } /** @@ -46,7 +46,7 @@ public List getDefectItems() */ public List getItems() { - return Collections.unmodifiableList(this.items); + return this.items; } /** diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImportSettings.java b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImportSettings.java index 91cf107fa..4f8a3f4eb 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImportSettings.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImportSettings.java @@ -2,6 +2,7 @@ import java.nio.file.Path; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -52,7 +53,7 @@ public FilterSettings getFilters() */ public List getPathConfigs() { - return Collections.unmodifiableList(this.pathConfigs); + return this.pathConfigs; } /** @@ -110,10 +111,7 @@ public Builder addInputs(final List inputs) */ public Builder addInputs(final Path... inputs) { - for (final Path input : inputs) - { - this.inputs.add(input); - } + this.inputs.addAll(Arrays.asList(inputs)); return this; } From f3ed0b84879818d93f98d0c3add534ac7906598e Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Sat, 6 Jun 2026 12:53:53 +0200 Subject: [PATCH 15/16] #536: Fixed review findings of @kaklakariada. --- .../org/itsallcode/openfasttrace/api/FilterSettings.java | 8 +++++--- .../openfasttrace/api/importer/ImportSettings.java | 8 ++++---- .../api/importer/tag/config/DescribedPathMatcher.java | 2 +- .../java/org/itsallcode/openfasttrace/core/Linker.java | 1 - .../openfasttrace/core/report/ReportService.java | 5 +++-- .../core/serviceloader/ChildFirstClassLoader.java | 8 +++++--- .../openfasttrace/core/importer/TestImporterService.java | 2 -- .../itsallcode/openfasttrace/importer/tag/LineReader.java | 3 +-- 8 files changed, 19 insertions(+), 18 deletions(-) diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java b/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java index b282ac9e2..1e24d1123 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java @@ -3,6 +3,7 @@ import java.util.Collections; import java.util.Objects; import java.util.Set; +import org.jetbrains.annotations.Unmodifiable; /** * Settings for import filtering @@ -25,7 +26,7 @@ private FilterSettings(final Builder builder) * * @return artifact types that must be matched */ - public Set getArtifactTypes() + public getArtifactTypes() { return this.artifactTypes; } @@ -35,6 +36,7 @@ public Set getArtifactTypes() * * @return artifact types that must be matched */ + public Set getTags() { return this.tags; @@ -139,7 +141,7 @@ private Builder() */ public Builder artifactTypes(final Set artifactTypes) { - this.artifactTypes = Collections.unmodifiableSet(artifactTypes); + this.artifactTypes = Set.copyOf(artifactTypes); return this; } @@ -152,7 +154,7 @@ public Builder artifactTypes(final Set artifactTypes) */ public Builder tags(final Set tags) { - this.tags = Collections.unmodifiableSet(tags); + this.tags = Set.copyOf(tags); return this; } diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImportSettings.java b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImportSettings.java index 4f8a3f4eb..58d690bfb 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImportSettings.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/ImportSettings.java @@ -20,9 +20,9 @@ public final class ImportSettings private ImportSettings(final Builder builder) { - this.inputs = builder.inputs; + this.inputs = Collections.unmodifiableList(builder.inputs); this.filter = builder.filter; - this.pathConfigs = builder.pathConfigs; + this.pathConfigs = Collections.unmodifiableList(builder.pathConfigs); } /** @@ -32,7 +32,7 @@ private ImportSettings(final Builder builder) */ public List getInputs() { - return Collections.unmodifiableList(this.inputs); + return this.inputs; } /** @@ -57,7 +57,7 @@ public List getPathConfigs() } /** - * Create a the default import settings + * Create the default import settings * * @return default import settings */ diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/tag/config/DescribedPathMatcher.java b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/tag/config/DescribedPathMatcher.java index b9c4f583a..0df802bc0 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/importer/tag/config/DescribedPathMatcher.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/importer/tag/config/DescribedPathMatcher.java @@ -95,7 +95,7 @@ private static class ListBasedPathMatcher implements PathMatcher public ListBasedPathMatcher(final Set paths) { - this.paths = Collections.unmodifiableSet(paths); + this.paths = Set.copyOf(paths); } @Override diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/Linker.java b/core/src/main/java/org/itsallcode/openfasttrace/core/Linker.java index bf20bcc0a..943eba552 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/Linker.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/Linker.java @@ -46,7 +46,6 @@ private static List wrapItems(final Listdsn~tracing.needed-coverage-status~1] public List link() { - for (final LinkedSpecificationItem linkedItem : this.linkedItems) { linkItem(linkedItem); diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/report/ReportService.java b/core/src/main/java/org/itsallcode/openfasttrace/core/report/ReportService.java index 6ac089164..b3307fc78 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/report/ReportService.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/report/ReportService.java @@ -92,8 +92,9 @@ private void reportTraceToStream(final Trace trace, final OutputStream outputStr } catch (final IOException exception) { - LOGGER.log(Level.SEVERE, "Failed to flush report output stream", exception); - throw new ReportException(exception.getMessage()); + final String MESSAGE = "Failed to flush report output stream"; + LOGGER.log(Level.SEVERE, MESSAGE, exception); + throw new ReportException(MESSAGE + exception.getMessage()); } } diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/serviceloader/ChildFirstClassLoader.java b/core/src/main/java/org/itsallcode/openfasttrace/core/serviceloader/ChildFirstClassLoader.java index 5ae3ed4cc..663542f56 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/serviceloader/ChildFirstClassLoader.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/serviceloader/ChildFirstClassLoader.java @@ -48,6 +48,7 @@ private Class findClass(final String name, final boolean resolve) throws Clas return loadClassInternally(name, resolve); } + @SuppressWarnings("java:S3032") // Intentionally accessing non-standard classloader private Class loadClassInternally(final String name, final boolean resolve) throws ClassNotFoundException { try @@ -57,10 +58,11 @@ private Class loadClassInternally(final String name, final boolean resolve) t } catch (final ClassNotFoundException ignore) { - LOGGER.log(Level.FINEST, () -> "Unable to find class " + name + " with child logger." - + "Falling back to parent logger"); + LOGGER.log(Level.FINEST, () -> "Unable to find class " + name + " with child classloader '" + + this.getClass().getClassLoader().getName() + "'. " + + "Falling back to parent classloader '" + super.getClass().getClassLoader().getName() + "'."); // Class does not exist in the given URLs. - // Let's try finding it in our parent classloader. + // Let's try finding it in our parent class's classloader. // This will throw ClassNotFoundException on failure. return super.loadClass(name, resolve); } diff --git a/core/src/test/java/org/itsallcode/openfasttrace/core/importer/TestImporterService.java b/core/src/test/java/org/itsallcode/openfasttrace/core/importer/TestImporterService.java index 4e5fe027a..0047f4a7c 100644 --- a/core/src/test/java/org/itsallcode/openfasttrace/core/importer/TestImporterService.java +++ b/core/src/test/java/org/itsallcode/openfasttrace/core/importer/TestImporterService.java @@ -77,11 +77,9 @@ void testImportUnix() private void runImporter() { final List result = this.importerService.importFile(this.file); - verify(this.importerMock).runImport(); verify(this.importerFactoryMock).createImporter(this.fileArg.capture(), this.builderArg.capture()); - final SpecificationListBuilder builder = this.builderArg.getValue(); assertThat(result, equalTo(builder.build())); } diff --git a/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/LineReader.java b/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/LineReader.java index 535268f05..0591511da 100644 --- a/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/LineReader.java +++ b/importer/tag/src/main/java/org/itsallcode/openfasttrace/importer/tag/LineReader.java @@ -39,7 +39,6 @@ void readLines(final LineConsumer consumer) } } - @SuppressWarnings("java:S2221") // Catching Exception is intentional. private void processLine(final LineConsumer consumer, final int currentLineNumber, final String line) { @@ -47,7 +46,7 @@ private void processLine(final LineConsumer consumer, final int currentLineNumbe { consumer.readLine(currentLineNumber, line); } - catch (final Exception exception) + catch (final RuntimeException exception) { throw new ImporterException("Error processing line " + this.file.getPath() + ":" + currentLineNumber + " '" + line + "': " + exception, exception); From c34e8c8fc9fa87119a16ec587d648351e7fffd72 Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Sat, 6 Jun 2026 12:57:50 +0200 Subject: [PATCH 16/16] #536: Added missing method return type. --- .../java/org/itsallcode/openfasttrace/api/FilterSettings.java | 3 +-- .../core/serviceloader/ChildFirstClassLoader.java | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java b/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java index 1e24d1123..a79d1eda9 100644 --- a/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java +++ b/api/src/main/java/org/itsallcode/openfasttrace/api/FilterSettings.java @@ -3,7 +3,6 @@ import java.util.Collections; import java.util.Objects; import java.util.Set; -import org.jetbrains.annotations.Unmodifiable; /** * Settings for import filtering @@ -26,7 +25,7 @@ private FilterSettings(final Builder builder) * * @return artifact types that must be matched */ - public getArtifactTypes() + public Set getArtifactTypes() { return this.artifactTypes; } diff --git a/core/src/main/java/org/itsallcode/openfasttrace/core/serviceloader/ChildFirstClassLoader.java b/core/src/main/java/org/itsallcode/openfasttrace/core/serviceloader/ChildFirstClassLoader.java index 663542f56..3330b8447 100644 --- a/core/src/main/java/org/itsallcode/openfasttrace/core/serviceloader/ChildFirstClassLoader.java +++ b/core/src/main/java/org/itsallcode/openfasttrace/core/serviceloader/ChildFirstClassLoader.java @@ -14,7 +14,9 @@ * included with OFT. *

* This is based on - * https://medium.com/@isuru89/java-a-child-first-class-loader-cbd9c3d0305 + * + * "Java: A Child First Class Loader" by Isuru Weerarathna + * *

*/ class ChildFirstClassLoader extends URLClassLoader