#39 Lazily read inputstream

use URI loading where applicable
This commit is contained in:
Andreas Penski (init) 2019-12-18 16:38:08 +01:00
parent 0c26fa7420
commit 7ec7414875
2 changed files with 36 additions and 56 deletions

View file

@ -21,8 +21,6 @@ package de.kosit.validationtool.api;
import static org.apache.commons.lang3.StringUtils.isNotEmpty; import static org.apache.commons.lang3.StringUtils.isNotEmpty;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -30,13 +28,8 @@ import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.xml.bind.DatatypeConverter;
import javax.xml.transform.Source; import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource; import javax.xml.transform.stream.StreamSource;
@ -101,11 +94,7 @@ public class InputFactory {
*/ */
public static Input read(final Path path, final String digestAlgorithm) { public static Input read(final Path path, final String digestAlgorithm) {
checkNull(path); checkNull(path);
try ( final InputStream stream = Files.newInputStream(path) ) { return read(path.toUri(), digestAlgorithm);
return read(stream, path.toString(), digestAlgorithm);
} catch (final IOException e) {
throw new IllegalArgumentException(MESSAGE_OPEN_STREAM_ERROR + path, e);
}
} }
/** /**
@ -119,6 +108,34 @@ public class InputFactory {
return read(file, DEFAULT_ALGORITH); return read(file, DEFAULT_ALGORITH);
} }
/**
* Liest einen Prüfling von der übergebenen URI. Es wird der Default-Prüfsummenalgorithmus zur Ermittlung der Prüfsumme
* genutzt.
*
* @param uri URI des Prüflings
* @return ein Prüf-Eingabe-Objekt
*/
public static Input read(final URI uri) {
return read(uri, DEFAULT_ALGORITH);
}
/**
* Liest einen Prüfling von der übergebenen URL. Es wird ein definierter Algorithmis zur Ermittlung der Prüfsumme
* genutzt.
*
* @param uri URI des Prüflings
* @param digestAlgorithm der Prüfsummenalgorithmus
* @return ein Prüf-Eingabe-Objekt
*/
public static Input read(final URI uri, final String digestAlgorithm) {
try {
return read(uri.toURL(), digestAlgorithm);
} catch (final MalformedURLException e) {
throw new IllegalArgumentException(String.format("Can not read from uri %s Not a valid uri supplied", uri));
}
}
/** /**
* Liest einen Prüfling von der übergebenen URL. Es wird der Default-Prüfsummenalgorithmus zur Ermittlung der Prüfsumme * Liest einen Prüfling von der übergebenen URL. Es wird der Default-Prüfsummenalgorithmus zur Ermittlung der Prüfsumme
* genutzt. * genutzt.
@ -130,14 +147,6 @@ public class InputFactory {
return read(url, DEFAULT_ALGORITH); return read(url, DEFAULT_ALGORITH);
} }
public static Input read(final URI uri) {
try {
return read(uri.toURL(), DEFAULT_ALGORITH);
} catch (final MalformedURLException e) {
throw new IllegalArgumentException(String.format("Can not read from uri %s Not a valid uri supplied", uri));
}
}
/** /**
* Liest einen Prüfling von der übergebenen URL. Es wird ein definierter Algorithmis zur Ermittlung der Prüfsumme * Liest einen Prüfling von der übergebenen URL. Es wird ein definierter Algorithmis zur Ermittlung der Prüfsumme
* genutzt. * genutzt.
@ -152,7 +161,7 @@ public class InputFactory {
try { try {
final URLConnection urlConnection = url.openConnection(); final URLConnection urlConnection = url.openConnection();
urlConnection.connect(); urlConnection.connect();
} catch (IOException e) { } catch (final IOException e) {
throw new IllegalArgumentException(MESSAGE_OPEN_STREAM_ERROR + url, e); throw new IllegalArgumentException(MESSAGE_OPEN_STREAM_ERROR + url, e);
} }
return new ResourceInput(url, url.getFile(), digestAlgorithm); return new ResourceInput(url, url.getFile(), digestAlgorithm);
@ -268,36 +277,8 @@ public class InputFactory {
* @return einen Prüfling in eingelesener Form * @return einen Prüfling in eingelesener Form
*/ */
public static Input read(final InputStream inputStream, final String name, final String digestAlgorithm) { public static Input read(final InputStream inputStream, final String name, final String digestAlgorithm) {
return new InputFactory(digestAlgorithm).readStream(inputStream, name); checkNull(inputStream);
} return read(new StreamSource(inputStream, name), digestAlgorithm);
private Input readStream(final InputStream inputStream, final String name) {
if (StringUtils.isNotBlank(name)) {
log.debug("Generating hashcode for {} using {} algorithm", name, getAlgorithm());
final MessageDigest digest = StreamHelper.createDigest(getAlgorithm());
final byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
try ( final BufferedInputStream bis = new BufferedInputStream(inputStream);
final DigestInputStream dis = new DigestInputStream(bis, digest);
final ByteArrayOutputStream out = new ByteArrayOutputStream() ) {
// read the file and update the hash calculation
int n;
while (EOF != (n = dis.read(buffer))) {
out.write(buffer, 0, n);
}
// get the hash value as byte array
final byte[] hash = digest.digest();
log.debug("Generated hashcode for {} is {}", name, DatatypeConverter.printHexBinary(hash));
out.flush();
final ByteArrayInput input = new ByteArrayInput(out.toByteArray(), name, digest.getAlgorithm());
input.setHashCode(hash);
return input;
} catch (final IOException e) {
throw new IllegalArgumentException(MESSAGE_OPEN_STREAM_ERROR + name, e);
}
} else {
throw new IllegalArgumentException("Must supply a valid name/identifier for the input");
}
} }
} }

View file

@ -30,7 +30,7 @@ import de.kosit.validationtool.api.CheckConfiguration;
import de.kosit.validationtool.api.InputFactory; import de.kosit.validationtool.api.InputFactory;
import de.kosit.validationtool.impl.DefaultCheck; import de.kosit.validationtool.impl.DefaultCheck;
import de.kosit.validationtool.impl.ObjectFactory; import de.kosit.validationtool.impl.ObjectFactory;
import de.kosit.validationtool.impl.input.ByteArrayInput; import de.kosit.validationtool.impl.input.SourceInput;
import de.kosit.validationtool.model.scenarios.Scenarios; import de.kosit.validationtool.model.scenarios.Scenarios;
/** /**
@ -72,10 +72,9 @@ class Daemon {
final String requestMethod = httpExchange.getRequestMethod(); final String requestMethod = httpExchange.getRequestMethod();
if (requestMethod.equals("POST")) { if (requestMethod.equals("POST")) {
final InputStream inputStream = httpExchange.getRequestBody(); final InputStream inputStream = httpExchange.getRequestBody();
final ByteArrayInput serverInput = (ByteArrayInput) InputFactory.read(inputStream, final SourceInput serverInput = (SourceInput) InputFactory.read(inputStream, "Prüfling" + counter.incrementAndGet());
"Prüfling" + counter.incrementAndGet());
if (serverInput.getLength() > 0) { if (inputStream.available() > 0) {
writeOutputstreamArray(httpExchange, this.implemenation.check(serverInput)); writeOutputstreamArray(httpExchange, this.implemenation.check(serverInput));
} else { } else {
writeError(httpExchange, 400, "XML-Inhalt erforderlich!"); writeError(httpExchange, 400, "XML-Inhalt erforderlich!");