From e82365c9e5440e75f977bc49c196f339843bfc19 Mon Sep 17 00:00:00 2001 From: "Andreas Penski (init)" Date: Fri, 8 Feb 2019 10:20:48 +0100 Subject: [PATCH] #20 Initiales Parsen schon mit s9api umgesetzt. Kein w3c Document benutzt --- pom.xml | 2 +- .../impl/ScenarioRepository.java | 34 +++++++------- .../impl/tasks/CheckAction.java | 4 +- .../impl/tasks/CreateReportAction.java | 5 +- .../impl/tasks/DocumentParseAction.java | 47 +++++++++---------- .../tasks/SchematronValidationAction.java | 22 ++++----- .../impl/DocumentParserTest.java | 7 +-- .../impl/ScenarioRepositoryTest.java | 5 +- 8 files changed, 62 insertions(+), 64 deletions(-) diff --git a/pom.xml b/pom.xml index 724d50c..905da62 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ UTF-8 0.7.9 1.16.16 - 9.7.0-15 + 9.9.0-1 1.7.25 diff --git a/src/main/java/de/kosit/validationtool/impl/ScenarioRepository.java b/src/main/java/de/kosit/validationtool/impl/ScenarioRepository.java index 9234a8e..f43b43e 100644 --- a/src/main/java/de/kosit/validationtool/impl/ScenarioRepository.java +++ b/src/main/java/de/kosit/validationtool/impl/ScenarioRepository.java @@ -19,16 +19,13 @@ package de.kosit.validationtool.impl; +import static org.apache.commons.lang3.StringUtils.startsWith; + import java.net.MalformedURLException; import java.net.URI; import java.util.List; import java.util.stream.Collectors; -import javax.xml.transform.dom.DOMSource; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; - import lombok.AccessLevel; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -42,7 +39,12 @@ import de.kosit.validationtool.model.reportInput.XMLSyntaxError; import de.kosit.validationtool.model.scenarios.ScenarioType; import de.kosit.validationtool.model.scenarios.Scenarios; -import net.sf.saxon.s9api.*; +import net.sf.saxon.s9api.Processor; +import net.sf.saxon.s9api.QName; +import net.sf.saxon.s9api.SaxonApiException; +import net.sf.saxon.s9api.XPathSelector; +import net.sf.saxon.s9api.XdmNode; +import net.sf.saxon.s9api.XsltExecutable; /** * Repository for die aktiven Szenario einer Prüfinstanz. @@ -69,16 +71,17 @@ public class ScenarioRepository { @Getter(value = AccessLevel.PACKAGE) private Scenarios scenarios; - private static boolean isSupportedDocument(Document doc) { - final Element root = doc.getDocumentElement(); - return root.hasAttribute("frameworkVersion") && root.getAttribute("frameworkVersion").startsWith(SUPPORTED_MAJOR_VERSION) - && doc.getDocumentElement().getNamespaceURI().equals(SUPPORTED_MAJOR_VERSION_SCHEMA); + private static boolean isSupportedDocument(XdmNode doc) { + final XdmNode root = doc.children().iterator().next(); + final String frameworkVersion = root.getAttributeValue(new QName("frameworkVersion")); + return startsWith(frameworkVersion, SUPPORTED_MAJOR_VERSION) + && root.getNodeName().getNamespaceURI().equals(SUPPORTED_MAJOR_VERSION_SCHEMA); } private static void checkVersion(URI scenarioDefinition) { DocumentParseAction p = new DocumentParseAction(); try { - final Result result = p.parseDocument(InputFactory.read(scenarioDefinition.toURL())); + final Result result = p.parseDocument(InputFactory.read(scenarioDefinition.toURL())); if (result.isValid() && !isSupportedDocument(result.getObject())) { throw new IllegalStateException(String.format( "Specified scenario configuration %s is not supported.%nThis version only supports definitions of '%s'", @@ -138,7 +141,7 @@ public class ScenarioRepository { * @param document das Eingabedokument * @return ein Ergebnis-Objekt zur weiteren Verarbeitung */ - public Result selectScenario(Document document) { + public Result selectScenario(XdmNode document) { Result result = new Result<>(); final List collect = scenarios.getScenario().stream().filter(s -> match(document, s)).collect(Collectors.toList()); if (collect.size() == 1) { @@ -152,13 +155,10 @@ public class ScenarioRepository { } - private boolean match(Document document, ScenarioType scenario) { + private boolean match(XdmNode document, ScenarioType scenario) { try { final XPathSelector selector = scenario.getSelector(); - DocumentBuilder documentBuilder = getProcessor().newDocumentBuilder(); - - final XdmNode xdmSource = documentBuilder.build(new DOMSource(document)); - selector.setContextItem(xdmSource); + selector.setContextItem(document); return selector.effectiveBooleanValue(); } catch (SaxonApiException e) { log.error("Error evaluating xpath expression", e); diff --git a/src/main/java/de/kosit/validationtool/impl/tasks/CheckAction.java b/src/main/java/de/kosit/validationtool/impl/tasks/CheckAction.java index fbacf46..c569663 100644 --- a/src/main/java/de/kosit/validationtool/impl/tasks/CheckAction.java +++ b/src/main/java/de/kosit/validationtool/impl/tasks/CheckAction.java @@ -22,8 +22,6 @@ package de.kosit.validationtool.impl.tasks; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.w3c.dom.Document; - import lombok.Getter; import lombok.Setter; @@ -85,7 +83,7 @@ public interface CheckAction { /** Das zu prüfende Dokument */ private Input input; - private Result parserResult; + private Result parserResult; private Result assertionResult; diff --git a/src/main/java/de/kosit/validationtool/impl/tasks/CreateReportAction.java b/src/main/java/de/kosit/validationtool/impl/tasks/CreateReportAction.java index 616e7b2..966859a 100644 --- a/src/main/java/de/kosit/validationtool/impl/tasks/CreateReportAction.java +++ b/src/main/java/de/kosit/validationtool/impl/tasks/CreateReportAction.java @@ -70,10 +70,9 @@ public class CreateReportAction implements CheckAction { final DocumentBuilder documentBuilder = processor.newDocumentBuilder(); try { - final Document inputDoc = results.getParserResult().isValid() ? results.getParserResult().getObject() - : ObjectFactory.createDocumentBuilder(true).newDocument(); + final XdmNode parsedDocument = results.getParserResult().isValid() ? results.getParserResult().getObject() + : ObjectFactory.createProcessor().newDocumentBuilder().newBuildingContentHandler().getDocumentNode(); - final XdmNode parsedDocument = documentBuilder.build(new DOMSource(inputDoc)); final Document reportInput = conversionService.writeDocument(results.getReportInput()); final XdmNode root = documentBuilder.build(new DOMSource(reportInput)); final XsltTransformer transformer = getTransformation(results).load(); diff --git a/src/main/java/de/kosit/validationtool/impl/tasks/DocumentParseAction.java b/src/main/java/de/kosit/validationtool/impl/tasks/DocumentParseAction.java index 874666c..9bc8313 100644 --- a/src/main/java/de/kosit/validationtool/impl/tasks/DocumentParseAction.java +++ b/src/main/java/de/kosit/validationtool/impl/tasks/DocumentParseAction.java @@ -19,23 +19,26 @@ package de.kosit.validationtool.impl.tasks; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collections; + +import javax.xml.transform.stream.StreamSource; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + import de.kosit.validationtool.api.Input; -import de.kosit.validationtool.impl.CollectingErrorEventHandler; import de.kosit.validationtool.impl.ObjectFactory; import de.kosit.validationtool.impl.model.Result; import de.kosit.validationtool.model.reportInput.ValidationResultsWellformedness; import de.kosit.validationtool.model.reportInput.XMLSyntaxError; import de.kosit.validationtool.model.reportInput.XMLSyntaxErrorSeverity; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.w3c.dom.Document; -import org.xml.sax.SAXException; -import javax.xml.parsers.DocumentBuilder; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Collections; +import net.sf.saxon.s9api.DocumentBuilder; +import net.sf.saxon.s9api.SaxonApiException; +import net.sf.saxon.s9api.XdmNode; /** * Setzt Parsing-Funktionalitäten um. Prüft auf well-formedness @@ -53,22 +56,18 @@ public class DocumentParseAction implements CheckAction { * @param content ein Dokument * @return Ergebnis des Parsings inklusive etwaiger Fehler */ - public Result parseDocument(Input content) { + public Result parseDocument(Input content) { if (content == null) { - throw new IllegalArgumentException("Url may not be null"); + throw new IllegalArgumentException("Input may not be null"); } - Result result; - CollectingErrorEventHandler errorHandler = new CollectingErrorEventHandler(); + Result result; try ( InputStream input = new ByteArrayInputStream(content.getContent()) ) { - DocumentBuilder db = ObjectFactory.createDocumentBuilder(false); - db.setErrorHandler(errorHandler); - Document doc = db.parse(input); - result = new Result<>(doc, errorHandler.getErrors()); - } catch (SAXException e) { - log.debug("SAXException while parsing {}", content.getName(), e); - result = new Result<>(errorHandler.getErrors()); - } catch (IOException e) { - log.debug("IOException while parsing {}", content, e); + final DocumentBuilder builder = ObjectFactory.createProcessor().newDocumentBuilder(); + builder.setLineNumbering(true); + XdmNode doc = builder.build(new StreamSource(input)); + result = new Result<>(doc, Collections.emptyList()); + } catch (SaxonApiException | IOException e) { + log.debug("Exception while parsing {}", content.getName(), e); XMLSyntaxError error = new XMLSyntaxError(); error.setSeverity(XMLSyntaxErrorSeverity.SEVERITY_FATAL_ERROR); error.setMessage(String.format("IOException while reading resource %s", content.getName())); @@ -80,7 +79,7 @@ public class DocumentParseAction implements CheckAction { @Override public void check(Bag results) { - Result parserResult = parseDocument(results.getInput()); + Result parserResult = parseDocument(results.getInput()); ValidationResultsWellformedness v = new ValidationResultsWellformedness(); results.setParserResult(parserResult); v.getXmlSyntaxError().addAll(parserResult.getErrors()); diff --git a/src/main/java/de/kosit/validationtool/impl/tasks/SchematronValidationAction.java b/src/main/java/de/kosit/validationtool/impl/tasks/SchematronValidationAction.java index 51002f1..f9d38d1 100644 --- a/src/main/java/de/kosit/validationtool/impl/tasks/SchematronValidationAction.java +++ b/src/main/java/de/kosit/validationtool/impl/tasks/SchematronValidationAction.java @@ -23,8 +23,6 @@ import java.net.URI; import java.util.List; import java.util.stream.Collectors; -import javax.xml.transform.dom.DOMSource; - import org.w3c.dom.Document; import lombok.RequiredArgsConstructor; @@ -37,7 +35,11 @@ import de.kosit.validationtool.model.reportInput.CreateReportInput; import de.kosit.validationtool.model.reportInput.ValidationResultsSchematron; import de.kosit.validationtool.model.scenarios.ScenarioType; -import net.sf.saxon.s9api.*; +import net.sf.saxon.s9api.DOMDestination; +import net.sf.saxon.s9api.Processor; +import net.sf.saxon.s9api.SaxonApiException; +import net.sf.saxon.s9api.XdmNode; +import net.sf.saxon.s9api.XsltTransformer; /** * Ausführung von konfigurierten Schematron Validierungen eines Szenarios. @@ -51,16 +53,14 @@ public class SchematronValidationAction implements CheckAction { private final URI repository; - private List validate(Document document, ScenarioType scenario) { + private List validate(XdmNode document, ScenarioType scenario) { return scenario.getSchematronValidations().stream().map(v -> validate(document, v)).collect(Collectors.toList()); } - private ValidationResultsSchematron validate(Document document, BaseScenario.Transformation validation) { - final DocumentBuilder documentBuilder = processor.newDocumentBuilder(); + private ValidationResultsSchematron validate(XdmNode document, BaseScenario.Transformation validation) { try { - final XdmNode root = documentBuilder.build(new DOMSource(document)); final XsltTransformer transformer = validation.getExecutable().load(); - //resolving nur relative zum Repository + // resolving nur relative zum Repository final RelativeUriResolver resolver = new RelativeUriResolver(repository); transformer.setURIResolver(resolver); CollectingErrorEventHandler e = new CollectingErrorEventHandler(); @@ -68,7 +68,7 @@ public class SchematronValidationAction implements CheckAction { Document result = ObjectFactory.createDocumentBuilder(false).newDocument(); transformer.setDestination(new DOMDestination(result)); - transformer.setInitialContextNode(root); + transformer.setInitialContextNode(document); transformer.transform(); ValidationResultsSchematron s = new ValidationResultsSchematron(); s.setResource(validation.getResourceType()); @@ -85,9 +85,9 @@ public class SchematronValidationAction implements CheckAction { @Override public void check(Bag results) { final CreateReportInput report = results.getReportInput(); - final List bla = validate(results.getParserResult().getObject(), + final List validationResult = validate(results.getParserResult().getObject(), results.getScenarioSelectionResult().getObject()); - report.getValidationResultsSchematron().addAll(bla); + report.getValidationResultsSchematron().addAll(validationResult); } @Override diff --git a/src/test/java/de/kosit/validationtool/impl/DocumentParserTest.java b/src/test/java/de/kosit/validationtool/impl/DocumentParserTest.java index f902bb7..3e54ee6 100644 --- a/src/test/java/de/kosit/validationtool/impl/DocumentParserTest.java +++ b/src/test/java/de/kosit/validationtool/impl/DocumentParserTest.java @@ -29,12 +29,13 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.w3c.dom.Document; import de.kosit.validationtool.impl.model.Result; import de.kosit.validationtool.impl.tasks.DocumentParseAction; import de.kosit.validationtool.model.reportInput.XMLSyntaxError; +import net.sf.saxon.s9api.XdmNode; + /** * @author Andreas Penski */ @@ -60,7 +61,7 @@ public class DocumentParserTest { @Test public void testSimple() throws IOException { - final Result result = parser.parseDocument(read(CONTENT)); + final Result result = parser.parseDocument(read(CONTENT)); assertThat(result).isNotNull(); assertThat(result.getObject()).isNotNull(); assertThat(result.getErrors()).isEmpty(); @@ -70,7 +71,7 @@ public class DocumentParserTest { @Test public void testIllformed() throws IOException { - final Result result = parser.parseDocument(read(ILLFORMED)); + final Result result = parser.parseDocument(read(ILLFORMED)); assertThat(result).isNotNull(); assertThat(result.getErrors()).isNotEmpty(); assertThat(result.getObject()).isNull(); diff --git a/src/test/java/de/kosit/validationtool/impl/ScenarioRepositoryTest.java b/src/test/java/de/kosit/validationtool/impl/ScenarioRepositoryTest.java index 76da77f..4e1492b 100644 --- a/src/test/java/de/kosit/validationtool/impl/ScenarioRepositoryTest.java +++ b/src/test/java/de/kosit/validationtool/impl/ScenarioRepositoryTest.java @@ -30,13 +30,14 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.w3c.dom.Document; import de.kosit.validationtool.impl.model.Result; import de.kosit.validationtool.impl.tasks.DocumentParseAction; import de.kosit.validationtool.model.scenarios.ScenarioType; import de.kosit.validationtool.model.scenarios.Scenarios; +import net.sf.saxon.s9api.XdmNode; + /** * Testet das {@link ScenarioRepository}. * @@ -94,7 +95,7 @@ public class ScenarioRepositoryTest { assertThat(scenario.isValid()).isFalse(); } - private Document load(URL url) throws IOException { + private XdmNode load(URL url) throws IOException { DocumentParseAction p = new DocumentParseAction(); return p.parseDocument(read(url)).getObject(); }