package com.eoeandorid.reader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import android.os.Environment;
public class EpubKernel {
// xml parser
private DocumentBuilderFactory mDocumentBuilderFactory;
private DocumentBuilder mDocumentBuilder;
// epub基本目录(每个epub解压后的基本目录)
private String epubBaseDir = "";
// opf
private List<String> opfList;
// metadata
private Map<String,String> metadataMap;
// manifestitme
private Map<String,EpubManifestItem> manifestItemMap;
// spine
private Map<String,String> spineMap;
private String ncx;
private static final String CONTAINER_FILE = "/META-INF/container.xml";
private static final String CONTAINER_FILE_MEDIA_TYPE = "application/oebps-package+xml";
private static final String EPUB_ROOT_PATH = Environment.getExternalStorageDirectory().getPath()+"/EoeReader/epub/";
// 初始化APP的epub工作目录
public void init() throws ParserConfigurationException{
File file = new File(EPUB_ROOT_PATH);
if(!file.exists()){
file.mkdirs();
}
mDocumentBuilderFactory = DocumentBuilderFactory.newInstance();
mDocumentBuilder = mDocumentBuilderFactory.newDocumentBuilder();
}
public void openEpubFile(String epubFilePath,String epubWorkDiectory) throws FileNotFoundException,IOException
,SAXException,ParserConfigurationException{
init();
unzipEpub(epubFilePath,epubWorkDiectory);
this.epubBaseDir = epubWorkDiectory;
parserEpubFile(epubWorkDiectory);
}
// 解压epub到workDiectory目录�?workDiectory的命名规则为BOOKID)
public void unzipEpub(String epubFilePath,String epubWorkDiectory){
try {
ZipUtil.unzipEpub(epubFilePath, epubWorkDiectory);
} catch (Exception e) {
}
}
// 解析解压后的epub目录
public void parserEpubFile(String epubUnzipDiectory) throws FileNotFoundException,IOException,SAXException{
File file = new File(epubUnzipDiectory);
if(!file.exists()){
return;
}
parseContainer();
parseOpfFile();
//prrseNcxFile();
}
private void parseContainer() throws FileNotFoundException,IOException,SAXException{
String containerFile = this.epubBaseDir + CONTAINER_FILE;
System.out.println("container file: "+containerFile);
File file = new File(containerFile);
FileInputStream fis = new FileInputStream(file);
Document document = mDocumentBuilder.parse(fis);
String fullPath = "";
String mediaType = "";
Element rootNode = (Element)document.getElementsByTagName("rootfiles").item(0);
NodeList nodes = rootNode.getChildNodes();
if(nodes.getLength() > 0){
opfList = new ArrayList<String>();
for (int i = 0; i < nodes.getLength(); i++) {
fullPath = DomUtil.getElementAttr(document,"rootfile","full-path",i);
mediaType = DomUtil.getElementAttr(document,"rootfile","media-type",i);
if (mediaType.equals(CONTAINER_FILE_MEDIA_TYPE)){
opfList.add(fullPath);
break;
}
}
}
}
private void parseOpfFile() throws FileNotFoundException,IOException,SAXException{
if(opfList == null || opfList.size() <= 0){
return;
}
String opfFile = this.epubBaseDir + "/" + opfList.get(0);
System.out.println("opfFile: "+opfFile);
File file = new File(opfFile);
InputStream is = new FileInputStream(file);
Document document = mDocumentBuilder.parse(is);
// 获取opf文件中metadata相关数据(图书基础信息)
metadataMap = new HashMap<String,String>();
metadataMap.put("title", DomUtil.getElementValue(document, "dc:title", 0));
metadataMap.put("creator", DomUtil.getElementValue(document, "dc:creator", 0));
metadataMap.put("description", DomUtil.getElementValue(document, "dc:description", 0));
// 获取opf文件中manifest相关数据(资源清单)
Element manifestNode = (Element)document.getElementsByTagName("manifest").item(0);
NodeList nodes = manifestNode.getChildNodes();
if(nodes.getLength() > 0){
manifestItemMap = new HashMap<String,EpubManifestItem>();
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if ( node.getNodeType() == Node.ELEMENT_NODE ){
Element elManifestItem = (Element)node;
EpubManifestItem item = new EpubManifestItem();
item.itemId = elManifestItem.getAttribute("id");
item.href = elManifestItem.getAttribute("href");
item.mediaType = elManifestItem.getAttribute("media_type");
manifestItemMap.put(item.itemId, item);
}
}
}
// 获取opf文件中spine相关数据(阅读顺序)
Element spineNode = (Element)document.getElementsByTagName("spine").item(0);
// 获取spine中的toc属�?(之后就能根据该属性在manifestItemMap中获取href属�?对应的文件路�?
ncx = spineNode.getAttribute("toc");
NodeList spines = document.getElementsByTagName("itemref");
if(spines.getLength() > 0){
spineMap = new HashMap<String,String>();
for (int i = 0; i < spines.getLength(); i++) {
String idref = DomUtil.getElementAttr(document, "itemref", "idref", i);
spineMap.put(String.valueOf(i), idref);
}
}
}
private void prrseNcxFile() throws FileNotFoundException,IOException,SAXException{
}
public Map<String, String> getSpineMap() {
return spineMap;
}
public String getHtmlUrlByIndex(int index){
String pageIndex = spineMap.get(String.valueOf(index));
EpubManifestItem item = manifestItemMap.get(pageIndex);
return "file:///"+this.epubBaseDir + "/" + item.href;
}
private class EpubManifestItem{
public EpubManifestItem(){}
public String itemId;
public String href;
public String mediaType;
}
}