--- /dev/null
+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;
+ }
+}