Merge remote-tracking branch 'origin/configuration_api' into configuration_api

This commit is contained in:
Andreas Penski 2020-05-11 09:07:55 +02:00
commit fdd2a5be18
4 changed files with 72 additions and 23 deletions

View file

@ -4,7 +4,7 @@ The Validator offers an API which allows you to integrate Validator in your own
## Dependency Management ## Dependency Management
Currently, we *do not* deploy to Maven Central or similar. Hence you need to build and optionally deploy the Validator artifacts to your own Currently, we *do not* deploy to Maven Central or similar. Hence, you need to build and optionally deploy the Validator artifacts to your own
shared (or local) repository (see for example [Maven Documentation](https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html)). shared (or local) repository (see for example [Maven Documentation](https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html)).
### Maven ### Maven

View file

@ -164,7 +164,9 @@ public class InputFactory {
} }
/** /**
* Reads a test document from a {@link Source}. * Reads a test document from a {@link Source}. <br/>
* Note: computing the hashcode is only supported for {@link StreamSource}. You can not directly use other {@link Source
* Soures}. You need to supply the hashcode for identification then.
* *
* @param source source * @param source source
* @return an {@link Input} * @return an {@link Input}
@ -176,6 +178,9 @@ public class InputFactory {
/** /**
* Reads a test document from a {@link Source} using a specified digest algorithm. * Reads a test document from a {@link Source} using a specified digest algorithm.
* *
* Note: computing the hashcode is only supported for {@link StreamSource}. You can not directly use other {@link Source
* Soures}. You need to supply the hashcode for identification then.
*
* @param source source * @param source source
* @param digestAlgorithm the digest algorithm * @param digestAlgorithm the digest algorithm
* @return an {@link Input} * @return an {@link Input}

View file

@ -7,13 +7,25 @@ import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource; import javax.xml.transform.stream.StreamSource;
import org.apache.commons.io.input.ReaderInputStream; import org.apache.commons.io.input.ReaderInputStream;
import org.apache.commons.lang3.NotImplementedException;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
/** /**
* A validator {@link de.kosit.validationtool.api.Input} based an on a {@link Source}. * A validator {@link de.kosit.validationtool.api.Input} based on a {@link Source}. <br/>
* <p>
* Note: The various implementations of {@link Source} varies wether the can be read twice or no. This implementation
* tries to handle this with respect document identification (hashcode).
*
* This class is know to work with:
* <ul>
* <li>{@link StreamSource} - both {@link java.io.InputStream} based and {@link java.io.Reader} based</li>
* <li>{@link javax.xml.transform.dom.DOMSource}</li>
* <li>{@link javax.xml.bind.util.JAXBSource}</li>
* </ul>
*
* Other {@link Source Sources} may work as well, please try and let us know.
* </p>
* *
* @author Andreas Penski * @author Andreas Penski
*/ */
@ -40,26 +52,23 @@ public class SourceInput extends AbstractInput {
} }
private void validate() { private void validate() {
if (!isSupported()) { if (!isHashcodeComputed() && !isSupported()) {
throw new IllegalStateException("Unsupported source. Only StreamSource supported yet"); throw new IllegalStateException("Unsupported source. Only StreamSource supported yet");
} }
if (((StreamSource) this.source).getInputStream() == null && !isHashcodeComputed()) { if (!isHashcodeComputed() && ((StreamSource) this.source).getInputStream() == null) {
log.warn("No hashcode supplied, will wrap the reader using system default charset"); log.warn("No hashcode supplied, will wrap the reader using system default charset");
} }
} }
@Override @Override
public Source getSource() throws IOException { public Source getSource() throws IOException {
if (!isSupported()) { if (!isHashcodeComputed() && !isSupported()) {
throw new IllegalStateException("Unsupported source. Only InputStream-based StreamSource supported yet"); throw new IllegalStateException("Unsupported source. Only InputStream-based StreamSource supported yet");
} }
if (isWrappingRequired()) {
return wrap();
}
if (isConsumed()) { if (isConsumed()) {
throw new IllegalStateException("A SourceInput can only read once"); throw new IllegalStateException("A SourceInput can only read once");
} }
return this.source; return isHashcodeComputed() ? this.source : wrappedSource();
} }
private boolean isSupported() { private boolean isSupported() {
@ -67,9 +76,8 @@ public class SourceInput extends AbstractInput {
} }
private boolean isConsumed() throws IOException { private boolean isConsumed() throws IOException {
if (!isStreamSource()) { if (isStreamSource()) {
throw new NotImplementedException("Supports only StreamSource yet");
}
final StreamSource ss = (StreamSource) this.source; final StreamSource ss = (StreamSource) this.source;
try { try {
return (ss.getInputStream() != null && ss.getInputStream().available() == 0) return (ss.getInputStream() != null && ss.getInputStream().available() == 0)
@ -79,12 +87,14 @@ public class SourceInput extends AbstractInput {
return true; return true;
} }
} }
return false;
}
private boolean isStreamSource() { private boolean isStreamSource() {
return this.source instanceof StreamSource; return this.source instanceof StreamSource;
} }
private Source wrap() { private Source wrappedSource() {
Source result = this.source; Source result = this.source;
if (isStreamSource()) { if (isStreamSource()) {
final StreamSource ss = (StreamSource) this.source; final StreamSource ss = (StreamSource) this.source;

View file

@ -31,14 +31,29 @@ import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.nio.file.Paths; import java.nio.file.Paths;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource; import javax.xml.transform.stream.StreamSource;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import de.kosit.validationtool.impl.Helper;
import de.kosit.validationtool.impl.Helper.Simple; import de.kosit.validationtool.impl.Helper.Simple;
import de.kosit.validationtool.impl.TestObjectFactory;
import de.kosit.validationtool.impl.input.SourceInput; import de.kosit.validationtool.impl.input.SourceInput;
import de.kosit.validationtool.impl.model.Result;
import de.kosit.validationtool.model.reportInput.XMLSyntaxError;
import net.sf.saxon.dom.NodeOverNodeInfo;
import net.sf.saxon.s9api.BuildingContentHandler;
import net.sf.saxon.s9api.DocumentBuilder;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.XdmNode;
/** /**
* Testet den Hashcode-Service. * Testet den Hashcode-Service.
@ -163,4 +178,23 @@ public class InputFactoryTest {
InputFactory.read(Simple.NOT_EXISTING); InputFactory.read(Simple.NOT_EXISTING);
} }
@Test
public void testDomSource() throws SaxonApiException, SAXException, IOException {
final DocumentBuilder builder = TestObjectFactory.createProcessor().newDocumentBuilder();
final BuildingContentHandler handler = builder.newBuildingContentHandler();
handler.startDocument();
handler.startElement("http://some.ns", "mynode", "mynode", new AttributesImpl());
final Document dom = NodeOverNodeInfo.wrap(handler.getDocumentNode().getUnderlyingNode()).getOwnerDocument();
final Input domInput = InputFactory.read(new DOMSource(dom), "MD5", "id".getBytes());
assertThat(domInput).isNotNull();
final Source source = domInput.getSource();
assertThat(source).isNotNull();
final Result<XdmNode, XMLSyntaxError> parsed = Helper.parseDocument(domInput);
assertThat(parsed.isValid()).isTrue();
// read twice
assertThat(Helper.parseDocument(domInput).getObject()).isNotNull();
}
} }