Upgrade Saxon to 11.4

This commit is contained in:
apenski 2022-11-08 08:32:11 +01:00
parent bf50b6ff49
commit 0281d94929
6 changed files with 84 additions and 87 deletions

View file

@ -16,7 +16,7 @@
# limitations under the License.
#
TAGS=("3-openjdk-16" "3-jdk-11" "3-jdk-11-openj9" "3-jdk-8" "3-jdk-8-openj9" "3-openjdk-15" "3-openjdk-17")
TAGS=("3-openjdk-16" "3-jdk-11" "3-jdk-11-openj9" "3-jdk-8" "3-jdk-8-openj9" "3-openjdk-15" "3-openjdk-17", "3-openjdk-18")
docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
for i in "${TAGS[@]}"

View file

@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [ResolvingConfigurationStrategy.java#getProcessor()](de/kosit/validationtool/api/ResolvingConfigurationStrategy) is
removed.
- Bump [Saxon HE](https://www.saxonica.com/documentation11/documentation.xml) to 11.4
- Bump [jaxb-ri](https://github.com/eclipse-ee4j/jaxb-ri) to 2.3.7
- [INTERNAL] CLI parsing based on pico-cli, commons-cli is removed

View file

@ -57,7 +57,7 @@
<version.jacoco>0.8.7</version.jacoco>
<version.jaxb>2.3.7</version.jaxb>
<version.lombok>1.18.20</version.lombok>
<version.saxon-he>9.9.1-7</version.saxon-he>
<version.saxon-he>11.4</version.saxon-he>
<version.slf4j>1.7.25</version.slf4j>
</properties>
<repositories>

View file

@ -49,7 +49,7 @@ import net.sf.saxon.s9api.XPathExecutable;
@Slf4j
class XPathBuilder implements Builder<XPathExecutable> {
private static final String[] IGNORED_PREFIXES = new String[] { "xsd", "saxon", "xsl", "xs" };
private static final String[] IGNORED_PREFIXES = new String[] { "xsd", "saxon", "xsl", "xs", "xml" };
private final String name;
@ -60,6 +60,10 @@ class XPathBuilder implements Builder<XPathExecutable> {
@Setter(AccessLevel.PACKAGE)
private Map<String, String> namespaces;
private static Result<XPathExecutable, String> createError(final String msg) {
return new Result<>(null, Collections.singletonList(msg));
}
Map<String, String> getNamespaces() {
if (this.namespaces == null) {
this.namespaces = new HashMap<>();
@ -69,7 +73,7 @@ class XPathBuilder implements Builder<XPathExecutable> {
/**
* Returns the xpath expression.
*
*
* @return xpath expression
*/
public String getXPath() {
@ -118,8 +122,4 @@ class XPathBuilder implements Builder<XPathExecutable> {
private String extractExpression() {
return this.executable.getUnderlyingExpression().getInternalExpression().toString();
}
private static Result<XPathExecutable, String> createError(final String msg) {
return new Result<>(null, Collections.singletonList(msg));
}
}

View file

@ -35,7 +35,8 @@ import lombok.Getter;
import de.kosit.validationtool.model.reportInput.XMLSyntaxError;
import de.kosit.validationtool.model.reportInput.XMLSyntaxErrorSeverity;
import net.sf.saxon.s9api.MessageListener;
import net.sf.saxon.s9api.MessageListener2;
import net.sf.saxon.s9api.QName;
import net.sf.saxon.s9api.XdmNode;
/**
@ -44,7 +45,7 @@ import net.sf.saxon.s9api.XdmNode;
* @author Andreas Penski
*/
@Getter
public class CollectingErrorEventHandler implements ValidationEventHandler, ErrorHandler, MessageListener, ErrorListener {
public class CollectingErrorEventHandler implements ValidationEventHandler, ErrorHandler, MessageListener2, ErrorListener {
private static final int DEFAULT_ABORT_COUNT = 50;
@ -131,7 +132,7 @@ public class CollectingErrorEventHandler implements ValidationEventHandler, Erro
}
@Override
public void message(final XdmNode content, final boolean terminate, final SourceLocator locator) {
public void message(final XdmNode content, final QName errorCode, final boolean terminate, final SourceLocator locator) {
final XMLSyntaxError e = new XMLSyntaxError();
if (locator != null) {
e.setColumnNumber(locator.getColumnNumber());

View file

@ -33,7 +33,6 @@ import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.AttributesImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -44,7 +43,6 @@ import de.kosit.validationtool.impl.EngineInformation;
import de.kosit.validationtool.impl.Scenario;
import de.kosit.validationtool.model.reportInput.XMLSyntaxError;
import net.sf.saxon.s9api.BuildingContentHandler;
import net.sf.saxon.s9api.DocumentBuilder;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.QName;
@ -53,6 +51,8 @@ import net.sf.saxon.s9api.XdmDestination;
import net.sf.saxon.s9api.XdmNode;
import net.sf.saxon.s9api.XsltExecutable;
import net.sf.saxon.s9api.XsltTransformer;
import net.sf.saxon.sapling.SaplingDocument;
import net.sf.saxon.sapling.Saplings;
/**
* Erzeugt den Report auf Basis der gesammelten Informationen über den Prüfling. Sollte kein Szenario identifiziert
@ -64,6 +64,64 @@ import net.sf.saxon.s9api.XsltTransformer;
@Slf4j
public class CreateReportAction implements CheckAction {
private static final String ERROR_MESSAGE_ELEMENT = "error-message";
private final Processor processor;
private final ConversionService conversionService;
private static XsltExecutable loadFromScenario(final Scenario object) {
return object.getReportTransformation().getExecutable();
}
private static XsltExecutable getTransformation(final Bag results) {
return loadFromScenario(results.getScenarioSelectionResult().getObject());
}
@Override
public void check(final Bag results) {
final DocumentBuilder documentBuilder = this.processor.newDocumentBuilder();
try {
final XdmNode parsedDocument = results.getParserResult().isValid() ? results.getParserResult().getObject()
: createErrorInformation(results.getParserResult().getErrors());
final Marshaller marshaller = this.conversionService.getJaxbContext().createMarshaller();
final JAXBSource source = new JAXBSource(marshaller, results.getReportInput());
// wrap to circumvent inconsistency between sax and saxon
source.setXMLReader(new ReaderWrapper(source.getXMLReader()));
final XdmNode root = documentBuilder.build(source);
final XsltTransformer transformer = getTransformation(results).load();
transformer.setInitialContextNode(root);
final CollectingErrorEventHandler e = new CollectingErrorEventHandler();
transformer.setMessageListener(e);
final Scenario scenario = results.getScenarioSelectionResult().getObject();
transformer.setURIResolver(scenario.getUriResolver());
if (scenario.getUnparsedTextURIResolver() != null) {
transformer.getUnderlyingController().setUnparsedTextURIResolver(scenario.getUnparsedTextURIResolver());
}
if (parsedDocument != null) {
transformer.setParameter(new QName("input-document"), parsedDocument);
}
final XdmDestination destination = new XdmDestination();
transformer.setDestination(destination);
transformer.transform();
results.setReport(destination.getXdmNode());
} catch (final SaxonApiException | JAXBException e) {
log.error("Error creating final report", e);
results.stopProcessing("Can not create final report: " + e.getMessage());
}
}
private XdmNode createErrorInformation(final Collection<XMLSyntaxError> errors) throws SaxonApiException {
final String message = errors.stream().map(XMLSyntaxError::getMessage).collect(Collectors.joining());
final SaplingDocument doc = Saplings.doc(EngineInformation.getFrameworkNamespace());
return doc.withChild(Saplings.elem(ERROR_MESSAGE_ELEMENT).withText(message)).toXdmNode(this.processor);
}
/**
* Wrapper to fix some inconsistencies between sax and saxon. Saxon tries to set some properties which has no effect
* on {@link JAXBSource}'s XMLReader, but it throws exceptions on unknown properties. This just drops this
@ -113,19 +171,14 @@ public class CreateReportAction implements CheckAction {
this.delegate.setProperty(name, value);
}
@Override
public void setEntityResolver(final EntityResolver resolver) {
this.delegate.setEntityResolver(resolver);
}
@Override
public EntityResolver getEntityResolver() {
return this.delegate.getEntityResolver();
}
@Override
public void setDTDHandler(final DTDHandler handler) {
this.delegate.setDTDHandler(handler);
public void setEntityResolver(final EntityResolver resolver) {
this.delegate.setEntityResolver(resolver);
}
@Override
@ -134,8 +187,8 @@ public class CreateReportAction implements CheckAction {
}
@Override
public void setContentHandler(final ContentHandler handler) {
this.delegate.setContentHandler(handler);
public void setDTDHandler(final DTDHandler handler) {
this.delegate.setDTDHandler(handler);
}
@Override
@ -144,8 +197,8 @@ public class CreateReportAction implements CheckAction {
}
@Override
public void setErrorHandler(final ErrorHandler handler) {
this.delegate.setErrorHandler(handler);
public void setContentHandler(final ContentHandler handler) {
this.delegate.setContentHandler(handler);
}
@Override
@ -153,6 +206,11 @@ public class CreateReportAction implements CheckAction {
return this.delegate.getErrorHandler();
}
@Override
public void setErrorHandler(final ErrorHandler handler) {
this.delegate.setErrorHandler(handler);
}
@Override
public void parse(final InputSource input) throws IOException, SAXException {
this.delegate.parse(input);
@ -164,67 +222,4 @@ public class CreateReportAction implements CheckAction {
}
}
private static final String ERROR_MESSAGE_ELEMENT = "error-message";
private final Processor processor;
private final ConversionService conversionService;
private static XsltExecutable loadFromScenario(final Scenario object) {
return object.getReportTransformation().getExecutable();
}
@Override
public void check(final Bag results) {
final DocumentBuilder documentBuilder = this.processor.newDocumentBuilder();
try {
final XdmNode parsedDocument = results.getParserResult().isValid() ? results.getParserResult().getObject()
: createErrorInformation(results.getParserResult().getErrors());
final Marshaller marshaller = this.conversionService.getJaxbContext().createMarshaller();
final JAXBSource source = new JAXBSource(marshaller, results.getReportInput());
// wrap to circumvent inconsistency between sax and saxon
source.setXMLReader(new ReaderWrapper(source.getXMLReader()));
final XdmNode root = documentBuilder.build(source);
final XsltTransformer transformer = getTransformation(results).load();
transformer.setInitialContextNode(root);
final CollectingErrorEventHandler e = new CollectingErrorEventHandler();
transformer.setMessageListener(e);
final Scenario scenario = results.getScenarioSelectionResult().getObject();
transformer.setURIResolver(scenario.getUriResolver());
if (scenario.getUnparsedTextURIResolver() != null) {
transformer.getUnderlyingController().setUnparsedTextURIResolver(scenario.getUnparsedTextURIResolver());
}
if (parsedDocument != null) {
transformer.setParameter(new QName("input-document"), parsedDocument);
}
final XdmDestination destination = new XdmDestination();
transformer.setDestination(destination);
transformer.transform();
results.setReport(destination.getXdmNode());
} catch (final SaxonApiException | SAXException | JAXBException e) {
log.error("Error creating final report", e);
results.stopProcessing("Can not create final report: " + e.getMessage());
}
}
private XdmNode createErrorInformation(final Collection<XMLSyntaxError> errors) throws SaxonApiException, SAXException {
final BuildingContentHandler contentHandler = this.processor.newDocumentBuilder().newBuildingContentHandler();
contentHandler.startDocument();
contentHandler.startElement(EngineInformation.getFrameworkNamespace(), ERROR_MESSAGE_ELEMENT, ERROR_MESSAGE_ELEMENT,
new AttributesImpl());
final String message = errors.stream().map(XMLSyntaxError::getMessage).collect(Collectors.joining());
contentHandler.characters(message.toCharArray(), 0, message.length());
contentHandler.endElement(EngineInformation.getFrameworkNamespace(), ERROR_MESSAGE_ELEMENT, ERROR_MESSAGE_ELEMENT);
return contentHandler.getDocumentNode();
}
private static XsltExecutable getTransformation(final Bag results) {
return loadFromScenario(results.getScenarioSelectionResult().getObject());
}
}