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. # 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" docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
for i in "${TAGS[@]}" 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 - [ResolvingConfigurationStrategy.java#getProcessor()](de/kosit/validationtool/api/ResolvingConfigurationStrategy) is
removed. 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 - 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 - [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.jacoco>0.8.7</version.jacoco>
<version.jaxb>2.3.7</version.jaxb> <version.jaxb>2.3.7</version.jaxb>
<version.lombok>1.18.20</version.lombok> <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> <version.slf4j>1.7.25</version.slf4j>
</properties> </properties>
<repositories> <repositories>

View file

@ -49,7 +49,7 @@ import net.sf.saxon.s9api.XPathExecutable;
@Slf4j @Slf4j
class XPathBuilder implements Builder<XPathExecutable> { 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; private final String name;
@ -60,6 +60,10 @@ class XPathBuilder implements Builder<XPathExecutable> {
@Setter(AccessLevel.PACKAGE) @Setter(AccessLevel.PACKAGE)
private Map<String, String> namespaces; 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() { Map<String, String> getNamespaces() {
if (this.namespaces == null) { if (this.namespaces == null) {
this.namespaces = new HashMap<>(); this.namespaces = new HashMap<>();
@ -118,8 +122,4 @@ class XPathBuilder implements Builder<XPathExecutable> {
private String extractExpression() { private String extractExpression() {
return this.executable.getUnderlyingExpression().getInternalExpression().toString(); 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.XMLSyntaxError;
import de.kosit.validationtool.model.reportInput.XMLSyntaxErrorSeverity; 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; import net.sf.saxon.s9api.XdmNode;
/** /**
@ -44,7 +45,7 @@ import net.sf.saxon.s9api.XdmNode;
* @author Andreas Penski * @author Andreas Penski
*/ */
@Getter @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; private static final int DEFAULT_ABORT_COUNT = 50;
@ -131,7 +132,7 @@ public class CollectingErrorEventHandler implements ValidationEventHandler, Erro
} }
@Override @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(); final XMLSyntaxError e = new XMLSyntaxError();
if (locator != null) { if (locator != null) {
e.setColumnNumber(locator.getColumnNumber()); e.setColumnNumber(locator.getColumnNumber());

View file

@ -33,7 +33,6 @@ import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException; import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.XMLReader; import org.xml.sax.XMLReader;
import org.xml.sax.helpers.AttributesImpl;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; 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.impl.Scenario;
import de.kosit.validationtool.model.reportInput.XMLSyntaxError; import de.kosit.validationtool.model.reportInput.XMLSyntaxError;
import net.sf.saxon.s9api.BuildingContentHandler;
import net.sf.saxon.s9api.DocumentBuilder; import net.sf.saxon.s9api.DocumentBuilder;
import net.sf.saxon.s9api.Processor; import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.QName; 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.XdmNode;
import net.sf.saxon.s9api.XsltExecutable; import net.sf.saxon.s9api.XsltExecutable;
import net.sf.saxon.s9api.XsltTransformer; 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 * 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 @Slf4j
public class CreateReportAction implements CheckAction { 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 * 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 * 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); this.delegate.setProperty(name, value);
} }
@Override
public void setEntityResolver(final EntityResolver resolver) {
this.delegate.setEntityResolver(resolver);
}
@Override @Override
public EntityResolver getEntityResolver() { public EntityResolver getEntityResolver() {
return this.delegate.getEntityResolver(); return this.delegate.getEntityResolver();
} }
@Override @Override
public void setDTDHandler(final DTDHandler handler) { public void setEntityResolver(final EntityResolver resolver) {
this.delegate.setDTDHandler(handler); this.delegate.setEntityResolver(resolver);
} }
@Override @Override
@ -134,8 +187,8 @@ public class CreateReportAction implements CheckAction {
} }
@Override @Override
public void setContentHandler(final ContentHandler handler) { public void setDTDHandler(final DTDHandler handler) {
this.delegate.setContentHandler(handler); this.delegate.setDTDHandler(handler);
} }
@Override @Override
@ -144,8 +197,8 @@ public class CreateReportAction implements CheckAction {
} }
@Override @Override
public void setErrorHandler(final ErrorHandler handler) { public void setContentHandler(final ContentHandler handler) {
this.delegate.setErrorHandler(handler); this.delegate.setContentHandler(handler);
} }
@Override @Override
@ -153,6 +206,11 @@ public class CreateReportAction implements CheckAction {
return this.delegate.getErrorHandler(); return this.delegate.getErrorHandler();
} }
@Override
public void setErrorHandler(final ErrorHandler handler) {
this.delegate.setErrorHandler(handler);
}
@Override @Override
public void parse(final InputSource input) throws IOException, SAXException { public void parse(final InputSource input) throws IOException, SAXException {
this.delegate.parse(input); 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());
}
} }