From 0920baefea04ba861831547851712af0908f6adc Mon Sep 17 00:00:00 2001 From: Ulli Hafner Date: Thu, 19 Sep 2024 12:30:42 +0200 Subject: [PATCH 1/7] Switch the java version to 17. --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index a9c79c4f..6c6ff6bf 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ edu.hm.hafner codingstyle - 4.14.0-SNAPSHOT + 5.0.0-SNAPSHOT jar Java coding style @@ -56,7 +56,7 @@ UTF-8 ${source.encoding} - 11 + 17 ${project.groupId}.codingstyle From 0008cd4eeca9abfe6b5c583de807cb33f5c8bae8 Mon Sep 17 00:00:00 2001 From: Ulli Hafner Date: Thu, 19 Sep 2024 12:30:42 +0200 Subject: [PATCH 2/7] Switch the java version to 17. --- README.md | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3f431abd..c80f9c09 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ static analysis tools via Maven (and partly in IntelliJ): - [SpotBugs](https://spotbugs.github.io) - [Error Prone](https://errorprone.info) -❗This project requires a JDK version of 11 or higher.❗ +❗This project requires a JDK version of 17 or higher.❗ Moreover, this project provides some sample classes that already use this style guide. These classes can be used as such but are not required in this project. These classes also use some additional libraries that are included diff --git a/pom.xml b/pom.xml index 6c6ff6bf..dabf7a15 100644 --- a/pom.xml +++ b/pom.xml @@ -336,7 +336,7 @@ - 11 + 17 From e7acb470d8b14147d58bf52b4b10a70834d2b172 Mon Sep 17 00:00:00 2001 From: Ulli Hafner Date: Thu, 19 Sep 2024 13:21:25 +0200 Subject: [PATCH 3/7] Apply OpenRewrite Java 17 migration. --- pom.xml | 3 +-- src/main/java/edu/hm/hafner/util/Ensure.java | 6 +++--- src/main/java/edu/hm/hafner/util/FilteredLog.java | 4 ++-- src/main/java/edu/hm/hafner/util/LineRangeList.java | 4 +--- src/main/java/edu/hm/hafner/util/LookaheadStream.java | 2 +- src/main/java/edu/hm/hafner/util/PrefixLogger.java | 4 ++-- .../java/edu/hm/hafner/util/SecureXmlParserFactory.java | 6 +++--- src/test/java/edu/hm/hafner/util/ArchitectureRules.java | 2 +- 8 files changed, 14 insertions(+), 17 deletions(-) diff --git a/pom.xml b/pom.xml index dabf7a15..1e94986b 100644 --- a/pom.xml +++ b/pom.xml @@ -282,8 +282,7 @@ org.openrewrite.staticanalysis.MissingOverrideAnnotation org.openrewrite.staticanalysis.CommonStaticAnalysis org.openrewrite.staticanalysis.RemoveExtraSemicolons - org.openrewrite.java.migrate.Java8toJava11 - org.openrewrite.java.RemoveUnusedImports + org.openrewrite.java.migrate.UpgradeToJava17 org.openrewrite.java.migrate.util.SequencedCollection org.openrewrite.java.migrate.lang.var.UseVarForObject org.openrewrite.java.format.RemoveTrailingWhitespace diff --git a/src/main/java/edu/hm/hafner/util/Ensure.java b/src/main/java/edu/hm/hafner/util/Ensure.java index 4f472219..0cd34bfe 100644 --- a/src/main/java/edu/hm/hafner/util/Ensure.java +++ b/src/main/java/edu/hm/hafner/util/Ensure.java @@ -168,7 +168,7 @@ public static void thatStatementIsNeverReached(final String explanation, final O */ @FormatMethod private static void throwException(final String message, @CheckForNull final Object... args) { - throw new AssertionError(String.format(message, args)); + throw new AssertionError(message.formatted(args)); } /** @@ -185,7 +185,7 @@ private static void throwException(final String message, @CheckForNull final Obj */ @FormatMethod private static void throwNullPointerException(final String message, final Object... args) { - throw new NullPointerException(String.format(message, args)); // NOPMD + throw new NullPointerException(message.formatted(args)); // NOPMD } private Ensure() { @@ -764,7 +764,7 @@ public ExceptionCondition(@CheckForNull final Throwable value) { */ @FormatMethod public void isNeverThrown(final String explanation, final Object... args) { - throw new AssertionError(String.format(explanation, args), value); + throw new AssertionError(explanation.formatted(args), value); } } } diff --git a/src/main/java/edu/hm/hafner/util/FilteredLog.java b/src/main/java/edu/hm/hafner/util/FilteredLog.java index 9b9691e3..f038c31e 100644 --- a/src/main/java/edu/hm/hafner/util/FilteredLog.java +++ b/src/main/java/edu/hm/hafner/util/FilteredLog.java @@ -105,7 +105,7 @@ public void logInfo(final String message) { */ @FormatMethod public void logInfo(final String format, final Object... args) { - logInfo(String.format(format, args)); + logInfo(format.formatted(args)); } /** @@ -142,7 +142,7 @@ public void logError(final String message) { */ @FormatMethod public void logError(final String format, final Object... args) { - logError(String.format(format, args)); + logError(format.formatted(args)); } /** diff --git a/src/main/java/edu/hm/hafner/util/LineRangeList.java b/src/main/java/edu/hm/hafner/util/LineRangeList.java index eb0b8789..ee5b199a 100644 --- a/src/main/java/edu/hm/hafner/util/LineRangeList.java +++ b/src/main/java/edu/hm/hafner/util/LineRangeList.java @@ -133,9 +133,7 @@ private void ensure(final int n) { @Override public boolean contains(final Object o) { - if (o instanceof LineRange) { - var other = (LineRange) o; - + if (o instanceof final LineRange other) { for (var cursor = new Cursor(); cursor.hasNext();) { if (cursor.compare(other)) { return true; diff --git a/src/main/java/edu/hm/hafner/util/LookaheadStream.java b/src/main/java/edu/hm/hafner/util/LookaheadStream.java index 3c3113d3..afc96318 100644 --- a/src/main/java/edu/hm/hafner/util/LookaheadStream.java +++ b/src/main/java/edu/hm/hafner/util/LookaheadStream.java @@ -132,6 +132,6 @@ public int getLine() { @Override @Generated public String toString() { - return String.format("[%d] -> '%s'", line, lookaheadLine); + return "[%d] -> '%s'".formatted(line, lookaheadLine); } } diff --git a/src/main/java/edu/hm/hafner/util/PrefixLogger.java b/src/main/java/edu/hm/hafner/util/PrefixLogger.java index 92fae5f3..1edfc6f1 100644 --- a/src/main/java/edu/hm/hafner/util/PrefixLogger.java +++ b/src/main/java/edu/hm/hafner/util/PrefixLogger.java @@ -27,7 +27,7 @@ public PrefixLogger(final PrintStream logger, final String prefix) { this.toolName = prefix + " "; } else { - this.toolName = String.format("[%s] ", prefix); + this.toolName = "[%s] ".formatted(prefix); } delegate = logger; } @@ -44,7 +44,7 @@ public PrefixLogger(final PrintStream logger, final String prefix) { */ @FormatMethod public void log(final String format, final Object... args) { - print(String.format(format, args)); + print(format.formatted(args)); } /** diff --git a/src/main/java/edu/hm/hafner/util/SecureXmlParserFactory.java b/src/main/java/edu/hm/hafner/util/SecureXmlParserFactory.java index 133f1ee0..c54e54e2 100644 --- a/src/main/java/edu/hm/hafner/util/SecureXmlParserFactory.java +++ b/src/main/java/edu/hm/hafner/util/SecureXmlParserFactory.java @@ -368,7 +368,7 @@ public ParsingException(final Throwable cause) { */ @FormatMethod public ParsingException(final String messageFormat, final Object... args) { - super(String.format(messageFormat, args)); + super(messageFormat.formatted(args)); } /** @@ -388,11 +388,11 @@ public ParsingException(final String messageFormat, final Object... args) { */ @FormatMethod public ParsingException(final Throwable cause, final String messageFormat, final Object... args) { - super(createMessage(cause, String.format(messageFormat, args)), cause); + super(createMessage(cause, messageFormat.formatted(args)), cause); } private static String createMessage(final Throwable cause, final String message) { - return String.format("%s%n%s%n%s", message, + return "%s%n%s%n%s".formatted(message, ExceptionUtils.getMessage(cause), ExceptionUtils.getStackTrace(cause)); } } diff --git a/src/test/java/edu/hm/hafner/util/ArchitectureRules.java b/src/test/java/edu/hm/hafner/util/ArchitectureRules.java index 67b12e55..fb15f466 100644 --- a/src/test/java/edu/hm/hafner/util/ArchitectureRules.java +++ b/src/test/java/edu/hm/hafner/util/ArchitectureRules.java @@ -214,7 +214,7 @@ public void check(final JavaMethod method, final ConditionEvents events) { return; } events.add(SimpleConditionEvent.violated(method, - String.format("%s is not protected but the class might be extended in %s", + "%s is not protected but the class might be extended in %s".formatted( method.getDescription(), method.getSourceCodeLocation()))); } } From b6a282f051a1a38b1e20aeee84deaee9b3dcf5f1 Mon Sep 17 00:00:00 2001 From: Ulli Hafner Date: Thu, 19 Sep 2024 14:51:06 +0200 Subject: [PATCH 4/7] Apply additional OpenRewrite Java migrations. --- pom.xml | 6 ++++++ src/test/java/edu/hm/hafner/util/PrefixLoggerTest.java | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 1e94986b..8f0ad62d 100644 --- a/pom.xml +++ b/pom.xml @@ -275,16 +275,22 @@ **/docker/** **/AbstractComparableTest.java + **/AbstractEqualsTest.java + **/EnsureTest.java **/ResourceExtractorTest.java org.openrewrite.maven.BestPractices + org.openrewrite.maven.RemoveRedundantDependencyVersions org.openrewrite.staticanalysis.MissingOverrideAnnotation org.openrewrite.staticanalysis.CommonStaticAnalysis org.openrewrite.staticanalysis.RemoveExtraSemicolons org.openrewrite.java.migrate.UpgradeToJava17 org.openrewrite.java.migrate.util.SequencedCollection org.openrewrite.java.migrate.lang.var.UseVarForObject + org.openrewrite.java.migrate.net.JavaNetAPIs + org.openrewrite.java.migrate.util.JavaUtilAPIs + org.openrewrite.java.migrate.lang.StringRulesRecipes org.openrewrite.java.format.RemoveTrailingWhitespace org.openrewrite.java.format.BlankLines org.openrewrite.java.format.EmptyNewlineAtEndOfFile diff --git a/src/test/java/edu/hm/hafner/util/PrefixLoggerTest.java b/src/test/java/edu/hm/hafner/util/PrefixLoggerTest.java index ec4848bc..eb39afee 100644 --- a/src/test/java/edu/hm/hafner/util/PrefixLoggerTest.java +++ b/src/test/java/edu/hm/hafner/util/PrefixLoggerTest.java @@ -1,11 +1,12 @@ package edu.hm.hafner.util; import java.io.PrintStream; +import java.util.List; import org.junit.jupiter.api.Test; import static java.util.Arrays.*; -import static java.util.Collections.*; +import static java.util.Collections.emptyList; import static org.mockito.Mockito.*; /** @@ -39,7 +40,7 @@ void shouldLogSingleAndMultipleLines() { verifyNoMoreInteractions(printStream); - logger.logEachLine(singletonList(FIRST_MESSAGE)); + logger.logEachLine(List.of(FIRST_MESSAGE)); verify(printStream).println(EXPECTED_TOOL_PREFIX + " " + FIRST_MESSAGE); From 0eb5823f15b9ae3f1377b6a306bf575cbc5be192 Mon Sep 17 00:00:00 2001 From: Ulli Hafner Date: Sat, 26 Oct 2024 18:02:34 +0200 Subject: [PATCH 5/7] Add `@Serial` annotation. --- pom.xml | 20 +++++++++++++++++-- .../java/edu/hm/hafner/util/FilteredLog.java | 2 ++ .../java/edu/hm/hafner/util/LineRange.java | 2 ++ .../edu/hm/hafner/util/LineRangeList.java | 2 ++ .../java/edu/hm/hafner/util/TreeString.java | 2 ++ 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 46a2137d..7d3d1939 100644 --- a/pom.xml +++ b/pom.xml @@ -91,7 +91,7 @@ 3.4.2 3.25.0 7.6.0 - 3.5.0 + 3.6.0 10.18.2 4.8.6.4 1.13.0 @@ -384,7 +384,9 @@ org.openrewrite.maven.BestPractices org.openrewrite.maven.RemoveRedundantDependencyVersions + org.openrewrite.staticanalysis.AddSerialAnnotationToSerialVersionUID org.openrewrite.staticanalysis.MissingOverrideAnnotation + org.openrewrite.staticanalysis.CodeCleanup org.openrewrite.staticanalysis.CommonStaticAnalysis org.openrewrite.staticanalysis.RemoveExtraSemicolons org.openrewrite.java.migrate.UpgradeToJava17 @@ -503,6 +505,8 @@ check + verify + @@ -680,7 +684,7 @@ - 17 + ${java.version} @@ -890,6 +894,17 @@ + + org.apache.maven.plugins + maven-dependency-plugin + + + + properties + + + + org.apache.maven.plugins maven-surefire-plugin @@ -900,6 +915,7 @@ **/*ITest.* **/*ArchitectureRulesTest$* + @{argLine} -javaagent:${org.mockito:mockito-core:jar} diff --git a/src/main/java/edu/hm/hafner/util/FilteredLog.java b/src/main/java/edu/hm/hafner/util/FilteredLog.java index f038c31e..7a344e03 100644 --- a/src/main/java/edu/hm/hafner/util/FilteredLog.java +++ b/src/main/java/edu/hm/hafner/util/FilteredLog.java @@ -1,5 +1,6 @@ package edu.hm.hafner.util; +import java.io.Serial; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; @@ -21,6 +22,7 @@ * @author Ullrich Hafner */ public class FilteredLog implements Serializable { + @Serial private static final long serialVersionUID = -8552323621953159904L; private static final int DEFAULT_MAX_LINES = 20; diff --git a/src/main/java/edu/hm/hafner/util/LineRange.java b/src/main/java/edu/hm/hafner/util/LineRange.java index f9130eba..61a46314 100644 --- a/src/main/java/edu/hm/hafner/util/LineRange.java +++ b/src/main/java/edu/hm/hafner/util/LineRange.java @@ -1,5 +1,6 @@ package edu.hm.hafner.util; +import java.io.Serial; import java.io.Serializable; import java.util.Locale; import java.util.NavigableSet; @@ -12,6 +13,7 @@ * @author Ullrich Hafner */ public final class LineRange implements Serializable { + @Serial private static final long serialVersionUID = -4124143085672930110L; private final int start; diff --git a/src/main/java/edu/hm/hafner/util/LineRangeList.java b/src/main/java/edu/hm/hafner/util/LineRangeList.java index ee5b199a..342c599f 100644 --- a/src/main/java/edu/hm/hafner/util/LineRangeList.java +++ b/src/main/java/edu/hm/hafner/util/LineRangeList.java @@ -1,5 +1,6 @@ package edu.hm.hafner.util; +import java.io.Serial; import java.io.Serializable; import java.util.AbstractList; import java.util.Arrays; @@ -35,6 +36,7 @@ * @author Kohsuke Kawaguchi */ public class LineRangeList extends AbstractList implements Serializable { + @Serial private static final long serialVersionUID = -1123973098942984623L; private static final int DEFAULT_CAPACITY = 16; private static final boolean SEQUENTIAL = false; diff --git a/src/main/java/edu/hm/hafner/util/TreeString.java b/src/main/java/edu/hm/hafner/util/TreeString.java index 9a5dfd4b..f5409047 100644 --- a/src/main/java/edu/hm/hafner/util/TreeString.java +++ b/src/main/java/edu/hm/hafner/util/TreeString.java @@ -1,5 +1,6 @@ package edu.hm.hafner.util; +import java.io.Serial; import java.io.Serializable; import java.util.Map; @@ -18,6 +19,7 @@ * @author Kohsuke Kawaguchi */ public final class TreeString implements Serializable { + @Serial private static final long serialVersionUID = 3621959682117480904L; /** Parent node that represents the prefix. */ From 3a6a988c62816c75296a31e57ef1b132073ed1d0 Mon Sep 17 00:00:00 2001 From: Ulli Hafner Date: Sat, 26 Oct 2024 18:09:19 +0200 Subject: [PATCH 6/7] Simplify lambda expressions. --- .../java/edu/hm/hafner/util/EnsureTest.java | 62 ++++++++----------- 1 file changed, 25 insertions(+), 37 deletions(-) diff --git a/src/test/java/edu/hm/hafner/util/EnsureTest.java b/src/test/java/edu/hm/hafner/util/EnsureTest.java index e480b356..4a87a526 100644 --- a/src/test/java/edu/hm/hafner/util/EnsureTest.java +++ b/src/test/java/edu/hm/hafner/util/EnsureTest.java @@ -87,44 +87,32 @@ void shouldThrowExceptionIfContractIsViolated() { /** * Checks whether we throw an exception if a contract is violated. */ - @Test + @Test @SuppressWarnings("NullAway") void shouldThrowNpeIfContractIsViolated() { - assertThatThrownBy(() -> { - Ensure.that((Object)null).isNotNull(ERROR_MESSAGE); - }).isInstanceOf(NullPointerException.class).hasMessage(ERROR_MESSAGE); - assertThatThrownBy(() -> { - Ensure.that(SOME_STRING, (Object)null).isNotNull(ERROR_MESSAGE); - }).isInstanceOf(NullPointerException.class).hasMessage(ERROR_MESSAGE); - assertThatThrownBy(() -> { - Ensure.that(null, SOME_STRING).isNotNull(ERROR_MESSAGE); - }).isInstanceOf(NullPointerException.class).hasMessage(ERROR_MESSAGE); - assertThatThrownBy(() -> { - Ensure.that(null, (Object[]) null).isNotNull(ERROR_MESSAGE); - }).isInstanceOf(NullPointerException.class).hasMessage(ERROR_MESSAGE); - assertThatThrownBy(() -> { - Ensure.that((Object)null).isNotNull(); - }).isInstanceOf(NullPointerException.class); - assertThatThrownBy(() -> { - Ensure.that(SOME_STRING, (Object)null).isNotNull(); - }).isInstanceOf(NullPointerException.class); - assertThatThrownBy(() -> { - Ensure.that(null, SOME_STRING).isNotNull(); - }).isInstanceOf(NullPointerException.class); - assertThatThrownBy(() -> { - Ensure.that(null, (Object[]) null).isNotNull(); - }).isInstanceOf(NullPointerException.class); - assertThatThrownBy(() -> { - Ensure.that((Object[])null).isNotEmpty(ERROR_MESSAGE); - }).isInstanceOf(NullPointerException.class).hasMessage(ERROR_MESSAGE); - assertThatThrownBy(() -> { - Ensure.that((String)null).isNotEmpty(ERROR_MESSAGE); - }).isInstanceOf(NullPointerException.class).hasMessage(ERROR_MESSAGE); - assertThatThrownBy(() -> { - Ensure.that((Object[])null).isNotEmpty(); - }).isInstanceOf(NullPointerException.class); - assertThatThrownBy(() -> { - Ensure.that((String)null).isNotEmpty(); - }).isInstanceOf(NullPointerException.class); + assertThatThrownBy(() -> Ensure.that((Object)null).isNotNull(ERROR_MESSAGE)) + .isInstanceOf(NullPointerException.class).hasMessage(ERROR_MESSAGE); + assertThatThrownBy(() -> Ensure.that(SOME_STRING, (Object)null).isNotNull(ERROR_MESSAGE)) + .isInstanceOf(NullPointerException.class).hasMessage(ERROR_MESSAGE); + assertThatThrownBy(() -> Ensure.that(null, SOME_STRING).isNotNull(ERROR_MESSAGE)) + .isInstanceOf(NullPointerException.class).hasMessage(ERROR_MESSAGE); + assertThatThrownBy(() -> Ensure.that(null, (Object[]) null).isNotNull(ERROR_MESSAGE)) + .isInstanceOf(NullPointerException.class).hasMessage(ERROR_MESSAGE); + assertThatThrownBy(() -> Ensure.that((Object)null).isNotNull()) + .isInstanceOf(NullPointerException.class); + assertThatThrownBy(() -> Ensure.that(SOME_STRING, (Object)null).isNotNull()) + .isInstanceOf(NullPointerException.class); + assertThatThrownBy(() -> Ensure.that(null, SOME_STRING).isNotNull()) + .isInstanceOf(NullPointerException.class); + assertThatThrownBy(() -> Ensure.that(null, (Object[]) null).isNotNull()) + .isInstanceOf(NullPointerException.class); + assertThatThrownBy(() -> Ensure.that((Object[])null).isNotEmpty(ERROR_MESSAGE)) + .isInstanceOf(NullPointerException.class).hasMessage(ERROR_MESSAGE); + assertThatThrownBy(() -> Ensure.that((String)null).isNotEmpty(ERROR_MESSAGE)) + .isInstanceOf(NullPointerException.class).hasMessage(ERROR_MESSAGE); + assertThatThrownBy(() -> Ensure.that((Object[])null).isNotEmpty()) + .isInstanceOf(NullPointerException.class); + assertThatThrownBy(() -> Ensure.that((String)null).isNotEmpty()) + .isInstanceOf(NullPointerException.class); } /** From 3e9037e27cb9eb8ddcf2960a862e68e6bcd49c3b Mon Sep 17 00:00:00 2001 From: Ulli Hafner Date: Sat, 26 Oct 2024 18:37:31 +0200 Subject: [PATCH 7/7] Improve coverage of ParsingException. --- README.md | 30 ++++++++----------- .../hafner/util/SecureXmlParserFactory.java | 2 ++ .../util/SecureXmlParserFactoryTest.java | 17 +++++++++++ 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index c80f9c09..c98f0c39 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,12 @@ [![Warnings](https://raw.githubusercontent.com/uhafner/codingstyle/main/badges/style.svg)](https://github.com/uhafner/codingstyle/actions/workflows/quality-monitor.yml) [![Bugs](https://raw.githubusercontent.com/uhafner/codingstyle/main/badges/bugs.svg)](https://github.com/uhafner/codingstyle/actions/workflows/quality-monitor.yml) -Each Java project should follow a given coding style. I.e., all contributions to the source code should use the same -formatting rules, design principles, code patterns, idioms, etc. This coding style provides the set of rules that I -am using in my lectures about software development at Munich University of Applied Sciences. +Each Java project should follow a given coding style. +I.e., all contributions to the source code should use the same formatting rules, design principles, code patterns, idioms, etc. +This coding style provides the set of rules that I am using in my lectures about software development at Munich University of Applied Sciences. This project describes the coding style in detail (currently only available in German) and serves as a template project. -It provides all necessary resources for a Java project to enforce this coding style using the following -static analysis tools via Maven (and partly in IntelliJ): +It provides all necessary resources for a Java project to enforce this coding style using the following static analysis tools via Maven (and partly in IntelliJ): - [Checkstyle](https://checkstyle.org) - [PMD](https://pmd.github.io/) - [SpotBugs](https://spotbugs.github.io) @@ -20,17 +19,14 @@ static analysis tools via Maven (and partly in IntelliJ): ❗This project requires a JDK version of 17 or higher.❗ -Moreover, this project provides some sample classes that already use this style guide. These classes can be used -as such but are not required in this project. These classes also use some additional libraries that are included -using the Maven dependency mechanism. If the sample classes are deleted, then the dependencies can be safely -deleted, too. +Moreover, this project provides some sample classes that already use this style guide. +These classes can be used as such but are not required in this project. +These classes also use some additional libraries that are included using the Maven dependency mechanism. +If the sample classes are deleted, then the dependencies can be safely deleted, too. -This project and the associated static analysis tools are already running in continuous integration: an example -CI pipeline is active for GitHub Actions. For [Jenkins](https://jenkins.io/) a full CI pipeline has been -configured that includes stages to compile, test, run static code analysis, run code coverage analysis, -and run mutation coverage analysis, see section [Continuous Integration](doc/Continuous-Integration.md) for details. -Additionally, some development tools are configured in this GitHub project to evaluate the quality of pull requests, -see section [integration of external tools](doc/Externe-Tool-Integration.md). +This project and the associated static analysis tools are already running in continuous integration: an example CI pipeline is active for GitHub Actions. +For [Jenkins](https://jenkins.io/) a full CI pipeline has been configured that includes stages to compile, test, run static code analysis, run code coverage analysis, and run mutation coverage analysis, see section [Continuous Integration](doc/Continuous-Integration.md) for details. +Additionally, some development tools are configured in this GitHub project to evaluate the quality of pull requests, see section [integration of external tools](doc/Externe-Tool-Integration.md). Content of the style guide (only in German): - [Formatierung](doc/Formatierung.md) @@ -53,9 +49,9 @@ A lot of ideas in this style are based on the following path-breaking books abou - [6] "Refactoring: Improving the Design of Existing Code", Martin Fowler, Addison Wesley, 1999 - [7] "Java by Comparison", Simon Harrer, Jörg Lenhard, Linus Dietz, Pragmatic Programmers, 2018 -All documents in this project use the -[Creative Commons Attribution 4.0 International License](https://creativecommons.org/licenses/by/4.0/). +All documents in this project use the [Creative Commons Attribution 4.0 International License](https://creativecommons.org/licenses/by/4.0/). Source code (snippets, examples, and classes) are using the [MIT license](https://en.wikipedia.org/wiki/MIT_License). [![License: MIT](https://img.shields.io/badge/license-MIT-yellow.svg)](https://en.wikipedia.org/wiki/MIT_License) [![License: CC BY 4.0](https://img.shields.io/badge/License-CC%20BY%204.0-lightgrey.svg)](https://creativecommons.org/licenses/by/4.0/) +![JDK17](https://img.shields.io/badge/jdk-17-blue.svg) diff --git a/src/main/java/edu/hm/hafner/util/SecureXmlParserFactory.java b/src/main/java/edu/hm/hafner/util/SecureXmlParserFactory.java index c54e54e2..a7720335 100644 --- a/src/main/java/edu/hm/hafner/util/SecureXmlParserFactory.java +++ b/src/main/java/edu/hm/hafner/util/SecureXmlParserFactory.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.io.Reader; +import java.io.Serial; import java.nio.charset.Charset; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -341,6 +342,7 @@ TransformerFactory createTransformerFactory() { * Indicates that during parsing a non-recoverable error has been occurred. */ public static class ParsingException extends RuntimeException { + @Serial private static final long serialVersionUID = -9016364685084958944L; /** diff --git a/src/test/java/edu/hm/hafner/util/SecureXmlParserFactoryTest.java b/src/test/java/edu/hm/hafner/util/SecureXmlParserFactoryTest.java index 251013f4..12428b2f 100644 --- a/src/test/java/edu/hm/hafner/util/SecureXmlParserFactoryTest.java +++ b/src/test/java/edu/hm/hafner/util/SecureXmlParserFactoryTest.java @@ -28,6 +28,23 @@ class SecureXmlParserFactoryTest { private static final String EXPECTED_EXCEPTION = "EXPECTED EXCEPTION"; + @Test + void shouldFormatMessage() { + var cause = new IllegalArgumentException("IAE"); + + assertThat(new ParsingException(cause)) + .hasMessageContaining("Exception occurred during parsing") + .hasMessageContaining("IllegalArgumentException: IAE") + .hasCause(cause); + assertThat(new ParsingException(cause, "Message %s, Value: %d", "Hello World", 42)) + .hasMessageContaining("Message Hello World, Value: 42") + .hasMessageContaining("IllegalArgumentException: IAE") + .hasCause(cause); + assertThat(new ParsingException("Message %s, Value: %d", "Hello World", 42)) + .hasMessageContaining("Message Hello World, Value: 42") + .hasNoCause(); + } + @Test void shouldCreateDocumentBuilder() throws ParserConfigurationException { var factory = spy(new SecureXmlParserFactory());