diff --git a/epublib/src/main/java/me/ag2s/epublib/epub/NCXDocumentV2.java b/epublib/src/main/java/me/ag2s/epublib/epub/NCXDocumentV2.java index 572f7f97b..2bf47de51 100644 --- a/epublib/src/main/java/me/ag2s/epublib/epub/NCXDocumentV2.java +++ b/epublib/src/main/java/me/ag2s/epublib/epub/NCXDocumentV2.java @@ -148,9 +148,9 @@ public class NCXDocumentV2 { if (resource == null) { Log.e(TAG, "Resource with href " + href + " in NCX document not found"); } - Log.d(TAG, "label:" + label); - Log.d(TAG, "href:" + href); - Log.d(TAG, "fragmentId:" + fragmentId); + Log.v(TAG, "label:" + label); + Log.v(TAG, "href:" + href); + Log.v(TAG, "fragmentId:" + fragmentId); TOCReference result = new TOCReference(label, resource, fragmentId); List childTOCReferences = readTOCReferences( navpointElement.getChildNodes(), book); diff --git a/epublib/src/main/java/me/ag2s/epublib/epub/NCXDocumentV3.java b/epublib/src/main/java/me/ag2s/epublib/epub/NCXDocumentV3.java index a538a43f2..845b999d1 100644 --- a/epublib/src/main/java/me/ag2s/epublib/epub/NCXDocumentV3.java +++ b/epublib/src/main/java/me/ag2s/epublib/epub/NCXDocumentV3.java @@ -107,12 +107,21 @@ public class NCXDocumentV3 { if (ncxResource == 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); - //Log.d(TAG, ncxDocument.getNodeName()); + Log.d(TAG, ncxDocument.getNodeName()); 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); Log.d(TAG, navMapElement.getTagName()); diff --git a/epublib/src/main/java/me/ag2s/epublib/epub/PackageDocumentReader.java b/epublib/src/main/java/me/ag2s/epublib/epub/PackageDocumentReader.java index 0b0c83848..5cf8adf1a 100644 --- a/epublib/src/main/java/me/ag2s/epublib/epub/PackageDocumentReader.java +++ b/epublib/src/main/java/me/ag2s/epublib/epub/PackageDocumentReader.java @@ -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 * * @author paul - * */ public class PackageDocumentReader extends PackageDocumentBase { - private static final String TAG= PackageDocumentReader.class.getName(); - private static final String[] POSSIBLE_NCX_ITEM_IDS = new String[]{"toc", - "ncx", "ncxtoc","htmltoc"}; - - - public static void read( - Resource packageResource, EpubReader epubReader, EpubBook book, - Resources resources) - throws SAXException, IOException { - Document packageDocument = ResourceUtil.getAsDocument(packageResource); - String packageHref = packageResource.getHref(); - resources = fixHrefs(packageHref, resources); - readGuide(packageDocument, epubReader, book, resources); - - // Books sometimes use non-identifier ids. We map these here to legal ones - Map idMapping = new HashMap<>(); - String version=DOMUtil.getAttribute(packageDocument.getDocumentElement(),PREFIX_OPF,PackageDocumentBase.version); - - resources = readManifest(packageDocument, packageHref, epubReader, - resources, idMapping); - book.setResources(resources); - book.setVersion(version); - readCover(packageDocument, book); - book.setMetadata( - PackageDocumentMetadataReader.readMetadata(packageDocument)); - 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 (book.getCoverPage() == null && book.getSpine().size() > 0) { - book.setCoverPage(book.getSpine().getResource(0)); + private static final String TAG = PackageDocumentReader.class.getName(); + private static final String[] POSSIBLE_NCX_ITEM_IDS = new String[]{"toc", + "ncx", "ncxtoc", "htmltoc"}; + + + public static void read( + Resource packageResource, EpubReader epubReader, EpubBook book, + Resources resources) + throws SAXException, IOException { + Document packageDocument = ResourceUtil.getAsDocument(packageResource); + String packageHref = packageResource.getHref(); + resources = fixHrefs(packageHref, resources); + readGuide(packageDocument, epubReader, book, resources); + + // Books sometimes use non-identifier ids. We map these here to legal ones + Map idMapping = new HashMap<>(); + String version = DOMUtil.getAttribute(packageDocument.getDocumentElement(), PREFIX_OPF, PackageDocumentBase.version); + + resources = readManifest(packageDocument, packageHref, epubReader, + resources, idMapping); + book.setResources(resources); + book.setVersion(version); + readCover(packageDocument, book); + book.setMetadata( + PackageDocumentMetadataReader.readMetadata(packageDocument)); + 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 (book.getCoverPage() == null && book.getSpine().size() > 0) { + book.setCoverPage(book.getSpine().getResource(0)); + } } - } // 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); @@ -83,322 +82,325 @@ public class PackageDocumentReader extends PackageDocumentBase { // } - /** - * Reads the manifest containing the resource ids, hrefs and mediatypes. - * - * @param packageDocument e - * @param packageHref e - * @param epubReader e - * @param resources e - * @param idMapping e - * @return a Map with resources, with their id's as key. - */ - @SuppressWarnings("unused") - private static Resources readManifest(Document packageDocument, - String packageHref, - EpubReader epubReader, Resources resources, - Map idMapping) { - Element manifestElement = DOMUtil - .getFirstElementByTagNameNS(packageDocument.getDocumentElement(), - NAMESPACE_OPF, OPFTags.manifest); - Resources result = new Resources(); - if (manifestElement == null) { - Log.e(TAG, - "Package document does not contain element " + OPFTags.manifest); - return result; - } - NodeList itemElements = manifestElement - .getElementsByTagNameNS(NAMESPACE_OPF, OPFTags.item); - for (int i = 0; i < itemElements.getLength(); i++) { - Element itemElement = (Element) itemElements.item(i); - String id = DOMUtil - .getAttribute(itemElement, NAMESPACE_OPF, OPFAttributes.id); - String href = DOMUtil - .getAttribute(itemElement, NAMESPACE_OPF, OPFAttributes.href); - - try { - href = URLDecoder.decode(href, Constants.CHARACTER_ENCODING); - } catch (UnsupportedEncodingException e) { - Log.e(TAG,e.getMessage()); - } - String mediaTypeName = DOMUtil - .getAttribute(itemElement, NAMESPACE_OPF, OPFAttributes.media_type); - Resource resource = resources.remove(href); - if (resource == null) { - Log.e(TAG,"resource with href '" + href + "' not found"); - continue; - } - resource.setId(id); - //for epub3 - String properties=DOMUtil.getAttribute(itemElement,NAMESPACE_OPF,OPFAttributes.properties); - resource.setProperties(properties); - - MediaType mediaType = MediaTypes.getMediaTypeByName(mediaTypeName); - if (mediaType != null) { - resource.setMediaType(mediaType); - } - result.add(resource); - idMapping.put(id, resource.getId()); - } - 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 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); + /** + * Reads the manifest containing the resource ids, hrefs and mediatypes. + * + * @param packageDocument e + * @param packageHref e + * @param epubReader e + * @param resources e + * @param idMapping e + * @return a Map with resources, with their id's as key. + */ + @SuppressWarnings("unused") + private static Resources readManifest(Document packageDocument, + String packageHref, + EpubReader epubReader, Resources resources, + Map idMapping) { + Element manifestElement = DOMUtil + .getFirstElementByTagNameNS(packageDocument.getDocumentElement(), + NAMESPACE_OPF, OPFTags.manifest); + Resources result = new Resources(); + if (manifestElement == null) { + Log.e(TAG, + "Package document does not contain element " + OPFTags.manifest); + return result; + } + NodeList itemElements = manifestElement + .getElementsByTagNameNS(NAMESPACE_OPF, OPFTags.item); + for (int i = 0; i < itemElements.getLength(); i++) { + Element itemElement = (Element) itemElements.item(i); + String id = DOMUtil + .getAttribute(itemElement, NAMESPACE_OPF, OPFAttributes.id); + String href = DOMUtil + .getAttribute(itemElement, NAMESPACE_OPF, OPFAttributes.href); + + try { + href = URLDecoder.decode(href, Constants.CHARACTER_ENCODING); + } catch (UnsupportedEncodingException e) { + Log.e(TAG, e.getMessage()); + } + String mediaTypeName = DOMUtil + .getAttribute(itemElement, NAMESPACE_OPF, OPFAttributes.media_type); + Resource resource = resources.remove(href); + if (resource == null) { + Log.e(TAG, "resource with href '" + href + "' not found"); + continue; + } + resource.setId(id); + //for epub3 + String properties = DOMUtil.getAttribute(itemElement, NAMESPACE_OPF, OPFAttributes.properties); + resource.setProperties(properties); + + MediaType mediaType = MediaTypes.getMediaTypeByName(mediaTypeName); + if (mediaType != null) { + resource.setMediaType(mediaType); + } + result.add(resource); + idMapping.put(id, resource.getId()); + } + return result; } - 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 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); + + + /** + * 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); + } } - result.setSpineReferences(spineReferences); - return result; - } - - /** - * 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 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)); - } + + + /** + * 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; } - return result; - } - - - /** - * The spine tag should contain a 'toc' attribute with as value the resource id of the table of contents resource. - * - * 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 = null; - if (StringUtil.isNotBlank(tocResourceId)) { - tocResource = resources.getByIdOrHref(tocResourceId); + + /** + * 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 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 + .setTocResource(findTableOfContentsResource(tocResourceId, resources)); + NodeList spineNodes = packageDocument + .getElementsByTagNameNS(NAMESPACE_OPF, OPFTags.itemref); + List 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 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) { - tocResource = resources.getByIdOrHref(possibleNcxItemId); + /** + * The spine tag should contain a 'toc' attribute with as value the resource id of the table of contents resource. + *

+ * 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) { - break; + return tocResource; + } + + if (StringUtil.isNotBlank(tocResourceId)) { + tocResource = resources.getByIdOrHref(tocResourceId); } - tocResource = resources - .getByIdOrHref(possibleNcxItemId.toUpperCase()); + if (tocResource != null) { - break; + return tocResource; } - } - } - //For EPUB3 - if (tocResource==null){ - tocResource=resources.getByProperties("nav"); - } - if (tocResource == null) { - Log.e(TAG, - "Could not find table of contents resource. Tried resource with id '" - + tocResourceId + "', " + Constants.DEFAULT_TOC_ID + ", " - + Constants.DEFAULT_TOC_ID.toUpperCase() - + " and any NCX resource."); - } - return tocResource; - } - - - /** - * Find all resources that have something to do with the coverpage and the cover image. - * 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 - static Set findCoverHrefs(Document packageDocument) { - - Set 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 - } + // get the first resource with the NCX mediatype + tocResource = resources.findFirstResourceByMediaType(MediaTypes.NCX); + + if (tocResource == null) { + for (String possibleNcxItemId : POSSIBLE_NCX_ITEM_IDS) { + tocResource = resources.getByIdOrHref(possibleNcxItemId); + if (tocResource != null) { + break; + } + tocResource = resources + .getByIdOrHref(possibleNcxItemId.toUpperCase()); + if (tocResource != null) { + break; + } + } + } + + + if (tocResource == null) { + Log.e(TAG, + "Could not find table of contents resource. Tried resource with id '" + + tocResourceId + "', " + Constants.DEFAULT_TOC_ID + ", " + + Constants.DEFAULT_TOC_ID.toUpperCase() + + " and any NCX resource."); + } + return tocResource; } - // 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); + + + /** + * Find all resources that have something to do with the coverpage and the cover image. + * 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 + static Set findCoverHrefs(Document packageDocument) { + + Set 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. @@ -418,11 +420,11 @@ public class PackageDocumentReader extends PackageDocumentBase { } if (resource.getMediaType() == MediaTypes.XHTML) { book.setCoverPage(resource); - } else if (MediaTypes.isBitmapImage(resource.getMediaType())) { - book.setCoverImage(resource); - } + } else if (MediaTypes.isBitmapImage(resource.getMediaType())) { + book.setCoverImage(resource); + } + } } - } } diff --git a/epublib/src/main/java/me/ag2s/epublib/util/IOUtil.java b/epublib/src/main/java/me/ag2s/epublib/util/IOUtil.java index c5d57d64f..7d01e37db 100644 --- a/epublib/src/main/java/me/ag2s/epublib/util/IOUtil.java +++ b/epublib/src/main/java/me/ag2s/epublib/util/IOUtil.java @@ -1,5 +1,7 @@ package me.ag2s.epublib.util; +import android.util.Log; + import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.EOFException; @@ -18,6 +20,7 @@ import java.nio.CharBuffer; import java.nio.channels.ReadableByteChannel; import java.nio.charset.Charset; +import me.ag2s.epublib.epub.PackageDocumentReader; 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. */ public class IOUtil { + private static final String TAG = IOUtil.class.getName(); /** * Represents the end-of-file (or stream). @@ -146,7 +150,8 @@ public class IOUtil { if(buffer>IOUtil.DEFAULT_BUFFER_SIZE||buffer==0){ buffer=IOUtil.DEFAULT_BUFFER_SIZE; } - copy(in, result,buffer); + Log.d(TAG,"buffer size:"+buffer); + copy(in, result,DEFAULT_BUFFER_SIZE); } /**