Merge branch 'master' into 48-documentation-and-semantic-defintion-of-accpetmatch-functionality

This commit is contained in:
Renzo Kottmann 2020-06-20 17:49:39 +02:00
commit a670b227ed
24 changed files with 381 additions and 421 deletions

View file

@ -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<SchematronOutput> 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<FailedAssert> 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();
}

View file

@ -127,12 +127,19 @@ public class DefaultResult implements Result {
*
* @return die {@link FailedAssert}
*/
@Override
public List<FailedAssert> getFailedAsserts() {
return filterSchematronResult(FailedAssert.class);
}
private <T> List<T> filterSchematronResult(final Class<T> 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();
}
}

View file

@ -164,6 +164,7 @@ public class ScenarioRepository {
private ScenarioType createFallback() {
final ScenarioType t = new ScenarioType();
t.setFallback(true);
t.setName("Fallback-Scenario");
t.setMatch("count(/)<0");
final CreateReportType reportType = new CreateReportType();

View file

@ -70,6 +70,11 @@ public abstract class BaseScenario {
private ResourceType resourceType;
}
@XmlTransient
@Getter
@Setter
private boolean fallback;
private XPathExecutable matchExecutable;
private XPathExecutable acceptExecutable;

View file

@ -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;
}
}

View file

@ -20,6 +20,7 @@
package de.kosit.validationtool.impl.tasks;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import de.kosit.validationtool.impl.ScenarioRepository;
import de.kosit.validationtool.impl.model.Result;
@ -35,6 +36,7 @@ import net.sf.saxon.s9api.XdmNode;
* @author Andreas Penski
*/
@RequiredArgsConstructor
@Slf4j
public class ScenarioSelectionAction implements CheckAction {
private final ScenarioRepository repository;
@ -47,16 +49,21 @@ public class ScenarioSelectionAction implements CheckAction {
if (results.getParserResult().isValid()) {
scenarioTypeResult = determineScenario(results.getParserResult().getObject());
} else {
scenarioTypeResult = new Result<>(repository.getFallbackScenario());
scenarioTypeResult = new Result<>(this.repository.getFallbackScenario());
}
results.setScenarioSelectionResult(scenarioTypeResult);
report.setScenario(scenarioTypeResult.getObject());
if (!scenarioTypeResult.getObject().isFallback()) {
report.setScenario(scenarioTypeResult.getObject());
log.info("Schenario {} identified for {}", scenarioTypeResult.getObject().getName(), results.getInput().getName());
} else {
log.error("No valid schenario configuration found for {}", results.getInput().getName());
}
}
private Result<ScenarioType, String> determineScenario(final XdmNode document) {
final Result<ScenarioType, String> result = this.repository.selectScenario(document);
if (result.isInvalid()) {
return new Result<>(repository.getFallbackScenario());
return new Result<>(this.repository.getFallbackScenario());
}
return result;
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -21,8 +21,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 +29,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,34 +37,33 @@ 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;
private PrintReportAction action;
@Before
public void setup() throws IOException {
commandLine = new CommandLine();
commandLine.activate();
action = new PrintReportAction();
public void setup() {
this.commandLine = new CommandLine();
this.commandLine.activate();
this.action = new PrintReportAction();
}
@After
public void tearDownd() throws IOException {
commandLine.deactivate();
public void tearDown() {
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("<?xml version=\"1.0\" ");
// assertThat(commandLine.getErrorOutput()).isEmpty();
assertThat(this.commandLine.getOutput()).isNotEmpty();
assertThat(this.commandLine.getOutput()).contains("<?xml version=\"1.0\" ");
assertThat(this.commandLine.getErrorOutput()).isEmpty();
}
}

View file

@ -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);
}

View file

@ -22,10 +22,11 @@ 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 de.kosit.validationtool.impl.Helper.Simple.UNKNOWN;
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 +55,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);
@ -74,8 +75,8 @@ public class DefaultCheckTest {
final Result doc = this.implementation.checkInput(read(Simple.FOO));
assertThat(doc).isNotNull();
assertThat(doc.getReport()).isNotNull();
assertThat(doc.isAcceptable()).isFalse();
assertThat(doc.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.UNDEFINED);
assertThat(doc.isAcceptable()).isTrue();
assertThat(doc.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.ACCEPTABLE);
}
@Test
@ -120,6 +121,17 @@ public class DefaultCheckTest {
assertThat(result.isProcessingSuccessful()).isFalse();
}
@Test
public void testNoScenario() {
final Result result = this.implementation.checkInput(read(UNKNOWN));
assertThat(result).isNotNull();
assertThat(result.isWellformed()).isTrue();
assertThat(result.isProcessingSuccessful()).isTrue();
assertThat(result.isSchemaValid()).isFalse();
assertThat(result.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.REJECT);
assertThat(result.isAcceptable()).isFalse();
}
@Test
public void testNotWellFormed() {
final Result result = this.implementation.checkInput(read(NOT_WELLFORMED));
@ -130,7 +142,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();
}
}

