diff options
| author | Michael Williamson <mike@zwobble.org> | 2016-02-24 08:16:16 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2016-02-24 08:16:16 +0000 |
| commit | 3e2786a004eddf968a5fa7d5a92dff5b1b5f7734 (patch) | |
| tree | 7fa1bcc1e484cd0ef782f64baf504ee83333d397 /src/main/java/org/zwobble/mammoth/docx/BodyXmlReader.java | |
| parent | 0dc3a12affc2e46c1a0df2899cf51a1ae3fdbd61 (diff) | |
Create internal package
Diffstat (limited to 'src/main/java/org/zwobble/mammoth/docx/BodyXmlReader.java')
| -rw-r--r-- | src/main/java/org/zwobble/mammoth/docx/BodyXmlReader.java | 329 |
1 files changed, 0 insertions, 329 deletions
diff --git a/src/main/java/org/zwobble/mammoth/docx/BodyXmlReader.java b/src/main/java/org/zwobble/mammoth/docx/BodyXmlReader.java deleted file mode 100644 index 9a1f95b..0000000 --- a/src/main/java/org/zwobble/mammoth/docx/BodyXmlReader.java +++ /dev/null @@ -1,329 +0,0 @@ -package org.zwobble.mammoth.docx; - -import com.google.common.collect.ImmutableSet; -import org.zwobble.mammoth.documents.*; -import org.zwobble.mammoth.results.Result; -import org.zwobble.mammoth.results.Warning; -import org.zwobble.mammoth.util.InputStreamSupplier; -import org.zwobble.mammoth.util.MammothOptionals; -import org.zwobble.mammoth.xml.XmlElement; -import org.zwobble.mammoth.xml.XmlElementLike; -import org.zwobble.mammoth.xml.XmlElementList; -import org.zwobble.mammoth.xml.XmlNode; - -import java.util.Optional; -import java.util.Set; -import java.util.function.Function; - -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; -import static org.zwobble.mammoth.results.Warning.warning; -import static org.zwobble.mammoth.util.MammothLists.list; -import static org.zwobble.mammoth.util.MammothStrings.trimLeft; - -public class BodyXmlReader { - private static final Set<String> IMAGE_TYPES_SUPPORTED_BY_BROWSERS = ImmutableSet.of( - "image/png", "image/gif", "image/jpeg", "image/svg+xml", "image/tiff"); - - private final Styles styles; - private final Numbering numbering; - private final Relationships relationships; - private final ContentTypes contentTypes; - private final DocxFile file; - private final FileReader fileReader; - - public BodyXmlReader( - Styles styles, - Numbering numbering, - Relationships relationships, - ContentTypes contentTypes, - DocxFile file, - FileReader fileReader) - { - this.styles = styles; - this.numbering = numbering; - this.relationships = relationships; - this.contentTypes = contentTypes; - this.file = file; - this.fileReader = fileReader; - } - - public ReadResult readElement(XmlElement element) { - switch (element.getName()) { - case "w:t": - return success(new Text(element.innerText())); - case "w:r": - return readRun(element); - case "w:p": - return readParagraph(element); - - case "w:tab": - return success(Tab.TAB); - case "w:br": - return readBreak(element); - - case "w:tbl": - return readElements(element.children()).map(Table::new); - case "w:tr": - return readElements(element.children()).map(TableRow::new); - case "w:tc": - return readElements(element.children()).map(TableCell::new); - - case "w:hyperlink": - return readHyperlink(element); - case "w:bookmarkStart": - return readBookmark(element); - case "w:footnoteReference": - return readNoteReference(NoteType.FOOTNOTE, element); - case "w:endnoteReference": - return readNoteReference(NoteType.ENDNOTE, element); - - case "w:pict": - return readPict(element); - - case "v:imagedata": - return readImagedata(element); - - case "wp:inline": - case "wp:anchor": - return readInline(element); - - case "w:ins": - case "w:smartTag": - case "w:drawing": - case "v:roundrect": - case "v:shape": - case "v:textbox": - case "w:txbxContent": - return readElements(element.children()); - - case "office-word:wrap": - case "v:shadow": - case "v:shapetype": - case "w:bookmarkEnd": - case "w:sectPr": - case "w:proofErr": - case "w:lastRenderedPageBreak": - case "w:commentRangeStart": - case "w:commentRangeEnd": - case "w:commentReference": - case "w:del": - case "w:footnoteRef": - case "w:endnoteRef": - case "w:pPr": - case "w:rPr": - case "w:tblPr": - case "w:tblGrid": - case "w:tcPr": - return EMPTY_SUCCESS; - - default: - Warning warning = warning("An unrecognised element was ignored: " + element.getName()); - return ReadResult.emptyWithWarning(warning); - } - } - - private ReadResult readRun(XmlElement element) { - XmlElementLike properties = element.findChildOrEmpty("w:rPr"); - return ReadResult.map( - readRunStyle(properties), - readElements(element.children()), - (style, children) -> new Run( - isBold(properties), - isItalic(properties), - isUnderline(properties), - isStrikethrough(properties), - readVerticalAlignment(properties), - style, - children)); - } - - private boolean isBold(XmlElementLike properties) { - return properties.hasChild("w:b"); - } - - private boolean isItalic(XmlElementLike properties) { - return properties.hasChild("w:i"); - } - - private boolean isUnderline(XmlElementLike properties) { - return properties.hasChild("w:u"); - } - - private boolean isStrikethrough(XmlElementLike properties) { - return properties.hasChild("w:strike"); - } - - private VerticalAlignment readVerticalAlignment(XmlElementLike properties) { - String verticalAlignment = readVal(properties, "w:vertAlign").orElse(""); - switch (verticalAlignment) { - case "superscript": - return VerticalAlignment.SUPERSCRIPT; - case "subscript": - return VerticalAlignment.SUBSCRIPT; - default: - // TODO: warn if set? - return VerticalAlignment.BASELINE; - } - } - - private Result<Optional<Style>> readRunStyle(XmlElementLike properties) { - return readStyle(properties, "w:rStyle", "Run", styles::findCharacterStyleById); - } - - public ReadResult readElements(Iterable<XmlNode> nodes) { - return ReadResult.concat( - transform( - filter(nodes, XmlElement.class), - this::readElement)); - } - - private ReadResult readParagraph(XmlElement element) { - XmlElementLike properties = element.findChildOrEmpty("w:pPr"); - Optional<NumberingLevel> numbering = readNumbering(properties); - return ReadResult.map( - readParagraphStyle(properties), - readElements(element.children()), - (style, children) -> new Paragraph(style, numbering, children)).appendExtra(); - } - - private Result<Optional<Style>> readParagraphStyle(XmlElementLike properties) { - return readStyle(properties, "w:pStyle", "Paragraph", styles::findParagraphStyleById); - } - - private Result<Optional<Style>> readStyle( - XmlElementLike properties, - String styleTagName, - String styleType, - Function<String, Optional<Style>> findStyleById) - { - return readVal(properties, styleTagName) - .map(styleId -> findStyleById(styleType, styleId, findStyleById)) - .orElse(Result.empty()); - } - - private Result<Optional<Style>> findStyleById( - String styleType, - String styleId, - Function<String, Optional<Style>> findStyleById) - { - Optional<Style> style = findStyleById.apply(styleId); - if (style.isPresent()) { - return Result.success(style); - } else { - return new Result<>( - Optional.of(new Style(styleId, Optional.empty())), - list(warning(styleType + " style with ID " + styleId + " was referenced but not defined in the document"))); - } - - } - - private Optional<NumberingLevel> readNumbering(XmlElementLike properties) { - XmlElementLike numberingProperties = properties.findChildOrEmpty("w:numPr"); - return MammothOptionals.flatMap( - readVal(numberingProperties, "w:numId"), - readVal(numberingProperties, "w:ilvl"), - numbering::findLevel); - } - - private ReadResult readBreak(XmlElement element) { - String breakType = element.getAttributeOrNone("w:type").orElse(""); - if (breakType.equals("")) { - return success(LineBreak.LINE_BREAK); - } else { - return ReadResult.emptyWithWarning(warning("Unsupported break type: " + breakType)); - } - } - - private ReadResult readHyperlink(XmlElement element) { - Optional<String> relationshipId = element.getAttributeOrNone("r:id"); - Optional<String> anchor = element.getAttributeOrNone("w:anchor"); - ReadResult childrenResult = readElements(element.children()); - if (relationshipId.isPresent()) { - return childrenResult.map(children -> Hyperlink.href( - relationships.findRelationshipById(relationshipId.get()).getTarget(), children)); - } else if (anchor.isPresent()) { - return childrenResult.map(children -> Hyperlink.anchor( - anchor.get(), children)); - } else { - return childrenResult; - } - } - - private ReadResult readBookmark(XmlElement element) { - String name = element.getAttribute("w:name"); - if (name.equals("_GoBack")) { - return ReadResult.EMPTY_SUCCESS; - } else { - return success(new Bookmark(name)); - } - } - - private ReadResult readNoteReference(NoteType noteType, XmlElement element) { - String noteId = element.getAttribute("w:id"); - return success(new NoteReference(noteType, noteId)); - } - - private ReadResult readPict(XmlElement element) { - return readElements(element.children()).toExtra(); - } - - private ReadResult readImagedata(XmlElement element) { - Optional<String> title = element.getAttributeOrNone("o:title"); - String relationshipId = element.getAttribute("r:id"); - String imagePath = relationshipIdToDocxPath(relationshipId); - return readImage(imagePath, title, () -> DocxFile.getInputStream(file, imagePath)); - } - - private ReadResult readInline(XmlElement element) { - Optional<String> altText = element.findChildOrEmpty("wp:docPr").getAttributeOrNone("descr"); - XmlElementList blips = element.findChildren("a:graphic") - .findChildren("a:graphicData") - .findChildren("pic:pic") - .findChildren("pic:blipFill") - .findChildren("a:blip"); - return readBlips(blips, altText); - } - - private ReadResult readBlips(XmlElementList blips, Optional<String> altText) { - return ReadResult.concat(transform(blips, blip -> readBlip(blip, altText))); - } - - private ReadResult readBlip(XmlElement blip, Optional<String> altText) { - Optional<String> embedRelationshipId = blip.getAttributeOrNone("r:embed"); - Optional<String> linkRelationshipId = blip.getAttributeOrNone("r:link"); - if (embedRelationshipId.isPresent()) { - String imagePath = relationshipIdToDocxPath(embedRelationshipId.get()); - return readImage(imagePath, altText, () -> DocxFile.getInputStream(file, imagePath)); - } else if (linkRelationshipId.isPresent()) { - String imagePath = relationships.findRelationshipById(linkRelationshipId.get()).getTarget(); - return readImage(imagePath, altText, () -> fileReader.getInputStream(imagePath)); - } else { - // TODO: emit warning - return ReadResult.EMPTY_SUCCESS; - } - } - - private ReadResult readImage(String imagePath, Optional<String> altText, InputStreamSupplier open) { - Optional<String> contentType = contentTypes.findContentType(imagePath); - Image image = new Image(altText, contentType, open); - - String contentTypeString = contentType.orElse("(unknown)"); - if (IMAGE_TYPES_SUPPORTED_BY_BROWSERS.contains(contentTypeString)) { - return success(image); - } else { - return ReadResult.withWarning(image, warning("Image of type " + contentTypeString + " is unlikely to display in web browsers")); - } - } - - private String relationshipIdToDocxPath(String relationshipId) { - Relationship relationship = relationships.findRelationshipById(relationshipId); - return "word/" + trimLeft(relationship.getTarget(), '/'); - } - - private Optional<String> readVal(XmlElementLike element, String name) { - return element.findChildOrEmpty(name).getAttributeOrNone("w:val"); - } -} |
