diff options
| author | Michael Williamson <mike@zwobble.org> | 2016-02-13 18:18:33 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2016-02-13 18:18:33 +0000 |
| commit | a431972f98d98114dc9a5a65a3fbaf68967a8161 (patch) | |
| tree | 5a4e6f29a884ca1091b5a8f4d5c5a4f1558b2233 /src | |
| parent | cfff129846046a2549f8c78f6de458b9f4183f43 (diff) | |
Add result objects
Diffstat (limited to 'src')
10 files changed, 157 insertions, 61 deletions
diff --git a/src/main/java/org/zwobble/mammoth/Mammoth.java b/src/main/java/org/zwobble/mammoth/Mammoth.java index 05080cf..7282082 100644 --- a/src/main/java/org/zwobble/mammoth/Mammoth.java +++ b/src/main/java/org/zwobble/mammoth/Mammoth.java @@ -13,15 +13,16 @@ import java.util.zip.ZipFile; import static com.google.common.collect.Iterables.transform; public class Mammoth { - public static String convertToHtml(File file) { + public static Result<String> convertToHtml(File file) { try (ZipFile zipFile = new ZipFile(file)) { ZipEntry entry = zipFile.getEntry("word/document.xml"); XmlElement documentXml = OfficeXml.parseXml(zipFile.getInputStream(entry)); Styles styles = Styles.EMPTY; Numbering numbering = Numbering.EMPTY; - Document document = new DocumentXmlReader(new BodyXmlReader(styles, numbering)).readElement(documentXml); - return convertToHtml(document); + DocumentXmlReader reader = new DocumentXmlReader(new BodyXmlReader(styles, numbering)); + return reader.readElement(documentXml) + .map(Mammoth::convertToHtml); } catch (IOException e) { throw new UnsupportedOperationException("Should return a result of failure"); } diff --git a/src/main/java/org/zwobble/mammoth/Result.java b/src/main/java/org/zwobble/mammoth/Result.java new file mode 100644 index 0000000..0665364 --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/Result.java @@ -0,0 +1,34 @@ +package org.zwobble.mammoth; + +import com.google.common.collect.ImmutableList; + +import java.util.List; +import java.util.function.Function; + +public class Result<T> { + public static <T> Result<List<T>> concat(Iterable<Result<T>> results) { + ImmutableList.Builder<T> elements = ImmutableList.builder(); + for (Result<T> result : results) { + elements.add(result.value); + } + return new Result<>(elements.build()); + } + + public static <T> Result<T> success(T value) { + return new Result<>(value); + } + + private final T value; + + public Result(T value) { + this.value = value; + } + + public T getValue() { + return value; + } + + public <R> Result<R> map(Function<T, R> function) { + return new Result<>(function.apply(value)); + } +} diff --git a/src/main/java/org/zwobble/mammoth/docx/BodyXmlReader.java b/src/main/java/org/zwobble/mammoth/docx/BodyXmlReader.java index 334f925..26958dd 100644 --- a/src/main/java/org/zwobble/mammoth/docx/BodyXmlReader.java +++ b/src/main/java/org/zwobble/mammoth/docx/BodyXmlReader.java @@ -1,17 +1,17 @@ package org.zwobble.mammoth.docx; -import com.google.common.collect.ImmutableList; import org.zwobble.mammoth.documents.*; import org.zwobble.mammoth.util.MammothOptionals; import org.zwobble.mammoth.xml.XmlElement; import org.zwobble.mammoth.xml.XmlElementLike; import org.zwobble.mammoth.xml.XmlNode; -import java.util.List; import java.util.Optional; -import static com.google.common.collect.Iterables.*; -import static org.zwobble.mammoth.util.MammothLists.list; +import static com.google.common.collect.Iterables.filter; +import static com.google.common.collect.Iterables.transform; +import static org.zwobble.mammoth.docx.ReadResult.EMPTY_SUCCESS; +import static org.zwobble.mammoth.docx.ReadResult.success; public class BodyXmlReader { private final Styles styles; @@ -22,38 +22,37 @@ public class BodyXmlReader { this.numbering = numbering; } - public List<DocumentElement> readElement(XmlElement element) { + public ReadResult readElement(XmlElement element) { switch (element.getName()) { case "w:t": - return list(new Text(element.innerText())); + return success(new Text(element.innerText())); case "w:r": - return list(new Run(readElements(element.children()))); + return readElements(element.children()).map(Run::new); case "w:p": - return list(readParagraph(element)); + return readParagraph(element); case "w:pPr": - return list(); + return EMPTY_SUCCESS; default: // TODO: emit warning - return list(); + return EMPTY_SUCCESS; } } - public List<DocumentElement> readElements(Iterable<XmlNode> nodes) { - return ImmutableList.copyOf( - concat( - transform( - filter(nodes, XmlElement.class), - this::readElement))); + public ReadResult readElements(Iterable<XmlNode> nodes) { + return ReadResult.concat( + transform( + filter(nodes, XmlElement.class), + this::readElement)); } - private Paragraph readParagraph(XmlElement element) { + private ReadResult readParagraph(XmlElement element) { XmlElementLike properties = element.findChildOrEmpty("w:pPr"); - return new Paragraph( - readParagraphStyle(properties), - readNumbering(properties), - readElements(element.children())); + Optional<Style> paragraphStyle = readParagraphStyle(properties); + Optional<NumberingLevel> numbering = readNumbering(properties); + return readElements(element.children()) + .map(children -> new Paragraph(paragraphStyle, numbering, children)); } private Optional<Style> readParagraphStyle(XmlElementLike properties) { diff --git a/src/main/java/org/zwobble/mammoth/docx/DocumentXmlReader.java b/src/main/java/org/zwobble/mammoth/docx/DocumentXmlReader.java index 0b51774..98570f2 100644 --- a/src/main/java/org/zwobble/mammoth/docx/DocumentXmlReader.java +++ b/src/main/java/org/zwobble/mammoth/docx/DocumentXmlReader.java @@ -1,5 +1,6 @@ package org.zwobble.mammoth.docx; +import org.zwobble.mammoth.Result; import org.zwobble.mammoth.documents.Document; import org.zwobble.mammoth.xml.XmlElement; @@ -10,8 +11,10 @@ public class DocumentXmlReader { this.bodyReader = bodyReader; } - public Document readElement(XmlElement element) { + public Result<Document> readElement(XmlElement element) { XmlElement body = element.findChild("w:body"); - return new Document(bodyReader.readElements(body.children())); + return bodyReader.readElements(body.children()) + .toResult() + .map(Document::new); } } diff --git a/src/main/java/org/zwobble/mammoth/docx/NotesXmlReader.java b/src/main/java/org/zwobble/mammoth/docx/NotesXmlReader.java index 06d17ca..7cd0419 100644 --- a/src/main/java/org/zwobble/mammoth/docx/NotesXmlReader.java +++ b/src/main/java/org/zwobble/mammoth/docx/NotesXmlReader.java @@ -1,6 +1,6 @@ package org.zwobble.mammoth.docx; -import com.google.common.collect.ImmutableList; +import org.zwobble.mammoth.Result; import org.zwobble.mammoth.documents.Note; import org.zwobble.mammoth.xml.XmlElement; @@ -18,9 +18,9 @@ public class NotesXmlReader { this.noteType = noteType; } - public List<Note> readElement(XmlElement element) { + public Result<List<Note>> readElement(XmlElement element) { Iterable<XmlElement> elements = filter(element.findChildren("w:" + noteType), this::isNoteElement); - return ImmutableList.copyOf(transform(elements, this::readNoteElement)); + return Result.concat(transform(elements, this::readNoteElement)); } private boolean isNoteElement(XmlElement element) { @@ -33,9 +33,11 @@ public class NotesXmlReader { return type.equals("continuationSeparator") || type.equals("separator"); } - private Note readNoteElement(XmlElement element) { - return new Note( - element.getAttribute("w:id"), - bodyReader.readElements(element.children())); + private Result<Note> readNoteElement(XmlElement element) { + return bodyReader.readElements(element.children()) + .toResult() + .map(children -> new Note( + element.getAttribute("w:id"), + children)); } } diff --git a/src/main/java/org/zwobble/mammoth/docx/ReadResult.java b/src/main/java/org/zwobble/mammoth/docx/ReadResult.java new file mode 100644 index 0000000..f3eb7ce --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/docx/ReadResult.java @@ -0,0 +1,44 @@ +package org.zwobble.mammoth.docx; + +import com.google.common.collect.ImmutableList; +import org.zwobble.mammoth.Result; +import org.zwobble.mammoth.documents.DocumentElement; + +import java.util.List; +import java.util.function.Function; + +import static org.zwobble.mammoth.util.MammothLists.list; + +public class ReadResult { + public static final ReadResult EMPTY_SUCCESS = success(list()); + + public static ReadResult concat(Iterable<ReadResult> results) { + ImmutableList.Builder<DocumentElement> elements = ImmutableList.builder(); + for (ReadResult result : results) { + elements.addAll(result.elements); + } + return new ReadResult(elements.build()); + } + + public static ReadResult success(DocumentElement element) { + return success(list(element)); + } + + public static ReadResult success(List<DocumentElement> elements) { + return new ReadResult(elements); + } + + private final List<DocumentElement> elements; + + public ReadResult(List<DocumentElement> elements) { + this.elements = elements; + } + + public ReadResult map(Function<List<DocumentElement>, DocumentElement> function) { + return new ReadResult(list(function.apply(elements))); + } + + public Result<List<DocumentElement>> toResult() { + return new Result<>(elements); + } +} diff --git a/src/test/java/org/zwobble/mammoth/tests/MammothTests.java b/src/test/java/org/zwobble/mammoth/tests/MammothTests.java index 3bbc3e9..7966cee 100644 --- a/src/test/java/org/zwobble/mammoth/tests/MammothTests.java +++ b/src/test/java/org/zwobble/mammoth/tests/MammothTests.java @@ -1,27 +1,31 @@ package org.zwobble.mammoth.tests; -import java.io.File; - import org.junit.Test; import org.zwobble.mammoth.Mammoth; +import org.zwobble.mammoth.Result; + +import java.io.File; -import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertThat; +import static org.zwobble.mammoth.Result.success; +import static org.zwobble.mammoth.tests.DeepReflectionMatcher.deepEquals; public class MammothTests { @Test public void emptyParagraphsAreIgnoredByDefault() { - assertThat(convertToHtml("empty.docx"), is("")); + assertThat( + convertToHtml("empty.docx"), + deepEquals(success(""))); } @Test public void docxContainingOneParagraphIsConvertedToSingleParagraphElement() { assertThat( convertToHtml("single-paragraph.docx"), - is("<p>Walking on imported air</p>")); + deepEquals(success("<p>Walking on imported air</p>"))); } - private String convertToHtml(String name) { + private Result<String> convertToHtml(String name) { File file = TestData.file(name); return Mammoth.convertToHtml(file); } diff --git a/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlTests.java b/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlTests.java index 1faaf98..3506e57 100644 --- a/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlTests.java +++ b/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlTests.java @@ -3,6 +3,7 @@ package org.zwobble.mammoth.tests.docx; import com.natpryce.makeiteasy.Maker; import org.hamcrest.Matcher; import org.junit.Test; +import org.zwobble.mammoth.Result; import org.zwobble.mammoth.documents.*; import org.zwobble.mammoth.docx.BodyXmlReader; import org.zwobble.mammoth.docx.Numbering; @@ -22,9 +23,7 @@ import static org.hamcrest.Matchers.hasProperty; import static org.zwobble.mammoth.tests.DeepReflectionMatcher.deepEquals; import static org.zwobble.mammoth.tests.documents.DocumentElementMakers.CHILDREN; import static org.zwobble.mammoth.tests.documents.DocumentElementMakers.PARAGRAPH; -import static org.zwobble.mammoth.tests.docx.BodyXmlReaderMakers.NUMBERING; -import static org.zwobble.mammoth.tests.docx.BodyXmlReaderMakers.STYLES; -import static org.zwobble.mammoth.tests.docx.BodyXmlReaderMakers.bodyReader; +import static org.zwobble.mammoth.tests.docx.BodyXmlReaderMakers.*; import static org.zwobble.mammoth.util.MammothLists.list; import static org.zwobble.mammoth.util.MammothMaps.map; import static org.zwobble.mammoth.xml.XmlNodes.element; @@ -34,14 +33,14 @@ public class BodyXmlTests { @Test public void textFromTextElementIsRead() { XmlElement element = textXml("Hello!"); - assertThat(read(a(bodyReader), element), isTextElement("Hello!")); + assertThat(readSuccess(a(bodyReader), element), isTextElement("Hello!")); } @Test public void canReadTextWithinRun() { XmlElement element = runXml(list(textXml("Hello!"))); assertThat( - read(a(bodyReader), element), + readSuccess(a(bodyReader), element), isRun(run(text("Hello!")))); } @@ -49,7 +48,7 @@ public class BodyXmlTests { public void canReadTextWithinParagraph() { XmlElement element = paragraphXml(list(runXml(list(textXml("Hello!"))))); assertThat( - read(a(bodyReader), element), + readSuccess(a(bodyReader), element), isParagraph(make(a(PARAGRAPH, with(CHILDREN, list(run(text("Hello!")))))))); } @@ -57,7 +56,7 @@ public class BodyXmlTests { public void paragraphHasNoStyleIfItHasNoProperties() { XmlElement element = paragraphXml(); assertThat( - read(a(bodyReader), element), + readSuccess(a(bodyReader), element), hasStyle(Optional.empty())); } @@ -72,7 +71,7 @@ public class BodyXmlTests { map("Heading1", style), map()); assertThat( - read(a(bodyReader, with(STYLES, styles)), element), + readSuccess(a(bodyReader, with(STYLES, styles)), element), hasStyle(Optional.of(style))); } @@ -83,7 +82,7 @@ public class BodyXmlTests { element("w:pPr", list( element("w:pStyle", map("w:val", "Heading1")))))); assertThat( - read(a(bodyReader), element), + readSuccess(a(bodyReader), element), hasStyle(Optional.of(new Style("Heading1", Optional.empty())))); } @@ -91,7 +90,7 @@ public class BodyXmlTests { public void paragraphHasNoNumberingIfItHasNoNumberingProperties() { XmlElement element = paragraphXml(); assertThat( - read(a(bodyReader), element), + readSuccess(a(bodyReader), element), hasNumbering(Optional.empty())); } @@ -106,7 +105,7 @@ public class BodyXmlTests { Numbering numbering = new Numbering(map("42", map("1", NumberingLevel.ordered("1")))); assertThat( - read(a(bodyReader, with(NUMBERING, numbering)), element), + readSuccess(a(bodyReader, with(NUMBERING, numbering)), element), hasNumbering(NumberingLevel.ordered("1"))); } @@ -121,7 +120,7 @@ public class BodyXmlTests { Numbering numbering = new Numbering(map("42", map("1", NumberingLevel.ordered("1")))); assertThat( - read(a(bodyReader, with(NUMBERING, numbering)), element), + readSuccess(a(bodyReader, with(NUMBERING, numbering)), element), hasNumbering(Optional.empty())); } @@ -136,12 +135,18 @@ public class BodyXmlTests { Numbering numbering = new Numbering(map("42", map("1", NumberingLevel.ordered("1")))); assertThat( - read(a(bodyReader, with(NUMBERING, numbering)), element), + readSuccess(a(bodyReader, with(NUMBERING, numbering)), element), hasNumbering(Optional.empty())); } - private static DocumentElement read(Maker<BodyXmlReader> reader, XmlElement element) { - return reader.make().readElement(element).get(0); + private static DocumentElement readSuccess(Maker<BodyXmlReader> reader, XmlElement element) { + // TODO: assert no warnings when they get added + return read(reader, element).getValue(); + } + + private static Result<DocumentElement> read(Maker<BodyXmlReader> reader, XmlElement element) { + return reader.make().readElement(element).toResult() + .map(elements -> elements.get(0)); } private XmlElement paragraphXml() { diff --git a/src/test/java/org/zwobble/mammoth/tests/docx/DocumentXmlTests.java b/src/test/java/org/zwobble/mammoth/tests/docx/DocumentXmlTests.java index 0f547a8..c98061e 100644 --- a/src/test/java/org/zwobble/mammoth/tests/docx/DocumentXmlTests.java +++ b/src/test/java/org/zwobble/mammoth/tests/docx/DocumentXmlTests.java @@ -1,6 +1,7 @@ package org.zwobble.mammoth.tests.docx; import org.junit.Test; +import org.zwobble.mammoth.Result; import org.zwobble.mammoth.documents.Document; import org.zwobble.mammoth.documents.Run; import org.zwobble.mammoth.documents.Text; @@ -11,6 +12,7 @@ import org.zwobble.mammoth.xml.XmlNodes; import static com.natpryce.makeiteasy.MakeItEasy.*; import static org.hamcrest.MatcherAssert.assertThat; +import static org.zwobble.mammoth.Result.success; import static org.zwobble.mammoth.tests.DeepReflectionMatcher.deepEquals; import static org.zwobble.mammoth.tests.documents.DocumentElementMakers.CHILDREN; import static org.zwobble.mammoth.tests.documents.DocumentElementMakers.PARAGRAPH; @@ -29,13 +31,13 @@ public class DocumentXmlTests { element("w:t", list( XmlNodes.text("Hello!"))))))))))); - Document document = new DocumentXmlReader(bodyReader).readElement(documentElement); + Result<Document> document = new DocumentXmlReader(bodyReader).readElement(documentElement); assertThat( document, - deepEquals(new Document(list( + deepEquals(success(new Document(list( make(a(PARAGRAPH, with(CHILDREN, list( new Run(list( - new Text("Hello!"))))))))))); + new Text("Hello!")))))))))))); } } diff --git a/src/test/java/org/zwobble/mammoth/tests/docx/NotesXmlReaderTests.java b/src/test/java/org/zwobble/mammoth/tests/docx/NotesXmlReaderTests.java index b8ada2e..d18cbe3 100644 --- a/src/test/java/org/zwobble/mammoth/tests/docx/NotesXmlReaderTests.java +++ b/src/test/java/org/zwobble/mammoth/tests/docx/NotesXmlReaderTests.java @@ -1,6 +1,7 @@ package org.zwobble.mammoth.tests.docx; import org.junit.Test; +import org.zwobble.mammoth.Result; import org.zwobble.mammoth.documents.Note; import org.zwobble.mammoth.docx.BodyXmlReader; import org.zwobble.mammoth.docx.NotesXmlReader; @@ -11,6 +12,7 @@ import java.util.List; import static com.natpryce.makeiteasy.MakeItEasy.a; import static com.natpryce.makeiteasy.MakeItEasy.make; import static org.hamcrest.MatcherAssert.assertThat; +import static org.zwobble.mammoth.Result.success; import static org.zwobble.mammoth.tests.DeepReflectionMatcher.deepEquals; import static org.zwobble.mammoth.tests.documents.DocumentElementMakers.PARAGRAPH; import static org.zwobble.mammoth.util.MammothLists.list; @@ -27,11 +29,11 @@ public class NotesXmlReaderTests { element("w:p"))))); NotesXmlReader reader = new NotesXmlReader(bodyReader, "footnote"); - List<Note> notes = reader.readElement(element); + Result<List<Note>> notes = reader.readElement(element); assertThat( notes, - deepEquals(list(new Note("1", list(make(a(PARAGRAPH))))))); + deepEquals(success(list(new Note("1", list(make(a(PARAGRAPH)))))))); } @Test @@ -50,8 +52,8 @@ public class NotesXmlReaderTests { element("w:p"))))); NotesXmlReader reader = new NotesXmlReader(bodyReader, "footnote"); - List<Note> notes = reader.readElement(element); + Result<List<Note>> notes = reader.readElement(element); - assertThat(notes, deepEquals(list())); + assertThat(notes, deepEquals(success(list()))); } } |
