Added Android code
[wl-app.git] / Android / r2-streamer / r2-parser / src / main / java / org / readium / r2_streamer / parser / NCXParser.java
diff --git a/Android/r2-streamer/r2-parser/src/main/java/org/readium/r2_streamer/parser/NCXParser.java b/Android/r2-streamer/r2-parser/src/main/java/org/readium/r2_streamer/parser/NCXParser.java
new file mode 100755 (executable)
index 0000000..b9a21dd
--- /dev/null
@@ -0,0 +1,105 @@
+package org.readium.r2_streamer.parser;
+
+import org.readium.r2_streamer.model.container.Container;
+import org.readium.r2_streamer.model.publication.EpubPublication;
+import org.readium.r2_streamer.model.tableofcontents.TOCLink;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by gautam chibde on 31/5/17.
+ */
+
+public class NCXParser {
+
+    private static final String TAG = NCXParser.class.getSimpleName();
+
+    public static void parseNCXFile(String ncxFile, Container container, EpubPublication publication, String rootPath) throws EpubParserException {
+        String ncxData = container.rawData(ncxFile);
+        if (ncxData == null) {
+            return; // File is missing
+        }
+        Document document = EpubParser.xmlParser(ncxData);
+        if (document == null) {
+            throw new EpubParserException("Error while parsing");
+        }
+
+        Element navMapElement = (Element) document.getElementsByTagName("navMap").item(0);
+        // Parse table of contents (toc) from ncx file
+        if (navMapElement != null) {
+            publication.tableOfContents = nodeArray(navMapElement, "navPoint", rootPath);
+        }
+
+        Element pageList = (Element) document.getElementsByTagName("pageList").item(0);
+        // Parse page list if exists from ncx file
+        if (pageList != null) {
+            publication.pageList = nodeArray(pageList, "pageTarget", rootPath);
+        }
+    }
+
+    /**
+     * Generate an array of {@link TOCLink} elements representation of the XML
+     * structure in the ncx file. Each of them possibly having children.
+     *
+     * @param elements NCX DOM element object
+     * @param type     The sub elements names (e.g. 'navPoint' for 'navMap',
+     *                 'pageTarget' for 'pageList'.
+     * @return The Object representation of the data contained in the given NCX XML element.
+     */
+    private static List<TOCLink> nodeArray(Element elements, String type, String rootPath) {
+        // The "to be returned" node array.
+        List<TOCLink> newNodeArray = new ArrayList<>();
+
+        // Find the elements of `type` in the XML element.
+        for (Node n = elements.getFirstChild(); n != null; n = n.getNextSibling()) {
+            if (n.getNodeType() == Node.ELEMENT_NODE) {
+                Element e = (Element) n;
+                if (e.getTagName().equalsIgnoreCase(type)) {
+                    newNodeArray.add(node(e, type, rootPath));
+                }
+            }
+        }
+        return newNodeArray;
+    }
+
+    /**
+     * [RECURSIVE]
+     * Create a node link from the specified type element.
+     * recur if there are child elements
+     *
+     * @param element the DOM NCX file elemet
+     * @param type    The sub elements names (e.g. 'navPoint' for 'navMap',
+     *                'pageTarget' for 'pageList'.
+     * @return The generated node {@link TOCLink}.
+     */
+    private static TOCLink node(Element element, String type, String rootPath) {
+        TOCLink newNode = new TOCLink();
+
+        Element content = (Element) element.getElementsByTagName("content").item(0);
+        Element navLabel = (Element) element.getElementsByTagName("navLabel").item(0);
+        if (content != null) {
+            newNode.href = rootPath + content.getAttribute("src");
+        }
+        if (navLabel != null) {
+            Element text = (Element) navLabel.getElementsByTagName("text").item(0);
+            if (text != null) {
+                newNode.bookTitle = text.getTextContent();
+            }
+        }
+
+        for (Node n = element.getFirstChild(); n != null; n = n.getNextSibling()) {
+            if (n.getNodeType() == Node.ELEMENT_NODE) {
+                Element e = (Element) n;
+                if (e.getTagName().equalsIgnoreCase(type)) {
+                    newNode.tocLinks.add(node(e, type, rootPath));
+                }
+            }
+        }
+        return newNode;
+    }
+}