From 162339d485b09c661d5acfd2fdc6b44ba837ae78 Mon Sep 17 00:00:00 2001 From: Philip Helger Date: Wed, 3 Sep 2025 15:30:37 +0200 Subject: [PATCH 01/28] Added Maven Central badge --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index cf6d9f7..49a3257 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # KoSIT Validator +[![Maven Central](https://img.shields.io/maven-central/v/org.kosit/validator)](https://img.shields.io/maven-central/v/org.kosit/validator) + - [Introduction](#introduction) - [Validation Configurations](#validation-configurations) * [Third Party Validation Configurations](#third-party-validation-configurations) From 78e5d3d4ee73291eb1fc2e3ffb7e58fa6e349ace Mon Sep 17 00:00:00 2001 From: Philip Helger Date: Wed, 3 Sep 2025 16:22:22 +0200 Subject: [PATCH 02/28] Added badge, roadmap, contributors and license --- README.md | 73 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 49a3257..208e588 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # KoSIT Validator -[![Maven Central](https://img.shields.io/maven-central/v/org.kosit/validator)](https://img.shields.io/maven-central/v/org.kosit/validator) +[![Maven Central](https://img.shields.io/maven-central/v/org.kosit/validator)](https://central.sonatype.com/artifact/org.kosit/validator) +[![Apache 2.0 license](https://img.shields.io/badge/license-Apache%202-blue)](https://www.apache.org/licenses/LICENSE-2.0) + - [Introduction](#introduction) - [Validation Configurations](#validation-configurations) @@ -13,14 +15,14 @@ ## Introduction -The validator is an XML validation engine to validate and process XML files in various formats. It basically does the following in order: +The Validator is an XML validation engine to validate and process XML files in various formats. It basically does the following in order: 1. identify actual XML format 1. validate the XML file (using schema and schematron rules) 1. generate a custom report / extract custom data from the XML file 1. compute an acceptance status (according the supplied schema and rules) -The validator depends on self defined [scenarios](docs/configurations.md) in order to fully configure the whole process. +The Validator depends on self defined [scenarios](docs/configurations.md) in order to fully configure the whole process. It always creates a [validation report in XML](docs/configurations.md#validators-report). The actual content of the report can also be controlled by the scenario. See [architecture](docs/architecture.md) for information about the whole validation process. @@ -28,7 +30,7 @@ See [architecture](docs/architecture.md) for information about the whole validat ## Validation configurations -The validator is just an engine and does not know anything about XML documents and has no own validation rules. +The Validator is just an engine and does not know anything about XML documents and has no own validation rules. Validation rules and details are defined in [validation scenarios](docs/configurations.md) which are used to fully configure the validation process. All configurations are self-contained modules which are deployed and developed on their own. @@ -45,7 +47,7 @@ Here are two public third party validation configurations available which might ## Usage -The validator can be used in three different ways: +The Validator can be used in three different ways: * as standalone application running from the CLI * as library embedded within a custom application @@ -75,7 +77,7 @@ The [CLI documentation](./docs/cli.md) shows further configuration options. ### Application User Interface (API / embedded usage) -The validator can also be used in own Java Applications via the API. An example use of the API as follows: +The Validator can also be used in own Java Applications via the API. An example use of the API as follows: ```java Path scenarios = Paths.get("scenarios.xml"); @@ -91,8 +93,7 @@ Result validationResult = validator.checkInput(document); The [API documentation](./docs/api.md) shows further configuration options. **Note:** With Java 11+, you need to include a dependency to `org.glassfish.jaxb:jaxb-runtime` in your project explicitly, -as that dependency is marked `optional` in this project and -will thus not be resolved transitively. +as that dependency is marked `optional` in this project and will thus not be resolved transitively. ### Daemon-Mode @@ -107,9 +108,59 @@ The [daemon documentation](./docs/daemon.md) shows more usage details and furthe ## Packages -The validator distribution contains the following artifacts: +The Validator distribution contains the following artifacts: 1. **validator-``.jar**: Java library for embedded use within an application -1. **validator-`-standalone.jar**: Uber-JAR for standalone usage containing all dependencies in one jar file. This file comes with JAXB *embedded* and can be used with Java 8 and Java >= 11) -1. **validator-`-java8-standalone.jar**: Uber-JAR for standalone usage with Java JDK 8 containing all dependencies in one jar file. This file file *does not* contain JAXB and depends on the bundled version of the JDK. +1. **validator-``-standalone.jar**: Uber-JAR for standalone usage containing all dependencies in one jar file. This file comes with JAXB *embedded* and can be used with Java 8 and Java >= 11) +1. **validator-``-java8-standalone.jar**: Uber-JAR for standalone usage with Java JDK 8 containing all dependencies in one jar file. This file file *does not* contain JAXB and depends on the bundled version of the JDK. 1. **libs/***: directory containing all (incl. optional) dependencies of the validator + +## Installation + +The Validator distribution can be publicly download from the following sources: + +* GitHub releases: https://github.com/itplr-kosit/validator/releases + * This release contains a ZIP file with all the different JAR variants +* Maven Central with the below coordinates (replace `x.y.z` with the actual version to use) + +```xml + + org.kosit + validator + x.y.z + +``` + +To use the standalone version with Maven coordinates, add the respective classifier: + +```xml + + org.kosit + validator + x.y.z + standalone + +``` + +## Roadmap + +This section describes the next steps planned in the Validator development. + +* Release version 1.6.0 based on Java 11 and using Jakarta 4.x. - Autumn 2025 + * Drop support of version 1.5.x when version 1.6 is released +* Develop version 2.0.0 which will include major API incompatibilities - Winter 2025 + * Rework scenarios.xml + * Rework report output engine + * Change the output type to [XVRL](https://github.com/xproc/xvrl)-based document types → this implies that existing XSL templates need to be updated + * Consider multi Schematron engine support + * Extract the daemon mode into its own submodule + * Consider extracting the CLI into its own submodule +* The release of version 2.0.0 implies a feature-freeze for version 1.6 + +## Authors & Acknowledgements + +We are thankful to numerous third-party [contributors](https://github.com/itplr-kosit/validator/graphs/contributors). + +## License + +The Validator is licensed under the [Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0). From 52e42fe6dc99e96e8f3298c4158d92fe23eedd56 Mon Sep 17 00:00:00 2001 From: Philip Helger Date: Wed, 3 Sep 2025 16:23:12 +0200 Subject: [PATCH 03/28] Removed ToC --- README.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/README.md b/README.md index 208e588..de3595e 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,6 @@ [![Apache 2.0 license](https://img.shields.io/badge/license-Apache%202-blue)](https://www.apache.org/licenses/LICENSE-2.0) -- [Introduction](#introduction) -- [Validation Configurations](#validation-configurations) - * [Third Party Validation Configurations](#third-party-validation-configurations) -- [Usage](#usage) - * [Standalone Command-Line Interface](#standalone-command-line-interface) - * [Application User Interface (API / embedded usage)](#application-user-interface--api---embedded-usage-) - * [Daemon-Mode](#daemon-mode) -- [Packages](#packages) - ## Introduction The Validator is an XML validation engine to validate and process XML files in various formats. It basically does the following in order: From 93a64223b8d705867794542aab0c459f5c2c6b7a Mon Sep 17 00:00:00 2001 From: Renzo Kottmann Date: Thu, 4 Sep 2025 12:07:23 +0200 Subject: [PATCH 04/28] minor grammar in README.md (cherry picked from commit a96751e08f2b7d95cdd8d47a0a6bfa3b5ef7ef9c) Co-authored-by: Renzo Kottmann --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index de3595e..355550f 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,7 @@ The Validator distribution contains the following artifacts: ## Installation -The Validator distribution can be publicly download from the following sources: +Download from the following sources is possible: * GitHub releases: https://github.com/itplr-kosit/validator/releases * This release contains a ZIP file with all the different JAR variants From 1ed9377b8366b5357658853b050126790ba80a03 Mon Sep 17 00:00:00 2001 From: yunussozeri <124086013+yunussozeri@users.noreply.github.com> Date: Mon, 8 Sep 2025 14:43:51 +0200 Subject: [PATCH 05/28] Update links to source code to current locations The links were old and not redirecting to the correct location --- docs/api.md | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/docs/api.md b/docs/api.md index caa93fe..5e03c85 100644 --- a/docs/api.md +++ b/docs/api.md @@ -92,25 +92,26 @@ public class StandardExample { ``` The `Result` interface has convenience methods to retrieve details about XSD validation errors and Schematron messages and other processing results. See -[Result.java](https://github.com/itplr-kosit/validator/blob/master/src/main/java/de/kosit/validationtool/api/Result.java) for details. +[Result.java](https://github.com/itplr-kosit/validator/blob/main/src/main/java/de/kosit/validationtool/api/Result.java) for details. + Initializing all XML artifacts and XSLT-executables is expensive. The `Check` instance is *threadsafe* and keeps all artifacts. Therefore, we recommend the re-use of a `Check` instance. -Beside the validator's configuration the only input are instances of [Input](https://github.com/itplr-kosit/validator/blob/master/src/main/java/de/kosit/validationtool/api/Input.java) -which can be created by various methods of the [InputFactory](https://github.com/itplr-kosit/validator/blob/master/src/main/java/de/kosit/validationtool/api/InputFactory.java). -The [InputFactory](https://github.com/itplr-kosit/validator/blob/master/src/main/java/de/kosit/validationtool/api/InputFactory.java) +Beside the validator's configuration the only input are instances of [Input](https://github.com/itplr-kosit/validator/blob/main/src/main/java/de/kosit/validationtool/api/Input.java) +which can be created by various methods of the [InputFactory](https://github.com/itplr-kosit/validator/blob/main/src/main/java/de/kosit/validationtool/api/InputFactory.java). +The [InputFactory](https://github.com/itplr-kosit/validator/blob/main/src/main/java/de/kosit/validationtool/api/InputFactory.java) calculates a hash sum for each Input which is also written to the Report. _SHA-256_ from the JDK is the default algorithm. -It can be changed using other `read`-methods of [InputFactory](https://github.com/itplr-kosit/validator/blob/master/src/main/java/de/kosit/validationtool/api/InputFactory.java). +It can be changed using other `read`-methods of [InputFactory](https://github.com/itplr-kosit/validator/blob/main/src/main/java/de/kosit/validationtool/api/InputFactory.java). -The main interface [Check.java](https://github.com/itplr-kosit/validator/blob/master/src/main/java/de/kosit/validationtool/api/Check.java) -allows using a batch interface (processing list of [Inputs](https://github.com/itplr-kosit/validator/blob/master/src/main/java/de/kosit/validationtool/api/Input.java)). +The main interface [Check.java](https://github.com/itplr-kosit/validator/blob/main/src/main/java/de/kosit/validationtool/api/Check.java) +allows using a batch interface (processing list of [Inputs](https://github.com/itplr-kosit/validator/blob/main/src/main/java/de/kosit/validationtool/api/Input.java)). However, there is no parallel processing implemented at the moment. ## Accept Recommendation and Accept Match -A tri-state object [AcceptRecommendation](https://github.com/itplr-kosit/validator/blob/master/src/main/java/de/kosit/validationtool/api/AcceptRecommendation.java) -can be retrieved from the [Result](https://github.com/itplr-kosit/validator/blob/master/src/main/java/de/kosit/validationtool/api/Result.java) using `getAcceptRecommendation()`. +A tri-state object [AcceptRecommendation](https://github.com/itplr-kosit/validator/blob/main/src/main/java/de/kosit/validationtool/api/AcceptRecommendation.java) +can be retrieved from the [Result](https://github.com/itplr-kosit/validator/blob/main/src/main/java/de/kosit/validationtool/api/Result.java) using `getAcceptRecommendation()`. The three defined states are: @@ -195,15 +196,15 @@ When using XML related technologies you are supposed to handle certain security * allows loading/resolving only from a configured local content repository (a specific folder) * tries to prevent known XML security issues (see [OWASP XML_Security_Cheat_Sheet.html](https://cheatsheetseries.owasp.org/cheatsheets/XML_Security_Cheat_Sheet.html)) -However, you can configure certain aspects related to resolving and security yourself. The validator uses a single interface for accessing or creating the necessary XML API objects like `SchemaFactory`, `Validator`,`URIResolver` or `Processor`: [ResolvingConfigurationStrategy.java](https://github.com/itplr-kosit/validator/tree/master/src/main/java/de/kosit/validationtool/api/ResolvingConfigurationStrategy.java) +However, you can configure certain aspects related to resolving and security yourself. The validator uses a single interface for accessing or creating the necessary XML API objects like `SchemaFactory`, `Validator`,`URIResolver` or `Processor`: [ResolvingConfigurationStrategy.java](https://github.com/itplr-kosit/validator/tree/main/src/main/java/de/kosit/validationtool/api/ResolvingConfigurationStrategy.java) There are 3 implementations available out of the box: -1. [StrictRelativeResolvingStrategy.java](https://github.com/itplr-kosit/validator/tree/master/src/main/java/de/kosit/validationtool/impl/xml/StrictRelativeResolvingStrategy.java) +1. [StrictRelativeResolvingStrategy.java](https://github.com/itplr-kosit/validator/tree/main/src/main/java/de/kosit/validationtool/impl/xml/StrictRelativeResolvingStrategy.java) which is the **default**, prevents known XML attacks and only allows loading from a specific local repository location -1. [StrictLocalResolvingStrategy.java](https://github.com/itplr-kosit/validator/tree/master/src/main/java/de/kosit/validationtool/impl/xml/StrictLocalResolvingStrategy.java) +1. [StrictLocalResolvingStrategy.java](https://github.com/itplr-kosit/validator/tree/main/src/main/java/de/kosit/validationtool/impl/xml/StrictLocalResolvingStrategy.java) which opens the first strategy to load resources from local locations -1. [RemoteResolvingStrategy.java](https://github.com/itplr-kosit/validator/tree/master/src/main/java/de/kosit/validationtool/impl/xml/RemoteResolvingStrategy.java) +1. [RemoteResolvingStrategy.java](https://github.com/itplr-kosit/validator/tree/main/src/main/java/de/kosit/validationtool/impl/xml/RemoteResolvingStrategy.java) which further opens the second to load resources also from remote locations via http and https You can configure usage of one of these implementations using the `ResolvingMode` via @@ -222,6 +223,6 @@ final Configuration config = Configuration.load(URI.create("myscenarios.xml")) --- -:warning: **Attention:** If you decide to implement a custom strategy you need to handle XML security risks on your own. Please make sure, that you prevent XXE and other kind of attacks. Consider using [BaseResolvingStrategy.java](https://github.com/itplr-kosit/validator/tree/master/src/main/java/de/kosit/validationtool/impl/xml/BaseResolvingStrategy.java) and the protected methods within to disable certain features. +:warning: **Attention:** If you decide to implement a custom strategy you need to handle XML security risks on your own. Please make sure, that you prevent XXE and other kind of attacks. Consider using [BaseResolvingStrategy.java](https://github.com/itplr-kosit/validator/blob/main/src/main/java/de/kosit/validationtool/impl/xml/BaseResolvingStrategy.java) and the protected methods within to disable certain features. --- From 705b0b2501e8bd14e458c437de6e7472eee412db Mon Sep 17 00:00:00 2001 From: Philip Helger Date: Wed, 10 Sep 2025 14:52:29 +0200 Subject: [PATCH 06/28] Updated examples + links --- README.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 355550f..7fa37f1 100644 --- a/README.md +++ b/README.md @@ -25,13 +25,16 @@ The Validator is just an engine and does not know anything about XML documents a Validation rules and details are defined in [validation scenarios](docs/configurations.md) which are used to fully configure the validation process. All configurations are self-contained modules which are deployed and developed on their own. -### Third party validation configurations +### Example validation configurations -Here are two public third party validation configurations available which might serve as examples: +Here are some public validation configurations: -* Validation Configuration for [XRechnung](http://www.xoev.de/de/xrechnung): +* Validation Configuration for [XRechnung](https://xeinkauf.de/xrechnung/): * Source code is available on [GitHub](https://github.com/itplr-kosit/validator-configuration-xrechnung) * [Releases](https://github.com/itplr-kosit/validator-configuration-xrechnung/releases) can also be downloaded +* Validation Configuration for [Peppol BIS Billing](docs.peppol.eu/poacc/billing/3.0/): + * Source code is available on [GitHub](https://github.com/itplr-kosit/validator-configuration-bis) + * [Releases](https://github.com/itplr-kosit/validator-configuration-bis/releases) can also be downloaded * Validation Configuration for [XGewerbeanzeige](https://xgewerbeanzeige.de/) * Source code is available on [GitHub](https://github.com/itplr-kosit/validator-configuration-xgewerbeanzeige) * [Releases](https://github.com/itplr-kosit/validator-configuration-xgewerbeanzeige/releases) can also be downloaded @@ -42,7 +45,7 @@ The Validator can be used in three different ways: * as standalone application running from the CLI * as library embedded within a custom application -* as a daemon providing a http interface +* as a daemon providing an http interface ### Standalone Command Line Interface (CLI) @@ -51,18 +54,18 @@ The Validator can be used in three different ways: The general way using the CLI is: ```shell -java -jar validator--standalone.jar -s -r +java -jar validator--standalone.jar -s [-r ] [OPTIONS] [FILE] [FILE] [FILE] ... ``` The help option displays further CLI options to customize the process: ```shell -java -jar validator--standalone.jar --help +java -jar validator--standalone.jar --help ``` -A concrete example with a specific validator configuration can be found on -[GitHub](https://github.com/itplr-kosit/validator-configuration-xrechnung) +A concrete example with a specific Validator configuration can be found on +[validator-configuration-bis](https://github.com/itplr-kosit/validator-configuration-bis) The [CLI documentation](./docs/cli.md) shows further configuration options. From 9ed443ffdb6d1f5b08fda2f2d45fca1a9b4a165f Mon Sep 17 00:00:00 2001 From: Marija Stojanovic Date: Wed, 22 Oct 2025 12:59:35 +0000 Subject: [PATCH 07/28] Added custom error level to Result object. --- .../de/kosit/validationtool/api/Input.java | 2 +- .../de/kosit/validationtool/api/Result.java | 19 ++++++--- .../impl/CollectingErrorEventHandler.java | 12 +++--- .../validationtool/impl/DefaultCheck.java | 35 +++++++++++++--- .../validationtool/impl/DefaultResult.java | 31 ++++++++++---- .../impl/ScenarioRepository.java | 6 +-- .../impl/model/CustomFailedAssert.java | 41 +++++++++++++++++++ .../validationtool/impl/model/Result.java | 8 ++-- .../impl/tasks/CheckAction.java | 18 ++++---- .../impl/tasks/DocumentParseAction.java | 9 ++-- .../cmd/CommandlineApplicationTest.java | 2 +- .../validationtool/impl/DefaultCheckTest.java | 21 +++++++++- .../de/kosit/validationtool/impl/Helper.java | 2 + .../simple/input/foo-custom-level-error.xml | 24 +++++++++++ .../examples/simple/scenarios-with-errors.xml | 32 +++++++++++++++ 15 files changed, 211 insertions(+), 51 deletions(-) create mode 100644 src/main/java/de/kosit/validationtool/impl/model/CustomFailedAssert.java create mode 100644 src/test/resources/examples/simple/input/foo-custom-level-error.xml diff --git a/src/main/java/de/kosit/validationtool/api/Input.java b/src/main/java/de/kosit/validationtool/api/Input.java index 12f9fee..8d93c7a 100644 --- a/src/main/java/de/kosit/validationtool/api/Input.java +++ b/src/main/java/de/kosit/validationtool/api/Input.java @@ -45,7 +45,7 @@ public interface Input { /** * The digest algorithm used for computing the {@link #getHashCode()} * - * @return the name of the digest algorith + * @return the name of the digest algorithm */ String getDigestAlgorithm(); diff --git a/src/main/java/de/kosit/validationtool/api/Result.java b/src/main/java/de/kosit/validationtool/api/Result.java index 4c04ab4..f3ed697 100644 --- a/src/main/java/de/kosit/validationtool/api/Result.java +++ b/src/main/java/de/kosit/validationtool/api/Result.java @@ -22,6 +22,7 @@ import org.oclc.purl.dsdl.svrl.FailedAssert; import org.oclc.purl.dsdl.svrl.SchematronOutput; import org.w3c.dom.Document; +import de.kosit.validationtool.impl.model.CustomFailedAssert; import net.sf.saxon.s9api.XdmNode; /** @@ -69,23 +70,31 @@ public interface Result { /** * Schnellzugriff auf die Empfehlung zur Weiterverarbeitung des Dokuments. * - * @return true wenn {@link AcceptRecommendation#ACCEPTABLE} + * @return true wenn {@link AcceptRecommendation#ACCEPTABLE} */ boolean isAcceptable(); /** * Gibt eine Liste mit gefundenen Schema-Validation-Fehler zurück. Diese Liste ist leer, wenn keine Fehler gefunden * wurden. + * + * @return List of schema validation errors. */ List getSchemaViolations(); /** * Liefert die Ergebnisse der Schematron-Prüfungen, in der Reihenfolge der Szenario-Konfiguration. * - * @return Liste mit Schematron-Ergebnissen + * @return List with Schematron results */ List getSchematronResult(); + /** + * @return List of custom failed asserts per Schematron level. Only failed assertions with a custom level are + * contained. Never null but maybe empty. + */ + List getCustomFailedAsserts(); + /** * Returns {@link org.oclc.purl.dsdl.svrl.FailedAssert FailedAsserts} of a schematron evaluation. * @@ -96,14 +105,14 @@ public interface Result { /** * Liefert ein true, wenn keine Schema-Violations vorhanden sind. * - * @return true wenn Schema-valide + * @return true if XML Schema compliant */ boolean isSchemaValid(); /** * Liefert ein true, wenn der Prüfling eine well-formed XML-Datei ist. * - * @return true wenn well-formed + * @return true if wellformed */ boolean isWellformed(); @@ -111,7 +120,7 @@ public interface Result { * Returns true, if schematron has been checked and the result does not contain any {@link FailedAssert * FailedAsserts}. * - * @return true, if valid + * @return true, if valid */ boolean isSchematronValid(); } diff --git a/src/main/java/de/kosit/validationtool/impl/CollectingErrorEventHandler.java b/src/main/java/de/kosit/validationtool/impl/CollectingErrorEventHandler.java index 3f522a6..be10111 100644 --- a/src/main/java/de/kosit/validationtool/impl/CollectingErrorEventHandler.java +++ b/src/main/java/de/kosit/validationtool/impl/CollectingErrorEventHandler.java @@ -17,11 +17,9 @@ package de.kosit.validationtool.impl; import java.util.ArrayList; -import java.util.Collection; +import java.util.List; import java.util.StringJoiner; -import jakarta.xml.bind.ValidationEvent; -import jakarta.xml.bind.ValidationEventHandler; import javax.xml.transform.ErrorListener; import javax.xml.transform.SourceLocator; import javax.xml.transform.TransformerException; @@ -30,11 +28,11 @@ import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; -import lombok.Getter; - import de.kosit.validationtool.model.reportInput.XMLSyntaxError; import de.kosit.validationtool.model.reportInput.XMLSyntaxErrorSeverity; - +import jakarta.xml.bind.ValidationEvent; +import jakarta.xml.bind.ValidationEventHandler; +import lombok.Getter; import net.sf.saxon.s9api.MessageListener2; import net.sf.saxon.s9api.QName; import net.sf.saxon.s9api.XdmNode; @@ -51,7 +49,7 @@ public class CollectingErrorEventHandler implements ValidationEventHandler, Erro private static final int stopProcessCount = DEFAULT_ABORT_COUNT; - private final Collection errors = new ArrayList<>(); + private final List errors = new ArrayList<>(); private static XMLSyntaxError createError(final XMLSyntaxErrorSeverity severity, final String message) { final XMLSyntaxError e = new XMLSyntaxError(); diff --git a/src/main/java/de/kosit/validationtool/impl/DefaultCheck.java b/src/main/java/de/kosit/validationtool/impl/DefaultCheck.java index 66bff80..2e614ce 100644 --- a/src/main/java/de/kosit/validationtool/impl/DefaultCheck.java +++ b/src/main/java/de/kosit/validationtool/impl/DefaultCheck.java @@ -20,19 +20,21 @@ import static de.kosit.validationtool.impl.DateFactory.createTimestamp; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; +import org.oclc.purl.dsdl.svrl.FailedAssert; +import org.oclc.purl.dsdl.svrl.SchematronOutput; import de.kosit.validationtool.api.Check; import de.kosit.validationtool.api.Configuration; import de.kosit.validationtool.api.Input; import de.kosit.validationtool.api.Result; import de.kosit.validationtool.api.XmlError; +import de.kosit.validationtool.impl.model.CustomFailedAssert; import de.kosit.validationtool.impl.tasks.CheckAction; import de.kosit.validationtool.impl.tasks.CheckAction.Bag; import de.kosit.validationtool.impl.tasks.ComputeAcceptanceAction; @@ -47,7 +49,10 @@ import de.kosit.validationtool.impl.xml.ProcessorProvider; import de.kosit.validationtool.model.reportInput.CreateReportInput; import de.kosit.validationtool.model.reportInput.EngineType; import de.kosit.validationtool.model.reportInput.XMLSyntaxError; - +import de.kosit.validationtool.model.scenarios.ErrorLevelType; +import de.kosit.validationtool.model.scenarios.ScenarioType; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import net.sf.saxon.s9api.Processor; /** @@ -141,10 +146,30 @@ public class DefaultCheck implements Check { result.setProcessingSuccessful(!t.isStopped() && t.isFinished()); result.setSchematronResult(t.getReportInput().getValidationResultsSchematron().stream().filter(e -> e.getResults() != null) .map(e -> e.getResults().getSchematronOutput()).collect(Collectors.toList())); + + result.setCustomFailedAsserts(buildCustomFailedAssertsList(t, result.getSchematronResult())); + return result; } - private static List convertErrors(final Collection errors) { + private List buildCustomFailedAssertsList(final Bag t, final List schematronResult) { + // Get Map of Assertion ID to custom error levels for the current scenario + final Map customLevels = Optional.ofNullable(t.getScenarioSelectionResult()) + .map(de.kosit.validationtool.impl.model.Result::getObject).map(Scenario::getConfiguration) + .map(ScenarioType::getCreateReport) + .map(r -> r.getCustomLevel().stream() + .flatMap(customLevel -> customLevel.getValue().stream().map(id -> Map.entry(id, customLevel.getLevel()))) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))) + .orElse(Collections.emptyMap()); + + // Now check all failed assertions of all schematron validations if they contain a failed assertion with one of + // the changed IDs + return schematronResult.stream().flatMap(x -> x.getActivePatternAndFiredRuleAndFailedAssert().stream()) + .filter(FailedAssert.class::isInstance).map(FailedAssert.class::cast).filter(fa -> customLevels.containsKey(fa.getId())) + .map(fa -> new CustomFailedAssert(fa, customLevels.get(fa.getId()))).collect(Collectors.toList()); + } + + private static List convertErrors(final List errors) { // noinspection unchecked return (List) (List) errors; } diff --git a/src/main/java/de/kosit/validationtool/impl/DefaultResult.java b/src/main/java/de/kosit/validationtool/impl/DefaultResult.java index 9892198..162e3f9 100644 --- a/src/main/java/de/kosit/validationtool/impl/DefaultResult.java +++ b/src/main/java/de/kosit/validationtool/impl/DefaultResult.java @@ -25,15 +25,14 @@ import org.oclc.purl.dsdl.svrl.SchematronOutput; import org.w3c.dom.Document; import org.w3c.dom.Element; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.Setter; - import de.kosit.validationtool.api.AcceptRecommendation; import de.kosit.validationtool.api.Result; import de.kosit.validationtool.api.XmlError; +import de.kosit.validationtool.impl.model.CustomFailedAssert; import de.kosit.validationtool.model.reportInput.CreateReportInput; - +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; import net.sf.saxon.dom.NodeOverNodeInfo; import net.sf.saxon.s9api.XdmNode; @@ -67,6 +66,11 @@ public class DefaultResult implements Result { @Setter(AccessLevel.PACKAGE) private List schematronResult; + /** + * List of custom failed asserts per Schematron level. Only failed assertions with a custom level are contained. + */ + private List customFailedAsserts; + @Getter @Setter private boolean processingSuccessful; @@ -149,19 +153,28 @@ public class DefaultResult implements Result { } private List filterSchematronResult(final Class type) { - return getSchematronResult() != null - ? getSchematronResult().stream().flatMap(e -> e.getActivePatternAndFiredRuleAndFailedAssert().stream()) + return this.schematronResult != null + ? this.schematronResult.stream().flatMap(e -> e.getActivePatternAndFiredRuleAndFailedAssert().stream()) .filter(type::isInstance).map(type::cast).collect(Collectors.toList()) : Collections.emptyList(); } private boolean isSchematronEvaluated() { - return getSchematronResult() != null - && getSchematronResult().stream().noneMatch(e -> e.getActivePatternAndFiredRuleAndFailedAssert().isEmpty()); + return this.schematronResult != null + && this.schematronResult.stream().noneMatch(e -> e.getActivePatternAndFiredRuleAndFailedAssert().isEmpty()); } @Override public boolean isSchematronValid() { return isSchematronEvaluated() && getFailedAsserts().isEmpty(); } + + @Override + public List getCustomFailedAsserts() { + return this.customFailedAsserts; + } + + public void setCustomFailedAsserts(List customFailedAsserts) { + this.customFailedAsserts = customFailedAsserts; + } } diff --git a/src/main/java/de/kosit/validationtool/impl/ScenarioRepository.java b/src/main/java/de/kosit/validationtool/impl/ScenarioRepository.java index 6306403..267bc23 100644 --- a/src/main/java/de/kosit/validationtool/impl/ScenarioRepository.java +++ b/src/main/java/de/kosit/validationtool/impl/ScenarioRepository.java @@ -17,7 +17,6 @@ package de.kosit.validationtool.impl; import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -81,10 +80,9 @@ public class ScenarioRepository { if (collect.size() == 1) { result = new Result<>(collect.get(0)); } else if (collect.isEmpty()) { - result = new Result<>(getFallbackScenario(), - Collections.singleton("None of the loaded scenarios matches the specified document")); + result = new Result<>(getFallbackScenario(), Arrays.asList("None of the loaded scenarios matches the specified document")); } else { - result = new Result<>(getFallbackScenario(), Collections.singleton("More than one scenario matches the specified document")); + result = new Result<>(getFallbackScenario(), Arrays.asList("More than one scenario matches the specified document")); } return result; diff --git a/src/main/java/de/kosit/validationtool/impl/model/CustomFailedAssert.java b/src/main/java/de/kosit/validationtool/impl/model/CustomFailedAssert.java new file mode 100644 index 0000000..e2163cb --- /dev/null +++ b/src/main/java/de/kosit/validationtool/impl/model/CustomFailedAssert.java @@ -0,0 +1,41 @@ +package de.kosit.validationtool.impl.model; + +import java.util.Objects; + +import org.oclc.purl.dsdl.svrl.FailedAssert; + +import de.kosit.validationtool.model.scenarios.ErrorLevelType; + +/** + * This class contains a single Schematron failed assertion that has a custom error level. + * + * @since 1.6.0 + */ +public class CustomFailedAssert { + + private final FailedAssert originalFailedAssert; + + private final ErrorLevelType customLevelFlag; + + /** + * Constructor + * + * @param failedAssert The failed assert from Schematron. May not be null. + * @param customLevelFlag The custom error level. May not be null. + */ + public CustomFailedAssert(final FailedAssert failedAssert, final ErrorLevelType customLevelFlag) { + Objects.requireNonNull(failedAssert); + Objects.requireNonNull(customLevelFlag); + this.originalFailedAssert = failedAssert; + this.customLevelFlag = customLevelFlag; + } + + public FailedAssert getFailedAssert() { + return this.originalFailedAssert; + } + + public ErrorLevelType getCustomLevelFlag() { + return this.customLevelFlag; + } + +} diff --git a/src/main/java/de/kosit/validationtool/impl/model/Result.java b/src/main/java/de/kosit/validationtool/impl/model/Result.java index 5f94261..893f586 100644 --- a/src/main/java/de/kosit/validationtool/impl/model/Result.java +++ b/src/main/java/de/kosit/validationtool/impl/model/Result.java @@ -17,8 +17,8 @@ package de.kosit.validationtool.impl.model; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; +import java.util.List; import lombok.AllArgsConstructor; import lombok.Getter; @@ -37,14 +37,14 @@ public class Result { private T object; - private Collection errors = new ArrayList<>(); + private List errors = new ArrayList<>(); /** * Erzeugt ein neues Ergebnis mit Fehler * * @param errors die Fehler */ - public Result(Collection errors) { + public Result(final List errors) { this(null, errors); } @@ -53,7 +53,7 @@ public class Result { * * @param o */ - public Result(T o) { + public Result(final T o) { this(o, Collections.emptyList()); } diff --git a/src/main/java/de/kosit/validationtool/impl/tasks/CheckAction.java b/src/main/java/de/kosit/validationtool/impl/tasks/CheckAction.java index 5d0915f..22f03ca 100644 --- a/src/main/java/de/kosit/validationtool/impl/tasks/CheckAction.java +++ b/src/main/java/de/kosit/validationtool/impl/tasks/CheckAction.java @@ -21,10 +21,6 @@ import java.util.Collections; import org.apache.commons.io.FilenameUtils; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.Setter; - import de.kosit.validationtool.api.AcceptRecommendation; import de.kosit.validationtool.api.Input; import de.kosit.validationtool.impl.Scenario; @@ -32,7 +28,9 @@ import de.kosit.validationtool.impl.model.Result; import de.kosit.validationtool.model.reportInput.CreateReportInput; import de.kosit.validationtool.model.reportInput.ProcessingError; import de.kosit.validationtool.model.reportInput.XMLSyntaxError; - +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; import net.sf.saxon.s9api.XdmNode; /** @@ -55,9 +53,9 @@ public interface CheckAction { private Result scenarioSelectionResult; @Setter(AccessLevel.NONE) - private CreateReportInput reportInput; + private final CreateReportInput reportInput; - /** Das finale Ergebnis */ + /** The final result */ private XdmNode report; private boolean finished; @@ -66,7 +64,7 @@ public interface CheckAction { private AcceptRecommendation acceptStatus = AcceptRecommendation.UNDEFINED; - /** Das zu prüfende Dokument */ + /** The document to validate */ private Input input; private Result parserResult; @@ -85,7 +83,9 @@ public interface CheckAction { } /** - * Signalisiert einen vorzeitigen Stop der Vearbeitung. + * Indicates an early stop in processing. + * + * @param error Error text */ public void stopProcessing(final String error) { stopProcessing(Collections.singleton(error)); diff --git a/src/main/java/de/kosit/validationtool/impl/tasks/DocumentParseAction.java b/src/main/java/de/kosit/validationtool/impl/tasks/DocumentParseAction.java index 7eeb728..57de17f 100644 --- a/src/main/java/de/kosit/validationtool/impl/tasks/DocumentParseAction.java +++ b/src/main/java/de/kosit/validationtool/impl/tasks/DocumentParseAction.java @@ -17,19 +17,18 @@ package de.kosit.validationtool.impl.tasks; import java.io.IOException; +import java.util.Arrays; import java.util.Collections; import java.util.stream.Collectors; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - import de.kosit.validationtool.api.Input; import de.kosit.validationtool.impl.input.XdmNodeInput; import de.kosit.validationtool.impl.model.Result; import de.kosit.validationtool.model.reportInput.ValidationResultsWellformedness; import de.kosit.validationtool.model.reportInput.XMLSyntaxError; import de.kosit.validationtool.model.reportInput.XMLSyntaxErrorSeverity; - +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import net.sf.saxon.s9api.DocumentBuilder; import net.sf.saxon.s9api.Processor; import net.sf.saxon.s9api.SaxonApiException; @@ -75,7 +74,7 @@ public class DocumentParseAction implements CheckAction { final XMLSyntaxError error = new XMLSyntaxError(); error.setSeverityCode(XMLSyntaxErrorSeverity.SEVERITY_FATAL_ERROR); error.setMessage(String.format("IOException while reading resource %s: %s", content.getName(), e.getMessage())); - result = new Result<>(Collections.singleton(error)); + result = new Result<>(Arrays.asList(error)); } return result; diff --git a/src/test/java/de/kosit/validationtool/cmd/CommandlineApplicationTest.java b/src/test/java/de/kosit/validationtool/cmd/CommandlineApplicationTest.java index f8ce55d..86eb983 100644 --- a/src/test/java/de/kosit/validationtool/cmd/CommandlineApplicationTest.java +++ b/src/test/java/de/kosit/validationtool/cmd/CommandlineApplicationTest.java @@ -164,7 +164,7 @@ public class CommandlineApplicationTest { final String[] args = { "-s", Paths.get(Simple.SCENARIOS).toString(), "-o", this.output.toString(), "-r", Paths.get(Simple.REPOSITORY_URI).toString(), Paths.get(Simple.EXAMPLES).toString() }; CommandLineApplication.mainProgram(args); - assertThat(CommandLine.getErrorOutput()).contains("Processing 8 object(s) completed"); + assertThat(CommandLine.getErrorOutput()).contains("Processing 9 object(s) completed"); } @Test diff --git a/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java b/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java index 5144652..d26b295 100644 --- a/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java +++ b/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java @@ -17,6 +17,7 @@ package de.kosit.validationtool.impl; import static de.kosit.validationtool.api.InputFactory.read; +import static de.kosit.validationtool.impl.Helper.Simple.FOO_CUSTOM_LEVEL_ERROR; import static de.kosit.validationtool.impl.Helper.Simple.FOO_SCHEMATRON_INVALID; import static de.kosit.validationtool.impl.Helper.Simple.GARBAGE; import static de.kosit.validationtool.impl.Helper.Simple.NOT_WELLFORMED; @@ -44,7 +45,8 @@ import de.kosit.validationtool.api.Input; import de.kosit.validationtool.api.InputFactory; import de.kosit.validationtool.api.Result; import de.kosit.validationtool.impl.Helper.Simple; - +import de.kosit.validationtool.impl.model.CustomFailedAssert; +import de.kosit.validationtool.model.scenarios.ErrorLevelType; import net.sf.saxon.s9api.XdmNode; /** @@ -239,6 +241,8 @@ public class DefaultCheckTest { assertThat(result.isAcceptable()).isFalse(); assertThat(result.getReport()).isNotNull(); assertThat(result.getProcessingErrors()).hasSize(1); + assertThat(result.getCustomFailedAsserts()).isNotNull(); + assertThat(result.getCustomFailedAsserts()).hasSize(0); } @Test @@ -254,4 +258,19 @@ public class DefaultCheckTest { result = this.validCheck.checkInput(domInput); assertThat(result.isProcessingSuccessful()).isEqualTo(true); } + + @Test + public void testCustomFailedAssertsWarning() { + final Result result = this.errorCheck.checkInput(read(FOO_CUSTOM_LEVEL_ERROR)); + assertThat(result.isSchematronValid()).isFalse(); + assertThat(result.getFailedAsserts()).isNotEmpty(); + assertThat(result.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.ACCEPTABLE); + + assertThat(result.getCustomFailedAsserts()).isNotNull(); + assertThat(result.getCustomFailedAsserts()).hasSize(1); + CustomFailedAssert customFailedAssert = result.getCustomFailedAsserts().get(0); + assertThat(result.getFailedAsserts().get(0).getId()).isEqualTo(customFailedAssert.getFailedAssert().getId()); + assertThat(customFailedAssert.getCustomLevelFlag()).isEqualTo(ErrorLevelType.WARNING); + } + } diff --git a/src/test/java/de/kosit/validationtool/impl/Helper.java b/src/test/java/de/kosit/validationtool/impl/Helper.java index f60c8a1..00da5a3 100644 --- a/src/test/java/de/kosit/validationtool/impl/Helper.java +++ b/src/test/java/de/kosit/validationtool/impl/Helper.java @@ -57,6 +57,8 @@ public class Helper { public static final URI FOO_SCHEMATRON_INVALID = EXAMPLES.resolve("foo-schematron-invalid.xml"); + public static final URI FOO_CUSTOM_LEVEL_ERROR = EXAMPLES.resolve("foo-custom-level-error.xml"); + public static final URI REJECTED = ROOT.resolve("input/withManualReject.xml"); public static final URI SCENARIOS = ROOT.resolve("scenarios.xml"); diff --git a/src/test/resources/examples/simple/input/foo-custom-level-error.xml b/src/test/resources/examples/simple/input/foo-custom-level-error.xml new file mode 100644 index 0000000..c802e08 --- /dev/null +++ b/src/test/resources/examples/simple/input/foo-custom-level-error.xml @@ -0,0 +1,24 @@ + + + + + + asldkfj + asldkfj + + + \ No newline at end of file diff --git a/src/test/resources/examples/simple/scenarios-with-errors.xml b/src/test/resources/examples/simple/scenarios-with-errors.xml index 2a4896f..a726508 100644 --- a/src/test/resources/examples/simple/scenarios-with-errors.xml +++ b/src/test/resources/examples/simple/scenarios-with-errors.xml @@ -52,6 +52,38 @@ + + Simple + +

