diff --git a/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt b/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt index 8a809e701..2b50a9e61 100644 --- a/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt +++ b/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt @@ -62,19 +62,19 @@ class EpubFile(var book: Book) { } } - private var epubBook: EpubBook? = null private var mCharset: Charset = Charset.defaultCharset() + private var epubBook: EpubBook? = null + get() { + if (field != null) { + return field + } + field = readEpub() + return field + } init { try { - val inputStream = if (book.bookUrl.isContentScheme()) { - val uri = Uri.parse(book.bookUrl) - appCtx.contentResolver.openInputStream(uri) - } else { - File(book.bookUrl).inputStream() - } - epubBook = readEpub(inputStream) - if (epubBook != null) { + epubBook?.let { if (book.coverUrl.isNullOrEmpty()) { book.coverUrl = FileUtils.getPath( appCtx.externalFilesDir, @@ -84,8 +84,8 @@ class EpubFile(var book: Book) { } if (!File(book.coverUrl!!).exists()) { /*部分书籍DRM处理后,封面获取异常,待优化*/ - epubBook!!.coverImage?.inputStream?.use { - val cover = BitmapFactory.decodeStream(it) + it.coverImage?.inputStream?.use { input -> + val cover = BitmapFactory.decodeStream(input) val out = FileOutputStream(FileUtils.createFileIfNotExist(book.coverUrl!!)) cover.compress(Bitmap.CompressFormat.JPEG, 90, out) out.flush() @@ -99,9 +99,15 @@ class EpubFile(var book: Book) { } /*重写epub文件解析代码,直接读出压缩包文件生成Resources给epublib,这样的好处是可以逐一修改某些文件的格式错误*/ - private fun readEpub(input: InputStream?): EpubBook? { - if (input == null) return null + private fun readEpub(): EpubBook? { try { + val input = if (book.bookUrl.isContentScheme()) { + val uri = Uri.parse(book.bookUrl) + appCtx.contentResolver.openInputStream(uri) + } else { + File(book.bookUrl).inputStream() + } + input ?: return null val inZip = ZipInputStream(input) var zipEntry: ZipEntry? val resources = Resources() @@ -120,7 +126,7 @@ class EpubFile(var book: Book) { } resources.add(resource) } while (zipEntry != null) - if (resources.size() > 0) return EpubReader().readEpubBook(resources) + if (resources.size() > 0) return EpubReader().readEpub(resources) } catch (e: Exception) { e.printStackTrace() } @@ -129,9 +135,7 @@ class EpubFile(var book: Book) { private fun getContent(chapter: BookChapter): String? { /*获取当前章节文本*/ - val string = getChildChapter(chapter, chapter.url) - - return string + return getChildChapter(chapter, chapter.url) } private fun getChildChapter(chapter: BookChapter, href: String): String? { diff --git a/epublib/src/main/java/me/ag2s/epublib/browsersupport/NavigationEvent.java b/epublib/src/main/java/me/ag2s/epublib/browsersupport/NavigationEvent.java index 25d5fd46d..9b52e01cb 100644 --- a/epublib/src/main/java/me/ag2s/epublib/browsersupport/NavigationEvent.java +++ b/epublib/src/main/java/me/ag2s/epublib/browsersupport/NavigationEvent.java @@ -2,7 +2,7 @@ package me.ag2s.epublib.browsersupport; import java.util.EventObject; -import me.ag2s.epublib.domain.Book; +import me.ag2s.epublib.domain.EpubBook; import me.ag2s.epublib.domain.Resource; import me.ag2s.epublib.util.StringUtil; @@ -20,9 +20,9 @@ public class NavigationEvent extends EventObject { private Resource oldResource; private int oldSpinePos; - private Navigator navigator; - private Book oldBook; - private int oldSectionPos; + private Navigator navigator; + private EpubBook oldBook; + private int oldSectionPos; private String oldFragmentId; public NavigationEvent(Object source) { @@ -61,9 +61,9 @@ public class NavigationEvent extends EventObject { this.oldFragmentId = oldFragmentId; } - public Book getOldBook() { - return oldBook; - } + public EpubBook getOldBook() { + return oldBook; + } // package void setOldPagePos(int oldPagePos) { @@ -124,13 +124,13 @@ public class NavigationEvent extends EventObject { } - public void setOldBook(Book oldBook) { - this.oldBook = oldBook; - } + public void setOldBook(EpubBook oldBook) { + this.oldBook = oldBook; + } - public Book getCurrentBook() { - return getNavigator().getBook(); - } + public EpubBook getCurrentBook() { + return getNavigator().getBook(); + } public boolean isResourceChanged() { return oldResource != getCurrentResource(); diff --git a/epublib/src/main/java/me/ag2s/epublib/browsersupport/NavigationHistory.java b/epublib/src/main/java/me/ag2s/epublib/browsersupport/NavigationHistory.java index eec56dd6f..710f0240c 100644 --- a/epublib/src/main/java/me/ag2s/epublib/browsersupport/NavigationHistory.java +++ b/epublib/src/main/java/me/ag2s/epublib/browsersupport/NavigationHistory.java @@ -1,15 +1,15 @@ package me.ag2s.epublib.browsersupport; -import me.ag2s.epublib.domain.Book; -import me.ag2s.epublib.domain.Resource; import java.util.ArrayList; import java.util.List; +import me.ag2s.epublib.domain.EpubBook; +import me.ag2s.epublib.domain.Resource; + /** * A history of the user's locations with the epub. * * @author paul.siegmann - * */ public class NavigationHistory implements NavigationEventListener { @@ -58,7 +58,7 @@ public class NavigationHistory implements NavigationEventListener { return currentSize; } - public void initBook(Book book) { + public void initBook(EpubBook book) { if (book == null) { return; } diff --git a/epublib/src/main/java/me/ag2s/epublib/browsersupport/Navigator.java b/epublib/src/main/java/me/ag2s/epublib/browsersupport/Navigator.java index e73fbe166..84319e65e 100644 --- a/epublib/src/main/java/me/ag2s/epublib/browsersupport/Navigator.java +++ b/epublib/src/main/java/me/ag2s/epublib/browsersupport/Navigator.java @@ -1,14 +1,15 @@ package me.ag2s.epublib.browsersupport; -import me.ag2s.epublib.domain.Book; -import me.ag2s.epublib.domain.Resource; import java.io.Serializable; import java.util.ArrayList; import java.util.List; +import me.ag2s.epublib.domain.EpubBook; +import me.ag2s.epublib.domain.Resource; + /** * A helper class for epub browser applications. - * + *
* It helps moving from one resource to the other, from one resource * to the other and keeping other elements of the application up-to-date * by calling the NavigationEventListeners. @@ -18,7 +19,7 @@ import java.util.List; public class Navigator implements Serializable { private static final long serialVersionUID = 1076126986424925474L; - private Book book; + private EpubBook book; private int currentSpinePos; private Resource currentResource; private int currentPagePos; @@ -30,7 +31,7 @@ public class Navigator implements Serializable { this(null); } - public Navigator(Book book) { + public Navigator(EpubBook book) { this.book = book; this.currentSpinePos = 0; if (book != null) { @@ -158,7 +159,7 @@ public class Navigator implements Serializable { return gotoSpineSection(book.getSpine().size() - 1, source); } - public void gotoBook(Book book, Object source) { + public void gotoBook(EpubBook book, Object source) { NavigationEvent navigationEvent = new NavigationEvent(source, this); this.book = book; this.currentFragmentId = null; @@ -193,7 +194,7 @@ public class Navigator implements Serializable { this.currentResource = book.getSpine().getResource(currentIndex); } - public Book getBook() { + public EpubBook getBook() { return book; } diff --git a/epublib/src/main/java/me/ag2s/epublib/domain/Book.java b/epublib/src/main/java/me/ag2s/epublib/domain/Book.java deleted file mode 100644 index 24e79be79..000000000 --- a/epublib/src/main/java/me/ag2s/epublib/domain/Book.java +++ /dev/null @@ -1,323 +0,0 @@ -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. - *
- * All resources of a Book (html, css, xml, fonts, images) are represented
- * as Resources. See getResources() for access to these.
- * A Book as 3 indexes into these Resources, as per the epub specification.
- *
- * The Content page may be in the Table of Contents, the Guide, but not - * in the Spine. - * Etc. - *
- *- * 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. - *
- * Consists of a list of "reachable" resources: - *
+ * All resources of a Book (html, css, xml, fonts, images) are represented
+ * as Resources. See getResources() for access to these.
+ * A Book as 3 indexes into these Resources, as per the epub specification.
+ *
+ * The Content page may be in the Table of Contents, the Guide, but not + * in the Spine. + * Etc. + *
+ *+ * Please see the illustration at: doc/schema.svg + * + * @author paul + * @author jake */ -@SuppressWarnings("unused declaration") -public class EpubBook extends Book { +public class EpubBook 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. + *
+ * Consists of a list of "reachable" resources: + *
* Fixes coverpage/coverimage.
* Cleans up the XHTML.
*
@@ -30,7 +31,7 @@ public class BookProcessorPipeline implements BookProcessor {
}
@Override
- public Book processBook(Book book) {
+ public EpubBook processBook(EpubBook book) {
if (bookProcessors == null) {
return book;
}
@@ -38,7 +39,7 @@ public class BookProcessorPipeline implements BookProcessor {
try {
book = bookProcessor.processBook(book);
} catch (Exception e) {
- Log.e(TAG,e.getMessage(), e);
+ Log.e(TAG, e.getMessage(), e);
}
}
return book;
diff --git a/epublib/src/main/java/me/ag2s/epublib/epub/EpubReader.java b/epublib/src/main/java/me/ag2s/epublib/epub/EpubReader.java
index 361fe8527..78fd6ab94 100644
--- a/epublib/src/main/java/me/ag2s/epublib/epub/EpubReader.java
+++ b/epublib/src/main/java/me/ag2s/epublib/epub/EpubReader.java
@@ -13,7 +13,6 @@ import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import me.ag2s.epublib.Constants;
-import me.ag2s.epublib.domain.Book;
import me.ag2s.epublib.domain.EpubBook;
import me.ag2s.epublib.domain.MediaType;
import me.ag2s.epublib.domain.MediaTypes;
@@ -27,22 +26,21 @@ import me.ag2s.epublib.util.StringUtil;
*
* @author paul
*/
+@SuppressWarnings("ALL")
public class EpubReader {
private static final String TAG = EpubReader.class.getName();
private final BookProcessor bookProcessor = BookProcessor.IDENTITY_BOOKPROCESSOR;
- @SuppressWarnings("unused")
- public Book readEpub(InputStream in) throws IOException {
+
+ public EpubBook readEpub(InputStream in) throws IOException {
return readEpub(in, Constants.CHARACTER_ENCODING);
}
- @SuppressWarnings("unused")
- public Book readEpub(ZipInputStream in) throws IOException {
+ public EpubBook readEpub(ZipInputStream in) throws IOException {
return readEpub(in, Constants.CHARACTER_ENCODING);
}
- @SuppressWarnings("unused")
- public Book readEpub(ZipFile zipfile) throws IOException {
+ public EpubBook readEpub(ZipFile zipfile) throws IOException {
return readEpub(zipfile, Constants.CHARACTER_ENCODING);
}
@@ -54,7 +52,7 @@ public class EpubReader {
* @return the Book as read from the inputstream
* @throws IOException IOException
*/
- public Book readEpub(InputStream in, String encoding) throws IOException {
+ public EpubBook readEpub(InputStream in, String encoding) throws IOException {
return readEpub(new ZipInputStream(in), encoding);
}
@@ -67,18 +65,17 @@ public class EpubReader {
* @return this Book without loading all resources into memory.
* @throws IOException IOException
*/
- @SuppressWarnings("unused")
- public Book readEpubLazy(ZipFile zipFile, String encoding)
+ public EpubBook readEpubLazy(ZipFile zipFile, String encoding)
throws IOException {
return readEpubLazy(zipFile, encoding,
Arrays.asList(MediaTypes.mediaTypes));
}
- public Book readEpub(ZipInputStream in, String encoding) throws IOException {
+ public EpubBook readEpub(ZipInputStream in, String encoding) throws IOException {
return readEpub(ResourcesLoader.loadResources(in, encoding));
}
- public Book readEpub(ZipFile in, String encoding) throws IOException {
+ public EpubBook readEpub(ZipFile in, String encoding) throws IOException {
return readEpub(ResourcesLoader.loadResources(in, encoding));
}
@@ -91,24 +88,20 @@ public class EpubReader {
* @return this Book without loading all resources into memory.
* @throws IOException IOException
*/
- public Book readEpubLazy(ZipFile zipFile, String encoding,
- List