/*******************************************************************************
*
* Copyright (c) 2013 blinkbox Entertainment Limited. All rights reserved.
*
*
*******************************************************************************/
package com.blinkbox.java.book.xml;
import com.blinkbox.java.book.factory.BBBEPubXMLFactory;
import com.blinkbox.java.book.model.BBBEPubMetaData;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
/**
* Class to parse a OPS/package.xml file and extract the spine, manifest and
* toc.ncx path
*/
public class BBBEPubPackage {
private static final String METADATA = "metadata";
private static final String MANIFEST = "manifest";
private static final String SPINE = "spine";
private static final String IDREF = "idref";
private static final String ID = "id";
private static final String HREF = "href";
private static final String MEDIATYPE = "media-type";
private static final String TOC = "toc";
private static final String ITEM = "item";
private static final String ITEMREF = "itemref";
private static final String META = "meta";
private static final String NAME = "name";
private static final String COVER = "cover";
private static final String CONTENT = "content";
private static final String COVER_URL_END = "_cover_epub.jpg";
private String mTocId = "ncx";
private String mNcxPath = "toc.ncx";
private String coverId = null;
private String coverUrl = null;
private BBBEPubMetaData bbBBBEPubMetaData;
private List<String> spineIdList;
private List<ManifestItem> manifestIdList;
private HashMap<String, String> mMimeTypeTable;
public HashMap<String, String> getmMimeTypeTable() {
return mMimeTypeTable;
}
private void parseSpine(XmlPullParser xmlPullParser) throws XmlPullParserException, IOException {
spineIdList = new LinkedList<String>();
int eventType = XmlPullParser.START_TAG;
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG && SPINE.equals(xmlPullParser.getName())) {
String tocId = xmlPullParser.getAttributeValue(null, TOC);
if (tocId != null) {
mTocId = tocId;
}
} else if (eventType == XmlPullParser.START_TAG && ITEMREF.equals(xmlPullParser.getName())) {
spineIdList.add(xmlPullParser.getAttributeValue(null, IDREF));
} else if (eventType == XmlPullParser.END_TAG) {
break;
}
eventType = xmlPullParser.nextTag();
}
}
private void parseManifest(XmlPullParser xmlPullParser) throws XmlPullParserException, IOException {
manifestIdList = new LinkedList<BBBEPubPackage.ManifestItem>();
mMimeTypeTable = new HashMap<String, String>();
int eventType = xmlPullParser.nextTag();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG && MANIFEST.equals(xmlPullParser.getName())) {
String id = xmlPullParser.getAttributeValue(null, ID);
String href = xmlPullParser.getAttributeValue(null, HREF);
String mediatype = xmlPullParser.getAttributeValue(null, MEDIATYPE);
mMimeTypeTable.put(href, mediatype);
manifestIdList.add(new ManifestItem(id, href, mediatype));
} else if (eventType == XmlPullParser.START_TAG && ITEM.equals(xmlPullParser.getName())) {
String id = xmlPullParser.getAttributeValue(null, ID);
String href = xmlPullParser.getAttributeValue(null, HREF);
String mediatype = xmlPullParser.getAttributeValue(null, MEDIATYPE);
mMimeTypeTable.put(href, mediatype);
manifestIdList.add(new ManifestItem(id, href, mediatype));
if (mTocId.equals(id)) {
mNcxPath = href;
}
} else if (eventType == XmlPullParser.END_TAG && MANIFEST.equals(xmlPullParser.getName())) {
break;
}
eventType = xmlPullParser.nextTag();
}
}
private void parseMetaDataList(XmlPullParser xmlPullParser) throws XmlPullParserException, IOException {
bbBBBEPubMetaData = new BBBEPubMetaData();
int eventType = xmlPullParser.nextTag();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
String name = xmlPullParser.getName();
if (META.equals(name)) {
String attr = xmlPullParser.getAttributeValue(null, NAME);
if (COVER.equals(attr)) {
coverId = xmlPullParser.getAttributeValue(null, CONTENT);
}
} else {
String label = xmlPullParser.nextText();
if (!"".equals(label)) {
bbBBBEPubMetaData.addAttribute(name, label);
}
}
} else if (eventType == XmlPullParser.END_TAG && METADATA.equals(xmlPullParser.getName())) {
break;
}
eventType = xmlPullParser.next();
}
}
public BBBEPubPackage(InputStream in) throws XmlPullParserException, IOException {
XmlPullParser xmlPullParser = BBBEPubXMLFactory.parseInputStream(in);
xmlPullParser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
int eventType = xmlPullParser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG && METADATA.equals(xmlPullParser.getName())) {
parseMetaDataList(xmlPullParser);
}
if (eventType == XmlPullParser.START_TAG && MANIFEST.equals(xmlPullParser.getName())) {
parseManifest(xmlPullParser);
}
if (eventType == XmlPullParser.START_TAG && SPINE.equals(xmlPullParser.getName())) {
parseSpine(xmlPullParser);
}
eventType = xmlPullParser.next();
}
if (manifestIdList != null) {
for (ManifestItem item : manifestIdList) {
if (mTocId != null && mTocId.equals(item.id)) {
mNcxPath = item.href;
}
if (coverId != null && coverId.equals(item.id)) {
coverUrl = item.href;
} else if (item.href != null && item.href.endsWith(COVER_URL_END)) {
coverUrl = item.href;
}
}
}
}
public String getNcxPath() {
return mNcxPath;
}
public BBBEPubMetaData getMetaData() {
return bbBBBEPubMetaData;
}
public List<String> getSpineIdList() {
return spineIdList;
}
public List<ManifestItem> getManifestIdList() {
return manifestIdList;
}
public String getCoverUrl() {
return coverUrl;
}
public class ManifestItem {
String id;
String href;
String mediatype;
public ManifestItem(String id, String href, String mediatype) {
this.id = id;
this.href = href;
this.mediatype = mediatype;
}
public String getId() {
return id;
}
public String getHref() {
return href;
}
public String getMediatype() {
return mediatype;
}
}
}