Foo schematron error

+
+ http://www.xoev.de/de/validator/framework/1/createreportinput + http://validator.kosit.de/test-sample + http://validator.kosit.de/test-report + /test:foo + + + + Sample Schema + simple.xsd + + + + + Sample Schematron + simple-schematron-error.xsl + + + + + Report für eRechnung + report.xsl + + content-2 + + count(//test:rejected) = 0 +
+ default From 1c5c3ab66f1d376ad373a6bd9f0585d2948039a1 Mon Sep 17 00:00:00 2001 From: Renzo Kottmann Date: Wed, 22 Oct 2025 15:19:06 +0200 Subject: [PATCH 08/28] Add github #127 to changelog.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5611067..b7d4237 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## 1.6.0 +### Added + +- (CORE) [GitHub #127](https://github.com/itplr-kosit/validator/issues/127) New API method `Result.getCustomFailedAsserts()` to access failed asserts with custom error levels + ### Fixed - (DOC) [GitHub PR#166](https://github.com/itplr-kosit/validator/pull/166) Fixed broken links in `docs/api.md` From 9774dddb17697f8c60ad3803191e5b1a5c2e96be Mon Sep 17 00:00:00 2001 From: Philip Helger Date: Wed, 22 Oct 2025 15:33:29 +0200 Subject: [PATCH 09/28] Lombok update for Java 25 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 953d5a6..6ebe11d 100644 --- a/pom.xml +++ b/pom.xml @@ -44,7 +44,7 @@ 0.8.13 4.0.2 4.0.5 - 1.18.38 + 1.18.42 4.11.0 10.0.4 5.5.5 From be9dcaac039c24ca0d9d9acef50024ddc8468605 Mon Sep 17 00:00:00 2001 From: Philip Helger Date: Wed, 22 Oct 2025 15:37:21 +0200 Subject: [PATCH 10/28] Using release instead of source/target --- pom.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 6ebe11d..438e301 100644 --- a/pom.xml +++ b/pom.xml @@ -251,8 +251,7 @@ maven-compiler-plugin 3.14.0 - 11 - 11 + 11 UTF-8 From 1da41a718f1d188d5744e1db8f24d88320d66833 Mon Sep 17 00:00:00 2001 From: Philip Helger Date: Wed, 22 Oct 2025 15:54:07 +0200 Subject: [PATCH 11/28] Enforcing specific Java versions for compilation --- CHANGELOG.md | 7 +++++++ pom.xml | 15 +++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7d4237..05b839d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - (CORE) Migration from javax to jakarta xml bind - (DOC) [GitHub PR#132](https://github.com/itplr-kosit/validator/pull/132) Updated the link to the example Validator scenario configuration +- (BUILD) Support for *building and compilation* is restricted to the following Java versions: + - Java 11: any version ≥ 11.0.23 + - Java 12 to 16 will not work + - Java 17: any version ≥ 17.0.11 + - Java 18 to 20 will not work + - Any version from Java 21 onwards will work + - The reason for this is the usage of the `-proc:full` compiler parameter which in turn is needed for Lombok usage in JDK 23+. ### Removed diff --git a/pom.xml b/pom.xml index 438e301..4b4eada 100644 --- a/pom.xml +++ b/pom.xml @@ -241,6 +241,16 @@ [3.3.9,) + + + [11.0.23,12),[17.0.11,18),[21,) + @@ -253,6 +263,11 @@ 11 UTF-8 + + full From 70f60261967bb5f835aa193e631a2676782f8586 Mon Sep 17 00:00:00 2001 From: Philip Helger Date: Wed, 22 Oct 2025 15:57:36 +0200 Subject: [PATCH 12/28] Add Java 25 instead of 24 --- .gitlab-ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ef39ded..afb86fc 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -66,9 +66,9 @@ java-21: extends: .java image: $CI_REGISTRY_IMAGE/maven:3-eclipse-temurin-21-alpine -java-24: - extends: .java_extended - image: $CI_REGISTRY_IMAGE/maven:3-eclipse-temurin-24-alpine +java-25: + extends: .java + image: $CI_REGISTRY_IMAGE/maven:3-eclipse-temurin-25-alpine deploy: stage: deploy From c030aaff02085da0ac598ac844db1b7d6698b573 Mon Sep 17 00:00:00 2001 From: Philip Helger Date: Wed, 22 Oct 2025 16:02:20 +0200 Subject: [PATCH 13/28] Back to 24 --- .gitlab-ci.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index afb86fc..cf82b43 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -66,10 +66,14 @@ java-21: extends: .java image: $CI_REGISTRY_IMAGE/maven:3-eclipse-temurin-21-alpine -java-25: - extends: .java - image: $CI_REGISTRY_IMAGE/maven:3-eclipse-temurin-25-alpine +java-24: + extends: .java_extended + image: $CI_REGISTRY_IMAGE/maven:3-eclipse-temurin-24-alpine +#java-25: +# extends: .java +# image: $CI_REGISTRY_IMAGE/maven:3-eclipse-temurin-25-alpine + deploy: stage: deploy image: $CI_REGISTRY_IMAGE/maven:3-eclipse-temurin-11-alpine From 0b22c3ea911e482c86f47799e4906725b5e01a0d Mon Sep 17 00:00:00 2001 From: Philip Helger Date: Fri, 24 Oct 2025 12:27:20 +0200 Subject: [PATCH 14/28] Replaced deprecated methods etc. --- .../cmd/CheckAssertionAction.java | 28 ++++--- .../cmd/CommandLineApplication.java | 2 + .../kosit/validationtool/cmd/Validator.java | 4 +- .../kosit/validationtool/cmd/report/Grid.java | 15 +--- .../config/ConfigurationLoader.java | 16 ++-- .../validationtool/daemon/BaseHandler.java | 12 +-- .../impl/ContentRepository.java | 8 +- .../impl/ConversionService.java | 17 +++-- .../validationtool/impl/DefaultCheck.java | 1 + .../impl/input/SourceInput.java | 14 +++- .../impl/input/StreamHelper.java | 24 +++--- .../impl/tasks/SchemaValidationAction.java | 14 ++-- .../impl/xml/ClassPathResourceResolver.java | 4 +- .../impl/xml/RelativeUriResolver.java | 11 +-- .../validationtool/api/InputFactoryTest.java | 40 +++------- .../cmd/CheckAssertionActionTest.java | 6 +- .../kosit/validationtool/cmd/CommandLine.java | 1 + .../cmd/CommandlineApplicationTest.java | 9 +-- .../cmd/PrintReportActionTest.java | 3 - .../config/ConfigurationBuilderTest.java | 76 +++++++++++-------- .../config/ScenarioBuilderTest.java | 7 +- .../config/XPathBuilderTest.java | 13 ++-- .../docs/MiscDocExampleCodes.java | 2 + .../validationtool/docs/MyValidator.java | 1 + .../validationtool/docs/StandardExample.java | 1 + .../impl/ContentRepositoryTest.java | 18 +---- .../impl/ConversionServiceTest.java | 33 +++----- .../impl/RelativeUriResolverTest.java | 11 +-- .../impl/ScenarioRepositoryTest.java | 9 +-- .../validationtool/impl/VersioningTest.java | 15 +--- .../impl/tasks/DocumentParseActionTest.java | 9 +-- .../impl/tasks/SchemaValidatorActionTest.java | 3 - .../xml/BaseResolverConfigurationTest.java | 8 +- .../impl/xml/RemoteResolvingStrategyTest.java | 5 -- .../impl/xml/SchemaProviderTest.java | 10 ++- .../impl/xml/StrictLocalResolvingTest.java | 21 +++-- .../impl/xml/StrictRelativeResolvingTest.java | 21 +++-- 37 files changed, 204 insertions(+), 288 deletions(-) diff --git a/src/main/java/de/kosit/validationtool/cmd/CheckAssertionAction.java b/src/main/java/de/kosit/validationtool/cmd/CheckAssertionAction.java index fb44ac9..655c080 100644 --- a/src/main/java/de/kosit/validationtool/cmd/CheckAssertionAction.java +++ b/src/main/java/de/kosit/validationtool/cmd/CheckAssertionAction.java @@ -23,16 +23,14 @@ import java.util.Map; import org.apache.commons.lang3.StringUtils; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - import de.kosit.validationtool.cmd.assertions.AssertionType; import de.kosit.validationtool.cmd.assertions.Assertions; import de.kosit.validationtool.impl.model.Result; import de.kosit.validationtool.impl.tasks.CheckAction; - +import lombok.AccessLevel; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import net.sf.saxon.s9api.Processor; import net.sf.saxon.s9api.SaxonApiException; import net.sf.saxon.s9api.XPathCompiler; @@ -56,12 +54,12 @@ class CheckAssertionAction implements CheckAction { private Map> mappedAssertions; - private static boolean matches(String key, String name) { + private static boolean matches(final String key, final String name) { return key.startsWith(name) || (name + ".xml").endsWith(key); } @Override - public void check(Bag results) { + public void check(final Bag results) { log.info("Checking assertions for {}", results.getInput().getName()); final List toCheck = findAssertions(results.getName()); final List errors = new ArrayList<>(); @@ -84,28 +82,28 @@ class CheckAssertionAction implements CheckAction { } } - private List findAssertions(String name) { + private List findAssertions(final String name) { return getMapped().entrySet().stream().filter(e -> matches(e.getKey(), name)).map(Map.Entry::getValue).findFirst().orElse(null); } - private boolean check(XdmNode document, AssertionType assertion) { + private boolean check(final XdmNode document, final AssertionType assertion) { try { final XPathSelector selector = createSelector(assertion); selector.setContextItem(document); return selector.effectiveBooleanValue(); - } catch (SaxonApiException e) { + } catch (final SaxonApiException e) { log.error("Error evaluating assertion {} for {}", assertion.getTest(), assertion.getReportDoc(), e); } return false; } - private XPathSelector createSelector(AssertionType assertion) throws SaxonApiException { + private XPathSelector createSelector(final AssertionType assertion) { try { final XPathCompiler compiler = getProcessor().newXPathCompiler(); assertions.getNamespace().forEach(ns -> compiler.declareNamespace(ns.getPrefix(), ns.getValue())); return compiler.compile(assertion.getTest()).load(); - } catch (SaxonApiException e) { + } catch (final SaxonApiException e) { throw new IllegalStateException(String.format("Can not compile xpath match expression '%s'", StringUtils.isNotBlank(assertion.getTest()) ? assertion.getTest() : "EMPTY EXPRESSION"), e); } @@ -114,8 +112,8 @@ class CheckAssertionAction implements CheckAction { private Map> getMapped() { if (mappedAssertions == null) { mappedAssertions = new HashMap<>(); - for (AssertionType assertionType : assertions.getAssertion()) { - List list = mappedAssertions.computeIfAbsent(assertionType.getReportDoc(), k -> new ArrayList<>()); + for (final AssertionType assertionType : assertions.getAssertion()) { + final List list = mappedAssertions.computeIfAbsent(assertionType.getReportDoc(), k -> new ArrayList<>()); list.add(assertionType); } } diff --git a/src/main/java/de/kosit/validationtool/cmd/CommandLineApplication.java b/src/main/java/de/kosit/validationtool/cmd/CommandLineApplication.java index 09e3757..37b9ed7 100644 --- a/src/main/java/de/kosit/validationtool/cmd/CommandLineApplication.java +++ b/src/main/java/de/kosit/validationtool/cmd/CommandLineApplication.java @@ -95,6 +95,8 @@ public class CommandLineApplication { return resultStatus; } + // The signature is required, because the method is used a lambda + @SuppressWarnings("unused") private static int logExecutionException(final Exception ex, final CommandLine cli, final ParseResult parseResult) { final String message = isNotEmpty(ex.getMessage()) ? ex.getMessage() : "Es ist eine Fehler aufgetreten"; Printer.writeErr(ex, message); diff --git a/src/main/java/de/kosit/validationtool/cmd/Validator.java b/src/main/java/de/kosit/validationtool/cmd/Validator.java index a54e3b5..3384768 100644 --- a/src/main/java/de/kosit/validationtool/cmd/Validator.java +++ b/src/main/java/de/kosit/validationtool/cmd/Validator.java @@ -321,10 +321,8 @@ public class Validator { private static URI determineRepository(final Path d) { if (Files.isDirectory(d)) { return d.toUri(); - } else { - throw new IllegalArgumentException( - String.format("Not a valid path for repository definition specified: '%s'", d.toAbsolutePath())); } + throw new IllegalArgumentException(String.format("Not a valid path for repository definition specified: '%s'", d.toAbsolutePath())); } diff --git a/src/main/java/de/kosit/validationtool/cmd/report/Grid.java b/src/main/java/de/kosit/validationtool/cmd/report/Grid.java index f374535..944acb6 100644 --- a/src/main/java/de/kosit/validationtool/cmd/report/Grid.java +++ b/src/main/java/de/kosit/validationtool/cmd/report/Grid.java @@ -82,6 +82,7 @@ public class Grid { * * @param name the name of the column * @param maxLength the max length of the column + * @param minLength the minimum length of the column */ public ColumnDefinition(final String name, final int maxLength, final int minLength) { this(name, maxLength, minLength, 1); @@ -91,7 +92,8 @@ public class Grid { * Constructor. * * @param name the name of the column - * @param minLength the max length of the column + * @param maxLength the max length of the column + * @param minLength the minimum length of the column * @param maxLines the max lines per cell */ public ColumnDefinition(final String name, final int maxLength, final int minLength, final int maxLines) { @@ -149,10 +151,6 @@ public class Grid { this.text.add(txt); } - public Cell(final Object object, final Code... codes) { - this(new Text(object, codes)); - } - protected Line getFormattedLine(final int lineNumber, final ColumnDefinition def) { final Line line = new Line(); int startSubstring = lineNumber * def.getLength(); @@ -194,11 +192,6 @@ public class Grid { } - public Cell add(final Object object, final Code... codes) { - this.text.add(new Text(object, codes)); - return this; - } - } private static final Format DEFAULT_FORMAT = new Format(); @@ -321,7 +314,7 @@ public class Grid { } private static boolean isEmpty(final StringBuilder current) { - return current.toString().replaceAll("\\|", "").trim().length() == 0; + return current.toString().replace("|", "").trim().length() == 0; } private int getMaxVirtualLine() { diff --git a/src/main/java/de/kosit/validationtool/config/ConfigurationLoader.java b/src/main/java/de/kosit/validationtool/config/ConfigurationLoader.java index bf1f2b8..0f279d8 100644 --- a/src/main/java/de/kosit/validationtool/config/ConfigurationLoader.java +++ b/src/main/java/de/kosit/validationtool/config/ConfigurationLoader.java @@ -16,8 +16,6 @@ package de.kosit.validationtool.config; -import static org.apache.commons.lang3.StringUtils.startsWith; - import java.net.MalformedURLException; import java.net.URI; import java.util.HashMap; @@ -27,10 +25,7 @@ import java.util.stream.Collectors; import javax.xml.validation.Schema; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.Strings; import de.kosit.validationtool.api.Check; import de.kosit.validationtool.api.Configuration; @@ -49,7 +44,10 @@ import de.kosit.validationtool.model.reportInput.XMLSyntaxError; import de.kosit.validationtool.model.scenarios.ResourceType; import de.kosit.validationtool.model.scenarios.ScenarioType; import de.kosit.validationtool.model.scenarios.Scenarios; - +import lombok.AccessLevel; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import net.sf.saxon.s9api.Processor; import net.sf.saxon.s9api.QName; import net.sf.saxon.s9api.XdmNode; @@ -113,8 +111,8 @@ public class ConfigurationLoader { private static boolean isSupportedDocument(final XdmNode doc) { final XdmNode root = findRoot(doc); final String frameworkVersion = root.getAttributeValue(new QName("frameworkVersion")); - return startsWith(frameworkVersion, SUPPORTED_MAJOR_VERSION) - && root.getNodeName().getNamespaceURI().equals(SUPPORTED_MAJOR_VERSION_SCHEMA); + return Strings.CS.startsWith(frameworkVersion, SUPPORTED_MAJOR_VERSION) + && root.getNodeName().getNamespace().equals(SUPPORTED_MAJOR_VERSION_SCHEMA); } private static Scenario createFallback(final Scenarios scenarios, final ContentRepository repository) { diff --git a/src/main/java/de/kosit/validationtool/daemon/BaseHandler.java b/src/main/java/de/kosit/validationtool/daemon/BaseHandler.java index ef1408c..e84dd28 100644 --- a/src/main/java/de/kosit/validationtool/daemon/BaseHandler.java +++ b/src/main/java/de/kosit/validationtool/daemon/BaseHandler.java @@ -44,18 +44,18 @@ abstract class BaseHandler implements HttpHandler { throws IOException { exchange.getResponseHeaders().add("Content-Type", contentType); exchange.sendResponseHeaders(statusCode, 0); - final OutputStream os = exchange.getResponseBody(); - write.write(os); - os.close(); + try ( final OutputStream os = exchange.getResponseBody() ) { + write.write(os); + } } protected static void error(final HttpExchange exchange, final int statusCode, final String message) throws IOException { final byte[] bytes = message.getBytes(); exchange.getResponseHeaders().add("Content-Type", "text/plain"); exchange.sendResponseHeaders(statusCode, bytes.length); - final OutputStream os = exchange.getResponseBody(); - os.write(bytes); - os.close(); + try ( final OutputStream os = exchange.getResponseBody() ) { + os.write(bytes); + } } @FunctionalInterface diff --git a/src/main/java/de/kosit/validationtool/impl/ContentRepository.java b/src/main/java/de/kosit/validationtool/impl/ContentRepository.java index 521e3fc..e530040 100644 --- a/src/main/java/de/kosit/validationtool/impl/ContentRepository.java +++ b/src/main/java/de/kosit/validationtool/impl/ContentRepository.java @@ -37,10 +37,6 @@ import javax.xml.validation.SchemaFactory; import org.apache.commons.lang3.StringUtils; import org.xml.sax.SAXException; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - import de.kosit.validationtool.api.ResolvingConfigurationStrategy; import de.kosit.validationtool.impl.Scenario.Transformation; import de.kosit.validationtool.impl.xml.RelativeUriResolver; @@ -49,7 +45,9 @@ import de.kosit.validationtool.model.scenarios.NamespaceType; import de.kosit.validationtool.model.scenarios.ResourceType; import de.kosit.validationtool.model.scenarios.ScenarioType; import de.kosit.validationtool.model.scenarios.ValidateWithSchematron; - +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import net.sf.saxon.lib.UnparsedTextURIResolver; import net.sf.saxon.s9api.Processor; import net.sf.saxon.s9api.SaxonApiException; diff --git a/src/main/java/de/kosit/validationtool/impl/ConversionService.java b/src/main/java/de/kosit/validationtool/impl/ConversionService.java index d2ca2d2..bd0ba6c 100644 --- a/src/main/java/de/kosit/validationtool/impl/ConversionService.java +++ b/src/main/java/de/kosit/validationtool/impl/ConversionService.java @@ -24,14 +24,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.StringJoiner; -import jakarta.xml.bind.JAXBContext; -import jakarta.xml.bind.JAXBElement; -import jakarta.xml.bind.JAXBException; -import jakarta.xml.bind.JAXBIntrospector; -import jakarta.xml.bind.Marshaller; -import jakarta.xml.bind.Unmarshaller; -import jakarta.xml.bind.ValidationEventHandler; -import jakarta.xml.bind.annotation.XmlRegistry; import javax.xml.namespace.QName; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLOutputFactory; @@ -44,6 +36,14 @@ import javax.xml.validation.Schema; import org.apache.commons.lang3.StringUtils; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBElement; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.JAXBIntrospector; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.Unmarshaller; +import jakarta.xml.bind.ValidationEventHandler; +import jakarta.xml.bind.annotation.XmlRegistry; import lombok.extern.slf4j.Slf4j; /** @@ -219,6 +219,7 @@ public class ConversionService { final XMLOutputFactory xof = XMLOutputFactory.newFactory(); final XMLStreamWriter xmlStreamWriter = xof.createXMLStreamWriter(w); if (null == introspector.getElementName(model)) { + @SuppressWarnings({ "rawtypes", "unchecked" }) final JAXBElement jaxbElement = new JAXBElement(createQName(model), model.getClass(), model); marshaller.marshal(jaxbElement, xmlStreamWriter); } else { diff --git a/src/main/java/de/kosit/validationtool/impl/DefaultCheck.java b/src/main/java/de/kosit/validationtool/impl/DefaultCheck.java index 2e614ce..26ab801 100644 --- a/src/main/java/de/kosit/validationtool/impl/DefaultCheck.java +++ b/src/main/java/de/kosit/validationtool/impl/DefaultCheck.java @@ -169,6 +169,7 @@ public class DefaultCheck implements Check { .map(fa -> new CustomFailedAssert(fa, customLevels.get(fa.getId()))).collect(Collectors.toList()); } + @SuppressWarnings("unchecked") private static List convertErrors(final List errors) { // noinspection unchecked return (List) (List) errors; diff --git a/src/main/java/de/kosit/validationtool/impl/input/SourceInput.java b/src/main/java/de/kosit/validationtool/impl/input/SourceInput.java index 7b0a9b8..60c926e 100644 --- a/src/main/java/de/kosit/validationtool/impl/input/SourceInput.java +++ b/src/main/java/de/kosit/validationtool/impl/input/SourceInput.java @@ -19,18 +19,18 @@ package de.kosit.validationtool.impl.input; import static org.apache.commons.lang3.StringUtils.defaultIfBlank; import java.io.IOException; +import java.io.UncheckedIOException; import java.nio.charset.Charset; -import jakarta.xml.bind.util.JAXBSource; import javax.xml.transform.Source; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamSource; import org.apache.commons.io.input.ReaderInputStream; +import jakarta.xml.bind.util.JAXBSource; import lombok.Getter; import lombok.extern.slf4j.Slf4j; - import net.sf.saxon.om.TreeInfo; /** @@ -102,7 +102,7 @@ public class SourceInput extends AbstractInput { return isStreamSource(); } - private boolean isConsumed() throws IOException { + private boolean isConsumed() { if (isStreamSource()) { final StreamSource ss = (StreamSource) this.source; @@ -140,7 +140,13 @@ public class SourceInput extends AbstractInput { if (ss.getInputStream() != null) { result = new StreamSource(wrap(ss.getInputStream()), this.source.getSystemId()); } else if (ss.getReader() != null) { - result = new StreamSource(wrap(new ReaderInputStream(ss.getReader(), Charset.defaultCharset())), this.source.getSystemId()); + try { + result = new StreamSource( + wrap(ReaderInputStream.builder().setReader(ss.getReader()).setCharset(Charset.defaultCharset()).get()), + this.source.getSystemId()); + } catch (final IOException ex) { + throw new UncheckedIOException(ex); + } } } return result; diff --git a/src/main/java/de/kosit/validationtool/impl/input/StreamHelper.java b/src/main/java/de/kosit/validationtool/impl/input/StreamHelper.java index 0a49c22..cefd0e3 100644 --- a/src/main/java/de/kosit/validationtool/impl/input/StreamHelper.java +++ b/src/main/java/de/kosit/validationtool/impl/input/StreamHelper.java @@ -20,13 +20,14 @@ import java.io.BufferedInputStream; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.UncheckedIOException; import java.security.DigestInputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import javax.xml.transform.stream.StreamSource; -import org.apache.commons.io.input.CountingInputStream; +import org.apache.commons.io.input.BoundedInputStream; import de.kosit.validationtool.api.Input; @@ -39,7 +40,7 @@ public class StreamHelper { /** * Helper class, which generates the hashcode while reading the stream e.g. for parsing the document. This allows - * generating the hashcode without an aditional reading step. + * generating the hashcode without an additional reading step. */ @SuppressWarnings("squid:S4929") // efficient read is done by internally used stream private static class DigestingInputStream extends FilterInputStream { @@ -96,15 +97,15 @@ public class StreamHelper { private final LazyReadInput reference; - public CountInputStream(final LazyReadInput input, final InputStream stream) { - super(new org.apache.commons.io.input.CountingInputStream(stream)); + public CountInputStream(final LazyReadInput input, final InputStream stream) throws IOException { + super(BoundedInputStream.builder().setInputStream(stream).get()); this.reference = input; } @Override public void close() throws IOException { super.close(); - this.reference.setLength(((CountingInputStream) this.in).getByteCount()); + this.reference.setLength(((BoundedInputStream) this.in).getCount()); } } @@ -130,19 +131,24 @@ public class StreamHelper { /** * Wraps the {@link InputStream} with a counting length implementation. * - * @param input the {@link LazyReadInput input} + * @param input the lazy read input * @param stream the stream * @return a wrapped stream */ public static InputStream wrapCount(final LazyReadInput input, final InputStream stream) { - return new CountInputStream(input, stream); + try { + return new CountInputStream(input, stream); + } catch (final IOException ex) { + throw new UncheckedIOException(ex); + } } /** * Wraps the {@link InputStream} with an implementation the generates a hash sum over the stream data. * - * @param input the {@link LazyReadInput input} + * @param input the lazy read input * @param stream the stream + * @param digestAlgorithm the message digest algorithm to use * @return a wrapped stream */ public static InputStream wrapDigesting(final LazyReadInput input, final InputStream stream, final String digestAlgorithm) { @@ -175,7 +181,7 @@ public class StreamHelper { * @param input the input * @throws IOException on I/O errors */ - @SuppressWarnings("squid:S1854") + @SuppressWarnings({ "squid:S1854", "unused" }) public static void drain(final InputStream input) throws IOException { final byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; diff --git a/src/main/java/de/kosit/validationtool/impl/tasks/SchemaValidationAction.java b/src/main/java/de/kosit/validationtool/impl/tasks/SchemaValidationAction.java index b11eee3..2a0b175 100644 --- a/src/main/java/de/kosit/validationtool/impl/tasks/SchemaValidationAction.java +++ b/src/main/java/de/kosit/validationtool/impl/tasks/SchemaValidationAction.java @@ -31,12 +31,6 @@ import javax.xml.validation.Validator; import org.apache.commons.io.FileUtils; import org.xml.sax.SAXException; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; - import de.kosit.validationtool.api.Input; import de.kosit.validationtool.impl.CollectingErrorEventHandler; import de.kosit.validationtool.impl.Scenario; @@ -45,7 +39,11 @@ import de.kosit.validationtool.impl.model.Result; import de.kosit.validationtool.model.reportInput.CreateReportInput; import de.kosit.validationtool.model.reportInput.ValidationResultsXmlSchema; import de.kosit.validationtool.model.reportInput.XMLSyntaxError; - +import lombok.AccessLevel; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; import net.sf.saxon.s9api.Processor; import net.sf.saxon.s9api.SaxonApiException; import net.sf.saxon.s9api.Serializer; @@ -216,7 +214,7 @@ public class SchemaValidationAction implements CheckAction { } } - private interface SerializedDocument extends AutoCloseable, SourceProvider { + private interface SerializedDocument extends SourceProvider { void serialize(XdmNode node) throws SaxonApiException, IOException; diff --git a/src/main/java/de/kosit/validationtool/impl/xml/ClassPathResourceResolver.java b/src/main/java/de/kosit/validationtool/impl/xml/ClassPathResourceResolver.java index d1a2cdd..d961b2f 100644 --- a/src/main/java/de/kosit/validationtool/impl/xml/ClassPathResourceResolver.java +++ b/src/main/java/de/kosit/validationtool/impl/xml/ClassPathResourceResolver.java @@ -22,7 +22,7 @@ import java.io.Reader; import java.net.URI; import java.net.URL; -import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Strings; import org.w3c.dom.ls.LSInput; import org.w3c.dom.ls.LSResourceResolver; @@ -90,7 +90,7 @@ public class ClassPathResourceResolver implements LSResourceResolver { * @param basePath der Basispfad */ public ClassPathResourceResolver(final String basePath) { - if (!StringUtils.startsWith(basePath, "/")) { + if (!Strings.CS.startsWith(basePath, "/")) { throw new IllegalArgumentException("Base path must start with a slash"); } this.base = URI.create(basePath + (basePath.endsWith("/") == basePath.length() > 1 ? "" : "/")); diff --git a/src/main/java/de/kosit/validationtool/impl/xml/RelativeUriResolver.java b/src/main/java/de/kosit/validationtool/impl/xml/RelativeUriResolver.java index b3b79e6..132ed7e 100644 --- a/src/main/java/de/kosit/validationtool/impl/xml/RelativeUriResolver.java +++ b/src/main/java/de/kosit/validationtool/impl/xml/RelativeUriResolver.java @@ -26,7 +26,6 @@ import javax.xml.transform.URIResolver; import javax.xml.transform.stream.StreamSource; import lombok.RequiredArgsConstructor; - import net.sf.saxon.Configuration; import net.sf.saxon.lib.StandardUnparsedTextResolver; import net.sf.saxon.lib.UnparsedTextURIResolver; @@ -54,10 +53,9 @@ public class RelativeUriResolver implements URIResolver, UnparsedTextURIResolver throw new TransformerException(String.format("Can not resolve required %s", href), e); } - } else { - throw new TransformerException(String - .format("The resolved transformation artifact %s is not within the configured repository %s", resolved, this.baseUri)); } + throw new TransformerException(String.format("The resolved transformation artifact %s is not within the configured repository %s", + resolved, this.baseUri)); } /** @@ -96,10 +94,9 @@ public class RelativeUriResolver implements URIResolver, UnparsedTextURIResolver public Reader resolve(final URI absoluteURI, final String encoding, final Configuration config) throws XPathException { if (isUnderBaseUri(absoluteURI, this.baseUri)) { return new StandardUnparsedTextResolver().resolve(absoluteURI, encoding, config); - } else { - throw new XPathException(String.format("The resolved transformation artifact %s is not within the configured repository %s", - absoluteURI, this.baseUri)); } + throw new XPathException(String.format("The resolved transformation artifact %s is not within the configured repository %s", + absoluteURI, this.baseUri)); } } \ No newline at end of file diff --git a/src/test/java/de/kosit/validationtool/api/InputFactoryTest.java b/src/test/java/de/kosit/validationtool/api/InputFactoryTest.java index 9031741..4a15843 100644 --- a/src/test/java/de/kosit/validationtool/api/InputFactoryTest.java +++ b/src/test/java/de/kosit/validationtool/api/InputFactoryTest.java @@ -25,16 +25,13 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Paths; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamSource; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.w3c.dom.Document; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; @@ -45,7 +42,6 @@ import de.kosit.validationtool.impl.TestObjectFactory; import de.kosit.validationtool.impl.input.SourceInput; import de.kosit.validationtool.impl.model.Result; import de.kosit.validationtool.model.reportInput.XMLSyntaxError; - import net.sf.saxon.dom.NodeOverNodeInfo; import net.sf.saxon.s9api.BuildingContentHandler; import net.sf.saxon.s9api.DocumentBuilder; @@ -61,9 +57,6 @@ public class InputFactoryTest { public static final String SOME_VALUE = "some value"; - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Test public void testDefaultDigestAlgorithm() { assertThat(new InputFactory().getAlgorithm()).isEqualTo(InputFactory.DEFAULT_ALGORITH); @@ -81,15 +74,13 @@ public class InputFactoryTest { assertThat(s1).isNotEqualTo(s3); } - @Test + @Test(expected = IllegalArgumentException.class) public void testWrongAlgorithm() { - this.expectedException.expect(IllegalArgumentException.class); new InputFactory("unknown"); } - @Test + @Test(expected = IllegalArgumentException.class) public void testNullInputURL() { - this.expectedException.expect(IllegalArgumentException.class); InputFactory.read((URL) null); } @@ -105,44 +96,40 @@ public class InputFactoryTest { assertThat(input).isNotNull(); } - @Test + @Test(expected = IllegalArgumentException.class) public void testNullStream() { - this.expectedException.expect(IllegalArgumentException.class); - final Input input = InputFactory.read((InputStream) null, SOME_VALUE); + InputFactory.read((InputStream) null, SOME_VALUE); } @Test - public void testInputFile() throws URISyntaxException { + public void testInputFile() { final Input input = InputFactory.read(new File(Simple.SIMPLE_VALID)); assertThat(input).isNotNull(); } @Test - public void testInputPath() throws URISyntaxException { + public void testInputPath() { final Input input = InputFactory.read(Paths.get(Simple.SIMPLE_VALID)); assertThat(input).isNotNull(); } - @Test + @Test(expected = IllegalArgumentException.class) public void testNullInput() { - this.expectedException.expect(IllegalArgumentException.class); InputFactory.read((byte[]) null, SOME_VALUE); } - @Test + @Test(expected = IllegalArgumentException.class) public void testNullInputName() { - this.expectedException.expect(IllegalArgumentException.class); InputFactory.read(SOME_VALUE.getBytes(), null); } - @Test + @Test(expected = IllegalArgumentException.class) public void testEmptyInputName() throws IOException { - this.expectedException.expect(IllegalArgumentException.class); final Input input = InputFactory.read(SOME_VALUE.getBytes(), ""); drain(input); } - @Test + @Test(expected = IllegalStateException.class) public void testSourceInput() throws IOException { try ( final InputStream s = Simple.SIMPLE_VALID.toURL().openStream() ) { final SourceInput input = (SourceInput) InputFactory.read(new StreamSource(s)); @@ -150,12 +137,11 @@ public class InputFactoryTest { drain(input); assertThat(input.getHashCode()).isNotNull(); assertThat(input.getLength()).isGreaterThan(0L); - this.expectedException.expect(IllegalStateException.class); input.getSource(); } } - @Test + @Test(expected = IllegalStateException.class) public void testSourceInputReader() throws IOException { try ( final InputStream s = Simple.SIMPLE_VALID.toURL().openStream(); final InputStreamReader reader = new InputStreamReader(s) ) { @@ -164,14 +150,12 @@ public class InputFactoryTest { drain(input); assertThat(input.getHashCode()).isNotNull(); assertThat(input.getLength()).isGreaterThan(0L); - this.expectedException.expect(IllegalStateException.class); input.getSource(); } } - @Test + @Test(expected = IllegalArgumentException.class) public void testUnexistingInput() { - this.expectedException.expect(IllegalArgumentException.class); InputFactory.read(Simple.NOT_EXISTING); } diff --git a/src/test/java/de/kosit/validationtool/cmd/CheckAssertionActionTest.java b/src/test/java/de/kosit/validationtool/cmd/CheckAssertionActionTest.java index 99d98c4..b8dda73 100644 --- a/src/test/java/de/kosit/validationtool/cmd/CheckAssertionActionTest.java +++ b/src/test/java/de/kosit/validationtool/cmd/CheckAssertionActionTest.java @@ -18,7 +18,6 @@ package de.kosit.validationtool.cmd; import static org.assertj.core.api.Assertions.assertThat; -import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; @@ -45,11 +44,8 @@ public class CheckAssertionActionTest { private static final URL SAMPLE_ASSERTIONS = CheckAssertionActionTest.class.getResource("/examples/assertions/tests-xrechnung.xml"); - private CommandLine commandLine; - @Before - public void setup() throws IOException { - this.commandLine = new CommandLine(); + public void setup() { CommandLine.activate(); } diff --git a/src/test/java/de/kosit/validationtool/cmd/CommandLine.java b/src/test/java/de/kosit/validationtool/cmd/CommandLine.java index b4a3338..37961a7 100644 --- a/src/test/java/de/kosit/validationtool/cmd/CommandLine.java +++ b/src/test/java/de/kosit/validationtool/cmd/CommandLine.java @@ -46,6 +46,7 @@ public class CommandLine { */ private static class ReplaceableOutputStream extends OutputStream { + @SuppressWarnings("hiding") @Getter @Setter private O out; diff --git a/src/test/java/de/kosit/validationtool/cmd/CommandlineApplicationTest.java b/src/test/java/de/kosit/validationtool/cmd/CommandlineApplicationTest.java index 86eb983..b9b2ed8 100644 --- a/src/test/java/de/kosit/validationtool/cmd/CommandlineApplicationTest.java +++ b/src/test/java/de/kosit/validationtool/cmd/CommandlineApplicationTest.java @@ -26,7 +26,7 @@ import java.nio.file.Paths; import java.util.List; import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Strings; import org.assertj.core.api.Condition; import org.junit.After; import org.junit.Before; @@ -45,13 +45,10 @@ public class CommandlineApplicationTest { public static final String RESULT_OUTPUT = "Processing 1 object(s) completed"; - private CommandLine commandLine; - private final Path output = Paths.get("target/test-output"); @Before public void setup() throws IOException { - this.commandLine = new CommandLine(); CommandLine.activate(); if (Files.exists(this.output)) { FileUtils.deleteDirectory(this.output.toFile()); @@ -194,7 +191,7 @@ public class CommandlineApplicationTest { CommandLineApplication.mainProgram(args); assertThat(CommandLine.getErrorOutput()).contains(RESULT_OUTPUT); assertThat(CommandLine.getOutputLines()).haveAtLeastOne(new Condition<>( - s -> StringUtils.contains(s, ""), "Must " + "contain xml preambel")); + s -> Strings.CS.contains(s, ""), "Must " + "contain xml preambel")); } @Test @@ -242,7 +239,7 @@ public class CommandlineApplicationTest { } @Test - public void testAndre() throws IOException { + public void testAndre() { final String[] args = { "-s", Paths.get(Simple.SCENARIOS).toString(), "-r", Paths.get(Simple.REPOSITORY_URI).toString(), Paths.get(Simple.SIMPLE_VALID).toString(), "--report-prefix", "andre1" }; CommandLineApplication.mainProgram(args); diff --git a/src/test/java/de/kosit/validationtool/cmd/PrintReportActionTest.java b/src/test/java/de/kosit/validationtool/cmd/PrintReportActionTest.java index 63c2732..cd015db 100644 --- a/src/test/java/de/kosit/validationtool/cmd/PrintReportActionTest.java +++ b/src/test/java/de/kosit/validationtool/cmd/PrintReportActionTest.java @@ -35,13 +35,10 @@ import de.kosit.validationtool.impl.tasks.CheckAction; */ public class PrintReportActionTest { - private CommandLine commandLine; - private PrintReportAction action; @Before public void setup() { - this.commandLine = new CommandLine(); CommandLine.activate(); this.action = new PrintReportAction(TestObjectFactory.createProcessor()); } diff --git a/src/test/java/de/kosit/validationtool/config/ConfigurationBuilderTest.java b/src/test/java/de/kosit/validationtool/config/ConfigurationBuilderTest.java index b9f9001..26aa915 100644 --- a/src/test/java/de/kosit/validationtool/config/ConfigurationBuilderTest.java +++ b/src/test/java/de/kosit/validationtool/config/ConfigurationBuilderTest.java @@ -20,15 +20,14 @@ import static de.kosit.validationtool.config.ConfigurationBuilder.report; import static de.kosit.validationtool.config.ConfigurationBuilder.schematron; import static de.kosit.validationtool.config.TestConfigurationFactory.createSimpleConfiguration; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.net.URI; import java.time.LocalDate; import java.util.Date; -import org.hamcrest.Matchers; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import de.kosit.validationtool.impl.Helper; @@ -41,58 +40,69 @@ public class ConfigurationBuilderTest { public static final LocalDate EPOCH = LocalDate.of(1970, 1, 1); - @Rule - public ExpectedException exceptions = ExpectedException.none(); - - @Test + @Test(expected = IllegalStateException.class) public void testNoConfiguration() { - this.exceptions.expect(IllegalStateException.class); new ConfigurationBuilder().build(Helper.getTestProcessor()); } @Test public void testNoFallback() { - this.exceptions.expect(IllegalStateException.class); - this.exceptions.expectMessage(Matchers.containsString("fallback")); - final ConfigurationBuilder builder = createSimpleConfiguration(); - builder.with((FallbackBuilder) null); - builder.build(Helper.getTestProcessor()); + try { + final ConfigurationBuilder builder = createSimpleConfiguration(); + builder.with((FallbackBuilder) null); + builder.build(Helper.getTestProcessor()); + fail(); + } catch (final IllegalStateException ex) { + assertTrue(ex.getMessage().contains("fallback")); + } } @Test public void testNoSchema() { - this.exceptions.expect(IllegalStateException.class); - this.exceptions.expectMessage(Matchers.containsString("schema")); - final ConfigurationBuilder builder = createSimpleConfiguration(); - builder.getScenarios().get(0).validate((SchemaBuilder) null); - builder.build(Helper.getTestProcessor()); + try { + final ConfigurationBuilder builder = createSimpleConfiguration(); + builder.getScenarios().get(0).validate((SchemaBuilder) null); + builder.build(Helper.getTestProcessor()); + fail(); + } catch (final IllegalStateException ex) { + assertTrue(ex.getMessage().contains("schema")); + } } @Test public void testInvalidSchematron() { - this.exceptions.expect(IllegalStateException.class); - this.exceptions.expectMessage(Matchers.containsString("schematron")); - final ConfigurationBuilder builder = createSimpleConfiguration(); - builder.getScenarios().get(0).validate(schematron("invalid").source(URI.create("DoesNotExist"))); - builder.build(Helper.getTestProcessor()); + try { + final ConfigurationBuilder builder = createSimpleConfiguration(); + builder.getScenarios().get(0).validate(schematron("invalid").source(URI.create("DoesNotExist"))); + builder.build(Helper.getTestProcessor()); + fail(); + } catch (final IllegalStateException ex) { + assertTrue(ex.getMessage().contains("schematron")); + } } @Test public void testInsufficientSchematron() { - this.exceptions.expect(IllegalStateException.class); - this.exceptions.expectMessage(Matchers.containsString("schematron")); - final ConfigurationBuilder builder = createSimpleConfiguration(); - builder.getScenarios().get(0).validate(schematron("invalid")); - builder.build(Helper.getTestProcessor()); + try { + final ConfigurationBuilder builder = createSimpleConfiguration(); + builder.getScenarios().get(0).validate(schematron("invalid")); + builder.build(Helper.getTestProcessor()); + fail(); + } catch (final IllegalStateException ex) { + assertTrue(ex.getMessage().contains("schematron")); + } } @Test public void testNoReport() { - this.exceptions.expect(IllegalStateException.class); - this.exceptions.expectMessage(Matchers.containsString("report")); - final ConfigurationBuilder builder = createSimpleConfiguration(); - builder.getScenarios().get(0).with(report("invalid")); - builder.build(Helper.getTestProcessor()); + try { + final ConfigurationBuilder builder = createSimpleConfiguration(); + builder.getScenarios().get(0).with(report("invalid")); + builder.build(Helper.getTestProcessor()); + fail(); + } catch (final IllegalStateException ex) { + assertTrue(ex.getMessage().contains("report")); + } } @Test diff --git a/src/test/java/de/kosit/validationtool/config/ScenarioBuilderTest.java b/src/test/java/de/kosit/validationtool/config/ScenarioBuilderTest.java index f9f5590..c1c635f 100644 --- a/src/test/java/de/kosit/validationtool/config/ScenarioBuilderTest.java +++ b/src/test/java/de/kosit/validationtool/config/ScenarioBuilderTest.java @@ -24,9 +24,7 @@ import java.util.List; import java.util.Map; import org.apache.commons.lang3.RandomStringUtils; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import de.kosit.validationtool.impl.ContentRepository; import de.kosit.validationtool.impl.Helper.Simple; @@ -43,9 +41,6 @@ import net.sf.saxon.s9api.XPathExecutable; */ public class ScenarioBuilderTest { - @Rule - public ExpectedException exceptions = ExpectedException.none(); - @Test public void simpleValid() { final Result result = createScenario().build(Simple.createContentRepository()); @@ -161,7 +156,7 @@ public class ScenarioBuilderTest { @Test public void testBasicAttributes() { final ContentRepository repository = Simple.createContentRepository(); - final String random = RandomStringUtils.random(5); + final String random = RandomStringUtils.secure().next(5); final ScenarioBuilder builder = createScenario(); builder.name(random).description(random); final Result result = builder.build(repository); diff --git a/src/test/java/de/kosit/validationtool/config/XPathBuilderTest.java b/src/test/java/de/kosit/validationtool/config/XPathBuilderTest.java index d55e7f7..c8a1646 100644 --- a/src/test/java/de/kosit/validationtool/config/XPathBuilderTest.java +++ b/src/test/java/de/kosit/validationtool/config/XPathBuilderTest.java @@ -28,7 +28,6 @@ import org.junit.Test; import de.kosit.validationtool.impl.ContentRepository; import de.kosit.validationtool.impl.Helper.Simple; import de.kosit.validationtool.impl.model.Result; - import net.sf.saxon.s9api.XPathExecutable; /** @@ -40,7 +39,7 @@ public class XPathBuilderTest { @Test public void testSimpleString() { - final String name = RandomStringUtils.randomAlphanumeric(5); + final String name = RandomStringUtils.secure().nextAlphanumeric(5); final XPathBuilder b = new XPathBuilder(name); b.setXpath("//*"); final Result result = b.build(Simple.createContentRepository()); @@ -54,7 +53,7 @@ public class XPathBuilderTest { @Test public void testStringWithNamespace() { - final String name = RandomStringUtils.randomAlphanumeric(5); + final String name = RandomStringUtils.secure().nextAlphanumeric(5); final XPathBuilder b = new XPathBuilder(name); final Map ns = new HashMap<>(); ns.put("p", "http://somens"); @@ -69,7 +68,7 @@ public class XPathBuilderTest { @Test public void testStringWithUnknownNamespace() { - final String name = RandomStringUtils.randomAlphanumeric(5); + final String name = RandomStringUtils.secure().nextAlphanumeric(5); final XPathBuilder b = new XPathBuilder(name); final Map ns = new HashMap<>(); ns.put("p", "http://somens"); @@ -82,7 +81,7 @@ public class XPathBuilderTest { @Test public void testExecutable() { - final String name = RandomStringUtils.randomAlphanumeric(5); + final String name = RandomStringUtils.secure().nextAlphanumeric(5); final ContentRepository repository = Simple.createContentRepository(); final XPathExecutable xpath = repository.createXPath("//*", Collections.emptyMap()); final XPathBuilder b = new XPathBuilder(name); @@ -96,7 +95,7 @@ public class XPathBuilderTest { @Test public void testExecutableWithNamespace() { - final String name = RandomStringUtils.randomAlphanumeric(5); + final String name = RandomStringUtils.secure().nextAlphanumeric(5); final ContentRepository repository = Simple.createContentRepository(); final Map ns = new HashMap<>(); ns.put("p", "http://somens"); @@ -123,7 +122,7 @@ public class XPathBuilderTest { @Test public void testNoConfig() { - final String name = RandomStringUtils.randomAlphanumeric(5); + final String name = RandomStringUtils.secure().nextAlphanumeric(5); final XPathBuilder b = new XPathBuilder(name); final Result result = b.build(Simple.createContentRepository()); assertThat(result).isNotNull(); diff --git a/src/test/java/de/kosit/validationtool/docs/MiscDocExampleCodes.java b/src/test/java/de/kosit/validationtool/docs/MiscDocExampleCodes.java index ae8aa29..9e56ed1 100644 --- a/src/test/java/de/kosit/validationtool/docs/MiscDocExampleCodes.java +++ b/src/test/java/de/kosit/validationtool/docs/MiscDocExampleCodes.java @@ -15,6 +15,7 @@ import net.sf.saxon.lib.UnparsedTextURIResolver; public class MiscDocExampleCodes { + @SuppressWarnings("unused") void m1() { final Configuration config = Configuration.load(URI.create("myscenarios.xml")).setResolvingMode(ResolvingMode.STRICT_LOCAL) .build(ProcessorProvider.getProcessor()); @@ -43,6 +44,7 @@ public class MiscDocExampleCodes { } } + @SuppressWarnings("unused") void m2() { final Configuration config = Configuration.load(URI.create("myscenarios.xml")) .setResolvingStrategy(new MyCustomResolvingConfigurationStrategy()).build(ProcessorProvider.getProcessor()); diff --git a/src/test/java/de/kosit/validationtool/docs/MyValidator.java b/src/test/java/de/kosit/validationtool/docs/MyValidator.java index 7d4acd9..56536a6 100644 --- a/src/test/java/de/kosit/validationtool/docs/MyValidator.java +++ b/src/test/java/de/kosit/validationtool/docs/MyValidator.java @@ -19,6 +19,7 @@ import de.kosit.validationtool.impl.xml.ProcessorProvider; */ public class MyValidator { + @SuppressWarnings("unused") public static void main(final String[] args) { final Configuration config = Configuration.create().name("myconfiguration") .with(scenario("firstScenario").match("//myNode").validate(schema("Sample Schema").schemaLocation(URI.create("simple.xsd"))) diff --git a/src/test/java/de/kosit/validationtool/docs/StandardExample.java b/src/test/java/de/kosit/validationtool/docs/StandardExample.java index 71025fe..e2408d2 100644 --- a/src/test/java/de/kosit/validationtool/docs/StandardExample.java +++ b/src/test/java/de/kosit/validationtool/docs/StandardExample.java @@ -20,6 +20,7 @@ import de.kosit.validationtool.impl.xml.ProcessorProvider; */ public class StandardExample { + @SuppressWarnings("unused") public void run(final Path testDocument) throws URISyntaxException { // Load scenarios.xml from classpath final URL scenarios = this.getClass().getClassLoader().getResource("examples/simple/scenarios-with-relative-paths.xml"); diff --git a/src/test/java/de/kosit/validationtool/impl/ContentRepositoryTest.java b/src/test/java/de/kosit/validationtool/impl/ContentRepositoryTest.java index 4fe3422..c63f2f5 100644 --- a/src/test/java/de/kosit/validationtool/impl/ContentRepositoryTest.java +++ b/src/test/java/de/kosit/validationtool/impl/ContentRepositoryTest.java @@ -28,12 +28,9 @@ import java.util.Map; import javax.xml.validation.Schema; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import de.kosit.validationtool.impl.Helper.Simple; - import net.sf.saxon.s9api.XPathExecutable; import net.sf.saxon.s9api.XsltExecutable; @@ -46,9 +43,6 @@ public class ContentRepositoryTest { private ContentRepository repository; - @Rule - public ExpectedException exception = ExpectedException.none(); - @Before public void setup() { this.repository = Simple.createContentRepository(); @@ -60,9 +54,8 @@ public class ContentRepositoryTest { assertThat(schema).isNotNull(); } - @Test + @Test(expected = IllegalStateException.class) public void testCreateSchemaNotExisting() throws Exception { - this.exception.expect(IllegalStateException.class); this.repository.createSchema(Simple.NOT_EXISTING.toURL()); } @@ -72,9 +65,8 @@ public class ContentRepositoryTest { assertThat(executable).isNotNull(); } - @Test + @Test(expected = IllegalStateException.class) public void testLoadXSLTNotExisting() { - this.exception.expect(IllegalStateException.class); this.repository.loadXsltScript(Simple.NOT_EXISTING); } @@ -90,15 +82,13 @@ public class ContentRepositoryTest { assertThat(xPath).isNotNull(); } - @Test + @Test(expected = IllegalStateException.class) public void testXpathCreationWithoutNamespace() { - this.exception.expect(IllegalStateException.class); this.repository.createXPath("//html:html", null); } - @Test + @Test(expected = IllegalStateException.class) public void testIllegalXpath() { - this.exception.expect(IllegalStateException.class); this.repository.createXPath("kein Xpath Ausdruck", null); } diff --git a/src/test/java/de/kosit/validationtool/impl/ConversionServiceTest.java b/src/test/java/de/kosit/validationtool/impl/ConversionServiceTest.java index 6c74b18..97ad5de 100644 --- a/src/test/java/de/kosit/validationtool/impl/ConversionServiceTest.java +++ b/src/test/java/de/kosit/validationtool/impl/ConversionServiceTest.java @@ -16,16 +16,13 @@ package de.kosit.validationtool.impl; -import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import java.io.Serializable; -import java.net.URISyntaxException; import java.net.URL; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import de.kosit.validationtool.impl.Helper.Invalid; import de.kosit.validationtool.impl.Helper.Simple; @@ -40,9 +37,6 @@ public class ConversionServiceTest { private static final URL SCHEMA = ConversionServiceTest.class.getResource("/xsd/scenarios.xsd"); - @Rule - public ExpectedException exception = ExpectedException.none(); - private ConversionService service; private ContentRepository repository; @@ -53,15 +47,13 @@ public class ConversionServiceTest { this.repository = Simple.createContentRepository(); } - @Test + @Test(expected = ConversionService.ConversionExeption.class) public void testMarshalNull() { - this.exception.expect(ConversionService.ConversionExeption.class); this.service.writeXml(null); } - @Test + @Test(expected = ConversionService.ConversionExeption.class) public void testMarshalUnknown() { - this.exception.expect(ConversionService.ConversionExeption.class); this.service.writeXml(new Serializable() { }); } @@ -80,33 +72,28 @@ public class ConversionServiceTest { assertThat(s.getName()).isEqualToIgnoringCase("HTML-TestSuite"); } - @Test + @Test(expected = ConversionService.ConversionExeption.class) public void testUnmarshalInvalidXml() { - this.exception.expect(ConversionService.ConversionExeption.class); this.service.readXml(Invalid.SCENARIOS, Scenarios.class, this.repository.createSchema(SCHEMA)); } - @Test + @Test(expected = ConversionService.ConversionExeption.class) public void testUnmarshalIllFormed() { - this.exception.expect(ConversionService.ConversionExeption.class); this.service.readXml(Invalid.SCENARIOS_ILLFORMED, Scenarios.class, this.repository.createSchema(SCHEMA)); } - @Test + @Test(expected = ConversionService.ConversionExeption.class) public void testUnmarshalEmpty() { - this.exception.expect(ConversionService.ConversionExeption.class); this.service.readXml(null, Scenarios.class); } - @Test - public void testUnmarshalUnknownType() throws URISyntaxException { - this.exception.expect(ConversionService.ConversionExeption.class); + @Test(expected = ConversionService.ConversionExeption.class) + public void testUnmarshalUnknownType() { this.service.readXml(Simple.SCENARIOS, ConversionService.class); } - @Test - public void testUnmarshalWithoutType() throws URISyntaxException { - this.exception.expect(ConversionService.ConversionExeption.class); + @Test(expected = ConversionService.ConversionExeption.class) + public void testUnmarshalWithoutType() { this.service.readXml(Simple.SCENARIOS, null); } diff --git a/src/test/java/de/kosit/validationtool/impl/RelativeUriResolverTest.java b/src/test/java/de/kosit/validationtool/impl/RelativeUriResolverTest.java index 5ce1030..4a5f937 100644 --- a/src/test/java/de/kosit/validationtool/impl/RelativeUriResolverTest.java +++ b/src/test/java/de/kosit/validationtool/impl/RelativeUriResolverTest.java @@ -26,9 +26,7 @@ import javax.xml.transform.Source; import javax.xml.transform.TransformerException; import javax.xml.transform.URIResolver; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import de.kosit.validationtool.impl.xml.RelativeUriResolver; @@ -49,9 +47,6 @@ public class RelativeUriResolverTest { } } - @Rule - public ExpectedException exception = ExpectedException.none(); - private URIResolver resolver = new RelativeUriResolver(BASE); @Test @@ -60,15 +55,13 @@ public class RelativeUriResolverTest { assertThat(resource).isNotNull(); } - @Test + @Test(expected = TransformerException.class) public void testNotExisting() throws TransformerException { - this.exception.expect(TransformerException.class); this.resolver.resolve("ubl-0001", BASE.toASCIIString()); } - @Test + @Test(expected = TransformerException.class) public void testOutOfPath() throws TransformerException { - this.exception.expect(TransformerException.class); this.resolver.resolve("../results/report.xml", BASE.toASCIIString()); } diff --git a/src/test/java/de/kosit/validationtool/impl/ScenarioRepositoryTest.java b/src/test/java/de/kosit/validationtool/impl/ScenarioRepositoryTest.java index 9bdc1fc..2c39f9c 100644 --- a/src/test/java/de/kosit/validationtool/impl/ScenarioRepositoryTest.java +++ b/src/test/java/de/kosit/validationtool/impl/ScenarioRepositoryTest.java @@ -25,15 +25,12 @@ import java.util.ArrayList; import java.util.HashMap; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import de.kosit.validationtool.config.TestConfiguration; import de.kosit.validationtool.impl.Helper.Simple; import de.kosit.validationtool.impl.model.Result; import de.kosit.validationtool.model.scenarios.ScenarioType; - import net.sf.saxon.s9api.XPathExecutable; import net.sf.saxon.s9api.XdmNode; @@ -45,9 +42,6 @@ import net.sf.saxon.s9api.XdmNode; public class ScenarioRepositoryTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - private ScenarioRepository repository; private TestConfiguration configInstance; @@ -107,9 +101,8 @@ public class ScenarioRepositoryTest { assertThat(scenario.getObject().getName()).isEqualTo("fallback"); } - @Test + @Test(expected = IllegalArgumentException.class) public void testNoConfiguration() { - this.expectedException.expect(IllegalArgumentException.class); this.repository = new ScenarioRepository(); } diff --git a/src/test/java/de/kosit/validationtool/impl/VersioningTest.java b/src/test/java/de/kosit/validationtool/impl/VersioningTest.java index 4c40c4e..da310ba 100644 --- a/src/test/java/de/kosit/validationtool/impl/VersioningTest.java +++ b/src/test/java/de/kosit/validationtool/impl/VersioningTest.java @@ -22,11 +22,8 @@ import java.net.URISyntaxException; import java.net.URL; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; -import de.kosit.validationtool.impl.Helper.Simple; import de.kosit.validationtool.model.scenarios.Scenarios; /** @@ -44,16 +41,10 @@ public class VersioningTest { private static final URL NEW_VERSION = VersioningTest.class.getResource("/examples/versioning/scenarios-newversion.xml"); - @Rule - public ExpectedException exception = ExpectedException.none(); - private ConversionService service; - private ContentRepository repository; - @Before public void setup() { - this.repository = Simple.createContentRepository(); this.service = new ConversionService(); } @@ -69,15 +60,13 @@ public class VersioningTest { assertThat(result).isNotNull(); } - @Test + @Test(expected = ConversionService.ConversionExeption.class) public void testNewFeature() throws URISyntaxException { - this.exception.expect(ConversionService.ConversionExeption.class); this.service.readXml(NEW_FEATURE.toURI(), Scenarios.class, SchemaProvider.getScenarioSchema()); } - @Test + @Test(expected = ConversionService.ConversionExeption.class) public void testNewVersion() throws URISyntaxException { - this.exception.expect(ConversionService.ConversionExeption.class); this.service.readXml(NEW_VERSION.toURI(), Scenarios.class, SchemaProvider.getScenarioSchema()); } } diff --git a/src/test/java/de/kosit/validationtool/impl/tasks/DocumentParseActionTest.java b/src/test/java/de/kosit/validationtool/impl/tasks/DocumentParseActionTest.java index d0b721f..ae53d5b 100644 --- a/src/test/java/de/kosit/validationtool/impl/tasks/DocumentParseActionTest.java +++ b/src/test/java/de/kosit/validationtool/impl/tasks/DocumentParseActionTest.java @@ -20,15 +20,12 @@ import static de.kosit.validationtool.api.InputFactory.read; import static org.assertj.core.api.Assertions.assertThat; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import de.kosit.validationtool.impl.Helper; import de.kosit.validationtool.impl.Helper.Simple; import de.kosit.validationtool.impl.model.Result; import de.kosit.validationtool.model.reportInput.XMLSyntaxError; - import net.sf.saxon.s9api.XdmNode; /** @@ -38,9 +35,6 @@ import net.sf.saxon.s9api.XdmNode; */ public class DocumentParseActionTest { - @Rule - public ExpectedException exception = ExpectedException.none(); - private DocumentParseAction action; @Before @@ -66,9 +60,8 @@ public class DocumentParseActionTest { assertThat(result.isValid()).isFalse(); } - @Test + @Test(expected = IllegalArgumentException.class) public void testNullInput() { - this.exception.expect(IllegalArgumentException.class); this.action.parseDocument(null); } diff --git a/src/test/java/de/kosit/validationtool/impl/tasks/SchemaValidatorActionTest.java b/src/test/java/de/kosit/validationtool/impl/tasks/SchemaValidatorActionTest.java index d02d4d4..0732541 100644 --- a/src/test/java/de/kosit/validationtool/impl/tasks/SchemaValidatorActionTest.java +++ b/src/test/java/de/kosit/validationtool/impl/tasks/SchemaValidatorActionTest.java @@ -35,7 +35,6 @@ import javax.xml.validation.Validator; import org.junit.Before; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.xml.sax.SAXException; import de.kosit.validationtool.api.Input; @@ -56,8 +55,6 @@ import de.kosit.validationtool.impl.tasks.CheckAction.Bag; */ public class SchemaValidatorActionTest { - public ExpectedException expectedException = ExpectedException.none(); - private SchemaValidationAction service; @Before diff --git a/src/test/java/de/kosit/validationtool/impl/xml/BaseResolverConfigurationTest.java b/src/test/java/de/kosit/validationtool/impl/xml/BaseResolverConfigurationTest.java index 631ff81..fbae6f1 100644 --- a/src/test/java/de/kosit/validationtool/impl/xml/BaseResolverConfigurationTest.java +++ b/src/test/java/de/kosit/validationtool/impl/xml/BaseResolverConfigurationTest.java @@ -25,9 +25,7 @@ import static org.mockito.Mockito.verify; import javax.xml.XMLConstants; import javax.xml.validation.SchemaFactory; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotSupportedException; @@ -51,9 +49,6 @@ public class BaseResolverConfigurationTest { public static final String NOT_EXISTING_SCHEME = "not-existing-scheme"; - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Test public void testIgnoreUnsupportedProperty() throws SAXNotRecognizedException, SAXNotSupportedException { final SchemaFactory sf = mock(SchemaFactory.class); @@ -62,9 +57,8 @@ public class BaseResolverConfigurationTest { s.setInternalProperty(sf, true); } - @Test + @Test(expected = IllegalStateException.class) public void testFailOnUnsupportedProperty() throws SAXNotRecognizedException, SAXNotSupportedException { - this.expectedException.expect(IllegalStateException.class); final SchemaFactory sf = mock(SchemaFactory.class); final TestResolvingStrategy s = new TestResolvingStrategy(); doThrow(new SAXNotRecognizedException("not supported")).when(sf).setProperty(any(), any()); diff --git a/src/test/java/de/kosit/validationtool/impl/xml/RemoteResolvingStrategyTest.java b/src/test/java/de/kosit/validationtool/impl/xml/RemoteResolvingStrategyTest.java index 431bc3a..a80a15b 100644 --- a/src/test/java/de/kosit/validationtool/impl/xml/RemoteResolvingStrategyTest.java +++ b/src/test/java/de/kosit/validationtool/impl/xml/RemoteResolvingStrategyTest.java @@ -21,9 +21,7 @@ import static org.assertj.core.api.Assertions.assertThat; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import de.kosit.validationtool.api.ResolvingConfigurationStrategy; import de.kosit.validationtool.impl.Helper.Resolving; @@ -35,9 +33,6 @@ import de.kosit.validationtool.impl.Helper.Resolving; */ public class RemoteResolvingStrategyTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Test public void testRemoteSchemaResolving() throws Exception { final ResolvingConfigurationStrategy s = new RemoteResolvingStrategy(); diff --git a/src/test/java/de/kosit/validationtool/impl/xml/SchemaProviderTest.java b/src/test/java/de/kosit/validationtool/impl/xml/SchemaProviderTest.java index 6e50378..8d9e442 100644 --- a/src/test/java/de/kosit/validationtool/impl/xml/SchemaProviderTest.java +++ b/src/test/java/de/kosit/validationtool/impl/xml/SchemaProviderTest.java @@ -16,8 +16,12 @@ package de.kosit.validationtool.impl.xml; +import static org.junit.Assert.assertNotNull; + import javax.xml.validation.SchemaFactory; +import org.junit.Test; + import de.kosit.validationtool.impl.ResolvingMode; /** @@ -25,6 +29,10 @@ import de.kosit.validationtool.impl.ResolvingMode; */ public class SchemaProviderTest { - private final SchemaFactory schemaFactory = ResolvingMode.STRICT_RELATIVE.getStrategy().createSchemaFactory(); + @Test + public void testBasic() { + final SchemaFactory schemaFactory = ResolvingMode.STRICT_RELATIVE.getStrategy().createSchemaFactory(); + assertNotNull(schemaFactory); + } } diff --git a/src/test/java/de/kosit/validationtool/impl/xml/StrictLocalResolvingTest.java b/src/test/java/de/kosit/validationtool/impl/xml/StrictLocalResolvingTest.java index 4c95953..8929d2c 100644 --- a/src/test/java/de/kosit/validationtool/impl/xml/StrictLocalResolvingTest.java +++ b/src/test/java/de/kosit/validationtool/impl/xml/StrictLocalResolvingTest.java @@ -17,14 +17,13 @@ package de.kosit.validationtool.impl.xml; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; +import static org.junit.Assert.assertTrue; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; -import org.hamcrest.Matchers; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.xml.sax.SAXParseException; import de.kosit.validationtool.api.ResolvingConfigurationStrategy; @@ -37,16 +36,16 @@ import de.kosit.validationtool.impl.Helper.Resolving; */ public class StrictLocalResolvingTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Test public void testRemoteSchemaResolving() throws Exception { - this.expectedException.expect(SAXParseException.class); - this.expectedException.expectMessage(Matchers.containsString("schema_reference")); - final ResolvingConfigurationStrategy s = new StrictLocalResolvingStrategy(); - final SchemaFactory schemaFactory = s.createSchemaFactory(); - schemaFactory.newSchema(Resolving.SCHEMA_WITH_REMOTE_REFERENCE.toURL()); + try { + final ResolvingConfigurationStrategy s = new StrictLocalResolvingStrategy(); + final SchemaFactory schemaFactory = s.createSchemaFactory(); + schemaFactory.newSchema(Resolving.SCHEMA_WITH_REMOTE_REFERENCE.toURL()); + fail(); + } catch (SAXParseException ex) { + assertTrue(ex.getMessage().contains("schema_reference")); + } } @Test diff --git a/src/test/java/de/kosit/validationtool/impl/xml/StrictRelativeResolvingTest.java b/src/test/java/de/kosit/validationtool/impl/xml/StrictRelativeResolvingTest.java index 32d5017..3b80d3d 100644 --- a/src/test/java/de/kosit/validationtool/impl/xml/StrictRelativeResolvingTest.java +++ b/src/test/java/de/kosit/validationtool/impl/xml/StrictRelativeResolvingTest.java @@ -17,14 +17,13 @@ package de.kosit.validationtool.impl.xml; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; +import static org.junit.Assert.assertTrue; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; -import org.hamcrest.Matchers; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.xml.sax.SAXParseException; import de.kosit.validationtool.api.ResolvingConfigurationStrategy; @@ -37,16 +36,16 @@ import de.kosit.validationtool.impl.Helper.Resolving; */ public class StrictRelativeResolvingTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Test public void testRemoteSchemaResolving() throws Exception { - this.expectedException.expect(SAXParseException.class); - this.expectedException.expectMessage(Matchers.containsString("schema_reference")); - final ResolvingConfigurationStrategy s = new StrictLocalResolvingStrategy(); - final SchemaFactory schemaFactory = s.createSchemaFactory(); - schemaFactory.newSchema(Resolving.SCHEMA_WITH_REMOTE_REFERENCE.toURL()); + try { + final ResolvingConfigurationStrategy s = new StrictLocalResolvingStrategy(); + final SchemaFactory schemaFactory = s.createSchemaFactory(); + schemaFactory.newSchema(Resolving.SCHEMA_WITH_REMOTE_REFERENCE.toURL()); + fail(); + } catch (SAXParseException ex) { + assertTrue(ex.getMessage().contains("schema_reference")); + } } @Test From f2d77b01e9d934d5ae46a67924024dac7728638e Mon Sep 17 00:00:00 2001 From: Philip Helger Date: Wed, 5 Nov 2025 13:51:41 +0100 Subject: [PATCH 15/28] Version bump --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4b4eada..4e03289 100644 --- a/pom.xml +++ b/pom.xml @@ -50,7 +50,7 @@ 5.5.5 12.8 2.0.17 - 4.0.9 + 4.0.11 From 140b6d009d6c03998b32bc69c4debcd89e1a3f4e Mon Sep 17 00:00:00 2001 From: Philip Helger Date: Wed, 5 Nov 2025 13:55:49 +0100 Subject: [PATCH 16/28] Re-added Java 25 --- .gitlab-ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cf82b43..1d43ba7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -70,9 +70,9 @@ java-24: extends: .java_extended image: $CI_REGISTRY_IMAGE/maven:3-eclipse-temurin-24-alpine -#java-25: -# extends: .java -# image: $CI_REGISTRY_IMAGE/maven:3-eclipse-temurin-25-alpine +java-25: + extends: .java + image: $CI_REGISTRY_IMAGE/maven:3-eclipse-temurin-25-alpine deploy: stage: deploy From 53a967f4a8480878dd91fbe985614a9501ffbba3 Mon Sep 17 00:00:00 2001 From: Philip Helger Date: Wed, 5 Nov 2025 14:01:29 +0100 Subject: [PATCH 17/28] Official images --- .gitlab-ci.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1d43ba7..f088435 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -39,7 +39,7 @@ cache: java-11: extends: .java - image: $CI_REGISTRY_IMAGE/maven:3-eclipse-temurin-11-alpine + image: maven:3-eclipse-temurin-11-alpine needs: [ ] script: - mvn $MAVEN_CLI_OPTS $BUILD_PROPS $CI_JOB_TIMESTAMP install @@ -56,27 +56,27 @@ java-11: java-11-openj9: extends: .java_extended - image: $CI_REGISTRY_IMAGE/maven:3-jdk-11-openj9 + image: maven:3-jdk-11-openj9 java-17: extends: .java - image: $CI_REGISTRY_IMAGE/maven:3-eclipse-temurin-17-alpine + image: maven:3-eclipse-temurin-17-alpine java-21: extends: .java - image: $CI_REGISTRY_IMAGE/maven:3-eclipse-temurin-21-alpine + image: maven:3-eclipse-temurin-21-alpine java-24: extends: .java_extended - image: $CI_REGISTRY_IMAGE/maven:3-eclipse-temurin-24-alpine + image: maven:3-eclipse-temurin-24-alpine java-25: extends: .java - image: $CI_REGISTRY_IMAGE/maven:3-eclipse-temurin-25-alpine + image: maven:3-eclipse-temurin-25-alpine deploy: stage: deploy - image: $CI_REGISTRY_IMAGE/maven:3-eclipse-temurin-11-alpine + image: maven:3-eclipse-temurin-11-alpine needs: - job: java-11 script: @@ -110,7 +110,7 @@ create-build-image: owasp-check: extends: .java - image: $CI_REGISTRY_IMAGE/maven:3-eclipse-temurin-11-alpine + image: maven:3-eclipse-temurin-11-alpine needs: [ ] script: - mvn $MAVEN_CLI_OPTS $BUILD_PROPS $CI_JOB_TIMESTAMP validate -Powasp-check From f412f721102a3f330ab91559013634036ed07849 Mon Sep 17 00:00:00 2001 From: Renzo Kottmann Date: Wed, 5 Nov 2025 18:31:08 +0100 Subject: [PATCH 18/28] chore: bump exec plugin to 3.6.2, use successCode for broken daemon shutdown --- pom.xml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 4e03289..a1c09a7 100644 --- a/pom.xml +++ b/pom.xml @@ -458,7 +458,7 @@ org.codehaus.mojo exec-maven-plugin - 3.5.0 + 3.6.2 run @@ -469,10 +469,15 @@ + true + + 0,1 java false true true + + false ${jacocoFailsafe} @@ -500,7 +505,7 @@ - ${jacoco.tcp.port} + jacoco.tcp.port=${jacoco.tcp.port} From 9601f921e5d6fdc8593e894c954e6f5c4d2d0462 Mon Sep 17 00:00:00 2001 From: Renzo Kottmann Date: Wed, 5 Nov 2025 18:31:08 +0100 Subject: [PATCH 19/28] chore: bump exec plugin to 3.6.2, use successCode for broken daemon shutdown --- pom.xml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 4e03289..c8c35f6 100644 --- a/pom.xml +++ b/pom.xml @@ -458,7 +458,7 @@ org.codehaus.mojo exec-maven-plugin - 3.5.0 + 3.6.2 run @@ -469,10 +469,15 @@ + true + + 0,1 java false true true + + false ${jacocoFailsafe} @@ -500,7 +505,7 @@ - ${jacoco.tcp.port} + jacoco.tcp.port=${jacoco.tcp.port} From 32bec7c749c9087e90228d384c6ba335b8031e20 Mon Sep 17 00:00:00 2001 From: Renzo Kottmann Date: Thu, 6 Nov 2025 13:23:14 +0100 Subject: [PATCH 20/28] chore: add release date for 1.6.0 to Changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05b839d..765ed85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 1.6.0 +## 1.6.0 - 2025-11-07 ### Added From f338f5f5f58cf47231a2902dbbe95a1a3837c39b Mon Sep 17 00:00:00 2001 From: Renzo Kottmann Date: Thu, 6 Nov 2025 13:32:47 +0100 Subject: [PATCH 21/28] [maven-release-plugin] prepare release v1.6.0 --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index c8c35f6..804d10f 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.kosit validator - 1.6.0-SNAPSHOT + 1.6.0 KoSIT XML Validator against XSD and Schematron based on defined scenarios. @@ -505,7 +505,7 @@ - jacoco.tcp.port=${jacoco.tcp.port} + jacoco.tcp.port=${jacoco.tcp.port} @@ -686,7 +686,7 @@ scm:git:https://github.com/itplr-kosit/validator.git scm:git:https://projekte.kosit.org/kosit/validator.git - release/1.6.x + v1.6.0 https://github.com/itplr-kosit/validator From 535d88c829a6dc7684e33cb03463948c4b56c509 Mon Sep 17 00:00:00 2001 From: Renzo Kottmann Date: Thu, 6 Nov 2025 13:32:55 +0100 Subject: [PATCH 22/28] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 804d10f..1003edc 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.kosit validator - 1.6.0 + 1.6.1-SNAPSHOT KoSIT XML Validator against XSD and Schematron based on defined scenarios. @@ -686,7 +686,7 @@ scm:git:https://github.com/itplr-kosit/validator.git scm:git:https://projekte.kosit.org/kosit/validator.git - v1.6.0 + release/1.6.x https://github.com/itplr-kosit/validator From 091c2c643c5bd5f31e5e5e79b67419bd5056cdd1 Mon Sep 17 00:00:00 2001 From: Renzo Kottmann Date: Fri, 7 Nov 2025 11:17:06 +0100 Subject: [PATCH 23/28] Add Unreleased section to Changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 765ed85..ef56bf3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## Unreleased + + ## 1.6.0 - 2025-11-07 ### Added From 29766cf34b5ee4d6e314fa9ced0dbf5b39ab360d Mon Sep 17 00:00:00 2001 From: Renzo Kottmann Date: Fri, 7 Nov 2025 11:17:32 +0100 Subject: [PATCH 24/28] chore: Minor correction --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1003edc..7269c73 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ fabian.buettner Fabian Büttner KoSIT - https://xeinkauf.de/ + https://xoev.de/ renzo.kottmann From af3ba73daf8465b0194b5bf67498aeea542dcf1c Mon Sep 17 00:00:00 2001 From: Philip Helger Date: Fri, 7 Nov 2025 13:10:45 +0100 Subject: [PATCH 25/28] Updated API code snippet in readme for GitHub #117 --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e87dedb..a363a7d 100644 --- a/README.md +++ b/README.md @@ -74,12 +74,12 @@ The [CLI documentation](./docs/cli.md) shows further configuration options. The Validator can also be used in own Java Applications via the API. An example use of the API as follows: ```java -Path scenarios = Paths.get("scenarios.xml"); -Configuration config = Configuration.load(scenarios.toUri()); -Input document = InputFactory.read(testDocument); - +URL scenarios = this.getClass().getClassLoader().getResource("scenarios.xml"); +Configuration config = Configuration.load(scenarios.toURI()).build(ProcessorProvider.getProcessor()); Check validator = new DefaultCheck(config); -Result validationResult = validator.checkInput(document); + +Input document = InputFactory.read(testDocument); +Result report = validator.checkInput(document); // examine the result here ``` @@ -139,8 +139,8 @@ To use the standalone version with Maven coordinates, add the respective classif This section describes the next steps planned in the Validator development. -* Release version 1.6.0 based on Java 11 and using Jakarta 4.x. - Autumn 2025 - * Drop support of version 1.5.x when version 1.6 is released +* Version 1.5.x is frozen - no maintainance, no support +* Version 1.6.x - no feature development, but maintainance and best-effort support * Develop version 2.0.0 which will include major API incompatibilities - Winter 2025 * Rework scenarios.xml * Rework report output engine From 28e85d3942c466108a9435560ee0ba356571651f Mon Sep 17 00:00:00 2001 From: Renzo Kottmann Date: Fri, 7 Nov 2025 15:04:48 +0100 Subject: [PATCH 26/28] Upgrade mvn owasp dep check to 12.1.8 --- pom.xml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 7269c73..5d04818 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ 4.0.5 1.18.42 4.11.0 - 10.0.4 + 12.1.8 5.5.5 12.8 2.0.17 @@ -239,7 +239,8 @@ - [3.3.9,) + + [3.6.3,) 0 ${project.basedir}/owasp-suppressions.xml From 7f180881bb21c5b9ff4ddf738675e76a678079f6 Mon Sep 17 00:00:00 2001 From: Renzo Kottmann Date: Fri, 7 Nov 2025 15:04:48 +0100 Subject: [PATCH 27/28] Upgrade mvn owasp dep check to 12.1.8 --- pom.xml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 7269c73..5d04818 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ 4.0.5 1.18.42 4.11.0 - 10.0.4 + 12.1.8 5.5.5 12.8 2.0.17 @@ -239,7 +239,8 @@ - [3.3.9,) + + [3.6.3,) 0 ${project.basedir}/owasp-suppressions.xml From e5acc2535ba030b322a1dbf6caf1a95e23869f8b Mon Sep 17 00:00:00 2001 From: Philip Helger Date: Fri, 7 Nov 2025 13:10:45 +0100 Subject: [PATCH 28/28] Updated API code snippet in readme for GitHub #117 --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e87dedb..a363a7d 100644 --- a/README.md +++ b/README.md @@ -74,12 +74,12 @@ The [CLI documentation](./docs/cli.md) shows further configuration options. The Validator can also be used in own Java Applications via the API. An example use of the API as follows: ```java -Path scenarios = Paths.get("scenarios.xml"); -Configuration config = Configuration.load(scenarios.toUri()); -Input document = InputFactory.read(testDocument); - +URL scenarios = this.getClass().getClassLoader().getResource("scenarios.xml"); +Configuration config = Configuration.load(scenarios.toURI()).build(ProcessorProvider.getProcessor()); Check validator = new DefaultCheck(config); -Result validationResult = validator.checkInput(document); + +Input document = InputFactory.read(testDocument); +Result report = validator.checkInput(document); // examine the result here ``` @@ -139,8 +139,8 @@ To use the standalone version with Maven coordinates, add the respective classif This section describes the next steps planned in the Validator development. -* Release version 1.6.0 based on Java 11 and using Jakarta 4.x. - Autumn 2025 - * Drop support of version 1.5.x when version 1.6 is released +* Version 1.5.x is frozen - no maintainance, no support +* Version 1.6.x - no feature development, but maintainance and best-effort support * Develop version 2.0.0 which will include major API incompatibilities - Winter 2025 * Rework scenarios.xml * Rework report output engine