修复解析一些epub3文件

一些epub3 的文件为了兼容epub2而保留了epub2的ncx目录导致解析目录失败。
pull/957/head
ag2s20150909 4 years ago
parent 937d4c61ef
commit b26cec93d0
  1. 6
      epublib/src/main/java/me/ag2s/epublib/epub/NCXDocumentV2.java
  2. 13
      epublib/src/main/java/me/ag2s/epublib/epub/NCXDocumentV3.java
  3. 676
      epublib/src/main/java/me/ag2s/epublib/epub/PackageDocumentReader.java
  4. 7
      epublib/src/main/java/me/ag2s/epublib/util/IOUtil.java

@ -148,9 +148,9 @@ public class NCXDocumentV2 {
if (resource == null) { if (resource == null) {
Log.e(TAG, "Resource with href " + href + " in NCX document not found"); Log.e(TAG, "Resource with href " + href + " in NCX document not found");
} }
Log.d(TAG, "label:" + label); Log.v(TAG, "label:" + label);
Log.d(TAG, "href:" + href); Log.v(TAG, "href:" + href);
Log.d(TAG, "fragmentId:" + fragmentId); Log.v(TAG, "fragmentId:" + fragmentId);
TOCReference result = new TOCReference(label, resource, fragmentId); TOCReference result = new TOCReference(label, resource, fragmentId);
List<TOCReference> childTOCReferences = readTOCReferences( List<TOCReference> childTOCReferences = readTOCReferences(
navpointElement.getChildNodes(), book); navpointElement.getChildNodes(), book);

@ -107,12 +107,21 @@ public class NCXDocumentV3 {
if (ncxResource == null) { if (ncxResource == null) {
return null; return null;
} }
//Log.d(TAG, ncxResource.getHref()); //一些epub 3 文件没有按照epub3的标准使用删除掉ncx目录文件
if (ncxResource.getHref().endsWith(".ncx")){
Log.v(TAG,"该epub文件不标准,使用了epub2的目录文件");
return NCXDocumentV2.read(book, epubReader);
}
Log.d(TAG, ncxResource.getHref());
Document ncxDocument = ResourceUtil.getAsDocument(ncxResource); Document ncxDocument = ResourceUtil.getAsDocument(ncxResource);
//Log.d(TAG, ncxDocument.getNodeName()); Log.d(TAG, ncxDocument.getNodeName());
Element navMapElement = (Element) ncxDocument.getElementsByTagName(XHTMLTgs.nav).item(0); Element navMapElement = (Element) ncxDocument.getElementsByTagName(XHTMLTgs.nav).item(0);
if(navMapElement==null){
Log.d(TAG,"epub3目录文件未发现nav节点,尝试使用epub2的规则解析");
return NCXDocumentV2.read(book, epubReader);
}
navMapElement = (Element) navMapElement.getElementsByTagName(XHTMLTgs.ol).item(0); navMapElement = (Element) navMapElement.getElementsByTagName(XHTMLTgs.ol).item(0);
Log.d(TAG, navMapElement.getTagName()); Log.d(TAG, navMapElement.getTagName());

@ -36,42 +36,41 @@ import me.ag2s.epublib.util.StringUtil;
* Reads the opf package document as defined by namespace http://www.idpf.org/2007/opf * Reads the opf package document as defined by namespace http://www.idpf.org/2007/opf
* *
* @author paul * @author paul
*
*/ */
public class PackageDocumentReader extends PackageDocumentBase { public class PackageDocumentReader extends PackageDocumentBase {
private static final String TAG= PackageDocumentReader.class.getName(); private static final String TAG = PackageDocumentReader.class.getName();
private static final String[] POSSIBLE_NCX_ITEM_IDS = new String[]{"toc", private static final String[] POSSIBLE_NCX_ITEM_IDS = new String[]{"toc",
"ncx", "ncxtoc","htmltoc"}; "ncx", "ncxtoc", "htmltoc"};
public static void read( public static void read(
Resource packageResource, EpubReader epubReader, EpubBook book, Resource packageResource, EpubReader epubReader, EpubBook book,
Resources resources) Resources resources)
throws SAXException, IOException { throws SAXException, IOException {
Document packageDocument = ResourceUtil.getAsDocument(packageResource); Document packageDocument = ResourceUtil.getAsDocument(packageResource);
String packageHref = packageResource.getHref(); String packageHref = packageResource.getHref();
resources = fixHrefs(packageHref, resources); resources = fixHrefs(packageHref, resources);
readGuide(packageDocument, epubReader, book, resources); readGuide(packageDocument, epubReader, book, resources);
// Books sometimes use non-identifier ids. We map these here to legal ones // Books sometimes use non-identifier ids. We map these here to legal ones
Map<String, String> idMapping = new HashMap<>(); Map<String, String> idMapping = new HashMap<>();
String version=DOMUtil.getAttribute(packageDocument.getDocumentElement(),PREFIX_OPF,PackageDocumentBase.version); String version = DOMUtil.getAttribute(packageDocument.getDocumentElement(), PREFIX_OPF, PackageDocumentBase.version);
resources = readManifest(packageDocument, packageHref, epubReader, resources = readManifest(packageDocument, packageHref, epubReader,
resources, idMapping); resources, idMapping);
book.setResources(resources); book.setResources(resources);
book.setVersion(version); book.setVersion(version);
readCover(packageDocument, book); readCover(packageDocument, book);
book.setMetadata( book.setMetadata(
PackageDocumentMetadataReader.readMetadata(packageDocument)); PackageDocumentMetadataReader.readMetadata(packageDocument));
book.setSpine(readSpine(packageDocument, book.getResources(), idMapping)); book.setSpine(readSpine(packageDocument, book.getResources(), idMapping));
// if we did not find a cover page then we make the first page of the book the cover page // if we did not find a cover page then we make the first page of the book the cover page
if (book.getCoverPage() == null && book.getSpine().size() > 0) { if (book.getCoverPage() == null && book.getSpine().size() > 0) {
book.setCoverPage(book.getSpine().getResource(0)); book.setCoverPage(book.getSpine().getResource(0));
}
} }
}
// private static Resource readCoverImage(Element metadataElement, Resources resources) { // private static Resource readCoverImage(Element metadataElement, Resources resources) {
// String coverResourceId = DOMUtil.getFindAttributeValue(metadataElement.getOwnerDocument(), NAMESPACE_OPF, OPFTags.meta, OPFAttributes.name, OPFValues.meta_cover, OPFAttributes.content); // String coverResourceId = DOMUtil.getFindAttributeValue(metadataElement.getOwnerDocument(), NAMESPACE_OPF, OPFTags.meta, OPFAttributes.name, OPFValues.meta_cover, OPFAttributes.content);
@ -83,322 +82,325 @@ public class PackageDocumentReader extends PackageDocumentBase {
// } // }
/** /**
* Reads the manifest containing the resource ids, hrefs and mediatypes. * Reads the manifest containing the resource ids, hrefs and mediatypes.
* *
* @param packageDocument e * @param packageDocument e
* @param packageHref e * @param packageHref e
* @param epubReader e * @param epubReader e
* @param resources e * @param resources e
* @param idMapping e * @param idMapping e
* @return a Map with resources, with their id's as key. * @return a Map with resources, with their id's as key.
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
private static Resources readManifest(Document packageDocument, private static Resources readManifest(Document packageDocument,
String packageHref, String packageHref,
EpubReader epubReader, Resources resources, EpubReader epubReader, Resources resources,
Map<String, String> idMapping) { Map<String, String> idMapping) {
Element manifestElement = DOMUtil Element manifestElement = DOMUtil
.getFirstElementByTagNameNS(packageDocument.getDocumentElement(), .getFirstElementByTagNameNS(packageDocument.getDocumentElement(),
NAMESPACE_OPF, OPFTags.manifest); NAMESPACE_OPF, OPFTags.manifest);
Resources result = new Resources(); Resources result = new Resources();
if (manifestElement == null) { if (manifestElement == null) {
Log.e(TAG, Log.e(TAG,
"Package document does not contain element " + OPFTags.manifest); "Package document does not contain element " + OPFTags.manifest);
return result; return result;
} }
NodeList itemElements = manifestElement NodeList itemElements = manifestElement
.getElementsByTagNameNS(NAMESPACE_OPF, OPFTags.item); .getElementsByTagNameNS(NAMESPACE_OPF, OPFTags.item);
for (int i = 0; i < itemElements.getLength(); i++) { for (int i = 0; i < itemElements.getLength(); i++) {
Element itemElement = (Element) itemElements.item(i); Element itemElement = (Element) itemElements.item(i);
String id = DOMUtil String id = DOMUtil
.getAttribute(itemElement, NAMESPACE_OPF, OPFAttributes.id); .getAttribute(itemElement, NAMESPACE_OPF, OPFAttributes.id);
String href = DOMUtil String href = DOMUtil
.getAttribute(itemElement, NAMESPACE_OPF, OPFAttributes.href); .getAttribute(itemElement, NAMESPACE_OPF, OPFAttributes.href);
try { try {
href = URLDecoder.decode(href, Constants.CHARACTER_ENCODING); href = URLDecoder.decode(href, Constants.CHARACTER_ENCODING);
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
Log.e(TAG,e.getMessage()); Log.e(TAG, e.getMessage());
} }
String mediaTypeName = DOMUtil String mediaTypeName = DOMUtil
.getAttribute(itemElement, NAMESPACE_OPF, OPFAttributes.media_type); .getAttribute(itemElement, NAMESPACE_OPF, OPFAttributes.media_type);
Resource resource = resources.remove(href); Resource resource = resources.remove(href);
if (resource == null) { if (resource == null) {
Log.e(TAG,"resource with href '" + href + "' not found"); Log.e(TAG, "resource with href '" + href + "' not found");
continue; continue;
} }
resource.setId(id); resource.setId(id);
//for epub3 //for epub3
String properties=DOMUtil.getAttribute(itemElement,NAMESPACE_OPF,OPFAttributes.properties); String properties = DOMUtil.getAttribute(itemElement, NAMESPACE_OPF, OPFAttributes.properties);
resource.setProperties(properties); resource.setProperties(properties);
MediaType mediaType = MediaTypes.getMediaTypeByName(mediaTypeName); MediaType mediaType = MediaTypes.getMediaTypeByName(mediaTypeName);
if (mediaType != null) { if (mediaType != null) {
resource.setMediaType(mediaType); resource.setMediaType(mediaType);
} }
result.add(resource); result.add(resource);
idMapping.put(id, resource.getId()); idMapping.put(id, resource.getId());
} }
return result; return result;
}
/**
* Reads the book's guide.
* Here some more attempts are made at finding the cover page.
*
* @param packageDocument r
* @param epubReader r
* @param book r
* @param resources g
*/
@SuppressWarnings("unused")
private static void readGuide(Document packageDocument,
EpubReader epubReader, EpubBook book, Resources resources) {
Element guideElement = DOMUtil
.getFirstElementByTagNameNS(packageDocument.getDocumentElement(),
NAMESPACE_OPF, OPFTags.guide);
if (guideElement == null) {
return;
}
Guide guide = book.getGuide();
NodeList guideReferences = guideElement
.getElementsByTagNameNS(NAMESPACE_OPF, OPFTags.reference);
for (int i = 0; i < guideReferences.getLength(); i++) {
Element referenceElement = (Element) guideReferences.item(i);
String resourceHref = DOMUtil
.getAttribute(referenceElement, NAMESPACE_OPF, OPFAttributes.href);
if (StringUtil.isBlank(resourceHref)) {
continue;
}
Resource resource = resources.getByHref(StringUtil
.substringBefore(resourceHref, Constants.FRAGMENT_SEPARATOR_CHAR));
if (resource == null) {
Log.e(TAG,"Guide is referencing resource with href " + resourceHref
+ " which could not be found");
continue;
}
String type = DOMUtil
.getAttribute(referenceElement, NAMESPACE_OPF, OPFAttributes.type);
if (StringUtil.isBlank(type)) {
Log.e(TAG,"Guide is referencing resource with href " + resourceHref
+ " which is missing the 'type' attribute");
continue;
}
String title = DOMUtil
.getAttribute(referenceElement, NAMESPACE_OPF, OPFAttributes.title);
if (GuideReference.COVER.equalsIgnoreCase(type)) {
continue; // cover is handled elsewhere
}
GuideReference reference = new GuideReference(resource, type, title,
StringUtil
.substringAfter(resourceHref, Constants.FRAGMENT_SEPARATOR_CHAR));
guide.addReference(reference);
}
}
/**
* Strips off the package prefixes up to the href of the packageHref.
*
* Example:
* If the packageHref is "OEBPS/content.opf" then a resource href like "OEBPS/foo/bar.html" will be turned into "foo/bar.html"
*
* @param packageHref f
* @param resourcesByHref g
* @return The stripped package href
*/
static Resources fixHrefs(String packageHref,
Resources resourcesByHref) {
int lastSlashPos = packageHref.lastIndexOf('/');
if (lastSlashPos < 0) {
return resourcesByHref;
}
Resources result = new Resources();
for (Resource resource : resourcesByHref.getAll()) {
if (StringUtil.isNotBlank(resource.getHref())
&& resource.getHref().length() > lastSlashPos) {
resource.setHref(resource.getHref().substring(lastSlashPos + 1));
}
result.add(resource);
}
return result;
}
/**
* Reads the document's spine, containing all sections in reading order.
*
* @param packageDocument b
* @param resources b
* @param idMapping b
* @return the document's spine, containing all sections in reading order.
*/
private static Spine readSpine(Document packageDocument, Resources resources,
Map<String, String> idMapping) {
Element spineElement = DOMUtil
.getFirstElementByTagNameNS(packageDocument.getDocumentElement(),
NAMESPACE_OPF, OPFTags.spine);
if (spineElement == null) {
Log.e(TAG,"Element " + OPFTags.spine
+ " not found in package document, generating one automatically");
return generateSpineFromResources(resources);
} }
Spine result = new Spine();
String tocResourceId = DOMUtil
.getAttribute(spineElement, NAMESPACE_OPF, OPFAttributes.toc); /**
result * Reads the book's guide.
.setTocResource(findTableOfContentsResource(tocResourceId, resources)); * Here some more attempts are made at finding the cover page.
NodeList spineNodes = packageDocument *
.getElementsByTagNameNS(NAMESPACE_OPF, OPFTags.itemref); * @param packageDocument r
List<SpineReference> spineReferences = new ArrayList<>( * @param epubReader r
spineNodes.getLength()); * @param book r
for (int i = 0; i < spineNodes.getLength(); i++) { * @param resources g
Element spineItem = (Element) spineNodes.item(i); */
String itemref = DOMUtil @SuppressWarnings("unused")
.getAttribute(spineItem, NAMESPACE_OPF, OPFAttributes.idref); private static void readGuide(Document packageDocument,
if (StringUtil.isBlank(itemref)) { EpubReader epubReader, EpubBook book, Resources resources) {
Log.e(TAG,"itemref with missing or empty idref"); // XXX Element guideElement = DOMUtil
continue; .getFirstElementByTagNameNS(packageDocument.getDocumentElement(),
} NAMESPACE_OPF, OPFTags.guide);
String id = idMapping.get(itemref); if (guideElement == null) {
if (id == null) { return;
id = itemref; }
} Guide guide = book.getGuide();
Resource resource = resources.getByIdOrHref(id); NodeList guideReferences = guideElement
if (resource == null) { .getElementsByTagNameNS(NAMESPACE_OPF, OPFTags.reference);
Log.e(TAG, "resource with id '" + id + "' not found"); for (int i = 0; i < guideReferences.getLength(); i++) {
continue; Element referenceElement = (Element) guideReferences.item(i);
} String resourceHref = DOMUtil
.getAttribute(referenceElement, NAMESPACE_OPF, OPFAttributes.href);
SpineReference spineReference = new SpineReference(resource); if (StringUtil.isBlank(resourceHref)) {
if (OPFValues.no.equalsIgnoreCase(DOMUtil continue;
.getAttribute(spineItem, NAMESPACE_OPF, OPFAttributes.linear))) { }
spineReference.setLinear(false); Resource resource = resources.getByHref(StringUtil
} .substringBefore(resourceHref, Constants.FRAGMENT_SEPARATOR_CHAR));
spineReferences.add(spineReference); if (resource == null) {
Log.e(TAG, "Guide is referencing resource with href " + resourceHref
+ " which could not be found");
continue;
}
String type = DOMUtil
.getAttribute(referenceElement, NAMESPACE_OPF, OPFAttributes.type);
if (StringUtil.isBlank(type)) {
Log.e(TAG, "Guide is referencing resource with href " + resourceHref
+ " which is missing the 'type' attribute");
continue;
}
String title = DOMUtil
.getAttribute(referenceElement, NAMESPACE_OPF, OPFAttributes.title);
if (GuideReference.COVER.equalsIgnoreCase(type)) {
continue; // cover is handled elsewhere
}
GuideReference reference = new GuideReference(resource, type, title,
StringUtil
.substringAfter(resourceHref, Constants.FRAGMENT_SEPARATOR_CHAR));
guide.addReference(reference);
}
} }
result.setSpineReferences(spineReferences);
return result;
} /**
* Strips off the package prefixes up to the href of the packageHref.
/** * <p>
* Creates a spine out of all resources in the resources. * Example:
* The generated spine consists of all XHTML pages in order of their href. * If the packageHref is "OEBPS/content.opf" then a resource href like "OEBPS/foo/bar.html" will be turned into "foo/bar.html"
* *
* @param resources f * @param packageHref f
* @return a spine created out of all resources in the resources. * @param resourcesByHref g
*/ * @return The stripped package href
private static Spine generateSpineFromResources(Resources resources) { */
Spine result = new Spine(); static Resources fixHrefs(String packageHref,
List<String> resourceHrefs = new ArrayList<>(resources.getAllHrefs()); Resources resourcesByHref) {
Collections.sort(resourceHrefs, String.CASE_INSENSITIVE_ORDER); int lastSlashPos = packageHref.lastIndexOf('/');
for (String resourceHref : resourceHrefs) { if (lastSlashPos < 0) {
Resource resource = resources.getByHref(resourceHref); return resourcesByHref;
if (resource.getMediaType() == MediaTypes.NCX) { }
result.setTocResource(resource); Resources result = new Resources();
} else if (resource.getMediaType() == MediaTypes.XHTML) { for (Resource resource : resourcesByHref.getAll()) {
result.addSpineReference(new SpineReference(resource)); if (StringUtil.isNotBlank(resource.getHref())
} && resource.getHref().length() > lastSlashPos) {
resource.setHref(resource.getHref().substring(lastSlashPos + 1));
}
result.add(resource);
}
return result;
} }
return result;
} /**
* Reads the document's spine, containing all sections in reading order.
*
/** * @param packageDocument b
* The spine tag should contain a 'toc' attribute with as value the resource id of the table of contents resource. * @param resources b
* * @param idMapping b
* Here we try several ways of finding this table of contents resource. * @return the document's spine, containing all sections in reading order.
* We try the given attribute value, some often-used ones and finally look through all resources for the first resource with the table of contents mimetype. */
* private static Spine readSpine(Document packageDocument, Resources resources,
* @param tocResourceId g Map<String, String> idMapping) {
* @param resources g
* @return the Resource containing the table of contents Element spineElement = DOMUtil
*/ .getFirstElementByTagNameNS(packageDocument.getDocumentElement(),
static Resource findTableOfContentsResource(String tocResourceId, NAMESPACE_OPF, OPFTags.spine);
Resources resources) { if (spineElement == null) {
Resource tocResource = null; Log.e(TAG, "Element " + OPFTags.spine
if (StringUtil.isNotBlank(tocResourceId)) { + " not found in package document, generating one automatically");
tocResource = resources.getByIdOrHref(tocResourceId); return generateSpineFromResources(resources);
}
Spine result = new Spine();
String tocResourceId = DOMUtil
.getAttribute(spineElement, NAMESPACE_OPF, OPFAttributes.toc);
result
.setTocResource(findTableOfContentsResource(tocResourceId, resources));
NodeList spineNodes = packageDocument
.getElementsByTagNameNS(NAMESPACE_OPF, OPFTags.itemref);
List<SpineReference> spineReferences = new ArrayList<>(
spineNodes.getLength());
for (int i = 0; i < spineNodes.getLength(); i++) {
Element spineItem = (Element) spineNodes.item(i);
String itemref = DOMUtil
.getAttribute(spineItem, NAMESPACE_OPF, OPFAttributes.idref);
if (StringUtil.isBlank(itemref)) {
Log.e(TAG, "itemref with missing or empty idref"); // XXX
continue;
}
String id = idMapping.get(itemref);
if (id == null) {
id = itemref;
}
Resource resource = resources.getByIdOrHref(id);
if (resource == null) {
Log.e(TAG, "resource with id '" + id + "' not found");
continue;
}
SpineReference spineReference = new SpineReference(resource);
if (OPFValues.no.equalsIgnoreCase(DOMUtil
.getAttribute(spineItem, NAMESPACE_OPF, OPFAttributes.linear))) {
spineReference.setLinear(false);
}
spineReferences.add(spineReference);
}
result.setSpineReferences(spineReferences);
return result;
} }
if (tocResource != null) { /**
return tocResource; * Creates a spine out of all resources in the resources.
* The generated spine consists of all XHTML pages in order of their href.
*
* @param resources f
* @return a spine created out of all resources in the resources.
*/
private static Spine generateSpineFromResources(Resources resources) {
Spine result = new Spine();
List<String> resourceHrefs = new ArrayList<>(resources.getAllHrefs());
Collections.sort(resourceHrefs, String.CASE_INSENSITIVE_ORDER);
for (String resourceHref : resourceHrefs) {
Resource resource = resources.getByHref(resourceHref);
if (resource.getMediaType() == MediaTypes.NCX) {
result.setTocResource(resource);
} else if (resource.getMediaType() == MediaTypes.XHTML) {
result.addSpineReference(new SpineReference(resource));
}
}
return result;
} }
// get the first resource with the NCX mediatype
tocResource = resources.findFirstResourceByMediaType(MediaTypes.NCX);
if (tocResource == null) { /**
for (String possibleNcxItemId : POSSIBLE_NCX_ITEM_IDS) { * The spine tag should contain a 'toc' attribute with as value the resource id of the table of contents resource.
tocResource = resources.getByIdOrHref(possibleNcxItemId); * <p>
* Here we try several ways of finding this table of contents resource.
* We try the given attribute value, some often-used ones and finally look through all resources for the first resource with the table of contents mimetype.
*
* @param tocResourceId g
* @param resources g
* @return the Resource containing the table of contents
*/
static Resource findTableOfContentsResource(String tocResourceId,
Resources resources) {
Resource tocResource;
//一些epub3的文件为了兼容epub2,保留的epub2的目录文件,这里优先选择epub3的xml目录
tocResource = resources.getByProperties("nav");
if (tocResource != null) { if (tocResource != null) {
break; return tocResource;
}
if (StringUtil.isNotBlank(tocResourceId)) {
tocResource = resources.getByIdOrHref(tocResourceId);
} }
tocResource = resources
.getByIdOrHref(possibleNcxItemId.toUpperCase());
if (tocResource != null) { if (tocResource != null) {
break; return tocResource;
} }
}
}
//For EPUB3
if (tocResource==null){
tocResource=resources.getByProperties("nav");
}
if (tocResource == null) { // get the first resource with the NCX mediatype
Log.e(TAG, tocResource = resources.findFirstResourceByMediaType(MediaTypes.NCX);
"Could not find table of contents resource. Tried resource with id '"
+ tocResourceId + "', " + Constants.DEFAULT_TOC_ID + ", " if (tocResource == null) {
+ Constants.DEFAULT_TOC_ID.toUpperCase() for (String possibleNcxItemId : POSSIBLE_NCX_ITEM_IDS) {
+ " and any NCX resource."); tocResource = resources.getByIdOrHref(possibleNcxItemId);
} if (tocResource != null) {
return tocResource; break;
} }
tocResource = resources
.getByIdOrHref(possibleNcxItemId.toUpperCase());
/** if (tocResource != null) {
* Find all resources that have something to do with the coverpage and the cover image. break;
* Search the meta tags and the guide references }
* }
* @param packageDocument s }
* @return all resources that have something to do with the coverpage and the cover image.
*/
// package if (tocResource == null) {
static Set<String> findCoverHrefs(Document packageDocument) { Log.e(TAG,
"Could not find table of contents resource. Tried resource with id '"
Set<String> result = new HashSet<>(); + tocResourceId + "', " + Constants.DEFAULT_TOC_ID + ", "
+ Constants.DEFAULT_TOC_ID.toUpperCase()
// try and find a meta tag with name = 'cover' and a non-blank id + " and any NCX resource.");
String coverResourceId = DOMUtil }
.getFindAttributeValue(packageDocument, NAMESPACE_OPF, return tocResource;
OPFTags.meta, OPFAttributes.name, OPFValues.meta_cover,
OPFAttributes.content);
if (StringUtil.isNotBlank(coverResourceId)) {
String coverHref = DOMUtil
.getFindAttributeValue(packageDocument, NAMESPACE_OPF,
OPFTags.item, OPFAttributes.id, coverResourceId,
OPFAttributes.href);
if (StringUtil.isNotBlank(coverHref)) {
result.add(coverHref);
} else {
result.add(
coverResourceId); // maybe there was a cover href put in the cover id attribute
}
} }
// try and find a reference tag with type is 'cover' and reference is not blank
String coverHref = DOMUtil
.getFindAttributeValue(packageDocument, NAMESPACE_OPF, /**
OPFTags.reference, OPFAttributes.type, OPFValues.reference_cover, * Find all resources that have something to do with the coverpage and the cover image.
OPFAttributes.href); * Search the meta tags and the guide references
if (StringUtil.isNotBlank(coverHref)) { *
result.add(coverHref); * @param packageDocument s
* @return all resources that have something to do with the coverpage and the cover image.
*/
// package
static Set<String> findCoverHrefs(Document packageDocument) {
Set<String> result = new HashSet<>();
// try and find a meta tag with name = 'cover' and a non-blank id
String coverResourceId = DOMUtil
.getFindAttributeValue(packageDocument, NAMESPACE_OPF,
OPFTags.meta, OPFAttributes.name, OPFValues.meta_cover,
OPFAttributes.content);
if (StringUtil.isNotBlank(coverResourceId)) {
String coverHref = DOMUtil
.getFindAttributeValue(packageDocument, NAMESPACE_OPF,
OPFTags.item, OPFAttributes.id, coverResourceId,
OPFAttributes.href);
if (StringUtil.isNotBlank(coverHref)) {
result.add(coverHref);
} else {
result.add(
coverResourceId); // maybe there was a cover href put in the cover id attribute
}
}
// try and find a reference tag with type is 'cover' and reference is not blank
String coverHref = DOMUtil
.getFindAttributeValue(packageDocument, NAMESPACE_OPF,
OPFTags.reference, OPFAttributes.type, OPFValues.reference_cover,
OPFAttributes.href);
if (StringUtil.isNotBlank(coverHref)) {
result.add(coverHref);
}
return result;
} }
return result;
}
/** /**
* Finds the cover resource in the packageDocument and adds it to the book if found. * Finds the cover resource in the packageDocument and adds it to the book if found.
@ -418,11 +420,11 @@ public class PackageDocumentReader extends PackageDocumentBase {
} }
if (resource.getMediaType() == MediaTypes.XHTML) { if (resource.getMediaType() == MediaTypes.XHTML) {
book.setCoverPage(resource); book.setCoverPage(resource);
} else if (MediaTypes.isBitmapImage(resource.getMediaType())) { } else if (MediaTypes.isBitmapImage(resource.getMediaType())) {
book.setCoverImage(resource); book.setCoverImage(resource);
} }
}
} }
}
} }

@ -1,5 +1,7 @@
package me.ag2s.epublib.util; package me.ag2s.epublib.util;
import android.util.Log;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.Closeable; import java.io.Closeable;
import java.io.EOFException; import java.io.EOFException;
@ -18,6 +20,7 @@ import java.nio.CharBuffer;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import me.ag2s.epublib.epub.PackageDocumentReader;
import me.ag2s.epublib.util.commons.io.IOConsumer; import me.ag2s.epublib.util.commons.io.IOConsumer;
/** /**
@ -28,6 +31,7 @@ import me.ag2s.epublib.util.commons.io.IOConsumer;
* and using my own implementation saves the inclusion of a 200Kb jar file. * and using my own implementation saves the inclusion of a 200Kb jar file.
*/ */
public class IOUtil { public class IOUtil {
private static final String TAG = IOUtil.class.getName();
/** /**
* Represents the end-of-file (or stream). * Represents the end-of-file (or stream).
@ -146,7 +150,8 @@ public class IOUtil {
if(buffer>IOUtil.DEFAULT_BUFFER_SIZE||buffer==0){ if(buffer>IOUtil.DEFAULT_BUFFER_SIZE||buffer==0){
buffer=IOUtil.DEFAULT_BUFFER_SIZE; buffer=IOUtil.DEFAULT_BUFFER_SIZE;
} }
copy(in, result,buffer); Log.d(TAG,"buffer size:"+buffer);
copy(in, result,DEFAULT_BUFFER_SIZE);
} }
/** /**

Loading…
Cancel
Save