mirror of
https://github.com/itplr-kosit/validator.git
synced 2026-05-25 16:55:39 +00:00
Merge branch '59-resolving-does-not-work-when-using-xslts-unparsed-text-function' into 'master'
Resolve "Resolving does not work when using XSLTs unparsed-text() function" See merge request kosit/validator!29
This commit is contained in:
commit
592a1e87da
10 changed files with 58 additions and 16 deletions
|
|
@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
### Fixed
|
### Fixed
|
||||||
- `getFailedAsserts()` and `isSchematronValid()` in [DefaultResult.java](https://github.com/itplr-kosit/validator/blob/master/src/main/java/de/kosit/validationtool/impl/DefaultResult.java)
|
- `getFailedAsserts()` and `isSchematronValid()` in [DefaultResult.java](https://github.com/itplr-kosit/validator/blob/master/src/main/java/de/kosit/validationtool/impl/DefaultResult.java)
|
||||||
do not reflect actual schematron validation result
|
do not reflect actual schematron validation result
|
||||||
|
- exception while resolving when using XSLT's `unparsed-text()` function within report generation
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- engine info contains version number of the validator (configurations can output this in the report for maintainance puposes)
|
- engine info contains version number of the validator (configurations can output this in the report for maintainance puposes)
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import javax.xml.validation.Schema;
|
||||||
import javax.xml.validation.SchemaFactory;
|
import javax.xml.validation.SchemaFactory;
|
||||||
import javax.xml.validation.Validator;
|
import javax.xml.validation.Validator;
|
||||||
|
|
||||||
|
import net.sf.saxon.lib.UnparsedTextURIResolver;
|
||||||
import net.sf.saxon.s9api.Processor;
|
import net.sf.saxon.s9api.Processor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -28,7 +29,7 @@ public interface ResolvingConfigurationStrategy {
|
||||||
/**
|
/**
|
||||||
* Creates a preconfigured {@link SchemaFactory} for loading {@link javax.xml.validation.Schema} objects. The
|
* Creates a preconfigured {@link SchemaFactory} for loading {@link javax.xml.validation.Schema} objects. The
|
||||||
* implementation is responsible for xml security. Take care
|
* implementation is responsible for xml security. Take care
|
||||||
*
|
*
|
||||||
* @return preconfigured {@link SchemaFactory}
|
* @return preconfigured {@link SchemaFactory}
|
||||||
*/
|
*/
|
||||||
SchemaFactory createSchemaFactory();
|
SchemaFactory createSchemaFactory();
|
||||||
|
|
@ -37,9 +38,9 @@ public interface ResolvingConfigurationStrategy {
|
||||||
* Returns a preconfigured {@link Processor Saxon Processor} for various tasks within the Validator. The validator
|
* Returns a preconfigured {@link Processor Saxon Processor} for various tasks within the Validator. The validator
|
||||||
* leverages the saxon s9api for internal processing e.g. xml reading and writing. So this is the main object to secure
|
* leverages the saxon s9api for internal processing e.g. xml reading and writing. So this is the main object to secure
|
||||||
* for reading, transforming and writing xml files.
|
* for reading, transforming and writing xml files.
|
||||||
*
|
*
|
||||||
* Note: you need exactly one instance for all validator related processing.
|
* Note: you need exactly one instance for all validator related processing.
|
||||||
*
|
*
|
||||||
* @return a preconfigured {@link Processor}
|
* @return a preconfigured {@link Processor}
|
||||||
*/
|
*/
|
||||||
Processor getProcessor();
|
Processor getProcessor();
|
||||||
|
|
@ -52,12 +53,20 @@ public interface ResolvingConfigurationStrategy {
|
||||||
* This URIResolver is used to dereference the URIs appearing in <code>xsl:import</code>, <code>xsl:include</code>, and
|
* This URIResolver is used to dereference the URIs appearing in <code>xsl:import</code>, <code>xsl:include</code>, and
|
||||||
* <code>xsl:import-schema</code> declarations.
|
* <code>xsl:import-schema</code> declarations.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param scenarioRepository an optional repository, your implementation might not need this
|
* @param scenarioRepository an optional repository, your implementation might not need this
|
||||||
* @return a preconfigured {@link URIResolver}
|
* @return a preconfigured {@link URIResolver}
|
||||||
*/
|
*/
|
||||||
URIResolver createResolver(URI scenarioRepository);
|
URIResolver createResolver(URI scenarioRepository);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a specific implementation for resolving objects referenced via XSLT's <code>unparsed-text()</code> function.
|
||||||
|
*
|
||||||
|
* @param scenarioRepository an optional repository, your implementation might not need this
|
||||||
|
* @return a preconfigured {@link net.sf.saxon.lib.UnparsedTextURIResolver} or null for using saxons default
|
||||||
|
*/
|
||||||
|
UnparsedTextURIResolver createUnparsedTextURIResolver(URI scenarioRepository);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a preconfigured {@link Validator } instance for a given schema for xml file validation. The implementation
|
* Creates a preconfigured {@link Validator } instance for a given schema for xml file validation. The implementation
|
||||||
* takes care about security and reference resolving strategies.
|
* takes care about security and reference resolving strategies.
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ import de.kosit.validationtool.model.scenarios.ResourceType;
|
||||||
import de.kosit.validationtool.model.scenarios.ScenarioType;
|
import de.kosit.validationtool.model.scenarios.ScenarioType;
|
||||||
import de.kosit.validationtool.model.scenarios.ValidateWithSchematron;
|
import de.kosit.validationtool.model.scenarios.ValidateWithSchematron;
|
||||||
|
|
||||||
|
import net.sf.saxon.lib.UnparsedTextURIResolver;
|
||||||
import net.sf.saxon.s9api.Processor;
|
import net.sf.saxon.s9api.Processor;
|
||||||
import net.sf.saxon.s9api.SaxonApiException;
|
import net.sf.saxon.s9api.SaxonApiException;
|
||||||
import net.sf.saxon.s9api.XPathCompiler;
|
import net.sf.saxon.s9api.XPathCompiler;
|
||||||
|
|
@ -77,6 +78,8 @@ public class ContentRepository {
|
||||||
|
|
||||||
private final URIResolver resolver;
|
private final URIResolver resolver;
|
||||||
|
|
||||||
|
private final UnparsedTextURIResolver unparsedTextURIResolver;
|
||||||
|
|
||||||
private final SchemaFactory schemaFactory;
|
private final SchemaFactory schemaFactory;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
|
|
@ -94,6 +97,7 @@ public class ContentRepository {
|
||||||
this.resolvingConfigurationStrategy = strategy;
|
this.resolvingConfigurationStrategy = strategy;
|
||||||
this.processor = this.resolvingConfigurationStrategy.getProcessor();
|
this.processor = this.resolvingConfigurationStrategy.getProcessor();
|
||||||
this.resolver = this.resolvingConfigurationStrategy.createResolver(repository);
|
this.resolver = this.resolvingConfigurationStrategy.createResolver(repository);
|
||||||
|
this.unparsedTextURIResolver = this.resolvingConfigurationStrategy.createUnparsedTextURIResolver(repository);
|
||||||
this.schemaFactory = this.resolvingConfigurationStrategy.createSchemaFactory();
|
this.schemaFactory = this.resolvingConfigurationStrategy.createSchemaFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -251,14 +255,18 @@ public class ContentRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Erzeugt einen resolver für dieses Repository, der nur relativ auflösen kann
|
* Returns the {@link URIResolver} to use for resolving xml artifacts.
|
||||||
*
|
*
|
||||||
* @return ein neuer Resolver
|
* @return the resolver
|
||||||
*/
|
*/
|
||||||
public URIResolver getResolver() {
|
public URIResolver getResolver() {
|
||||||
return this.resolver;
|
return this.resolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UnparsedTextURIResolver getUnparsedTextURIResolver() {
|
||||||
|
return this.unparsedTextURIResolver;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gibt eine Transformation zurück.
|
* Gibt eine Transformation zurück.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,8 @@ public class DefaultCheck implements Check {
|
||||||
this.checkSteps.add(new SchemaValidationAction(content.getResolvingConfigurationStrategy(), processor));
|
this.checkSteps.add(new SchemaValidationAction(content.getResolvingConfigurationStrategy(), processor));
|
||||||
this.checkSteps.add(new SchematronValidationAction(content.getResolver(), this.conversionService));
|
this.checkSteps.add(new SchematronValidationAction(content.getResolver(), this.conversionService));
|
||||||
this.checkSteps.add(new ValidateReportInputAction(this.conversionService, content.getReportInputSchema()));
|
this.checkSteps.add(new ValidateReportInputAction(this.conversionService, content.getReportInputSchema()));
|
||||||
this.checkSteps.add(new CreateReportAction(processor, this.conversionService, content.getResolver()));
|
this.checkSteps.add(
|
||||||
|
new CreateReportAction(processor, this.conversionService, content.getResolver(), content.getUnparsedTextURIResolver()));
|
||||||
this.checkSteps.add(new ComputeAcceptanceAction());
|
this.checkSteps.add(new ComputeAcceptanceAction());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ import javax.xml.bind.Marshaller;
|
||||||
import javax.xml.bind.util.JAXBSource;
|
import javax.xml.bind.util.JAXBSource;
|
||||||
import javax.xml.transform.URIResolver;
|
import javax.xml.transform.URIResolver;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.xml.sax.ContentHandler;
|
import org.xml.sax.ContentHandler;
|
||||||
import org.xml.sax.DTDHandler;
|
import org.xml.sax.DTDHandler;
|
||||||
import org.xml.sax.EntityResolver;
|
import org.xml.sax.EntityResolver;
|
||||||
|
|
@ -41,6 +40,7 @@ import org.xml.sax.XMLReader;
|
||||||
import org.xml.sax.helpers.AttributesImpl;
|
import org.xml.sax.helpers.AttributesImpl;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import de.kosit.validationtool.impl.CollectingErrorEventHandler;
|
import de.kosit.validationtool.impl.CollectingErrorEventHandler;
|
||||||
import de.kosit.validationtool.impl.ConversionService;
|
import de.kosit.validationtool.impl.ConversionService;
|
||||||
|
|
@ -48,6 +48,7 @@ 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.lib.UnparsedTextURIResolver;
|
||||||
import net.sf.saxon.s9api.BuildingContentHandler;
|
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;
|
||||||
|
|
@ -175,6 +176,8 @@ public class CreateReportAction implements CheckAction {
|
||||||
|
|
||||||
private final URIResolver resolver;
|
private final URIResolver resolver;
|
||||||
|
|
||||||
|
private final UnparsedTextURIResolver unparsedTextURIResolver;
|
||||||
|
|
||||||
private static XsltExecutable loadFromScenario(final Scenario object) {
|
private static XsltExecutable loadFromScenario(final Scenario object) {
|
||||||
return object.getReportTransformation().getExecutable();
|
return object.getReportTransformation().getExecutable();
|
||||||
}
|
}
|
||||||
|
|
@ -198,7 +201,9 @@ public class CreateReportAction implements CheckAction {
|
||||||
final CollectingErrorEventHandler e = new CollectingErrorEventHandler();
|
final CollectingErrorEventHandler e = new CollectingErrorEventHandler();
|
||||||
transformer.setMessageListener(e);
|
transformer.setMessageListener(e);
|
||||||
transformer.setURIResolver(this.resolver);
|
transformer.setURIResolver(this.resolver);
|
||||||
// transformer.getUnderlyingController().setUnparsedTextURIResolver(resolver);
|
if (this.unparsedTextURIResolver != null) {
|
||||||
|
transformer.getUnderlyingController().setUnparsedTextURIResolver(this.unparsedTextURIResolver);
|
||||||
|
}
|
||||||
if (parsedDocument != null) {
|
if (parsedDocument != null) {
|
||||||
transformer.setParameter(new QName("input-document"), parsedDocument);
|
transformer.setParameter(new QName("input-document"), parsedDocument);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@
|
||||||
package de.kosit.validationtool.impl.xml;
|
package de.kosit.validationtool.impl.xml;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
|
|
@ -32,6 +31,8 @@ import javax.xml.transform.stream.StreamSource;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import net.sf.saxon.Configuration;
|
import net.sf.saxon.Configuration;
|
||||||
|
import net.sf.saxon.lib.StandardUnparsedTextResolver;
|
||||||
|
import net.sf.saxon.lib.UnparsedTextURIResolver;
|
||||||
import net.sf.saxon.trans.XPathException;
|
import net.sf.saxon.trans.XPathException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -41,7 +42,7 @@ import net.sf.saxon.trans.XPathException;
|
||||||
* @author Andreas Penski
|
* @author Andreas Penski
|
||||||
*/
|
*/
|
||||||
@RequiredArgsConstructor()
|
@RequiredArgsConstructor()
|
||||||
public class RelativeUriResolver implements URIResolver {
|
public class RelativeUriResolver implements URIResolver, UnparsedTextURIResolver {
|
||||||
|
|
||||||
/** the base uri */
|
/** the base uri */
|
||||||
private final URI baseUri;
|
private final URI baseUri;
|
||||||
|
|
@ -93,6 +94,16 @@ public class RelativeUriResolver implements URIResolver {
|
||||||
return r.startsWith(base);
|
return r.startsWith(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// from UnparsedTextURIResolver
|
||||||
|
@Override
|
||||||
|
public Reader resolve(final URI absoluteURI, final String encoding, final Configuration config) throws XPathException {
|
||||||
|
if (isUnderBaseUri(absoluteURI, this.baseUri)) {
|
||||||
|
return new StandardUnparsedTextResolver().resolve(absoluteURI, encoding, config);
|
||||||
|
} else {
|
||||||
|
throw new XPathException(String.format("The resolved transformation artifact %s is not within the configured repository %s",
|
||||||
|
absoluteURI, this.baseUri));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -109,6 +109,11 @@ public class StrictRelativeResolvingStrategy extends BaseResolvingStrategy {
|
||||||
return new RelativeUriResolver(repositoryURI);
|
return new RelativeUriResolver(repositoryURI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UnparsedTextURIResolver createUnparsedTextURIResolver(final URI scenarioRepository) {
|
||||||
|
return new RelativeUriResolver(scenarioRepository);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Validator createValidator(final Schema schema) {
|
public Validator createValidator(final Schema schema) {
|
||||||
if (schema == null) {
|
if (schema == null) {
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,8 @@ import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import javax.xml.transform.Source;
|
import javax.xml.transform.Source;
|
||||||
|
|
||||||
import org.hamcrest.Matchers;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
|
||||||
|
|
||||||
import de.kosit.validationtool.api.InputFactory;
|
import de.kosit.validationtool.api.InputFactory;
|
||||||
import de.kosit.validationtool.impl.ContentRepository;
|
import de.kosit.validationtool.impl.ContentRepository;
|
||||||
|
|
@ -42,7 +39,8 @@ public class CreateReportActionTest {
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
this.repository = Simple.createContentRepository();
|
this.repository = Simple.createContentRepository();
|
||||||
this.action = new CreateReportAction(this.repository.getProcessor(), new ConversionService(), this.repository.getResolver());
|
this.action = new CreateReportAction(this.repository.getProcessor(), new ConversionService(), this.repository.getResolver(),
|
||||||
|
this.repository.getUnparsedTextURIResolver());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -72,7 +70,7 @@ public class CreateReportActionTest {
|
||||||
public void testExecutionException() throws SaxonApiException {
|
public void testExecutionException() throws SaxonApiException {
|
||||||
final Processor p = mock(Processor.class);
|
final Processor p = mock(Processor.class);
|
||||||
final DocumentBuilder documentBuilder = mock(DocumentBuilder.class);
|
final DocumentBuilder documentBuilder = mock(DocumentBuilder.class);
|
||||||
this.action = new CreateReportAction(p, new ConversionService(), null);
|
this.action = new CreateReportAction(p, new ConversionService(), null, null);
|
||||||
|
|
||||||
when(p.newDocumentBuilder()).thenReturn(documentBuilder);
|
when(p.newDocumentBuilder()).thenReturn(documentBuilder);
|
||||||
when(documentBuilder.build(any(Source.class))).thenThrow(new SaxonApiException("mocked"));
|
when(documentBuilder.build(any(Source.class))).thenThrow(new SaxonApiException("mocked"));
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,9 @@
|
||||||
<result>
|
<result>
|
||||||
<xsl:copy-of select="." />
|
<xsl:copy-of select="." />
|
||||||
</result>
|
</result>
|
||||||
|
<text>
|
||||||
|
<xsl:value-of select="unparsed-text('some.txt','UTF-8')" />
|
||||||
|
</text>
|
||||||
</report>
|
</report>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
|
|
|
||||||
1
src/test/resources/examples/simple/repository/some.txt
Normal file
1
src/test/resources/examples/simple/repository/some.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
This content should be transferred to the result document
|
||||||
Loading…
Add table
Add a link
Reference in a new issue