View file

@ -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/");

View file

@ -3,7 +3,6 @@ package de.kosit.validationtool.impl;
import static org.assertj.core.api.Assertions.assertThat;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import org.junit.Before;
import org.junit.Test;
@ -19,12 +18,12 @@ import de.kosit.validationtool.impl.Helper.Simple;
*
* @author Andreas Penski
*/
public class SimpleScenarioCheck {
public class SimpleScenarioCheckTest {
private DefaultCheck implementation;
@Before
public void setup() throws URISyntaxException {
public void setup() {
final CheckConfiguration d = new CheckConfiguration(Simple.SCENARIOS);
d.setScenarioRepository(Simple.REPOSITORY);
this.implementation = new DefaultCheck(d);
@ -49,14 +48,17 @@ public class SimpleScenarioCheck {
public void testUnknown() throws MalformedURLException {
final Result result = this.implementation.checkInput(InputFactory.read(Simple.UNKNOWN.toURL()));
assertThat(result).isNotNull();
assertThat(result.isProcessingSuccessful()).isFalse();
assertThat(result.isProcessingSuccessful()).isTrue();
assertThat(result.isAcceptable()).isFalse();
assertThat(result.getAcceptRecommendation()).isEqualTo(AcceptRecommendation.REJECT);
}
@Test
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);
}
}

View file

@ -0,0 +1,101 @@
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.Collections;
import org.junit.Test;
import de.kosit.validationtool.api.AcceptRecommendation;
import de.kosit.validationtool.impl.tasks.CheckAction.Bag;
/**
* 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 testAcceptMatchOverridesSchematronErrors() {
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 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);
bag.setReport(null);
this.action.check(bag);
assertThat(bag.getAcceptStatus()).isEqualTo(AcceptRecommendation.REJECT);
}
}

View file

@ -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("<some>xml</some>".getBytes(), "someXml")).getObject();
}
static Bag createBag(final boolean schemaValid, final boolean schematronValid) {
final Result<Boolean, XMLSyntaxError> schemaResult = schemaValid ? new Result<>(true)
: new Result<>(Collections.singletonList(new XMLSyntaxError()));
final List<ValidationResultsSchematron> schematronResult = schematronValid ? Collections.emptyList() : createSchematronError();
return createBag(schemaResult, schematronResult);
}
private static List<ValidationResultsSchematron> 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<Boolean, XMLSyntaxError> schemaResult,
final Collection<ValidationResultsSchematron> schematronResult) {
final CreateReportInput reportInput = new CreateReportInput();
reportInput.getValidationResultsSchematron().addAll(schematronResult);
final Bag b = createBag(InputFactory.read("<someXml></someXml>".getBytes(), "someCheck"), true, reportInput);
b.setSchemaValidationResult(schemaResult);
b.setReport(createReport());
return b;
}
}

View file

@ -1,330 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Koordinierungsstelle für IT-Standards (KoSIT) under
~ one or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. KoSIT licenses this file
~ to you under the Apache License, Version 2.0 (the
~ "License"); you may not use this file except in compliance
~ with the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<rep:report xmlns:rep="http://www.xoev.de/de/validator/varl/1 " valid="false" varlVersion="1.0.0">
<rep:engine>
<rep:name>KoSIT POC</rep:name>
</rep:engine>
<rep:timestamp>2017-09-01T13:13:59.055+02:00</rep:timestamp>
<rep:documentIdentification>
<rep:documentHash>
<rep:hashAlgorithm>SHA-256</rep:hashAlgorithm>
<rep:hashValue>4exhW9EJxAbhlZLHZ3mYZ3/hWGG5e6mIpiTAlGTpQ7s=</rep:hashValue>
</rep:documentHash>
<rep:documentReference>
/C:/Developer/source/init/eRechnung-Check/src/test/resources/examples/UBLReady/UBLReady_EU_UBL-NL_20170102_FULL.xml
</rep:documentReference>
</rep:documentIdentification>
<ns2:scenario xmlns:ns2="http://www.xoev.de/de/validator/framework/1/scenarios"
xmlns="http://www.xoev.de/de/validator/framework/1/createreportinput">
<ns2:name>UBL 2.1 Invoice</ns2:name>
<ns2:namespace prefix="invoice">urn:oasis:names:specification:ubl:schema:xsd:Invoice-2</ns2:namespace>
<ns2:match>/invoice:Invoice</ns2:match>
<ns2:validateWithXmlSchema>
<ns2:resource>
<ns2:name>UBL 2.1 Invoice</ns2:name>
<ns2:location>resources/eRechnung/UBL-2.1/xsdrt/maindoc/UBL-Invoice-2.1.xsd</ns2:location>
</ns2:resource>
</ns2:validateWithXmlSchema>
<ns2:validateWithSchematron>
<ns2:resource>
<ns2:name>BII Rules for Invoice</ns2:name>
<ns2:location>resources/eRechnung/UBL-2.1/xsl/BIIRULES-UBL-T10.xsl</ns2:location>
</ns2:resource>
</ns2:validateWithSchematron>
<ns2:validateWithSchematron>
<ns2:resource>
<ns2:name>openPEPPOL Rules for Invoice</ns2:name>
<ns2:location>resources/eRechnung/UBL-2.1/xsl/OPENPEPPOL-UBL-T10.xsl</ns2:location>
</ns2:resource>
</ns2:validateWithSchematron>
<ns2:createReport>
<ns2:resource>
<ns2:name>Report für eRechnung</ns2:name>
<ns2:location>resources/eRechnung/report.xsl</ns2:location>
</ns2:resource>
</ns2:createReport>
</ns2:scenario>
<rep:validationResult>
<rep:validationStepResult id="step_1" valid="true">
<ns2:resource xmlns:ns2="http://www.xoev.de/de/validator/framework/1/scenarios"
xmlns="http://www.xoev.de/de/validator/framework/1/createreportinput">
<ns2:name>UBL 2.1 Invoice</ns2:name>
<ns2:location>resources/eRechnung/UBL-2.1/xsdrt/maindoc/UBL-Invoice-2.1.xsd</ns2:location>
</ns2:resource>
</rep:validationStepResult>
<rep:validationStepResult id="step_2" valid="false">
<ns2:resource xmlns:ns2="http://www.xoev.de/de/validator/framework/1/scenarios"
xmlns="http://www.xoev.de/de/validator/framework/1/createreportinput">
<ns2:name>BII Rules for Invoice</ns2:name>
<ns2:location>resources/eRechnung/UBL-2.1/xsl/BIIRULES-UBL-T10.xsl</ns2:location>
</ns2:resource>
<rep:message code="CL-T10-R010" id="message_2.1" level="warning"
xpathLocation="/*:Invoice[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2'][1]/*:AllowanceCharge[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2'][3]/*:AllowanceChargeReasonCode[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2'][1]">
[CL-T10-R010]-Coded allowance and charge reasons SHOULD belong to the UNCL 4465 code list BII2 subset
</rep:message>
</rep:validationStepResult>
<rep:validationStepResult id="step_3" valid="false">
<ns2:resource xmlns:ns2="http://www.xoev.de/de/validator/framework/1/scenarios"
xmlns="http://www.xoev.de/de/validator/framework/1/createreportinput">
<ns2:name>openPEPPOL Rules for Invoice</ns2:name>
<ns2:location>resources/eRechnung/UBL-2.1/xsl/OPENPEPPOL-UBL-T10.xsl</ns2:location>
</ns2:resource>
<rep:message code="EUGEN-T10-R026" id="message_3.1" level="error"
xpathLocation="/*:Invoice[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2'][1]/*:DocumentCurrencyCode[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2'][1]">
[EUGEN-T10-R026]-A currency code element MUST have a list identifier attribute 'ISO4217'.
</rep:message>
<rep:message code="EUGEN-T10-R041" id="message_3.2" level="warning"
xpathLocation="/*:Invoice[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2'][1]/*:AccountingSupplierParty[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2'][1]">
[EUGEN-T10-R041]-The VAT identifier for the supplier SHOULD be prefixed with country code for companies
with VAT registration in EU countries
</rep:message>
<rep:message code="EUGEN-T10-R054" id="message_3.3" level="warning"
xpathLocation="/*:Invoice[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2'][1]/*:AccountingSupplierParty[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2'][1]/*:Party[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2'][1]/*:PartyLegalEntity[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2'][1]/*:CompanyID[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2'][1]">
[EUGEN-T10-R054]-A party legal entity company identifier SHOULD have a scheme identifier attribute.
</rep:message>
<rep:message code="EUGEN-T10-R029" id="message_3.4" level="error"
xpathLocation="/*:Invoice[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2'][1]/*:AllowanceCharge[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2'][1]/*:AllowanceChargeReasonCode[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2'][1]">
[EUGEN-T10-R029]-An allowance charge reason code MUST have a list identifier attribute 'UNCL4465'.
</rep:message>
<rep:message code="EUGEN-T10-R029" id="message_3.5" level="error"
xpathLocation="/*:Invoice[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2'][1]/*:AllowanceCharge[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2'][2]/*:AllowanceChargeReasonCode[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2'][1]">
[EUGEN-T10-R029]-An allowance charge reason code MUST have a list identifier attribute 'UNCL4465'.
</rep:message>
<rep:message code="EUGEN-T10-R029" id="message_3.6" level="error"
xpathLocation="/*:Invoice[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2'][1]/*:AllowanceCharge[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2'][3]/*:AllowanceChargeReasonCode[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2'][1]">
[EUGEN-T10-R029]-An allowance charge reason code MUST have a list identifier attribute 'UNCL4465'.
</rep:message>
</rep:validationStepResult>
</rep:validationResult>
<rep:assessment>
<rep:reject>
<rep:explanation>
<html xmlns="http://www.w3.org/1999/xhtml" data-report-type="devreport-reject">
<head>
<title>Pruefbericht der KoSIT</title>
<style>
body{
font-family: Calibri;
width: 230mm;
}
table{
border-collapse: collapse;
width: 100%;
}
table.tbl-errors{
font-size: 10pt;
}
.tbl-errors td{
border: 1px solid lightgray;
padding: 2px;
vertical-align: top;
}
thead{
font-weight: bold;
background-color: #f0f0f0;
padding-top: 6pt;
padding-bottom: 2pt;
}
.tbl-meta td{
padding-right: 1em;
}
tr{
vertical-align: bottom;
border-bottom: 1px solid #c0c0c0;
}
tr.error{
font-weight: bold;
color: red;
}
tr.warning{
font-weight: bold;
}
tr.pos{
font-weight: bold;
}
p.important{
font-weight: bold;
text-align: left;
background-color: #e0e0e0;
padding: 3pt;
}
td.right{
text-align: right
}
</style>
</head>
<body>
<h1>Prüfbericht der KoSIT</h1>
<h2>Angaben zum geprüften Dokument</h2>
<table class="tbl-meta">
<tr>
<td colspan="2">Dokument:</td>
<td colspan="3">
/C:/Developer/source/init/eRechnung-Check/src/test/resources/examples/UBLReady/UBLReady_EU_UBL-NL_20170102_FULL.xml
</td>
</tr>
<tr>
<td colspan="2">Szenario:</td>
<td colspan="3"/>
</tr>
<tr>
<td colspan="2">Zeitpunkt:</td>
<td colspan="3">1.9.2017 13:13:59</td>
</tr>
<tr>
<td colspan="2">Validierungsschritte:</td>
<td>Fehler</td>
<td>Warnung</td>
<td>Information</td>
</tr>
</table>
<p class="important"><b>Konformitätsprüfung:</b>Das geprüfte Dokument enthält 4 Fehler / 3
Warnungen. Es ist <b>nicht konform</b> zu den formalen Vorgaben.
</p>
<table class="tbl-errors">
<thead>
<tr>
<th>Pos</th>
<th>Code</th>
<th>CustomLevel (Level)</th>
<th>Step</th>
<th>Text</th>
</tr>
</thead>
<tbody>
<tr class="warning">
<td>1</td>
<td>CL-T10-R010</td>
<td>warning</td>
<td/>
<td>[CL-T10-R010]-Coded allowance and charge reasons SHOULD belong to the UNCL 4465
code list BII2 subset
</td>
</tr>
<tr>
<td colspan="4"/>
<td/>
</tr>
<tr class="error">
<td>2</td>
<td>EUGEN-T10-R026</td>
<td>error</td>
<td/>
<td>[EUGEN-T10-R026]-A currency code element MUST have a list identifier attribute
'ISO4217'.
</td>
</tr>
<tr>
<td colspan="4"/>
<td/>
</tr>
<tr class="warning">
<td>3</td>
<td>EUGEN-T10-R041</td>
<td>warning</td>
<td/>
<td>[EUGEN-T10-R041]-The VAT identifier for the supplier SHOULD be prefixed with
country code for companies with VAT registration in EU countries
</td>
</tr>
<tr>
<td colspan="4"/>
<td/>
</tr>
<tr class="warning">
<td>4</td>
<td>EUGEN-T10-R054</td>
<td>warning</td>
<td/>
<td>[EUGEN-T10-R054]-A party legal entity company identifier SHOULD have a scheme
identifier attribute.
</td>
</tr>
<tr>
<td colspan="4"/>
<td/>
</tr>
<tr class="error">
<td>5</td>
<td>EUGEN-T10-R029</td>
<td>error</td>
<td/>
<td>[EUGEN-T10-R029]-An allowance charge reason code MUST have a list identifier
attribute 'UNCL4465'.
</td>
</tr>
<tr>
<td colspan="4"/>
<td/>
</tr>
<tr class="error">
<td>6</td>
<td>EUGEN-T10-R029</td>
<td>error</td>
<td/>
<td>[EUGEN-T10-R029]-An allowance charge reason code MUST have a list identifier
attribute 'UNCL4465'.
</td>
</tr>
<tr>
<td colspan="4"/>
<td/>
</tr>
<tr class="error">
<td>7</td>
<td>EUGEN-T10-R029</td>
<td>error</td>
<td/>
<td>[EUGEN-T10-R029]-An allowance charge reason code MUST have a list identifier
attribute 'UNCL4465'.
</td>
</tr>
<tr>
<td colspan="4"/>
<td/>
</tr>
</tbody>
</table>
<p class="important"><b>Bewertung:</b>Es wird empfohlen das Dokument zurückzuweisen.
</p>
<p class="info">Erstellt mit: KoSIT POC für das InstructionSet
<em/>
vom .
</p>
</body>
</html>
</rep:explanation>
</rep:reject>
</rep:assessment>
</rep:report>

View file

@ -2,4 +2,7 @@
<foo xmlns="http://validator.kosit.de/test-sample">
<inner>asldkfj</inner>
<content>
<rejected/>
</content>
</foo>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<simple xmlns="http://validator.kosit.de/test-sample">
<inner>asldkfj</inner>
<content>
<rejected>directly transferred, so this is part of the report</rejected>
</content>
</simple>

View file

@ -47,7 +47,7 @@
<location>report.xsl</location>
</resource>
</createReport>
<acceptMatch>count(//cri:xmlSyntaxError) = 0</acceptMatch>
<acceptMatch>count(//test:rejected) = 0</acceptMatch>
</scenario>
<scenario>