From bd60ddc41d02caed98883a0ab2c275883926aac3 Mon Sep 17 00:00:00 2001 From: Renzo Kottmann Date: Wed, 18 Mar 2020 15:51:46 +0100 Subject: [PATCH 01/29] Translate to English --- .../kosit/validationtool/api/AcceptRecommendation.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/de/kosit/validationtool/api/AcceptRecommendation.java b/src/main/java/de/kosit/validationtool/api/AcceptRecommendation.java index 3d07933..c491201 100644 --- a/src/main/java/de/kosit/validationtool/api/AcceptRecommendation.java +++ b/src/main/java/de/kosit/validationtool/api/AcceptRecommendation.java @@ -1,21 +1,21 @@ package de.kosit.validationtool.api; /** - * Status der Empfehlung. + * Tri-state describtion of a Recommendation. */ public enum AcceptRecommendation { /** - * Nicht definiert, weil eine Evaluierung nicht durchgeführt wurde, oder nicht durchgeführt werden konnte. + * The evaluation of the overall validation could not be computed. */ UNDEFINED, /** - * Das Dokument ist gemäß Konfiguration valide und kann akzeptiert werden. + * Recommendation is to accept input based on the evaluation of the overall validation. */ ACCEPTABLE, /** - * Das Dokuemnt ist gemäß Konfiguration invalide und sollte NICHT akzeptiert werden. + * Recommendation is to reject input based on the evaluation of the overall validation. */ REJECT -} \ No newline at end of file +} From 13acb9ff7e774aa9caf7449e136423772d5be774 Mon Sep 17 00:00:00 2001 From: Renzo Kottmann Date: Wed, 18 Mar 2020 15:52:37 +0100 Subject: [PATCH 02/29] Translate getAcceptRecommendation javadoc to English --- .../java/de/kosit/validationtool/api/Result.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/de/kosit/validationtool/api/Result.java b/src/main/java/de/kosit/validationtool/api/Result.java index 11dfa20..5581e29 100644 --- a/src/main/java/de/kosit/validationtool/api/Result.java +++ b/src/main/java/de/kosit/validationtool/api/Result.java @@ -9,7 +9,7 @@ import net.sf.saxon.s9api.XdmNode; /** * API Rückgabe Objekt des Ergebnisses des Validierungsprozesses. - * + * * @author Andreas Penski */ public interface Result { @@ -17,7 +17,7 @@ public interface Result { /** * Zeigt an, ob die Verarbeitung durch den Validator erfolgreich durchlaufen wurde. Diese Funktion macht ausdrücklich * keine Aussage über die zur Akzeptanz. - * + * * @return true, wenn die Verarbeitung komplett und erfolgreich durchlaufen wurde * @see #getAcceptRecommendation() */ @@ -25,7 +25,7 @@ public interface Result { /** * Gibt eine Liste mit Verarbeitungsfehlermeldungen zurück. - * + * * @return Liste mit Fehlermeldungen */ List getProcessingErrors(); @@ -36,7 +36,9 @@ public interface Result { XdmNode getReport(); /** - * Das evaluierte Ergebnis. + * The Recommendation based on the evaluation of this Result. + * + * @return AcceptRecommendation */ AcceptRecommendation getAcceptRecommendation(); @@ -62,21 +64,21 @@ public interface Result { /** * Liefert die Ergebnisse der Schematron-Prüfungen, in der Reihenfolge der Szenario-Konfiguration. - * + * * @return Liste mit Schematron-Ergebnissen */ List getSchematronResult(); /** * Liefert ein true, wenn keine Schema-Violations vorhanden sind. - * + * * @return true wenn Schema-valide */ boolean isSchemaValid(); /** * Liefert ein true, wenn der Prüfling eine well-formed XML-Datei ist. - * + * * @return true wenn well-formed */ boolean isWellformed(); From a12ff356d8f6a18571dd2907a12b6dcc2ab338db Mon Sep 17 00:00:00 2001 From: Renzo Kottmann Date: Wed, 18 Mar 2020 18:07:47 +0100 Subject: [PATCH 03/29] Add a little englisch foc to acceptMatch Element --- src/main/model/xsd/scenarios.xsd | 81 ++++++++++++++++---------------- 1 file changed, 40 insertions(+), 41 deletions(-) diff --git a/src/main/model/xsd/scenarios.xsd b/src/main/model/xsd/scenarios.xsd index 1b2f9d9..2f41a1f 100644 --- a/src/main/model/xsd/scenarios.xsd +++ b/src/main/model/xsd/scenarios.xsd @@ -1,4 +1,4 @@ - + - + - - - - - - + + + + + + - + - + - + - + - + - + @@ -68,72 +66,73 @@ - - - + + + - + - - - - - - - + + + + + + + + - - + + - + - - + + - + - + - + - + - - - - + + + + - + From 84ef377324aa4414ca6b0ab5e8a27e4d426f6307 Mon Sep 17 00:00:00 2001 From: Renzo Kottmann Date: Wed, 18 Mar 2020 18:16:35 +0100 Subject: [PATCH 04/29] Add accept documentation about acceptRecommendation --- docs/api.md | 18 ++++++++++++++++++ docs/architecture.md | 10 ++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/docs/api.md b/docs/api.md index 848741c..e537f83 100644 --- a/docs/api.md +++ b/docs/api.md @@ -89,3 +89,21 @@ Initializing all XML artifacts and XSLT-executables is expensive. The `Check` in The only input `de.kosit.validationtool.api.Input` which can be created by various methods of `de.kosit.validationtool.api.InputFactory`. The `InputFactory` 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 the `read`-methods of `InputFactory`. + +## Accept Recommendation and Accept Match + +A tri-state Object `AcceptRecommendation` can be retrieved from the `Result` using `getAcceptRecommendation()`. + +The three defined states are: + +1. `UNDEFINED` i.e. the evaluation of the overall validation could not be computed. +2. `ACCEPTABLE` i.e. the recommendation is to accept input based on the evaluation of the overall validation. +3. `REJECT` i.e. the recommendation is to reject input based on the evaluation of the overall validation. + +By default it is `UNDEFINED`. + +### Accept Match in Scenario Configuration + +For your own configuration you can add an `acceptMatch` element in each scenario. It can contain in XPATH expression over your own defined `Report` to compute a boolean. An XPATH expression evaluating to true will lead to an `ACCEPTABLE` amd otherwise to a `REJECT` recommendation. + +This allows to have own control over what validation result is to be considered acceptable for your own application context. diff --git a/docs/architecture.md b/docs/architecture.md index fc9b2a2..18eb16c 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -13,9 +13,9 @@ the validation and generates a report in XML format. This report is then the inp The validator reports valid/invalid, a configuration reports acceptance/rejection! -## General process +## General default process -The general process is like this: +The general process is like this (the default is defined in `DefaultCheck`): ```mermaid @@ -30,6 +30,7 @@ sequenceDiagram e->>e: validate Schematron e->>e: create Validator Report e->>+c: execute configuration report generator + e->>e: Compute Recommendation ``` @@ -50,3 +51,8 @@ sequenceDiagram 6. *execute configuration report generator* The Validator will search for the XSLT as configured in scenario.xml and execute it with the Validator Report as input +7. compute Recommendation + + In case a scenario contains an `acceptMatch` element with an XPATH expression, this expression will be executed. + + In case the XPATH returns `true`, the recommendation will be set to `ACCEPT` else to `REJECT`. In case no such XPATH is defined it is `UNDEFINED`. From ab341feece2be9e73b06963d73dc2ce0e7258dd8 Mon Sep 17 00:00:00 2001 From: "Andreas Penski (init)" Date: Fri, 20 Mar 2020 14:22:33 +0100 Subject: [PATCH 05/29] (fix) Handling acceptMatch correctly, compute the result based on schema and schematron on absence of "acceptMath" --- .../impl/model/BaseScenario.java | 4 + .../impl/tasks/ComputeAcceptanceAction.java | 58 ++++++-- .../tasks/ComputeAcceptanceActionTest.java | 138 ++++++++++++++++++ 3 files changed, 186 insertions(+), 14 deletions(-) create mode 100644 src/test/java/de/kosit/validationtool/impl/tasks/ComputeAcceptanceActionTest.java diff --git a/src/main/java/de/kosit/validationtool/impl/model/BaseScenario.java b/src/main/java/de/kosit/validationtool/impl/model/BaseScenario.java index 71c723f..b983c61 100644 --- a/src/main/java/de/kosit/validationtool/impl/model/BaseScenario.java +++ b/src/main/java/de/kosit/validationtool/impl/model/BaseScenario.java @@ -69,9 +69,13 @@ public abstract class BaseScenario { private XPathExecutable matchExecutable; private XPathExecutable acceptExecutable; + private Schema schema; + private List schematronValidations; + private ContentRepository repository; + private Transformation reportTransformation; /** diff --git a/src/main/java/de/kosit/validationtool/impl/tasks/ComputeAcceptanceAction.java b/src/main/java/de/kosit/validationtool/impl/tasks/ComputeAcceptanceAction.java index e24ba4c..f4c5ca2 100644 --- a/src/main/java/de/kosit/validationtool/impl/tasks/ComputeAcceptanceAction.java +++ b/src/main/java/de/kosit/validationtool/impl/tasks/ComputeAcceptanceAction.java @@ -2,15 +2,19 @@ package de.kosit.validationtool.impl.tasks; import static org.apache.commons.lang3.StringUtils.isNotBlank; +import org.oclc.purl.dsdl.svrl.FailedAssert; + import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import de.kosit.validationtool.api.AcceptRecommendation; +import net.sf.saxon.s9api.SaxonApiException; import net.sf.saxon.s9api.XPathSelector; /** - * Berechnet die Akzeptanz-Empfehlung gemäß konfigurierten 'acceptMatch' des aktuellen Szenarios. + * Computes a {@link AcceptRecommendation} for this instance. This is either based on an 'acceptMatch'-configuration of + * the active scenario or based on overall evaluation about schema and semantic (schematron) correctness of the * * @author Andreas Penski */ @@ -20,23 +24,49 @@ public class ComputeAcceptanceAction implements CheckAction { @Override public void check(final Bag results) { - final String acceptMatch = results.getScenarioSelectionResult().getObject().getAcceptMatch(); - if (isNotBlank(acceptMatch)) { - - try { - - final XPathSelector selector = results.getScenarioSelectionResult().getObject().getAcceptSelector(); - selector.setContextItem(results.getReport()); - results.setAcceptStatus(selector.effectiveBooleanValue() ? AcceptRecommendation.ACCEPTABLE : AcceptRecommendation.REJECT); - } catch (final Exception e) { - log.error("Fehler bei Evaluierung des Accept-Status: {}", e.getMessage(), e); + if (preCondtionsMatch(results)) { + final String acceptMatch = results.getScenarioSelectionResult().getObject().getAcceptMatch(); + if (results.getSchemaValidationResult().isValid() && isNotBlank(acceptMatch)) { + evaluateAcceptanceMatch(results); + } else { + evaluateSchemaAndSchematron(results); } + } else { + results.setAcceptStatus(AcceptRecommendation.REJECT); } } - @Override - public boolean isSkipped(final Bag results) { - return results.getReport() == null; + private void evaluateSchemaAndSchematron(final Bag results) { + if (results.getSchemaValidationResult().isValid() && isSchematronValid(results)) { + results.setAcceptStatus(AcceptRecommendation.ACCEPTABLE); + } else { + results.setAcceptStatus(AcceptRecommendation.REJECT); + } + } + + private boolean isSchematronValid(final Bag results) { + return !hasSchematronErrors(results); + } + + private boolean hasSchematronErrors(final Bag results) { + return results.getReportInput().getValidationResultsSchematron().stream().map(e -> e.getResults().getSchematronOutput()) + .flatMap(e -> e.getActivePatternAndFiredRuleAndFailedAssert().stream()).anyMatch(FailedAssert.class::isInstance); + } + + private static void evaluateAcceptanceMatch(final Bag results) { + try { + final XPathSelector selector = results.getScenarioSelectionResult().getObject().getAcceptSelector(); + selector.setContextItem(results.getReport()); + results.setAcceptStatus(selector.effectiveBooleanValue() ? AcceptRecommendation.ACCEPTABLE : AcceptRecommendation.REJECT); + } catch (final SaxonApiException e) { + final String msg = "Error evaluating accept recommendation: %s"; + log.error(msg); + results.addProcessingError(msg); + } + } + + private static boolean preCondtionsMatch(final Bag results) { + return results.getReport() != null && results.getSchemaValidationResult() != null && results.getScenarioSelectionResult() != null; } } diff --git a/src/test/java/de/kosit/validationtool/impl/tasks/ComputeAcceptanceActionTest.java b/src/test/java/de/kosit/validationtool/impl/tasks/ComputeAcceptanceActionTest.java new file mode 100644 index 0000000..5798467 --- /dev/null +++ b/src/test/java/de/kosit/validationtool/impl/tasks/ComputeAcceptanceActionTest.java @@ -0,0 +1,138 @@ +package de.kosit.validationtool.impl.tasks; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.junit.Test; +import org.oclc.purl.dsdl.svrl.FailedAssert; +import org.oclc.purl.dsdl.svrl.SchematronOutput; + +import de.kosit.validationtool.api.AcceptRecommendation; +import de.kosit.validationtool.api.InputFactory; +import de.kosit.validationtool.impl.ContentRepository; +import de.kosit.validationtool.impl.Helper.Simple; +import de.kosit.validationtool.impl.ObjectFactory; +import de.kosit.validationtool.impl.model.Result; +import de.kosit.validationtool.impl.tasks.CheckAction.Bag; +import de.kosit.validationtool.model.reportInput.CreateReportInput; +import de.kosit.validationtool.model.reportInput.ValidationResultsSchematron; +import de.kosit.validationtool.model.reportInput.ValidationResultsSchematron.Results; +import de.kosit.validationtool.model.reportInput.XMLSyntaxError; +import de.kosit.validationtool.model.scenarios.ScenarioType; + +import net.sf.saxon.s9api.XdmNode; + +/** + * Tests the 'acceptMatch' functionality. + * + * @author Andreas Penski + */ +public class ComputeAcceptanceActionTest { + + private final ComputeAcceptanceAction action = new ComputeAcceptanceAction(); + + @Test + public void simpleTest() { + final Bag bag = createBag(true, true); + assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.UNDEFINED); + this.action.check(bag); + assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.ACCEPTABLE); + } + + @Test + public void testSchemaFailed() { + final Bag bag = createBag(false, true); + this.action.check(bag); + assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.REJECT); + } + + @Test + public void testSchematronFailed() { + final Bag bag = createBag(true, false); + this.action.check(bag); + assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.REJECT); + } + + @Test + public void testValidAcceptMatch() { + final Bag bag = createBag(true, true); + bag.getScenarioSelectionResult().getObject().setAcceptMatch("count(//doesnotExist) = 0"); + this.action.check(bag); + assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.ACCEPTABLE); + } + + @Test + public void testAcceptMatchNotSatisfied() { + final Bag bag = createBag(true, true); + bag.getScenarioSelectionResult().getObject().setAcceptMatch("count(//doesnotExist) = 1"); + this.action.check(bag); + assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.REJECT); + } + + @Test + public void testValidAcceptMatchOnSchematronFailed() { + final Bag bag = createBag(true, false); + bag.getScenarioSelectionResult().getObject().setAcceptMatch("count(//doesnotExist) = 0"); + this.action.check(bag); + assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.ACCEPTABLE); + } + + @Test + public void testValidAcceptMatchOnSchemaFailed() { + final Bag bag = createBag(false, true); + bag.getScenarioSelectionResult().getObject().setAcceptMatch("count(//doesnotExist) = 0"); + this.action.check(bag); + assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.REJECT); + } + + @Test + public void testMissingSchemaCheck() { + final Bag bag = createBag(null, Collections.emptyList()); + this.action.check(bag); + assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.REJECT); + } + + @Test + public void testMissingReport() { + final Bag bag = createBag(false, true); + bag.setReport(null); + this.action.check(bag); + assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.REJECT); + } + + private static Bag createBag(final boolean schemaValid, final boolean schematronValid) { + final Result schemaResult = schemaValid ? new Result<>(true) + : new Result<>(Collections.singletonList(new XMLSyntaxError())); + final List schematronResult = schematronValid ? Collections.emptyList() : createSchematronError(); + return createBag(schemaResult, schematronResult); + } + + private static List createSchematronError() { + final ValidationResultsSchematron v = new ValidationResultsSchematron(); + final SchematronOutput out = new SchematronOutput(); + final FailedAssert f = new FailedAssert(); + out.getActivePatternAndFiredRuleAndFailedAssert().add(f); + final Results r = new Results(); + r.setSchematronOutput(out); + v.setResults(r); + return Collections.singletonList(v); + } + + private static Bag createBag(final Result schemaResult, + final Collection schematronResult) { + final ScenarioType t = new ScenarioType(); + t.initialize(new ContentRepository(ObjectFactory.createProcessor(), Simple.REPOSITORY), true); + final CreateReportInput reportInput = new CreateReportInput(); + reportInput.getValidationResultsSchematron().addAll(schematronResult); + final Bag b = new Bag(InputFactory.read("".getBytes(), "someCheck"), reportInput); + final Result parseREsult = DocumentParseAction.parseDocument(b.getInput()); + b.setReport(parseREsult.getObject()); + b.setParserResult(parseREsult); + b.setSchemaValidationResult(schemaResult); + b.setScenarioSelectionResult(new Result<>(t)); + return b; + } +} From e313bc6328aecf7ef68f29a729e86696c20db756 Mon Sep 17 00:00:00 2001 From: "Andreas Penski (init)" Date: Fri, 20 Mar 2020 14:42:03 +0100 Subject: [PATCH 06/29] (fix) tests regarding acceptance computation --- .../java/de/kosit/validationtool/impl/DefaultCheckTest.java | 3 ++- ...{SimpleScenarioCheck.java => SimpleScenarioCheckTest.java} | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) rename src/test/java/de/kosit/validationtool/impl/{SimpleScenarioCheck.java => SimpleScenarioCheckTest.java} (96%) diff --git a/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java b/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java index 0b6edc6..461c024 100644 --- a/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java +++ b/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java @@ -68,8 +68,9 @@ public class DefaultCheckTest { final Result doc = this.implementation.checkInput(read(VALID_EXAMPLE)); assertThat(doc).isNotNull(); assertThat(doc.getReport()).isNotNull(); + // happy case has schematron errors !?? assertThat(doc.isAcceptable()).isFalse(); - assertThat(doc.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.UNDEFINED); + assertThat(doc.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.REJECT); } @Test diff --git a/src/test/java/de/kosit/validationtool/impl/SimpleScenarioCheck.java b/src/test/java/de/kosit/validationtool/impl/SimpleScenarioCheckTest.java similarity index 96% rename from src/test/java/de/kosit/validationtool/impl/SimpleScenarioCheck.java rename to src/test/java/de/kosit/validationtool/impl/SimpleScenarioCheckTest.java index 1444646..3ac63a2 100644 --- a/src/test/java/de/kosit/validationtool/impl/SimpleScenarioCheck.java +++ b/src/test/java/de/kosit/validationtool/impl/SimpleScenarioCheckTest.java @@ -19,7 +19,7 @@ import de.kosit.validationtool.impl.Helper.Simple; * * @author Andreas Penski */ -public class SimpleScenarioCheck { +public class SimpleScenarioCheckTest { private DefaultCheck implementation; @@ -56,7 +56,7 @@ public class SimpleScenarioCheck { public void testWithoutAcceptMatch() throws MalformedURLException { final Result result = this.implementation.checkInput(InputFactory.read(Simple.FOO.toURL())); assertThat(result).isNotNull(); - assertThat(result.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.UNDEFINED); + assertThat(result.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.ACCEPTABLE); } } From 2a9cdc551a0834229ea5c1f053c9a51b18926dc2 Mon Sep 17 00:00:00 2001 From: "Andreas Penski (init)" Date: Fri, 20 Mar 2020 15:13:44 +0100 Subject: [PATCH 07/29] (chore) Extends Result-API, provide more information about schematron results --- .../java/de/kosit/validationtool/api/Result.java | 15 +++++++++++++++ .../kosit/validationtool/impl/DefaultResult.java | 9 ++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/main/java/de/kosit/validationtool/api/Result.java b/src/main/java/de/kosit/validationtool/api/Result.java index 5581e29..dcbe19d 100644 --- a/src/main/java/de/kosit/validationtool/api/Result.java +++ b/src/main/java/de/kosit/validationtool/api/Result.java @@ -2,6 +2,7 @@ package de.kosit.validationtool.api; import java.util.List; +import org.oclc.purl.dsdl.svrl.FailedAssert; import org.oclc.purl.dsdl.svrl.SchematronOutput; import org.w3c.dom.Document; @@ -69,6 +70,13 @@ public interface Result { */ List getSchematronResult(); + /** + * Returns {@link org.oclc.purl.dsdl.svrl.FailedAssert FailedAsserts} of a schematron evaluation. + * + * @return list of {@link org.oclc.purl.dsdl.svrl.FailedAssert FailedAsserts}, if any, empty list otherwise + */ + List getFailedAsserts(); + /** * Liefert ein true, wenn keine Schema-Violations vorhanden sind. * @@ -82,4 +90,11 @@ public interface Result { * @return true wenn well-formed */ boolean isWellformed(); + + /** + * Returns true, if schematron has been checked and the result does not contain any {@link FailedAssert FailedAsserts}. + * + * @return true, if valid + */ + boolean isSchematronValid(); } diff --git a/src/main/java/de/kosit/validationtool/impl/DefaultResult.java b/src/main/java/de/kosit/validationtool/impl/DefaultResult.java index b878cee..e8be8ac 100644 --- a/src/main/java/de/kosit/validationtool/impl/DefaultResult.java +++ b/src/main/java/de/kosit/validationtool/impl/DefaultResult.java @@ -127,12 +127,19 @@ public class DefaultResult implements Result { * * @return die {@link FailedAssert} */ + @Override public List getFailedAsserts() { return filterSchematronResult(FailedAssert.class); } private List filterSchematronResult(final Class type) { - return getSchematronResult().stream().filter(type::isInstance).map(type::cast).collect(Collectors.toList()); + return getSchematronResult() != null + ? getSchematronResult().stream().filter(type::isInstance).map(type::cast).collect(Collectors.toList()) + : Collections.emptyList(); } + @Override + public boolean isSchematronValid() { + return getSchematronResult() != null && getFailedAsserts().isEmpty(); + } } From 554a6f080ae8e9339cab8f4c9bdb32e16bfbe3d9 Mon Sep 17 00:00:00 2001 From: "Andreas Penski (init)" Date: Fri, 20 Mar 2020 16:21:49 +0100 Subject: [PATCH 08/29] (chore) changelog documenation of api changes --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4c211c..cc4fdd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,17 @@ All notable changes to the Schematron Rules and this project will be documented The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.2.0 (unreleased) +### Added +- Provide access to schematron result through Result.java + - *Result#getFailedAsserts()* returns a list of failed asserts found by schematron + - *Result#isSchematronValid()* convinience access to evaluate whether schematron was processed without any *FailedAsserts* +### Changed +- *getAcceptRecommendation()* does not _only_ work when _acceptMatch_ is configured in the scenario + - schema correct is a precondion, of the checked instance is not valid, this evaluates to _REJECTED_ + - if _acceptMatch_ is configured, the result is based on the boolean result of the xpath expression evaluated against the generated report + - if *no* _acceptMatch_ is configured, the result is based on evaluation of schema and schematron correctnes + ## 1.1.3 ### Fixed - XXE vulnerability when reading xml documents with Saxon [#44](https://github.com/itplr-kosit/validator/issues/44) From fc419495e967e6ebd750d39a9b509293203a4ea1 Mon Sep 17 00:00:00 2001 From: "Andreas Penski (init)" Date: Fri, 20 Mar 2020 16:31:12 +0100 Subject: [PATCH 09/29] (chore) changelog for next release corrected --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc4fdd3..7b860f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - *getAcceptRecommendation()* does not _only_ work when _acceptMatch_ is configured in the scenario - schema correct is a precondion, of the checked instance is not valid, this evaluates to _REJECTED_ - if _acceptMatch_ is configured, the result is based on the boolean result of the xpath expression evaluated against the generated report - - if *no* _acceptMatch_ is configured, the result is based on evaluation of schema and schematron correctnes + - if *no* _acceptMatch_ is configured, the result is based on evaluation of schema and schematron correctness + - _UNDEFINED_ is only returned, when processing is stopped somehow +- *isAcceptable()* can no evaluate to true, when no _acceptMatch_ is configured (see above) ## 1.1.3 ### Fixed From 1790d301b63e363c3af40582ae83d98ae02e460e Mon Sep 17 00:00:00 2001 From: "Andreas Penski (init)" Date: Mon, 23 Mar 2020 11:27:17 +0100 Subject: [PATCH 10/29] (fix) acceptMatch tests work with new test environment --- .../java/de/kosit/validationtool/impl/DefaultCheckTest.java | 5 ++--- src/test/resources/examples/simple/input/foo.xml | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java b/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java index 3298176..aa1376b 100644 --- a/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java +++ b/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java @@ -74,9 +74,8 @@ public class DefaultCheckTest { final Result doc = this.implementation.checkInput(read(Simple.FOO)); assertThat(doc).isNotNull(); assertThat(doc.getReport()).isNotNull(); - // happy case has schematron errors !?? - assertThat(doc.isAcceptable()).isFalse(); - assertThat(doc.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.REJECT); + assertThat(doc.isAcceptable()).isTrue(); + assertThat(doc.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.ACCEPTABLE); } @Test diff --git a/src/test/resources/examples/simple/input/foo.xml b/src/test/resources/examples/simple/input/foo.xml index b84fe4f..7c22b1f 100644 --- a/src/test/resources/examples/simple/input/foo.xml +++ b/src/test/resources/examples/simple/input/foo.xml @@ -2,4 +2,5 @@ asldkfj + \ No newline at end of file From 65ed94560237f9de07ce43a7dd4792f1fbdcf20a Mon Sep 17 00:00:00 2001 From: "Andreas Penski (init)" Date: Mon, 23 Mar 2020 11:57:52 +0100 Subject: [PATCH 11/29] (chore) adopt new test infrastructure --- .../tasks/ComputeAcceptanceActionTest.java | 48 +----------------- .../impl/tasks/TestBagBuilder.java | 50 ++++++++++++++++++- 2 files changed, 50 insertions(+), 48 deletions(-) diff --git a/src/test/java/de/kosit/validationtool/impl/tasks/ComputeAcceptanceActionTest.java b/src/test/java/de/kosit/validationtool/impl/tasks/ComputeAcceptanceActionTest.java index 5798467..851b4ed 100644 --- a/src/test/java/de/kosit/validationtool/impl/tasks/ComputeAcceptanceActionTest.java +++ b/src/test/java/de/kosit/validationtool/impl/tasks/ComputeAcceptanceActionTest.java @@ -1,29 +1,14 @@ package de.kosit.validationtool.impl.tasks; +import static de.kosit.validationtool.impl.tasks.TestBagBuilder.createBag; import static org.assertj.core.api.Assertions.assertThat; -import java.util.Collection; import java.util.Collections; -import java.util.List; import org.junit.Test; -import org.oclc.purl.dsdl.svrl.FailedAssert; -import org.oclc.purl.dsdl.svrl.SchematronOutput; import de.kosit.validationtool.api.AcceptRecommendation; -import de.kosit.validationtool.api.InputFactory; -import de.kosit.validationtool.impl.ContentRepository; -import de.kosit.validationtool.impl.Helper.Simple; -import de.kosit.validationtool.impl.ObjectFactory; -import de.kosit.validationtool.impl.model.Result; import de.kosit.validationtool.impl.tasks.CheckAction.Bag; -import de.kosit.validationtool.model.reportInput.CreateReportInput; -import de.kosit.validationtool.model.reportInput.ValidationResultsSchematron; -import de.kosit.validationtool.model.reportInput.ValidationResultsSchematron.Results; -import de.kosit.validationtool.model.reportInput.XMLSyntaxError; -import de.kosit.validationtool.model.scenarios.ScenarioType; - -import net.sf.saxon.s9api.XdmNode; /** * Tests the 'acceptMatch' functionality. @@ -103,36 +88,5 @@ public class ComputeAcceptanceActionTest { assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.REJECT); } - private static Bag createBag(final boolean schemaValid, final boolean schematronValid) { - final Result schemaResult = schemaValid ? new Result<>(true) - : new Result<>(Collections.singletonList(new XMLSyntaxError())); - final List schematronResult = schematronValid ? Collections.emptyList() : createSchematronError(); - return createBag(schemaResult, schematronResult); - } - private static List createSchematronError() { - final ValidationResultsSchematron v = new ValidationResultsSchematron(); - final SchematronOutput out = new SchematronOutput(); - final FailedAssert f = new FailedAssert(); - out.getActivePatternAndFiredRuleAndFailedAssert().add(f); - final Results r = new Results(); - r.setSchematronOutput(out); - v.setResults(r); - return Collections.singletonList(v); - } - - private static Bag createBag(final Result schemaResult, - final Collection schematronResult) { - final ScenarioType t = new ScenarioType(); - t.initialize(new ContentRepository(ObjectFactory.createProcessor(), Simple.REPOSITORY), true); - final CreateReportInput reportInput = new CreateReportInput(); - reportInput.getValidationResultsSchematron().addAll(schematronResult); - final Bag b = new Bag(InputFactory.read("".getBytes(), "someCheck"), reportInput); - final Result parseREsult = DocumentParseAction.parseDocument(b.getInput()); - b.setReport(parseREsult.getObject()); - b.setParserResult(parseREsult); - b.setSchemaValidationResult(schemaResult); - b.setScenarioSelectionResult(new Result<>(t)); - return b; - } } diff --git a/src/test/java/de/kosit/validationtool/impl/tasks/TestBagBuilder.java b/src/test/java/de/kosit/validationtool/impl/tasks/TestBagBuilder.java index 2594786..0626a66 100644 --- a/src/test/java/de/kosit/validationtool/impl/tasks/TestBagBuilder.java +++ b/src/test/java/de/kosit/validationtool/impl/tasks/TestBagBuilder.java @@ -1,8 +1,15 @@ package de.kosit.validationtool.impl.tasks; import java.net.URI; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.oclc.purl.dsdl.svrl.FailedAssert; +import org.oclc.purl.dsdl.svrl.SchematronOutput; import de.kosit.validationtool.api.Input; +import de.kosit.validationtool.api.InputFactory; import de.kosit.validationtool.impl.ContentRepository; import de.kosit.validationtool.impl.Helper; import de.kosit.validationtool.impl.Helper.Simple; @@ -10,10 +17,15 @@ import de.kosit.validationtool.impl.ObjectFactory; import de.kosit.validationtool.impl.model.Result; import de.kosit.validationtool.impl.tasks.CheckAction.Bag; import de.kosit.validationtool.model.reportInput.CreateReportInput; +import de.kosit.validationtool.model.reportInput.ValidationResultsSchematron; +import de.kosit.validationtool.model.reportInput.ValidationResultsSchematron.Results; +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.ValidateWithXmlSchema; +import net.sf.saxon.s9api.XdmNode; + /** * Utilities for creating test objects. * @@ -26,7 +38,11 @@ public class TestBagBuilder { } public static Bag createBag(final Input input, final boolean parse) { - final Bag bag = new Bag(input, new CreateReportInput()); + return createBag(input, parse, new CreateReportInput()); + } + + public static Bag createBag(final Input input, final boolean parse, final CreateReportInput reportInput) { + final Bag bag = new Bag(input, reportInput); if (parse) { bag.setParserResult(DocumentParseAction.parseDocument(bag.getInput())); } @@ -46,4 +62,36 @@ public class TestBagBuilder { t.initialize(repository, true); return t; } + + private static XdmNode createReport() { + return DocumentParseAction.parseDocument(InputFactory.read("xml".getBytes(), "someXml")).getObject(); + } + + static Bag createBag(final boolean schemaValid, final boolean schematronValid) { + final Result schemaResult = schemaValid ? new Result<>(true) + : new Result<>(Collections.singletonList(new XMLSyntaxError())); + final List schematronResult = schematronValid ? Collections.emptyList() : createSchematronError(); + return createBag(schemaResult, schematronResult); + } + + private static List createSchematronError() { + final ValidationResultsSchematron v = new ValidationResultsSchematron(); + final SchematronOutput out = new SchematronOutput(); + final FailedAssert f = new FailedAssert(); + out.getActivePatternAndFiredRuleAndFailedAssert().add(f); + final Results r = new Results(); + r.setSchematronOutput(out); + v.setResults(r); + return Collections.singletonList(v); + } + + static Bag createBag(final Result schemaResult, + final Collection schematronResult) { + final CreateReportInput reportInput = new CreateReportInput(); + reportInput.getValidationResultsSchematron().addAll(schematronResult); + final Bag b = createBag(InputFactory.read("".getBytes(), "someCheck"), true, reportInput); + b.setSchemaValidationResult(schemaResult); + b.setReport(createReport()); + return b; + } } From 245d7d4cac64d225c9b3574b2b469b88216cadce Mon Sep 17 00:00:00 2001 From: "Andreas Penski (init)" Date: Mon, 23 Mar 2020 13:22:38 +0100 Subject: [PATCH 12/29] (chore) Integration Testing acceptMatch functionality --- .../cmd/CommandlineApplicationTest.java | 2 +- .../validationtool/impl/DefaultCheckTest.java | 18 +++++++++++++++--- .../de/kosit/validationtool/impl/Helper.java | 2 ++ .../resources/examples/simple/input/foo.xml | 4 +++- .../examples/simple/input/withManualReject.xml | 8 ++++++++ .../resources/examples/simple/scenarios.xml | 2 +- 6 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 src/test/resources/examples/simple/input/withManualReject.xml diff --git a/src/test/java/de/kosit/validationtool/cmd/CommandlineApplicationTest.java b/src/test/java/de/kosit/validationtool/cmd/CommandlineApplicationTest.java index 687841d..1207a1a 100644 --- a/src/test/java/de/kosit/validationtool/cmd/CommandlineApplicationTest.java +++ b/src/test/java/de/kosit/validationtool/cmd/CommandlineApplicationTest.java @@ -138,7 +138,7 @@ public class CommandlineApplicationTest { final String[] args = new String[] { "-s", Paths.get(Simple.SCENARIOS).toString(), "-o", this.output.toString(), "-r", Paths.get(Simple.REPOSITORY).toString(), Paths.get(Simple.EXAMPLES).toString() }; CommandLineApplication.mainProgram(args); - assertThat(this.commandLine.getErrorOutput()).contains("Processing 5 object(s) completed"); + assertThat(this.commandLine.getErrorOutput()).contains("Processing 6 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 aa1376b..624c8a2 100644 --- a/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java +++ b/src/test/java/de/kosit/validationtool/impl/DefaultCheckTest.java @@ -22,10 +22,10 @@ package de.kosit.validationtool.impl; import static de.kosit.validationtool.api.InputFactory.read; import static de.kosit.validationtool.impl.Helper.Simple.GARBAGE; import static de.kosit.validationtool.impl.Helper.Simple.NOT_WELLFORMED; +import static de.kosit.validationtool.impl.Helper.Simple.REJECTED; import static org.assertj.core.api.Assertions.assertThat; import java.io.File; -import java.net.URISyntaxException; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -54,7 +54,7 @@ public class DefaultCheckTest { private DefaultCheck implementation; @Before - public void setup() throws URISyntaxException { + public void setup() { final CheckConfiguration d = new CheckConfiguration(Simple.SCENARIOS); d.setScenarioRepository(new File(Simple.REPOSITORY).toURI()); this.implementation = new DefaultCheck(d); @@ -130,7 +130,19 @@ public class DefaultCheckTest { assertThat(result.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.REJECT); assertThat(result.getReport()).isNotNull(); assertThat(result.getReportDocument()).isNotNull(); - System.out.println(Helper.serialize(result.getReportDocument())); + } + + @Test + public void testRejectAcceptMatch() { + final Result result = this.implementation.checkInput(read(REJECTED)); + assertThat(result).isNotNull(); + assertThat(result.isWellformed()).isTrue(); + assertThat(result.isSchemaValid()).isTrue(); + assertThat(result.isProcessingSuccessful()).isTrue(); + assertThat(result.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.REJECT); + assertThat(result.isAcceptable()).isFalse(); + assertThat(result.getReport()).isNotNull(); + assertThat(result.getReportDocument()).isNotNull(); } } diff --git a/src/test/java/de/kosit/validationtool/impl/Helper.java b/src/test/java/de/kosit/validationtool/impl/Helper.java index f0e913d..1d50fc4 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 = Simple.ROOT.resolve("input/foo.xml"); + public static final URI REJECTED = Simple.ROOT.resolve("input/withManualReject.xml"); + public static final URI SCENARIOS = ROOT.resolve("scenarios.xml"); public static final URI REPOSITORY = ROOT.resolve("repository/"); diff --git a/src/test/resources/examples/simple/input/foo.xml b/src/test/resources/examples/simple/input/foo.xml index 7c22b1f..7122648 100644 --- a/src/test/resources/examples/simple/input/foo.xml +++ b/src/test/resources/examples/simple/input/foo.xml @@ -2,5 +2,7 @@ asldkfj - + + + \ No newline at end of file diff --git a/src/test/resources/examples/simple/input/withManualReject.xml b/src/test/resources/examples/simple/input/withManualReject.xml new file mode 100644 index 0000000..ed81f6d --- /dev/null +++ b/src/test/resources/examples/simple/input/withManualReject.xml @@ -0,0 +1,8 @@ + + + + asldkfj + + directly transferred, so this is part of the report + + \ No newline at end of file diff --git a/src/test/resources/examples/simple/scenarios.xml b/src/test/resources/examples/simple/scenarios.xml index 47e5ec8..3a99296 100644 --- a/src/test/resources/examples/simple/scenarios.xml +++ b/src/test/resources/examples/simple/scenarios.xml @@ -47,7 +47,7 @@ report.xsl - count(//cri:xmlSyntaxError) = 0 + count(//test:rejected) = 0 From 982b8fd79f0c05e9274a2ab1dc3f089f84447ee8 Mon Sep 17 00:00:00 2001 From: "Andreas Penski (init)" Date: Mon, 23 Mar 2020 13:31:06 +0100 Subject: [PATCH 13/29] (chore) reduce test objects, reuse simple stuff --- .../cmd/PrintReportActionTest.java | 28 +- .../resources/examples/results/report.xml | 330 ------------------ 2 files changed, 14 insertions(+), 344 deletions(-) delete mode 100644 src/test/resources/examples/results/report.xml diff --git a/src/test/java/de/kosit/validationtool/cmd/PrintReportActionTest.java b/src/test/java/de/kosit/validationtool/cmd/PrintReportActionTest.java index e28b7ab..2235236 100644 --- a/src/test/java/de/kosit/validationtool/cmd/PrintReportActionTest.java +++ b/src/test/java/de/kosit/validationtool/cmd/PrintReportActionTest.java @@ -22,7 +22,7 @@ package de.kosit.validationtool.cmd; import static org.assertj.core.api.Assertions.assertThat; import java.io.IOException; -import java.net.URL; +import java.net.MalformedURLException; import org.junit.After; import org.junit.Before; @@ -30,6 +30,7 @@ import org.junit.Test; import de.kosit.validationtool.api.InputFactory; import de.kosit.validationtool.impl.Helper; +import de.kosit.validationtool.impl.Helper.Simple; import de.kosit.validationtool.impl.tasks.CheckAction; /** @@ -37,7 +38,6 @@ import de.kosit.validationtool.impl.tasks.CheckAction; */ public class PrintReportActionTest { - private static final URL REPORT = SerializeReportActionTest.class.getResource("/examples/results/report.xml"); private CommandLine commandLine; @@ -45,26 +45,26 @@ public class PrintReportActionTest { @Before public void setup() throws IOException { - commandLine = new CommandLine(); - commandLine.activate(); - action = new PrintReportAction(); + this.commandLine = new CommandLine(); + this.commandLine.activate(); + this.action = new PrintReportAction(); } @After public void tearDownd() throws IOException { - commandLine.deactivate(); + this.commandLine.deactivate(); } @Test - public void testSimpleSerialize() { - CheckAction.Bag b = new CheckAction.Bag(InputFactory.read(REPORT)); - b.setReport(Helper.load(REPORT)); - assertThat(action.isSkipped(b)).isFalse(); - action.check(b); + public void testSimpleSerialize() throws MalformedURLException { + final CheckAction.Bag b = new CheckAction.Bag(InputFactory.read(Simple.SIMPLE_VALID)); + b.setReport(Helper.load(Simple.SIMPLE_VALID.toURL())); + assertThat(this.action.isSkipped(b)).isFalse(); + this.action.check(b); assertThat(b.isStopped()).isFalse(); - assertThat(commandLine.getOutput()).isNotEmpty(); - // assertThat(commandLine.getOutput()).contains(" - - - - - KoSIT POC - - 2017-09-01T13:13:59.055+02:00 - - - SHA-256 - 4exhW9EJxAbhlZLHZ3mYZ3/hWGG5e6mIpiTAlGTpQ7s= - - - /C:/Developer/source/init/eRechnung-Check/src/test/resources/examples/UBLReady/UBLReady_EU_UBL-NL_20170102_FULL.xml - - - - UBL 2.1 Invoice - urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 - /invoice:Invoice - - - UBL 2.1 Invoice - resources/eRechnung/UBL-2.1/xsdrt/maindoc/UBL-Invoice-2.1.xsd - - - - - BII Rules for Invoice - resources/eRechnung/UBL-2.1/xsl/BIIRULES-UBL-T10.xsl - - - - - openPEPPOL Rules for Invoice - resources/eRechnung/UBL-2.1/xsl/OPENPEPPOL-UBL-T10.xsl - - - - - Report für eRechnung - resources/eRechnung/report.xsl - - - - - - - UBL 2.1 Invoice - resources/eRechnung/UBL-2.1/xsdrt/maindoc/UBL-Invoice-2.1.xsd - - - - - BII Rules for Invoice - resources/eRechnung/UBL-2.1/xsl/BIIRULES-UBL-T10.xsl - - - [CL-T10-R010]-Coded allowance and charge reasons SHOULD belong to the UNCL 4465 code list BII2 subset - - - - - openPEPPOL Rules for Invoice - resources/eRechnung/UBL-2.1/xsl/OPENPEPPOL-UBL-T10.xsl - - - [EUGEN-T10-R026]-A currency code element MUST have a list identifier attribute 'ISO4217'. - - - [EUGEN-T10-R041]-The VAT identifier for the supplier SHOULD be prefixed with country code for companies - with VAT registration in EU countries - - - [EUGEN-T10-R054]-A party legal entity company identifier SHOULD have a scheme identifier attribute. - - - [EUGEN-T10-R029]-An allowance charge reason code MUST have a list identifier attribute 'UNCL4465'. - - - [EUGEN-T10-R029]-An allowance charge reason code MUST have a list identifier attribute 'UNCL4465'. - - - [EUGEN-T10-R029]-An allowance charge reason code MUST have a list identifier attribute 'UNCL4465'. - - - - - - - - - Pruefbericht der KoSIT - - - -

Prüfbericht der KoSIT

-

Angaben zum geprüften Dokument

- - - - - - - - - - - - - - - - - - -
Dokument: - /C:/Developer/source/init/eRechnung-Check/src/test/resources/examples/UBLReady/UBLReady_EU_UBL-NL_20170102_FULL.xml -
Szenario: -
Zeitpunkt:1.9.2017 13:13:59
Validierungsschritte:FehlerWarnungInformation
-

Konformitätsprüfung:Das geprüfte Dokument enthält 4 Fehler / 3 - Warnungen. Es ist nicht konform zu den formalen Vorgaben. -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PosCodeCustomLevel (Level)StepText
1CL-T10-R010warning - [CL-T10-R010]-Coded allowance and charge reasons SHOULD belong to the UNCL 4465 - code list BII2 subset -
- -
2EUGEN-T10-R026error - [EUGEN-T10-R026]-A currency code element MUST have a list identifier attribute - 'ISO4217'. -
- -
3EUGEN-T10-R041warning - [EUGEN-T10-R041]-The VAT identifier for the supplier SHOULD be prefixed with - country code for companies with VAT registration in EU countries -
- -
4EUGEN-T10-R054warning - [EUGEN-T10-R054]-A party legal entity company identifier SHOULD have a scheme - identifier attribute. -
- -
5EUGEN-T10-R029error - [EUGEN-T10-R029]-An allowance charge reason code MUST have a list identifier - attribute 'UNCL4465'. -
- -
6EUGEN-T10-R029error - [EUGEN-T10-R029]-An allowance charge reason code MUST have a list identifier - attribute 'UNCL4465'. -
- -
7EUGEN-T10-R029error - [EUGEN-T10-R029]-An allowance charge reason code MUST have a list identifier - attribute 'UNCL4465'. -
- -
-

Bewertung:Es wird empfohlen das Dokument zurückzuweisen. -

-

Erstellt mit: KoSIT POC für das InstructionSet - - vom . -

- - -
-
-
-
\ No newline at end of file From d7f4a78fbc3de87e8518c07f7636e5d8bd1f4290 Mon Sep 17 00:00:00 2001 From: "Andreas Penski (init)" Date: Mon, 23 Mar 2020 13:35:15 +0100 Subject: [PATCH 14/29] (chore) fix typo --- .../de/kosit/validationtool/cmd/PrintReportActionTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/java/de/kosit/validationtool/cmd/PrintReportActionTest.java b/src/test/java/de/kosit/validationtool/cmd/PrintReportActionTest.java index 2235236..e1b16f4 100644 --- a/src/test/java/de/kosit/validationtool/cmd/PrintReportActionTest.java +++ b/src/test/java/de/kosit/validationtool/cmd/PrintReportActionTest.java @@ -21,7 +21,6 @@ package de.kosit.validationtool.cmd; import static org.assertj.core.api.Assertions.assertThat; -import java.io.IOException; import java.net.MalformedURLException; import org.junit.After; @@ -44,14 +43,14 @@ public class PrintReportActionTest { private PrintReportAction action; @Before - public void setup() throws IOException { + public void setup() { this.commandLine = new CommandLine(); this.commandLine.activate(); this.action = new PrintReportAction(); } @After - public void tearDownd() throws IOException { + public void tearDown() { this.commandLine.deactivate(); } From b50bed91d18667ac3a5b55f9691bcf4cdcf6ac80 Mon Sep 17 00:00:00 2001 From: "Andreas Penski (init)" Date: Mon, 23 Mar 2020 13:39:38 +0100 Subject: [PATCH 15/29] (chore) test with no schematron check / results --- .../impl/tasks/ComputeAcceptanceActionTest.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/test/java/de/kosit/validationtool/impl/tasks/ComputeAcceptanceActionTest.java b/src/test/java/de/kosit/validationtool/impl/tasks/ComputeAcceptanceActionTest.java index 5798467..e0f4bcc 100644 --- a/src/test/java/de/kosit/validationtool/impl/tasks/ComputeAcceptanceActionTest.java +++ b/src/test/java/de/kosit/validationtool/impl/tasks/ComputeAcceptanceActionTest.java @@ -95,6 +95,15 @@ public class ComputeAcceptanceActionTest { assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.REJECT); } + @Test + public void testNoSchematronCheck() { + final Bag bag = createBag(true, true); + // remove schematron results + bag.getReportInput().getValidationResultsSchematron().clear(); + this.action.check(bag); + assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.ACCEPTABLE); + } + @Test public void testMissingReport() { final Bag bag = createBag(false, true); From 515b45bc6e5624dbf2be1d068b4d2acaa4403f73 Mon Sep 17 00:00:00 2001 From: "Andreas Penski (init)" Date: Mon, 23 Mar 2020 13:45:59 +0100 Subject: [PATCH 16/29] (chore) reduce test objects, reuse simple stuff --- .../cmd/ExtractHtmlActionTest.java | 23 ++++++++-------- .../cmd/SerializeReportActionTest.java | 26 +++++++++---------- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/test/java/de/kosit/validationtool/cmd/ExtractHtmlActionTest.java b/src/test/java/de/kosit/validationtool/cmd/ExtractHtmlActionTest.java index 9c308a1..75c0449 100644 --- a/src/test/java/de/kosit/validationtool/cmd/ExtractHtmlActionTest.java +++ b/src/test/java/de/kosit/validationtool/cmd/ExtractHtmlActionTest.java @@ -22,7 +22,6 @@ package de.kosit.validationtool.cmd; import static org.assertj.core.api.Assertions.assertThat; import java.io.IOException; -import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.util.stream.Collectors; @@ -34,6 +33,7 @@ import org.junit.Test; import de.kosit.validationtool.api.InputFactory; import de.kosit.validationtool.impl.Helper; +import de.kosit.validationtool.impl.Helper.Simple; import de.kosit.validationtool.impl.tasks.CheckAction; /** @@ -43,7 +43,6 @@ import de.kosit.validationtool.impl.tasks.CheckAction; */ public class ExtractHtmlActionTest { - private static final URL REPORT = SerializeReportActionTest.class.getResource("/examples/results/report.xml"); private ExtractHtmlContentAction action; @@ -51,24 +50,24 @@ public class ExtractHtmlActionTest { @Before public void setup() throws IOException { - tmpDirectory = Files.createTempDirectory("checktool"); - action = new ExtractHtmlContentAction(Helper.loadTestRepository(), tmpDirectory); + this.tmpDirectory = Files.createTempDirectory("checktool"); + this.action = new ExtractHtmlContentAction(Helper.loadTestRepository(), this.tmpDirectory); } @After public void tearDown() throws IOException { - FileUtils.deleteDirectory(tmpDirectory.toFile()); + FileUtils.deleteDirectory(this.tmpDirectory.toFile()); } @Test public void testSimple() throws IOException { - CheckAction.Bag b = new CheckAction.Bag(InputFactory.read(REPORT)); - assertThat(action.isSkipped(b)).isTrue(); - b.setReport(Helper.load(REPORT)); - action.check(b); - assertThat(action.isSkipped(b)).isFalse(); - action.check(b); + final CheckAction.Bag b = new CheckAction.Bag(InputFactory.read(Simple.SIMPLE_VALID)); + assertThat(this.action.isSkipped(b)).isTrue(); + b.setReport(Helper.load(Simple.SIMPLE_VALID.toURL())); + this.action.check(b); + assertThat(this.action.isSkipped(b)).isFalse(); + this.action.check(b); assertThat(b.isStopped()).isFalse(); - assertThat(Files.list(tmpDirectory).collect(Collectors.toList())).hasSize(1); + assertThat(Files.list(this.tmpDirectory).collect(Collectors.toList())).hasSize(1); } } diff --git a/src/test/java/de/kosit/validationtool/cmd/SerializeReportActionTest.java b/src/test/java/de/kosit/validationtool/cmd/SerializeReportActionTest.java index 12960c3..d0373f2 100644 --- a/src/test/java/de/kosit/validationtool/cmd/SerializeReportActionTest.java +++ b/src/test/java/de/kosit/validationtool/cmd/SerializeReportActionTest.java @@ -22,7 +22,7 @@ package de.kosit.validationtool.cmd; import static org.assertj.core.api.Assertions.assertThat; import java.io.IOException; -import java.net.URL; +import java.net.MalformedURLException; import java.nio.file.Files; import java.nio.file.Path; @@ -33,6 +33,7 @@ import org.junit.Test; import de.kosit.validationtool.api.InputFactory; import de.kosit.validationtool.impl.Helper; +import de.kosit.validationtool.impl.Helper.Simple; import de.kosit.validationtool.impl.tasks.CheckAction; /** @@ -40,7 +41,6 @@ import de.kosit.validationtool.impl.tasks.CheckAction; */ public class SerializeReportActionTest { - private static final URL REPORT = SerializeReportActionTest.class.getResource("/examples/results/report.xml"); private Path tmpDirectory; @@ -48,31 +48,31 @@ public class SerializeReportActionTest { @Before public void setup() throws IOException { - tmpDirectory = Files.createTempDirectory("checktool"); - action = new SerializeReportAction(tmpDirectory); + this.tmpDirectory = Files.createTempDirectory("checktool"); + this.action = new SerializeReportAction(this.tmpDirectory); } @After public void tearDown() throws IOException { - FileUtils.deleteDirectory(tmpDirectory.toFile()); + FileUtils.deleteDirectory(this.tmpDirectory.toFile()); } @Test - public void testSimpleSerialize() { - CheckAction.Bag b = new CheckAction.Bag(InputFactory.read(REPORT)); - assertThat(action.isSkipped(b)).isTrue(); - b.setReport(Helper.load(REPORT)); - assertThat(action.isSkipped(b)).isFalse(); - action.check(b); + public void testSimpleSerialize() throws MalformedURLException { + final CheckAction.Bag b = new CheckAction.Bag(InputFactory.read(Simple.SIMPLE_VALID)); + assertThat(this.action.isSkipped(b)).isTrue(); + b.setReport(Helper.load(Simple.SIMPLE_VALID.toURL())); + assertThat(this.action.isSkipped(b)).isFalse(); + this.action.check(b); assertThat(b.isStopped()).isFalse(); - assertThat(tmpDirectory.toFile().listFiles()).hasSize(1); + assertThat(this.tmpDirectory.toFile().listFiles()).hasSize(1); } //ERPT-83 @Test public void testName(){ final String name = "some.name.with.dots"; - CheckAction.Bag b = new CheckAction.Bag(InputFactory.read("ega".getBytes(), name + ".xml")); + final CheckAction.Bag b = new CheckAction.Bag(InputFactory.read("ega".getBytes(), name + ".xml")); assertThat(b.getName()).isEqualTo(name); } From 03cf40f32837e7b1d437067a767bd874f9babc4b Mon Sep 17 00:00:00 2001 From: "Andreas Penski (init)" Date: Mon, 23 Mar 2020 14:59:43 +0100 Subject: [PATCH 17/29] (chore) clarify actual test --- .../validationtool/impl/tasks/ComputeAcceptanceActionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/de/kosit/validationtool/impl/tasks/ComputeAcceptanceActionTest.java b/src/test/java/de/kosit/validationtool/impl/tasks/ComputeAcceptanceActionTest.java index e0f4bcc..8c99f6e 100644 --- a/src/test/java/de/kosit/validationtool/impl/tasks/ComputeAcceptanceActionTest.java +++ b/src/test/java/de/kosit/validationtool/impl/tasks/ComputeAcceptanceActionTest.java @@ -73,7 +73,7 @@ public class ComputeAcceptanceActionTest { } @Test - public void testValidAcceptMatchOnSchematronFailed() { + public void testAcceptMatchOverridesSchematronErrors() { final Bag bag = createBag(true, false); bag.getScenarioSelectionResult().getObject().setAcceptMatch("count(//doesnotExist) = 0"); this.action.check(bag); From 3388eba1d22af5b175b1b483ce25033d7a9760d8 Mon Sep 17 00:00:00 2001 From: "Andreas Penski (init)" Date: Tue, 24 Mar 2020 08:37:14 +0100 Subject: [PATCH 18/29] (chore) doc enhancements --- README.md | 6 ++++-- docs/api.md | 40 +++++++++++++++++++++++++++------------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 832ddf6..483ba8b 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,10 @@ java -jar validationtool--standalone.jar --help A concrete example with a specific validator configuration can be found on [GitHub](https://github.com/itplr-kosit/validator-configuration-xrechnung) +### Application User Interface (API / embedded usage) + +The validator can also be used in own Java Applications via the API. Details can be [found here](./docs/api.md). + ### Daemon-Mode You can also start the validator as an HTTP-Server. Just start it in _Daemon-Mode_ with the `-D` option. @@ -86,6 +90,4 @@ You can HTTP-POST to `/` and the response will return the report document as de Additionally there is the GET `/health` endpoint which can be used by monitoring systems. -### Application User Interface (embedded usage) -The validator can also be used in own Java Applications via the API. Details can be [found here](./docs/api.md). diff --git a/docs/api.md b/docs/api.md index e537f83..31d05ab 100644 --- a/docs/api.md +++ b/docs/api.md @@ -4,7 +4,8 @@ The Validator offers an API which allows you to integrate Validator in your own ## Dependency Management -Currently, we *do not* deploy to Maven Central or similar. Hence you need to build and optionally deploy the Validator artifacts to your own shared repository (see for example [Maven Documentation](https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html)). +Currently, we *do not* deploy to Maven Central or similar. Hence you need to build and optionally deploy the Validator artifacts to your own +shared (or local) repository (see for example [Maven Documentation](https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html)). ### Maven @@ -28,7 +29,8 @@ dependencies { ## Usage -Prerequisite for use is a valid [scenario definition](configurations.md) and the a folder with all necessary artifacts for validation (repository) either on the filesystem or on the classpath. +Prerequisite for use is a valid [scenario definition](configurations.md) and the a folder with all necessary artifacts for validation +(repository) either on the filesystem or on the classpath. The following example demonstrates loading scenario.xml and whole configuration from classpath and validating one XML document: @@ -81,14 +83,19 @@ public class StandardExample { } ``` -The `Result` interface has more methods to retrieve details about XSD validation errors and Schematron messages. +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. -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 an `Check` instance. - -* Batch use is serial and *not parallel* +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 an `Check` instance. The only input `de.kosit.validationtool.api.Input` which can be created by various methods of `de.kosit.validationtool.api.InputFactory`. -The `InputFactory` 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 the `read`-methods of `InputFactory`. +The `InputFactory` 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 the `read`-methods of `InputFactory`. + +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)). +However, there is no parallel processing implemented at the moment. ## Accept Recommendation and Accept Match @@ -96,14 +103,21 @@ A tri-state Object `AcceptRecommendation` can be retrieved from the `Result` usi The three defined states are: -1. `UNDEFINED` i.e. the evaluation of the overall validation could not be computed. -2. `ACCEPTABLE` i.e. the recommendation is to accept input based on the evaluation of the overall validation. -3. `REJECT` i.e. the recommendation is to reject input based on the evaluation of the overall validation. +1. `ACCEPTABLE` i.e. the recommendation is to accept input based on the evaluation of the overall validation. +1. `REJECT` i.e. the recommendation is to reject input based on the evaluation of the overall validation. +1. `UNDEFINED` i.e. the evaluation of the overall validation could not be computed (overall processing is incomplete) -By default it is `UNDEFINED`. +The accept recommendation is based on either: + +1. schema and schematron validation result +1. if configured based on _acceptMatch_ configuration of the scenario (see below) ### Accept Match in Scenario Configuration -For your own configuration you can add an `acceptMatch` element in each scenario. It can contain in XPATH expression over your own defined `Report` to compute a boolean. An XPATH expression evaluating to true will lead to an `ACCEPTABLE` amd otherwise to a `REJECT` recommendation. +For your own configuration you can add an `acceptMatch` element in each scenario. It can contain in XPATH expression over your own +defined `Report` to compute a boolean. An XPATH expression evaluating to true will lead to an `ACCEPTABLE` and otherwise to a `REJECT` +recommendation. -This allows to have own control over what validation result is to be considered acceptable for your own application context. +This allows to have control over what validation result is to be considered _acceptable_ for your own application context. E.g. you can +overrule schematron validation errors with _acceptMatch_ configuration and consider certain errors as _acceptable_. Nevertheless you can *not* +overrule schema errors with accept match. From b7376509371bcc57bc62d132168cb83dfbdee107 Mon Sep 17 00:00:00 2001 From: "Andreas Penski (init)" Date: Tue, 24 Mar 2020 08:39:36 +0100 Subject: [PATCH 19/29] (chore) export zip artefact --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dedc582..49ee7c6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -86,6 +86,7 @@ build-java-11: name: java-11 paths: - target/*.jar + - target/*.zip reports: junit: - target/surefire-reports/*.xml From cba3cdb139bdc9de4b176665aec73558fd48fc32 Mon Sep 17 00:00:00 2001 From: "Andreas Penski (init)" Date: Tue, 24 Mar 2020 08:41:57 +0100 Subject: [PATCH 20/29] (chore) prepare release version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7f74ebe..07bcbfa 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ KoSIT XML Prüftool Implementierung de.kosit - 1.1.4-SNAPSHOT + 1.2.0-SNAPSHOT validationtool KoSIT XML Validator against XSD and Schematron based on defined scenarios. From 0162433059e78b801ee264733639d4e4be5961f8 Mon Sep 17 00:00:00 2001 From: "Andreas Penski (init)" Date: Tue, 24 Mar 2020 08:46:11 +0100 Subject: [PATCH 21/29] (chore) config changes --- .idea/encodings.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.idea/encodings.xml b/.idea/encodings.xml index 67472d0..63fc954 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -1,7 +1,10 @@ - + + + + \ No newline at end of file From 4c9aefaa11739a054e2e414793be9ee940603bcb Mon Sep 17 00:00:00 2001 From: "Andreas Penski (init)" Date: Tue, 24 Mar 2020 09:15:31 +0100 Subject: [PATCH 22/29] [maven-release-plugin] prepare release v1.2.0 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 07bcbfa..e7e7bd8 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ KoSIT XML Prüftool Implementierung de.kosit - 1.2.0-SNAPSHOT + 1.2.0 validationtool KoSIT XML Validator against XSD and Schematron based on defined scenarios. @@ -451,7 +451,7 @@ https://github.com/itplr-kosit/validationtool.git scm:git:https://projekte.kosit.org/kosit/validator.git - v1.1.1 + v1.2.0