commit
023f5cf8d0
@ -1,7 +1,4 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||
package="me.ag2s.epublib"> |
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> |
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> |
||||
<manifest package="me.ag2s.epublib"> |
||||
|
||||
</manifest> |
@ -1,79 +1,89 @@ |
||||
package me.ag2s.epublib.domain; |
||||
|
||||
|
||||
|
||||
import me.ag2s.epublib.util.StringUtil; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
/** |
||||
* Represents one of the authors of the book |
||||
* |
||||
* @author paul |
||||
* |
||||
*/ |
||||
public class Author implements Serializable { |
||||
|
||||
private static final long serialVersionUID = 6663408501416574200L; |
||||
private static final long serialVersionUID = 6663408501416574200L; |
||||
|
||||
private String firstname; |
||||
private String lastname; |
||||
private Relator relator = Relator.AUTHOR; |
||||
private String firstname; |
||||
private String lastname; |
||||
private Relator relator = Relator.AUTHOR; |
||||
|
||||
public Author(String singleName) { |
||||
this("", singleName); |
||||
} |
||||
public Author(String singleName) { |
||||
this("", singleName); |
||||
} |
||||
|
||||
public Author(String firstname, String lastname) { |
||||
this.firstname = firstname; |
||||
this.lastname = lastname; |
||||
} |
||||
|
||||
public Author(String firstname, String lastname) { |
||||
this.firstname = firstname; |
||||
this.lastname = lastname; |
||||
} |
||||
public String getFirstname() { |
||||
return firstname; |
||||
} |
||||
|
||||
public String getFirstname() { |
||||
return firstname; |
||||
} |
||||
public void setFirstname(String firstname) { |
||||
this.firstname = firstname; |
||||
} |
||||
|
||||
public void setFirstname(String firstname) { |
||||
this.firstname = firstname; |
||||
} |
||||
public String getLastname() { |
||||
return lastname; |
||||
} |
||||
|
||||
public String getLastname() { |
||||
return lastname; |
||||
} |
||||
public void setLastname(String lastname) { |
||||
this.lastname = lastname; |
||||
} |
||||
|
||||
public void setLastname(String lastname) { |
||||
this.lastname = lastname; |
||||
} |
||||
|
||||
public String toString() { |
||||
return lastname + ", " + firstname; |
||||
} |
||||
@Override |
||||
@SuppressWarnings("NullableProblems") |
||||
public String toString() { |
||||
return this.lastname + ", " + this.firstname; |
||||
} |
||||
|
||||
public int hashCode() { |
||||
return StringUtil.hashCode(firstname, lastname); |
||||
} |
||||
public int hashCode() { |
||||
return StringUtil.hashCode(firstname, lastname); |
||||
} |
||||
|
||||
public boolean equals(Object authorObject) { |
||||
if (!(authorObject instanceof Author)) { |
||||
return false; |
||||
public boolean equals(Object authorObject) { |
||||
if (!(authorObject instanceof Author)) { |
||||
return false; |
||||
} |
||||
Author other = (Author) authorObject; |
||||
return StringUtil.equals(firstname, other.firstname) |
||||
&& StringUtil.equals(lastname, other.lastname); |
||||
} |
||||
Author other = (Author) authorObject; |
||||
return StringUtil.equals(firstname, other.firstname) |
||||
&& StringUtil.equals(lastname, other.lastname); |
||||
} |
||||
|
||||
public Relator setRole(String code) { |
||||
Relator result = Relator.byCode(code); |
||||
if (result == null) { |
||||
result = Relator.AUTHOR; |
||||
|
||||
/** |
||||
* 设置贡献者的角色 |
||||
* |
||||
* @param code 角色编号 |
||||
*/ |
||||
|
||||
public void setRole(String code) { |
||||
Relator result = Relator.byCode(code); |
||||
if (result == null) { |
||||
result = Relator.AUTHOR; |
||||
} |
||||
this.relator = result; |
||||
} |
||||
this.relator = result; |
||||
return result; |
||||
} |
||||
|
||||
public Relator getRelator() { |
||||
return relator; |
||||
} |
||||
public Relator getRelator() { |
||||
return relator; |
||||
} |
||||
|
||||
|
||||
public void setRelator(Relator relator) { |
||||
this.relator = relator; |
||||
} |
||||
public void setRelator(Relator relator) { |
||||
this.relator = relator; |
||||
} |
||||
} |
||||
|
@ -0,0 +1,323 @@ |
||||
package me.ag2s.epublib.domain; |
||||
|
||||
|
||||
import java.io.Serializable; |
||||
import java.util.ArrayList; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* Representation of a Book. |
||||
* <p> |
||||
* All resources of a Book (html, css, xml, fonts, images) are represented |
||||
* as Resources. See getResources() for access to these.<br/> |
||||
* A Book as 3 indexes into these Resources, as per the epub specification.<br/> |
||||
* <dl> |
||||
* <dt>Spine</dt> |
||||
* <dd>these are the Resources to be shown when a user reads the book from |
||||
* start to finish.</dd> |
||||
* <dt>Table of Contents<dt> |
||||
* <dd>The table of contents. Table of Contents references may be in a |
||||
* different order and contain different Resources than the spine, and often do. |
||||
* <dt>Guide</dt> |
||||
* <dd>The Guide has references to a set of special Resources like the |
||||
* cover page, the Glossary, the copyright page, etc. |
||||
* </dl> |
||||
* <p/> |
||||
* The complication is that these 3 indexes may and usually do point to |
||||
* different pages. |
||||
* A chapter may be split up in 2 pieces to fit it in to memory. Then the |
||||
* spine will contain both pieces, but the Table of Contents only the first. |
||||
* <p> |
||||
* The Content page may be in the Table of Contents, the Guide, but not |
||||
* in the Spine. |
||||
* Etc. |
||||
* <p/> |
||||
* <p> |
||||
* Please see the illustration at: doc/schema.svg |
||||
* |
||||
* @author paul |
||||
* @author jake |
||||
*/ |
||||
public class Book implements Serializable { |
||||
|
||||
private static final long serialVersionUID = 2068355170895770100L; |
||||
|
||||
private Resources resources = new Resources(); |
||||
private Metadata metadata = new Metadata(); |
||||
private Spine spine = new Spine(); |
||||
private TableOfContents tableOfContents = new TableOfContents(); |
||||
private final Guide guide = new Guide(); |
||||
private Resource opfResource; |
||||
private Resource ncxResource; |
||||
private Resource coverImage; |
||||
|
||||
|
||||
private String version="2.0"; |
||||
|
||||
public String getVersion() { |
||||
return version; |
||||
} |
||||
|
||||
public void setVersion(String version) { |
||||
this.version = version; |
||||
} |
||||
|
||||
public boolean isEpub3() { |
||||
return this.version.startsWith("3."); |
||||
} |
||||
|
||||
@SuppressWarnings("UnusedReturnValue") |
||||
public TOCReference addSection( |
||||
TOCReference parentSection, String sectionTitle, Resource resource) { |
||||
return addSection(parentSection, sectionTitle, resource, null); |
||||
} |
||||
|
||||
/** |
||||
* Adds the resource to the table of contents of the book as a child |
||||
* section of the given parentSection |
||||
* |
||||
* @param parentSection parentSection |
||||
* @param sectionTitle sectionTitle |
||||
* @param resource resource |
||||
* @param fragmentId fragmentId |
||||
* @return The table of contents |
||||
*/ |
||||
public TOCReference addSection( |
||||
TOCReference parentSection, String sectionTitle, Resource resource, |
||||
String fragmentId) { |
||||
getResources().add(resource); |
||||
if (spine.findFirstResourceById(resource.getId()) < 0) { |
||||
spine.addSpineReference(new SpineReference(resource)); |
||||
} |
||||
return parentSection.addChildSection( |
||||
new TOCReference(sectionTitle, resource, fragmentId)); |
||||
} |
||||
|
||||
public TOCReference addSection(String title, Resource resource) { |
||||
return addSection(title, resource, null); |
||||
} |
||||
|
||||
/** |
||||
* Adds a resource to the book's set of resources, table of contents and |
||||
* if there is no resource with the id in the spine also adds it to the spine. |
||||
* |
||||
* @param title title |
||||
* @param resource resource |
||||
* @param fragmentId fragmentId |
||||
* @return The table of contents |
||||
*/ |
||||
public TOCReference addSection( |
||||
String title, Resource resource, String fragmentId) { |
||||
getResources().add(resource); |
||||
TOCReference tocReference = tableOfContents |
||||
.addTOCReference(new TOCReference(title, resource, fragmentId)); |
||||
if (spine.findFirstResourceById(resource.getId()) < 0) { |
||||
spine.addSpineReference(new SpineReference(resource)); |
||||
} |
||||
return tocReference; |
||||
} |
||||
|
||||
@SuppressWarnings("unused") |
||||
public void generateSpineFromTableOfContents() { |
||||
Spine spine = new Spine(tableOfContents); |
||||
|
||||
// in case the tocResource was already found and assigned
|
||||
spine.setTocResource(this.spine.getTocResource()); |
||||
|
||||
this.spine = spine; |
||||
} |
||||
|
||||
/** |
||||
* The Book's metadata (titles, authors, etc) |
||||
* |
||||
* @return The Book's metadata (titles, authors, etc) |
||||
*/ |
||||
public Metadata getMetadata() { |
||||
return metadata; |
||||
} |
||||
|
||||
public void setMetadata(Metadata metadata) { |
||||
this.metadata = metadata; |
||||
} |
||||
|
||||
|
||||
public void setResources(Resources resources) { |
||||
this.resources = resources; |
||||
} |
||||
|
||||
@SuppressWarnings("unused") |
||||
public Resource addResource(Resource resource) { |
||||
return resources.add(resource); |
||||
} |
||||
|
||||
/** |
||||
* The collection of all images, chapters, sections, xhtml files, |
||||
* stylesheets, etc that make up the book. |
||||
* |
||||
* @return The collection of all images, chapters, sections, xhtml files, |
||||
* stylesheets, etc that make up the book. |
||||
*/ |
||||
public Resources getResources() { |
||||
return resources; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* The sections of the book that should be shown if a user reads the book |
||||
* from start to finish. |
||||
* |
||||
* @return The Spine |
||||
*/ |
||||
public Spine getSpine() { |
||||
return spine; |
||||
} |
||||
|
||||
|
||||
public void setSpine(Spine spine) { |
||||
this.spine = spine; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* The Table of Contents of the book. |
||||
* |
||||
* @return The Table of Contents of the book. |
||||
*/ |
||||
public TableOfContents getTableOfContents() { |
||||
return tableOfContents; |
||||
} |
||||
|
||||
|
||||
public void setTableOfContents(TableOfContents tableOfContents) { |
||||
this.tableOfContents = tableOfContents; |
||||
} |
||||
|
||||
/** |
||||
* The book's cover page as a Resource. |
||||
* An XHTML document containing a link to the cover image. |
||||
* |
||||
* @return The book's cover page as a Resource |
||||
*/ |
||||
public Resource getCoverPage() { |
||||
Resource coverPage = guide.getCoverPage(); |
||||
if (coverPage == null) { |
||||
coverPage = spine.getResource(0); |
||||
} |
||||
return coverPage; |
||||
} |
||||
|
||||
|
||||
public void setCoverPage(Resource coverPage) { |
||||
if (coverPage == null) { |
||||
return; |
||||
} |
||||
if (resources.notContainsByHref(coverPage.getHref())) { |
||||
resources.add(coverPage); |
||||
} |
||||
guide.setCoverPage(coverPage); |
||||
} |
||||
|
||||
/** |
||||
* Gets the first non-blank title from the book's metadata. |
||||
* |
||||
* @return the first non-blank title from the book's metadata. |
||||
*/ |
||||
public String getTitle() { |
||||
return getMetadata().getFirstTitle(); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* The book's cover image. |
||||
* |
||||
* @return The book's cover image. |
||||
*/ |
||||
public Resource getCoverImage() { |
||||
return coverImage; |
||||
} |
||||
|
||||
public void setCoverImage(Resource coverImage) { |
||||
if (coverImage == null) { |
||||
return; |
||||
} |
||||
if (resources.notContainsByHref(coverImage.getHref())) { |
||||
resources.add(coverImage); |
||||
} |
||||
this.coverImage = coverImage; |
||||
} |
||||
|
||||
/** |
||||
* The guide; contains references to special sections of the book like |
||||
* colophon, glossary, etc. |
||||
* |
||||
* @return The guide; contains references to special sections of the book |
||||
* like colophon, glossary, etc. |
||||
*/ |
||||
public Guide getGuide() { |
||||
return guide; |
||||
} |
||||
|
||||
/** |
||||
* All Resources of the Book that can be reached via the Spine, the |
||||
* TableOfContents or the Guide. |
||||
* <p/> |
||||
* Consists of a list of "reachable" resources: |
||||
* <ul> |
||||
* <li>The coverpage</li> |
||||
* <li>The resources of the Spine that are not already in the result</li> |
||||
* <li>The resources of the Table of Contents that are not already in the |
||||
* result</li> |
||||
* <li>The resources of the Guide that are not already in the result</li> |
||||
* </ul> |
||||
* To get all html files that make up the epub file use |
||||
* {@link #getResources()} |
||||
* |
||||
* @return All Resources of the Book that can be reached via the Spine, |
||||
* the TableOfContents or the Guide. |
||||
*/ |
||||
public List<Resource> getContents() { |
||||
Map<String, Resource> result = new LinkedHashMap<>(); |
||||
addToContentsResult(getCoverPage(), result); |
||||
|
||||
for (SpineReference spineReference : getSpine().getSpineReferences()) { |
||||
addToContentsResult(spineReference.getResource(), result); |
||||
} |
||||
|
||||
for (Resource resource : getTableOfContents().getAllUniqueResources()) { |
||||
addToContentsResult(resource, result); |
||||
} |
||||
|
||||
for (GuideReference guideReference : getGuide().getReferences()) { |
||||
addToContentsResult(guideReference.getResource(), result); |
||||
} |
||||
|
||||
return new ArrayList<>(result.values()); |
||||
} |
||||
|
||||
private static void addToContentsResult(Resource resource, |
||||
Map<String, Resource> allReachableResources) { |
||||
if (resource != null && (!allReachableResources |
||||
.containsKey(resource.getHref()))) { |
||||
allReachableResources.put(resource.getHref(), resource); |
||||
} |
||||
} |
||||
|
||||
public Resource getOpfResource() { |
||||
return opfResource; |
||||
} |
||||
|
||||
public void setOpfResource(Resource opfResource) { |
||||
this.opfResource = opfResource; |
||||
} |
||||
|
||||
public void setNcxResource(Resource ncxResource) { |
||||
this.ncxResource = ncxResource; |
||||
} |
||||
|
||||
public Resource getNcxResource() { |
||||
return ncxResource; |
||||
} |
||||
} |
||||
|
@ -1,104 +1,108 @@ |
||||
package me.ag2s.epublib.domain; |
||||
|
||||
import me.ag2s.epublib.epub.PackageDocumentBase; |
||||
|
||||
import java.io.Serializable; |
||||
import java.text.SimpleDateFormat; |
||||
import java.util.Locale; |
||||
|
||||
/** |
||||
* A Date used by the book's metadata. |
||||
* |
||||
* <p> |
||||
* Examples: creation-date, modification-date, etc |
||||
* |
||||
* @author paul |
||||
* |
||||
*/ |
||||
public class Date implements Serializable { |
||||
|
||||
private static final long serialVersionUID = 7533866830395120136L; |
||||
private static final long serialVersionUID = 7533866830395120136L; |
||||
|
||||
public enum Event { |
||||
PUBLICATION("publication"), |
||||
MODIFICATION("modification"), |
||||
CREATION("creation"); |
||||
public enum Event { |
||||
PUBLICATION("publication"), |
||||
MODIFICATION("modification"), |
||||
CREATION("creation"); |
||||
|
||||
private final String value; |
||||
private final String value; |
||||
|
||||
Event(String v) { |
||||
value = v; |
||||
} |
||||
Event(String v) { |
||||
value = v; |
||||
} |
||||
|
||||
public static Event fromValue(String v) { |
||||
for (Event c : Event.values()) { |
||||
if (c.value.equals(v)) { |
||||
return c; |
||||
public static Event fromValue(String v) { |
||||
for (Event c : Event.values()) { |
||||
if (c.value.equals(v)) { |
||||
return c; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public String toString() { |
||||
return value; |
||||
@Override |
||||
@SuppressWarnings("NullableProblems") |
||||
public String toString() { |
||||
return value; |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
private Event event; |
||||
private String dateString; |
||||
private Event event; |
||||
private String dateString; |
||||
|
||||
public Date(java.util.Date date) { |
||||
this(date, (Event) null); |
||||
} |
||||
public Date(java.util.Date date) { |
||||
this(date, (Event) null); |
||||
} |
||||
|
||||
public Date(String dateString) { |
||||
this(dateString, (Event) null); |
||||
} |
||||
public Date(String dateString) { |
||||
this(dateString, (Event) null); |
||||
} |
||||
|
||||
public Date(java.util.Date date, Event event) { |
||||
this((new SimpleDateFormat(PackageDocumentBase.dateFormat, Locale.US)).format(date), |
||||
event); |
||||
} |
||||
public Date(java.util.Date date, Event event) { |
||||
this((new SimpleDateFormat(PackageDocumentBase.dateFormat, Locale.US)).format(date), |
||||
event); |
||||
} |
||||
|
||||
public Date(String dateString, Event event) { |
||||
this.dateString = dateString; |
||||
this.event = event; |
||||
} |
||||
public Date(String dateString, Event event) { |
||||
this.dateString = dateString; |
||||
this.event = event; |
||||
} |
||||
|
||||
public Date(java.util.Date date, String event) { |
||||
this((new SimpleDateFormat(PackageDocumentBase.dateFormat,Locale.US)).format(date), |
||||
event); |
||||
} |
||||
public Date(java.util.Date date, String event) { |
||||
this((new SimpleDateFormat(PackageDocumentBase.dateFormat, Locale.US)).format(date), |
||||
event); |
||||
} |
||||
|
||||
public Date(String dateString, String event) { |
||||
this(checkDate(dateString), Event.fromValue(event)); |
||||
this.dateString = dateString; |
||||
} |
||||
public Date(String dateString, String event) { |
||||
this(checkDate(dateString), Event.fromValue(event)); |
||||
this.dateString = dateString; |
||||
} |
||||
|
||||
private static String checkDate(String dateString) { |
||||
if (dateString == null) { |
||||
throw new IllegalArgumentException( |
||||
"Cannot create a date from a blank string"); |
||||
private static String checkDate(String dateString) { |
||||
if (dateString == null) { |
||||
throw new IllegalArgumentException( |
||||
"Cannot create a date from a blank string"); |
||||
} |
||||
return dateString; |
||||
} |
||||
return dateString; |
||||
} |
||||
|
||||
public String getValue() { |
||||
return dateString; |
||||
} |
||||
public String getValue() { |
||||
return dateString; |
||||
} |
||||
|
||||
public Event getEvent() { |
||||
return event; |
||||
} |
||||
public Event getEvent() { |
||||
return event; |
||||
} |
||||
|
||||
public void setEvent(Event event) { |
||||
this.event = event; |
||||
} |
||||
public void setEvent(Event event) { |
||||
this.event = event; |
||||
} |
||||
|
||||
public String toString() { |
||||
if (event == null) { |
||||
return dateString; |
||||
@Override |
||||
@SuppressWarnings("NullableProblems") |
||||
public String toString() { |
||||
if (event == null) { |
||||
return dateString; |
||||
} |
||||
return "" + event + ":" + dateString; |
||||
} |
||||
return "" + event + ":" + dateString; |
||||
} |
||||
} |
||||
|
||||
|
@ -1,5 +0,0 @@ |
||||
package me.ag2s.epublib.epub; |
||||
|
||||
public class Main { |
||||
|
||||
} |
@ -1,296 +0,0 @@ |
||||
package me.ag2s.epublib.epub; |
||||
|
||||
import android.util.Log; |
||||
|
||||
import org.w3c.dom.Element; |
||||
import org.w3c.dom.NodeList; |
||||
import org.xmlpull.v1.XmlSerializer; |
||||
|
||||
import java.io.ByteArrayOutputStream; |
||||
import java.io.IOException; |
||||
import java.io.UnsupportedEncodingException; |
||||
import java.net.URLDecoder; |
||||
import java.util.List; |
||||
import java.util.zip.ZipEntry; |
||||
import java.util.zip.ZipOutputStream; |
||||
|
||||
import me.ag2s.epublib.Constants; |
||||
import me.ag2s.epublib.domain.Author; |
||||
import me.ag2s.epublib.domain.EpubBook; |
||||
import me.ag2s.epublib.domain.Identifier; |
||||
import me.ag2s.epublib.domain.MediaTypes; |
||||
import me.ag2s.epublib.domain.Resource; |
||||
import me.ag2s.epublib.domain.TOCReference; |
||||
import me.ag2s.epublib.domain.TableOfContents; |
||||
import me.ag2s.epublib.util.StringUtil; |
||||
|
||||
//import io.documentnode.minilog.Logger;
|
||||
//import javax.xml.stream.FactoryConfigurationError;
|
||||
|
||||
/** |
||||
* Writes the ncx document as defined by namespace http://www.daisy.org/z3986/2005/ncx/
|
||||
* |
||||
* @author paul |
||||
*/ |
||||
public class NCXDocument { |
||||
|
||||
public static final String NAMESPACE_NCX = "http://www.daisy.org/z3986/2005/ncx/"; |
||||
public static final String PREFIX_NCX = "ncx"; |
||||
public static final String NCX_ITEM_ID = "ncx"; |
||||
public static final String DEFAULT_NCX_HREF = "toc.ncx"; |
||||
public static final String PREFIX_DTB = "dtb"; |
||||
|
||||
private static String TAG = NCXDocument.class.getName(); |
||||
|
||||
private interface NCXTags { |
||||
|
||||
String ncx = "ncx"; |
||||
String meta = "meta"; |
||||
String navPoint = "navPoint"; |
||||
String navMap = "navMap"; |
||||
String navLabel = "navLabel"; |
||||
String content = "content"; |
||||
String text = "text"; |
||||
String docTitle = "docTitle"; |
||||
String docAuthor = "docAuthor"; |
||||
String head = "head"; |
||||
} |
||||
|
||||
private interface NCXAttributes { |
||||
|
||||
String src = "src"; |
||||
String name = "name"; |
||||
String content = "content"; |
||||
String id = "id"; |
||||
String playOrder = "playOrder"; |
||||
String clazz = "class"; |
||||
String version = "version"; |
||||
} |
||||
|
||||
private interface NCXAttributeValues { |
||||
|
||||
String chapter = "chapter"; |
||||
String version = "2005-1"; |
||||
|
||||
} |
||||
|
||||
public static Resource read(EpubBook book, EpubReader epubReader) { |
||||
Log.d(TAG, book.getVersion()); |
||||
String version = book.getVersion(); |
||||
if (version.startsWith("2.")) { |
||||
return NCXDocumentV2.read(book, epubReader); |
||||
} else if (version.startsWith("3.")) { |
||||
return NCXDocumentV3.read(book, epubReader); |
||||
} else { |
||||
return NCXDocumentV2.read(book, epubReader); |
||||
} |
||||
|
||||
} |
||||
|
||||
private static List<TOCReference> readTOCReferences(NodeList navpoints, |
||||
EpubBook book) { |
||||
Log.d(TAG, book.getVersion()); |
||||
String version = book.getVersion(); |
||||
if (version.startsWith("2.")) { |
||||
return NCXDocumentV2.readTOCReferences(navpoints, book); |
||||
} else if (version.startsWith("3.")) { |
||||
return NCXDocumentV3.readTOCReferences(navpoints, book); |
||||
} else { |
||||
return NCXDocumentV2.readTOCReferences(navpoints, book); |
||||
} |
||||
|
||||
} |
||||
|
||||
static TOCReference readTOCReference(Element navpointElement, EpubBook book) { |
||||
Log.d(TAG, book.getVersion()); |
||||
String version = book.getVersion(); |
||||
if (version.startsWith("2.")) { |
||||
return NCXDocumentV2.readTOCReference(navpointElement, book); |
||||
} else if (version.startsWith("3.")) { |
||||
return NCXDocumentV3.readTOCReference(navpointElement, book); |
||||
} else { |
||||
return NCXDocumentV2.readTOCReference(navpointElement, book); |
||||
} |
||||
|
||||
} |
||||
|
||||
private static String readNavReference(Element navpointElement) { |
||||
Element contentElement = DOMUtil |
||||
.getFirstElementByTagNameNS(navpointElement, NAMESPACE_NCX, |
||||
NCXTags.content); |
||||
String result = DOMUtil |
||||
.getAttribute(contentElement, NAMESPACE_NCX, NCXAttributes.src); |
||||
try { |
||||
result = URLDecoder.decode(result, Constants.CHARACTER_ENCODING); |
||||
} catch (UnsupportedEncodingException e) { |
||||
Log.e(TAG, e.getMessage()); |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
private static String readNavLabel(Element navpointElement) { |
||||
Element navLabel = DOMUtil |
||||
.getFirstElementByTagNameNS(navpointElement, NAMESPACE_NCX, |
||||
NCXTags.navLabel); |
||||
return DOMUtil.getTextChildrenContent(DOMUtil |
||||
.getFirstElementByTagNameNS(navLabel, NAMESPACE_NCX, NCXTags.text)); |
||||
} |
||||
|
||||
|
||||
public static void write(EpubWriter epubWriter, EpubBook book, |
||||
ZipOutputStream resultStream) throws IOException { |
||||
resultStream |
||||
.putNextEntry(new ZipEntry(book.getSpine().getTocResource().getHref())); |
||||
XmlSerializer out = EpubProcessorSupport.createXmlSerializer(resultStream); |
||||
write(out, book); |
||||
out.flush(); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Generates a resource containing an xml document containing the table of contents of the book in ncx format. |
||||
* |
||||
* @param xmlSerializer the serializer used |
||||
* @param book the book to serialize |
||||
* @throws IOException |
||||
* @throws IllegalStateException |
||||
* @throws IllegalArgumentException |
||||
* @1throws FactoryConfigurationError |
||||
*/ |
||||
public static void write(XmlSerializer xmlSerializer, EpubBook book) |
||||
throws IllegalArgumentException, IllegalStateException, IOException { |
||||
write(xmlSerializer, book.getMetadata().getIdentifiers(), book.getTitle(), |
||||
book.getMetadata().getAuthors(), book.getTableOfContents()); |
||||
} |
||||
|
||||
public static Resource createNCXResource(EpubBook book) |
||||
throws IllegalArgumentException, IllegalStateException, IOException { |
||||
return createNCXResource(book.getMetadata().getIdentifiers(), |
||||
book.getTitle(), book.getMetadata().getAuthors(), |
||||
book.getTableOfContents()); |
||||
} |
||||
|
||||
public static Resource createNCXResource(List<Identifier> identifiers, |
||||
String title, List<Author> authors, TableOfContents tableOfContents) |
||||
throws IllegalArgumentException, IllegalStateException, IOException { |
||||
ByteArrayOutputStream data = new ByteArrayOutputStream(); |
||||
XmlSerializer out = EpubProcessorSupport.createXmlSerializer(data); |
||||
write(out, identifiers, title, authors, tableOfContents); |
||||
Resource resource = new Resource(NCX_ITEM_ID, data.toByteArray(), |
||||
DEFAULT_NCX_HREF, MediaTypes.NCX); |
||||
return resource; |
||||
} |
||||
|
||||
public static void write(XmlSerializer serializer, |
||||
List<Identifier> identifiers, String title, List<Author> authors, |
||||
TableOfContents tableOfContents) |
||||
throws IllegalArgumentException, IllegalStateException, IOException { |
||||
serializer.startDocument(Constants.CHARACTER_ENCODING, false); |
||||
serializer.setPrefix(EpubWriter.EMPTY_NAMESPACE_PREFIX, NAMESPACE_NCX); |
||||
serializer.startTag(NAMESPACE_NCX, NCXTags.ncx); |
||||
// serializer.writeNamespace("ncx", NAMESPACE_NCX);
|
||||
// serializer.attribute("xmlns", NAMESPACE_NCX);
|
||||
serializer |
||||
.attribute(EpubWriter.EMPTY_NAMESPACE_PREFIX, NCXAttributes.version, |
||||
NCXAttributeValues.version); |
||||
serializer.startTag(NAMESPACE_NCX, NCXTags.head); |
||||
|
||||
for (Identifier identifier : identifiers) { |
||||
writeMetaElement(identifier.getScheme(), identifier.getValue(), |
||||
serializer); |
||||
} |
||||
|
||||
writeMetaElement("generator", Constants.EPUB4J_GENERATOR_NAME, serializer); |
||||
writeMetaElement("depth", String.valueOf(tableOfContents.calculateDepth()), |
||||
serializer); |
||||
writeMetaElement("totalPageCount", "0", serializer); |
||||
writeMetaElement("maxPageNumber", "0", serializer); |
||||
|
||||
serializer.endTag(NAMESPACE_NCX, "head"); |
||||
|
||||
serializer.startTag(NAMESPACE_NCX, NCXTags.docTitle); |
||||
serializer.startTag(NAMESPACE_NCX, NCXTags.text); |
||||
// write the first title
|
||||
serializer.text(StringUtil.defaultIfNull(title)); |
||||
serializer.endTag(NAMESPACE_NCX, NCXTags.text); |
||||
serializer.endTag(NAMESPACE_NCX, NCXTags.docTitle); |
||||
|
||||
for (Author author : authors) { |
||||
serializer.startTag(NAMESPACE_NCX, NCXTags.docAuthor); |
||||
serializer.startTag(NAMESPACE_NCX, NCXTags.text); |
||||
serializer.text(author.getLastname() + ", " + author.getFirstname()); |
||||
serializer.endTag(NAMESPACE_NCX, NCXTags.text); |
||||
serializer.endTag(NAMESPACE_NCX, NCXTags.docAuthor); |
||||
} |
||||
|
||||
serializer.startTag(NAMESPACE_NCX, NCXTags.navMap); |
||||
writeNavPoints(tableOfContents.getTocReferences(), 1, serializer); |
||||
serializer.endTag(NAMESPACE_NCX, NCXTags.navMap); |
||||
|
||||
serializer.endTag(NAMESPACE_NCX, "ncx"); |
||||
serializer.endDocument(); |
||||
} |
||||
|
||||
|
||||
private static void writeMetaElement(String dtbName, String content, |
||||
XmlSerializer serializer) |
||||
throws IllegalArgumentException, IllegalStateException, IOException { |
||||
serializer.startTag(NAMESPACE_NCX, NCXTags.meta); |
||||
serializer.attribute(EpubWriter.EMPTY_NAMESPACE_PREFIX, NCXAttributes.name, |
||||
PREFIX_DTB + ":" + dtbName); |
||||
serializer |
||||
.attribute(EpubWriter.EMPTY_NAMESPACE_PREFIX, NCXAttributes.content, |
||||
content); |
||||
serializer.endTag(NAMESPACE_NCX, NCXTags.meta); |
||||
} |
||||
|
||||
private static int writeNavPoints(List<TOCReference> tocReferences, |
||||
int playOrder, |
||||
XmlSerializer serializer) |
||||
throws IllegalArgumentException, IllegalStateException, IOException { |
||||
for (TOCReference tocReference : tocReferences) { |
||||
if (tocReference.getResource() == null) { |
||||
playOrder = writeNavPoints(tocReference.getChildren(), playOrder, |
||||
serializer); |
||||
continue; |
||||
} |
||||
writeNavPointStart(tocReference, playOrder, serializer); |
||||
playOrder++; |
||||
if (!tocReference.getChildren().isEmpty()) { |
||||
playOrder = writeNavPoints(tocReference.getChildren(), playOrder, |
||||
serializer); |
||||
} |
||||
writeNavPointEnd(tocReference, serializer); |
||||
} |
||||
return playOrder; |
||||
} |
||||
|
||||
|
||||
private static void writeNavPointStart(TOCReference tocReference, |
||||
int playOrder, XmlSerializer serializer) |
||||
throws IllegalArgumentException, IllegalStateException, IOException { |
||||
serializer.startTag(NAMESPACE_NCX, NCXTags.navPoint); |
||||
serializer.attribute(EpubWriter.EMPTY_NAMESPACE_PREFIX, NCXAttributes.id, |
||||
"navPoint-" + playOrder); |
||||
serializer |
||||
.attribute(EpubWriter.EMPTY_NAMESPACE_PREFIX, NCXAttributes.playOrder, |
||||
String.valueOf(playOrder)); |
||||
serializer.attribute(EpubWriter.EMPTY_NAMESPACE_PREFIX, NCXAttributes.clazz, |
||||
NCXAttributeValues.chapter); |
||||
serializer.startTag(NAMESPACE_NCX, NCXTags.navLabel); |
||||
serializer.startTag(NAMESPACE_NCX, NCXTags.text); |
||||
serializer.text(tocReference.getTitle()); |
||||
serializer.endTag(NAMESPACE_NCX, NCXTags.text); |
||||
serializer.endTag(NAMESPACE_NCX, NCXTags.navLabel); |
||||
serializer.startTag(NAMESPACE_NCX, NCXTags.content); |
||||
serializer.attribute(EpubWriter.EMPTY_NAMESPACE_PREFIX, NCXAttributes.src, |
||||
tocReference.getCompleteHref()); |
||||
serializer.endTag(NAMESPACE_NCX, NCXTags.content); |
||||
} |
||||
|
||||
private static void writeNavPointEnd(TOCReference tocReference, |
||||
XmlSerializer serializer) |
||||
throws IllegalArgumentException, IllegalStateException, IOException { |
||||
serializer.endTag(NAMESPACE_NCX, NCXTags.navPoint); |
||||
} |
||||
} |
@ -1,202 +0,0 @@ |
||||
package me.ag2s.epublib.util; |
||||
/* |
||||
* Copyright (c) 2006, John Kristian |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* |
||||
* * Neither the name of StAX-Utils nor the names of its contributors |
||||
* may be used to endorse or promote products derived from this |
||||
* software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
||||
* POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
import javax.xml.namespace.NamespaceContext; |
||||
import javax.xml.stream.XMLStreamException; |
||||
import javax.xml.stream.XMLStreamWriter; |
||||
|
||||
/** |
||||
* Abstract class for writing filtered XML streams. This class provides methods |
||||
* that merely delegate to the contained stream. Subclasses should override some |
||||
* of these methods, and may also provide additional methods and fields. |
||||
* |
||||
* @author <a href="mailto:jk2006@engineer.com">John Kristian</a> |
||||
*/ |
||||
public abstract class StreamWriterDelegate implements XMLStreamWriter { |
||||
|
||||
protected StreamWriterDelegate(XMLStreamWriter out) { |
||||
this.out = out; |
||||
} |
||||
|
||||
protected XMLStreamWriter out; |
||||
|
||||
public Object getProperty(String name) |
||||
throws IllegalArgumentException { |
||||
return out.getProperty(name); |
||||
} |
||||
|
||||
public NamespaceContext getNamespaceContext() { |
||||
return out.getNamespaceContext(); |
||||
} |
||||
|
||||
public void setNamespaceContext(NamespaceContext context) |
||||
throws XMLStreamException { |
||||
out.setNamespaceContext(context); |
||||
} |
||||
|
||||
public void setDefaultNamespace(String uri) |
||||
throws XMLStreamException { |
||||
out.setDefaultNamespace(uri); |
||||
} |
||||
|
||||
public void writeStartDocument() throws XMLStreamException { |
||||
out.writeStartDocument(); |
||||
} |
||||
|
||||
public void writeStartDocument(String version) |
||||
throws XMLStreamException { |
||||
out.writeStartDocument(version); |
||||
} |
||||
|
||||
public void writeStartDocument(String encoding, String version) |
||||
throws XMLStreamException { |
||||
out.writeStartDocument(encoding, version); |
||||
} |
||||
|
||||
public void writeDTD(String dtd) throws XMLStreamException { |
||||
out.writeDTD(dtd); |
||||
} |
||||
|
||||
public void writeProcessingInstruction(String target) |
||||
throws XMLStreamException { |
||||
out.writeProcessingInstruction(target); |
||||
} |
||||
|
||||
public void writeProcessingInstruction(String target, String data) |
||||
throws XMLStreamException { |
||||
out.writeProcessingInstruction(target, data); |
||||
} |
||||
|
||||
public void writeComment(String data) throws XMLStreamException { |
||||
out.writeComment(data); |
||||
} |
||||
|
||||
public void writeEmptyElement(String localName) |
||||
throws XMLStreamException { |
||||
out.writeEmptyElement(localName); |
||||
} |
||||
|
||||
public void writeEmptyElement(String namespaceURI, String localName) |
||||
throws XMLStreamException { |
||||
out.writeEmptyElement(namespaceURI, localName); |
||||
} |
||||
|
||||
public void writeEmptyElement(String prefix, String localName, |
||||
String namespaceURI) throws XMLStreamException { |
||||
out.writeEmptyElement(prefix, localName, namespaceURI); |
||||
} |
||||
|
||||
public void writeStartElement(String localName) |
||||
throws XMLStreamException { |
||||
out.writeStartElement(localName); |
||||
} |
||||
|
||||
public void writeStartElement(String namespaceURI, String localName) |
||||
throws XMLStreamException { |
||||
out.writeStartElement(namespaceURI, localName); |
||||
} |
||||
|
||||
public void writeStartElement(String prefix, String localName, |
||||
String namespaceURI) throws XMLStreamException { |
||||
out.writeStartElement(prefix, localName, namespaceURI); |
||||
} |
||||
|
||||
public void writeDefaultNamespace(String namespaceURI) |
||||
throws XMLStreamException { |
||||
out.writeDefaultNamespace(namespaceURI); |
||||
} |
||||
|
||||
public void writeNamespace(String prefix, String namespaceURI) |
||||
throws XMLStreamException { |
||||
out.writeNamespace(prefix, namespaceURI); |
||||
} |
||||
|
||||
public String getPrefix(String uri) throws XMLStreamException { |
||||
return out.getPrefix(uri); |
||||
} |
||||
|
||||
public void setPrefix(String prefix, String uri) |
||||
throws XMLStreamException { |
||||
out.setPrefix(prefix, uri); |
||||
} |
||||
|
||||
public void writeAttribute(String localName, String value) |
||||
throws XMLStreamException { |
||||
out.writeAttribute(localName, value); |
||||
} |
||||
|
||||
public void writeAttribute(String namespaceURI, String localName, |
||||
String value) throws XMLStreamException { |
||||
out.writeAttribute(namespaceURI, localName, value); |
||||
} |
||||
|
||||
public void writeAttribute(String prefix, String namespaceURI, |
||||
String localName, String value) throws XMLStreamException { |
||||
out.writeAttribute(prefix, namespaceURI, localName, value); |
||||
} |
||||
|
||||
public void writeCharacters(String text) throws XMLStreamException { |
||||
out.writeCharacters(text); |
||||
} |
||||
|
||||
public void writeCharacters(char[] text, int start, int len) |
||||
throws XMLStreamException { |
||||
out.writeCharacters(text, start, len); |
||||
} |
||||
|
||||
public void writeCData(String data) throws XMLStreamException { |
||||
out.writeCData(data); |
||||
} |
||||
|
||||
public void writeEntityRef(String name) throws XMLStreamException { |
||||
out.writeEntityRef(name); |
||||
} |
||||
|
||||
public void writeEndElement() throws XMLStreamException { |
||||
out.writeEndElement(); |
||||
} |
||||
|
||||
public void writeEndDocument() throws XMLStreamException { |
||||
out.writeEndDocument(); |
||||
} |
||||
|
||||
public void flush() throws XMLStreamException { |
||||
out.flush(); |
||||
} |
||||
|
||||
public void close() throws XMLStreamException { |
||||
out.close(); |
||||
} |
||||
|
||||
} |
||||
|
Loading…
Reference in new issue