aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/zwobble/mammoth/docx
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2016-02-21 09:44:16 +0000
committerMichael Williamson <mike@zwobble.org>2016-02-21 09:44:16 +0000
commitc1604e510cc831a00f6105df35c68a856f061b65 (patch)
tree699e55b0d654ec464fe25c0b21964de3d9bbc780 /src/main/java/org/zwobble/mammoth/docx
parent9d5da9d5339055198aac8d0d41c3d33d97344ebd (diff)
Allow input streams to be read
Diffstat (limited to 'src/main/java/org/zwobble/mammoth/docx')
-rw-r--r--src/main/java/org/zwobble/mammoth/docx/DocumentReader.java25
-rw-r--r--src/main/java/org/zwobble/mammoth/docx/InMemoryDocxFile.java46
2 files changed, 70 insertions, 1 deletions
diff --git a/src/main/java/org/zwobble/mammoth/docx/DocumentReader.java b/src/main/java/org/zwobble/mammoth/docx/DocumentReader.java
index 284dd89..1fc0fc8 100644
--- a/src/main/java/org/zwobble/mammoth/docx/DocumentReader.java
+++ b/src/main/java/org/zwobble/mammoth/docx/DocumentReader.java
@@ -7,6 +7,9 @@ import org.zwobble.mammoth.util.MammothLists;
import org.zwobble.mammoth.xml.XmlElement;
import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.nio.file.Path;
import java.util.Optional;
@@ -24,7 +27,14 @@ public class DocumentReader {
ContentTypes contentTypes = readContentTypes(zipFile);
FileReader fileReader = uri -> {
try {
- return path.get().toUri().resolve(uri).toURL().openStream();
+ Optional<URI> absoluteUri = asAbsoluteUri(uri);
+ if (absoluteUri.isPresent()) {
+ return open(absoluteUri.get());
+ } else if (path.isPresent()) {
+ return open(path.get().toUri().resolve(uri));
+ } else {
+ throw new IOException("path of document is unknown, but is required for relative URI");
+ }
} catch (IOException exception) {
throw new IOException("could not open external image '" + uri + "': " + exception.getMessage());
}
@@ -40,6 +50,19 @@ public class DocumentReader {
});
}
+ private static InputStream open(URI uri) throws IOException {
+ return uri.toURL().openStream();
+ }
+
+ private static Optional<URI> asAbsoluteUri(String uriString) {
+ try {
+ URI uri = new URI(uriString);
+ return uri.isAbsolute() ? Optional.of(uri) : Optional.empty();
+ } catch (URISyntaxException exception) {
+ return Optional.empty();
+ }
+ }
+
private static Result<Notes> readNotes(DocxFile file, BodyReaders bodyReaders) {
return Result.map(
tryParseOfficeXml(file, "word/footnotes.xml")
diff --git a/src/main/java/org/zwobble/mammoth/docx/InMemoryDocxFile.java b/src/main/java/org/zwobble/mammoth/docx/InMemoryDocxFile.java
new file mode 100644
index 0000000..3c6d4b4
--- /dev/null
+++ b/src/main/java/org/zwobble/mammoth/docx/InMemoryDocxFile.java
@@ -0,0 +1,46 @@
+package org.zwobble.mammoth.docx;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.common.io.ByteStreams;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Optional;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+public class InMemoryDocxFile implements DocxFile {
+ public static DocxFile fromStream(InputStream stream) throws IOException {
+ ZipInputStream zipStream = new ZipInputStream(stream);
+ ImmutableMap.Builder<String, byte[]> entries = ImmutableMap.builder();
+ ZipEntry entry;
+ while ((entry = zipStream.getNextEntry()) != null) {
+ entries.put(entry.getName(), ByteStreams.toByteArray(zipStream));
+ }
+ return new InMemoryDocxFile(entries.build());
+ }
+
+ public static DocxFile fromStrings(Map<String, String> entries) {
+ return new InMemoryDocxFile(Maps.transformValues(entries, value -> value.getBytes(StandardCharsets.UTF_8)));
+ }
+
+ private final Map<String, byte[]> entries;
+
+ public InMemoryDocxFile(Map<String, byte[]> entries) {
+ this.entries = entries;
+ }
+
+ @Override
+ public Optional<InputStream> tryGetInputStream(String name) throws IOException {
+ return Optional.ofNullable(entries.get(name))
+ .map(ByteArrayInputStream::new);
+ }
+
+ @Override
+ public void close() throws IOException {
+ }
+}