mirror of
https://github.com/geometer/FBReaderJ.git
synced 2025-10-05 02:39:23 +02:00
introduced AbstractBook (base class)
This commit is contained in:
parent
79a3d88952
commit
879ac50fa4
12 changed files with 677 additions and 640 deletions
|
@ -49,6 +49,7 @@ JavaClass AndroidUtil::Class_JavaEncodingCollection("org/geometerplus/zlibrary/c
|
||||||
JavaClass AndroidUtil::Class_NativeFormatPlugin("org/geometerplus/fbreader/formats/NativeFormatPlugin");
|
JavaClass AndroidUtil::Class_NativeFormatPlugin("org/geometerplus/fbreader/formats/NativeFormatPlugin");
|
||||||
JavaClass AndroidUtil::Class_PluginCollection("org/geometerplus/fbreader/formats/PluginCollection");
|
JavaClass AndroidUtil::Class_PluginCollection("org/geometerplus/fbreader/formats/PluginCollection");
|
||||||
JavaClass AndroidUtil::Class_Paths("org/geometerplus/fbreader/Paths");
|
JavaClass AndroidUtil::Class_Paths("org/geometerplus/fbreader/Paths");
|
||||||
|
JavaClass AndroidUtil::Class_AbstractBook("org/geometerplus/fbreader/book/AbstractBook");
|
||||||
JavaClass AndroidUtil::Class_Book("org/geometerplus/fbreader/book/Book");
|
JavaClass AndroidUtil::Class_Book("org/geometerplus/fbreader/book/Book");
|
||||||
JavaClass AndroidUtil::Class_Tag("org/geometerplus/fbreader/book/Tag");
|
JavaClass AndroidUtil::Class_Tag("org/geometerplus/fbreader/book/Tag");
|
||||||
JavaClass AndroidUtil::Class_BookModel("org/geometerplus/fbreader/bookmodel/BookModel");
|
JavaClass AndroidUtil::Class_BookModel("org/geometerplus/fbreader/bookmodel/BookModel");
|
||||||
|
@ -186,17 +187,17 @@ bool AndroidUtil::init(JavaVM* jvm) {
|
||||||
|
|
||||||
StaticMethod_Paths_tempDirectory = new StaticObjectMethod(Class_Paths, "tempDirectory", Class_java_lang_String, "()");
|
StaticMethod_Paths_tempDirectory = new StaticObjectMethod(Class_Paths, "tempDirectory", Class_java_lang_String, "()");
|
||||||
|
|
||||||
Field_Book_File = new ObjectField(Class_Book, "File", Class_ZLFile);
|
Field_Book_File = new ObjectField(Class_AbstractBook, "File", Class_ZLFile);
|
||||||
Method_Book_getTitle = new StringMethod(Class_Book, "getTitle", "()");
|
Method_Book_getTitle = new StringMethod(Class_AbstractBook, "getTitle", "()");
|
||||||
Method_Book_getLanguage = new StringMethod(Class_Book, "getLanguage", "()");
|
Method_Book_getLanguage = new StringMethod(Class_AbstractBook, "getLanguage", "()");
|
||||||
Method_Book_getEncodingNoDetection = new StringMethod(Class_Book, "getEncodingNoDetection", "()");
|
Method_Book_getEncodingNoDetection = new StringMethod(Class_AbstractBook, "getEncodingNoDetection", "()");
|
||||||
Method_Book_setTitle = new VoidMethod(Class_Book, "setTitle", "(Ljava/lang/String;)");
|
Method_Book_setTitle = new VoidMethod(Class_AbstractBook, "setTitle", "(Ljava/lang/String;)");
|
||||||
Method_Book_setSeriesInfo = new VoidMethod(Class_Book, "setSeriesInfo", "(Ljava/lang/String;Ljava/lang/String;)");
|
Method_Book_setSeriesInfo = new VoidMethod(Class_AbstractBook, "setSeriesInfo", "(Ljava/lang/String;Ljava/lang/String;)");
|
||||||
Method_Book_setLanguage = new VoidMethod(Class_Book, "setLanguage", "(Ljava/lang/String;)");
|
Method_Book_setLanguage = new VoidMethod(Class_AbstractBook, "setLanguage", "(Ljava/lang/String;)");
|
||||||
Method_Book_setEncoding = new VoidMethod(Class_Book, "setEncoding", "(Ljava/lang/String;)");
|
Method_Book_setEncoding = new VoidMethod(Class_AbstractBook, "setEncoding", "(Ljava/lang/String;)");
|
||||||
Method_Book_addAuthor = new VoidMethod(Class_Book, "addAuthor", "(Ljava/lang/String;Ljava/lang/String;)");
|
Method_Book_addAuthor = new VoidMethod(Class_AbstractBook, "addAuthor", "(Ljava/lang/String;Ljava/lang/String;)");
|
||||||
Method_Book_addTag = new VoidMethod(Class_Book, "addTag", "(Lorg/geometerplus/fbreader/book/Tag;)");
|
Method_Book_addTag = new VoidMethod(Class_AbstractBook, "addTag", "(Lorg/geometerplus/fbreader/book/Tag;)");
|
||||||
Method_Book_addUid = new VoidMethod(Class_Book, "addUid", "(Ljava/lang/String;Ljava/lang/String;)");
|
Method_Book_addUid = new VoidMethod(Class_AbstractBook, "addUid", "(Ljava/lang/String;Ljava/lang/String;)");
|
||||||
|
|
||||||
StaticMethod_Tag_getTag = new StaticObjectMethod(Class_Tag, "getTag", Class_Tag, "(Lorg/geometerplus/fbreader/book/Tag;Ljava/lang/String;)");
|
StaticMethod_Tag_getTag = new StaticObjectMethod(Class_Tag, "getTag", Class_Tag, "(Lorg/geometerplus/fbreader/book/Tag;Ljava/lang/String;)");
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ public:
|
||||||
static JavaClass Class_EncodingConverter;
|
static JavaClass Class_EncodingConverter;
|
||||||
static JavaClass Class_JavaEncodingCollection;
|
static JavaClass Class_JavaEncodingCollection;
|
||||||
static JavaClass Class_Paths;
|
static JavaClass Class_Paths;
|
||||||
|
static JavaClass Class_AbstractBook;
|
||||||
static JavaClass Class_Book;
|
static JavaClass Class_Book;
|
||||||
static JavaClass Class_Tag;
|
static JavaClass Class_Tag;
|
||||||
static JavaClass Class_BookModel;
|
static JavaClass Class_BookModel;
|
||||||
|
|
633
src/org/geometerplus/fbreader/book/AbstractBook.java
Normal file
633
src/org/geometerplus/fbreader/book/AbstractBook.java
Normal file
|
@ -0,0 +1,633 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2007-2015 FBReader.ORG Limited <contact@fbreader.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geometerplus.fbreader.book;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import org.geometerplus.zlibrary.core.filesystem.*;
|
||||||
|
import org.geometerplus.zlibrary.core.util.MiscUtil;
|
||||||
|
import org.geometerplus.zlibrary.core.util.RationalNumber;
|
||||||
|
|
||||||
|
import org.geometerplus.fbreader.bookmodel.BookReadingException;
|
||||||
|
import org.geometerplus.fbreader.formats.PluginCollection;
|
||||||
|
import org.geometerplus.fbreader.formats.FormatPlugin;
|
||||||
|
import org.geometerplus.fbreader.sort.TitledEntity;
|
||||||
|
|
||||||
|
public class AbstractBook extends TitledEntity<AbstractBook> {
|
||||||
|
public static final String FAVORITE_LABEL = "favorite";
|
||||||
|
public static final String READ_LABEL = "read";
|
||||||
|
public static final String SYNCHRONISED_LABEL = "sync-success";
|
||||||
|
public static final String SYNC_FAILURE_LABEL = "sync-failure";
|
||||||
|
public static final String SYNC_DELETED_LABEL = "sync-deleted";
|
||||||
|
public static final String SYNC_TOSYNC_LABEL = "sync-tosync";
|
||||||
|
|
||||||
|
public final ZLFile File;
|
||||||
|
|
||||||
|
private volatile long myId;
|
||||||
|
|
||||||
|
private volatile String myEncoding;
|
||||||
|
private volatile String myLanguage;
|
||||||
|
private volatile List<Author> myAuthors;
|
||||||
|
private volatile List<Tag> myTags;
|
||||||
|
private volatile List<String> myLabels;
|
||||||
|
private volatile SeriesInfo mySeriesInfo;
|
||||||
|
private volatile List<UID> myUids;
|
||||||
|
private volatile RationalNumber myProgress;
|
||||||
|
|
||||||
|
public volatile boolean HasBookmark;
|
||||||
|
|
||||||
|
private volatile boolean myIsSaved;
|
||||||
|
|
||||||
|
AbstractBook(long id, ZLFile file, String title, String encoding, String language) {
|
||||||
|
super(title);
|
||||||
|
if (file == null) {
|
||||||
|
throw new IllegalArgumentException("Creating book with no file");
|
||||||
|
}
|
||||||
|
myId = id;
|
||||||
|
File = file;
|
||||||
|
myEncoding = encoding;
|
||||||
|
myLanguage = language;
|
||||||
|
myIsSaved = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractBook(ZLFile file, FormatPlugin plugin) throws BookReadingException {
|
||||||
|
super(null);
|
||||||
|
if (file == null) {
|
||||||
|
throw new IllegalArgumentException("Creating book with no file");
|
||||||
|
}
|
||||||
|
myId = -1;
|
||||||
|
File = plugin.realBookFile(file);
|
||||||
|
readMetainfo(plugin);
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean hasSameMetainfoAs(AbstractBook other) {
|
||||||
|
return
|
||||||
|
MiscUtil.equals(getTitle(), other.getTitle()) &&
|
||||||
|
MiscUtil.equals(myEncoding, other.myEncoding) &&
|
||||||
|
MiscUtil.equals(myLanguage, other.myLanguage) &&
|
||||||
|
MiscUtil.equals(myAuthors, other.myAuthors) &&
|
||||||
|
MiscUtil.listsEquals(myTags, other.myTags) &&
|
||||||
|
MiscUtil.equals(mySeriesInfo, other.mySeriesInfo) &&
|
||||||
|
MiscUtil.equals(myUids, other.myUids);
|
||||||
|
}
|
||||||
|
|
||||||
|
void merge(AbstractBook other, AbstractBook base) {
|
||||||
|
if (!MiscUtil.equals(getTitle(), other.getTitle()) &&
|
||||||
|
MiscUtil.equals(getTitle(), base.getTitle())) {
|
||||||
|
setTitle(other.getTitle());
|
||||||
|
}
|
||||||
|
if (!MiscUtil.equals(myEncoding, other.myEncoding) &&
|
||||||
|
MiscUtil.equals(myEncoding, base.myEncoding)) {
|
||||||
|
setEncoding(other.myEncoding);
|
||||||
|
}
|
||||||
|
if (!MiscUtil.equals(myLanguage, other.myLanguage) &&
|
||||||
|
MiscUtil.equals(myLanguage, base.myLanguage)) {
|
||||||
|
setLanguage(other.myLanguage);
|
||||||
|
}
|
||||||
|
if (!MiscUtil.listsEquals(myTags, other.myTags) &&
|
||||||
|
MiscUtil.listsEquals(myTags, base.myTags)) {
|
||||||
|
myTags = other.myTags != null ? new ArrayList<Tag>(other.myTags) : null;
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
if (!MiscUtil.equals(mySeriesInfo, other.mySeriesInfo) &&
|
||||||
|
MiscUtil.equals(mySeriesInfo, base.mySeriesInfo)) {
|
||||||
|
mySeriesInfo = other.mySeriesInfo;
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
if (!MiscUtil.listsEquals(myUids, other.myUids) &&
|
||||||
|
MiscUtil.listsEquals(myUids, base.myUids)) {
|
||||||
|
myUids = other.myUids != null ? new ArrayList<UID>(other.myUids) : null;
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateFrom(AbstractBook book) {
|
||||||
|
if (book == null || myId != book.myId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setTitle(book.getTitle());
|
||||||
|
setEncoding(book.myEncoding);
|
||||||
|
setLanguage(book.myLanguage);
|
||||||
|
if (!MiscUtil.equals(myAuthors, book.myAuthors)) {
|
||||||
|
myAuthors = book.myAuthors != null ? new ArrayList<Author>(book.myAuthors) : null;
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
if (!MiscUtil.equals(myTags, book.myTags)) {
|
||||||
|
myTags = book.myTags != null ? new ArrayList<Tag>(book.myTags) : null;
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
if (!MiscUtil.listsEquals(myLabels, book.myLabels)) {
|
||||||
|
myLabels = book.myLabels != null ? new ArrayList<String>(book.myLabels) : null;
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
if (!MiscUtil.equals(mySeriesInfo, book.mySeriesInfo)) {
|
||||||
|
mySeriesInfo = book.mySeriesInfo;
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
if (!MiscUtil.listsEquals(myUids, book.myUids)) {
|
||||||
|
myUids = book.myUids != null ? new ArrayList<UID>(book.myUids) : null;
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
setProgress(book.myProgress);
|
||||||
|
if (HasBookmark != book.HasBookmark) {
|
||||||
|
HasBookmark = book.HasBookmark;
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reloadInfoFromFile() {
|
||||||
|
try {
|
||||||
|
readMetainfo(getPlugin());
|
||||||
|
} catch (BookReadingException e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public FormatPlugin getPlugin() throws BookReadingException {
|
||||||
|
final FormatPlugin plugin = PluginCollection.Instance().getPlugin(File);
|
||||||
|
if (plugin == null) {
|
||||||
|
throw new BookReadingException("pluginNotFound", File);
|
||||||
|
}
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void readMetainfo() throws BookReadingException {
|
||||||
|
readMetainfo(getPlugin());
|
||||||
|
}
|
||||||
|
|
||||||
|
void readMetainfo(FormatPlugin plugin) throws BookReadingException {
|
||||||
|
myEncoding = null;
|
||||||
|
myLanguage = null;
|
||||||
|
setTitle(null);
|
||||||
|
myAuthors = null;
|
||||||
|
myTags = null;
|
||||||
|
mySeriesInfo = null;
|
||||||
|
myUids = null;
|
||||||
|
|
||||||
|
myIsSaved = false;
|
||||||
|
|
||||||
|
plugin.readMetainfo(this);
|
||||||
|
if (myUids == null || myUids.isEmpty()) {
|
||||||
|
plugin.readUids(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isTitleEmpty()) {
|
||||||
|
final String fileName = File.getShortName();
|
||||||
|
final int index = fileName.lastIndexOf('.');
|
||||||
|
setTitle(index > 0 ? fileName.substring(0, index) : fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadLists(BooksDatabase database) {
|
||||||
|
myAuthors = database.listAuthors(myId);
|
||||||
|
myTags = database.listTags(myId);
|
||||||
|
myLabels = database.listLabels(myId);
|
||||||
|
mySeriesInfo = database.getSeriesInfo(myId);
|
||||||
|
myUids = database.listUids(myId);
|
||||||
|
myProgress = database.getProgress(myId);
|
||||||
|
HasBookmark = database.hasVisibleBookmark(myId);
|
||||||
|
myIsSaved = true;
|
||||||
|
if (myUids == null || myUids.isEmpty()) {
|
||||||
|
try {
|
||||||
|
getPlugin().readUids(this);
|
||||||
|
save(database, false);
|
||||||
|
} catch (BookReadingException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Author> authors() {
|
||||||
|
return (myAuthors != null) ? Collections.unmodifiableList(myAuthors) : Collections.<Author>emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void addAuthorWithNoCheck(Author author) {
|
||||||
|
if (myAuthors == null) {
|
||||||
|
myAuthors = new ArrayList<Author>();
|
||||||
|
}
|
||||||
|
myAuthors.add(author);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeAllAuthors() {
|
||||||
|
if (myAuthors != null) {
|
||||||
|
myAuthors = null;
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAuthor(Author author) {
|
||||||
|
if (author == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (myAuthors == null) {
|
||||||
|
myAuthors = new ArrayList<Author>();
|
||||||
|
myAuthors.add(author);
|
||||||
|
myIsSaved = false;
|
||||||
|
} else if (!myAuthors.contains(author)) {
|
||||||
|
myAuthors.add(author);
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAuthor(String name) {
|
||||||
|
addAuthor(name, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAuthor(String name, String sortKey) {
|
||||||
|
if (name == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String strippedName = name.trim();
|
||||||
|
if (strippedName.length() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String strippedKey = sortKey != null ? sortKey.trim() : "";
|
||||||
|
if (strippedKey.length() == 0) {
|
||||||
|
int index = strippedName.lastIndexOf(' ');
|
||||||
|
if (index == -1) {
|
||||||
|
strippedKey = strippedName;
|
||||||
|
} else {
|
||||||
|
strippedKey = strippedName.substring(index + 1);
|
||||||
|
while ((index >= 0) && (strippedName.charAt(index) == ' ')) {
|
||||||
|
--index;
|
||||||
|
}
|
||||||
|
strippedName = strippedName.substring(0, index + 1) + ' ' + strippedKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addAuthor(new Author(strippedName, strippedKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return myId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTitle(String title) {
|
||||||
|
if (title == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
title = title.trim();
|
||||||
|
if (title.length() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!getTitle().equals(title)) {
|
||||||
|
super.setTitle(title);
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SeriesInfo getSeriesInfo() {
|
||||||
|
return mySeriesInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSeriesInfoWithNoCheck(String name, String index) {
|
||||||
|
mySeriesInfo = SeriesInfo.createSeriesInfo(name, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSeriesInfo(String name, String index) {
|
||||||
|
setSeriesInfo(name, SeriesInfo.createIndex(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSeriesInfo(String name, BigDecimal index) {
|
||||||
|
if (mySeriesInfo == null) {
|
||||||
|
if (name != null) {
|
||||||
|
mySeriesInfo = new SeriesInfo(name, index);
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
} else if (name == null) {
|
||||||
|
mySeriesInfo = null;
|
||||||
|
myIsSaved = false;
|
||||||
|
} else if (!name.equals(mySeriesInfo.Series.getTitle()) || mySeriesInfo.Index != index) {
|
||||||
|
mySeriesInfo = new SeriesInfo(name, index);
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLanguage() {
|
||||||
|
return myLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLanguage(String language) {
|
||||||
|
if (!MiscUtil.equals(myLanguage, language)) {
|
||||||
|
myLanguage = language;
|
||||||
|
resetSortKey();
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEncoding() {
|
||||||
|
if (myEncoding == null) {
|
||||||
|
try {
|
||||||
|
getPlugin().detectLanguageAndEncoding(this);
|
||||||
|
} catch (BookReadingException e) {
|
||||||
|
}
|
||||||
|
if (myEncoding == null) {
|
||||||
|
setEncoding("utf-8");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return myEncoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEncodingNoDetection() {
|
||||||
|
return myEncoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEncoding(String encoding) {
|
||||||
|
if (!MiscUtil.equals(myEncoding, encoding)) {
|
||||||
|
myEncoding = encoding;
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Tag> tags() {
|
||||||
|
return myTags != null ? Collections.unmodifiableList(myTags) : Collections.<Tag>emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void addTagWithNoCheck(Tag tag) {
|
||||||
|
if (myTags == null) {
|
||||||
|
myTags = new ArrayList<Tag>();
|
||||||
|
}
|
||||||
|
myTags.add(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeAllTags() {
|
||||||
|
if (myTags != null) {
|
||||||
|
myTags = null;
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTag(Tag tag) {
|
||||||
|
if (tag != null) {
|
||||||
|
if (myTags == null) {
|
||||||
|
myTags = new ArrayList<Tag>();
|
||||||
|
}
|
||||||
|
if (!myTags.contains(tag)) {
|
||||||
|
myTags.add(tag);
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTag(String tagName) {
|
||||||
|
addTag(Tag.getTag(null, tagName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> labels() {
|
||||||
|
return myLabels != null ? Collections.unmodifiableList(myLabels) : Collections.<String>emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void addLabelWithNoCheck(String label) {
|
||||||
|
if (myLabels == null) {
|
||||||
|
myLabels = new ArrayList<String>();
|
||||||
|
}
|
||||||
|
myLabels.add(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLabel(String label) {
|
||||||
|
if (myLabels == null) {
|
||||||
|
myLabels = new ArrayList<String>();
|
||||||
|
}
|
||||||
|
if (!myLabels.contains(label)) {
|
||||||
|
myLabels.add(label);
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeLabel(String label) {
|
||||||
|
if (myLabels != null && myLabels.remove(label)) {
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<UID> uids() {
|
||||||
|
return myUids != null ? Collections.unmodifiableList(myUids) : Collections.<UID>emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addUid(String type, String id) {
|
||||||
|
addUid(new UID(type, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
void addUidWithNoCheck(UID uid) {
|
||||||
|
if (uid == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (myUids == null) {
|
||||||
|
myUids = new ArrayList<UID>();
|
||||||
|
}
|
||||||
|
myUids.add(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addUid(UID uid) {
|
||||||
|
if (uid == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (myUids == null) {
|
||||||
|
myUids = new ArrayList<UID>();
|
||||||
|
}
|
||||||
|
if (!myUids.contains(uid)) {
|
||||||
|
myUids.add(uid);
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean matchesUid(UID uid) {
|
||||||
|
return myUids.contains(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RationalNumber getProgress() {
|
||||||
|
return myProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProgress(RationalNumber progress) {
|
||||||
|
if (!MiscUtil.equals(myProgress, progress)) {
|
||||||
|
myProgress = progress;
|
||||||
|
myIsSaved = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProgressWithNoCheck(RationalNumber progress) {
|
||||||
|
myProgress = progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean matches(String pattern) {
|
||||||
|
if (MiscUtil.matchesIgnoreCase(getTitle(), pattern)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (mySeriesInfo != null && MiscUtil.matchesIgnoreCase(mySeriesInfo.Series.getTitle(), pattern)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (myAuthors != null) {
|
||||||
|
for (Author author : myAuthors) {
|
||||||
|
if (MiscUtil.matchesIgnoreCase(author.DisplayName, pattern)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (myTags != null) {
|
||||||
|
for (Tag tag : myTags) {
|
||||||
|
if (MiscUtil.matchesIgnoreCase(tag.Name, pattern)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (MiscUtil.matchesIgnoreCase(File.getLongName(), pattern)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean save(final BooksDatabase database, boolean force) {
|
||||||
|
if (!force && myId != -1 && myIsSaved) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean[] result = new boolean[] { true };
|
||||||
|
database.executeAsTransaction(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (myId >= 0) {
|
||||||
|
final FileInfoSet fileInfos = new FileInfoSet(database, File);
|
||||||
|
database.updateBookInfo(myId, fileInfos.getId(File), myEncoding, myLanguage, getTitle());
|
||||||
|
} else {
|
||||||
|
myId = database.insertBookInfo(File, myEncoding, myLanguage, getTitle());
|
||||||
|
if (myId == -1) {
|
||||||
|
result[0] = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (myVisitedHyperlinks != null) {
|
||||||
|
for (String linkId : myVisitedHyperlinks) {
|
||||||
|
database.addVisitedHyperlink(myId, linkId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
database.addBookHistoryEvent(myId, BooksDatabase.HistoryEvent.Added);
|
||||||
|
}
|
||||||
|
|
||||||
|
long index = 0;
|
||||||
|
database.deleteAllBookAuthors(myId);
|
||||||
|
for (Author author : authors()) {
|
||||||
|
database.saveBookAuthorInfo(myId, index++, author);
|
||||||
|
}
|
||||||
|
database.deleteAllBookTags(myId);
|
||||||
|
for (Tag tag : tags()) {
|
||||||
|
database.saveBookTagInfo(myId, tag);
|
||||||
|
}
|
||||||
|
final List<String> labelsInDb = database.listLabels(myId);
|
||||||
|
for (String label : labelsInDb) {
|
||||||
|
if (myLabels == null || !myLabels.contains(label)) {
|
||||||
|
database.removeLabel(myId, label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (myLabels != null) {
|
||||||
|
for (String label : myLabels) {
|
||||||
|
database.setLabel(myId, label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
database.saveBookSeriesInfo(myId, mySeriesInfo);
|
||||||
|
database.deleteAllBookUids(myId);
|
||||||
|
for (UID uid : uids()) {
|
||||||
|
database.saveBookUid(myId, uid);
|
||||||
|
}
|
||||||
|
if (myProgress != null) {
|
||||||
|
database.saveBookProgress(myId, myProgress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result[0]) {
|
||||||
|
myIsSaved = true;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> myVisitedHyperlinks;
|
||||||
|
private void initHyperlinkSet(BooksDatabase database) {
|
||||||
|
if (myVisitedHyperlinks == null) {
|
||||||
|
myVisitedHyperlinks = new TreeSet<String>();
|
||||||
|
if (myId != -1) {
|
||||||
|
myVisitedHyperlinks.addAll(database.loadVisitedHyperlinks(myId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isHyperlinkVisited(BooksDatabase database, String linkId) {
|
||||||
|
initHyperlinkSet(database);
|
||||||
|
return myVisitedHyperlinks.contains(linkId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void markHyperlinkAsVisited(BooksDatabase database, String linkId) {
|
||||||
|
initHyperlinkSet(database);
|
||||||
|
if (!myVisitedHyperlinks.contains(linkId)) {
|
||||||
|
myVisitedHyperlinks.add(linkId);
|
||||||
|
if (myId != -1) {
|
||||||
|
database.addVisitedHyperlink(myId, linkId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return File.getShortName().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(o instanceof AbstractBook)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final AbstractBook obook = ((AbstractBook)o);
|
||||||
|
final ZLFile ofile = obook.File;
|
||||||
|
if (File.equals(ofile)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!File.getShortName().equals(ofile.getShortName())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (myUids == null || obook.myUids == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (UID uid : obook.myUids) {
|
||||||
|
if (myUids.contains(uid)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new StringBuilder("Book[")
|
||||||
|
.append(File.getPath())
|
||||||
|
.append(", ")
|
||||||
|
.append(myId)
|
||||||
|
.append(", ")
|
||||||
|
.append(getTitle())
|
||||||
|
.append("]")
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,615 +19,17 @@
|
||||||
|
|
||||||
package org.geometerplus.fbreader.book;
|
package org.geometerplus.fbreader.book;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import org.geometerplus.zlibrary.core.filesystem.*;
|
|
||||||
import org.geometerplus.zlibrary.core.util.MiscUtil;
|
|
||||||
import org.geometerplus.zlibrary.core.util.RationalNumber;
|
|
||||||
|
|
||||||
import org.geometerplus.fbreader.bookmodel.BookReadingException;
|
import org.geometerplus.fbreader.bookmodel.BookReadingException;
|
||||||
import org.geometerplus.fbreader.formats.PluginCollection;
|
|
||||||
import org.geometerplus.fbreader.formats.FormatPlugin;
|
import org.geometerplus.fbreader.formats.FormatPlugin;
|
||||||
import org.geometerplus.fbreader.sort.TitledEntity;
|
|
||||||
|
|
||||||
public class Book extends TitledEntity<Book> {
|
|
||||||
public static final String FAVORITE_LABEL = "favorite";
|
|
||||||
public static final String READ_LABEL = "read";
|
|
||||||
public static final String SYNCHRONISED_LABEL = "sync-success";
|
|
||||||
public static final String SYNC_FAILURE_LABEL = "sync-failure";
|
|
||||||
public static final String SYNC_DELETED_LABEL = "sync-deleted";
|
|
||||||
public static final String SYNC_TOSYNC_LABEL = "sync-tosync";
|
|
||||||
|
|
||||||
public final ZLFile File;
|
|
||||||
|
|
||||||
private volatile long myId;
|
|
||||||
|
|
||||||
private volatile String myEncoding;
|
|
||||||
private volatile String myLanguage;
|
|
||||||
private volatile List<Author> myAuthors;
|
|
||||||
private volatile List<Tag> myTags;
|
|
||||||
private volatile List<String> myLabels;
|
|
||||||
private volatile SeriesInfo mySeriesInfo;
|
|
||||||
private volatile List<UID> myUids;
|
|
||||||
private volatile RationalNumber myProgress;
|
|
||||||
|
|
||||||
public volatile boolean HasBookmark;
|
|
||||||
|
|
||||||
private volatile boolean myIsSaved;
|
|
||||||
|
|
||||||
|
public class Book extends AbstractBook {
|
||||||
Book(long id, ZLFile file, String title, String encoding, String language) {
|
Book(long id, ZLFile file, String title, String encoding, String language) {
|
||||||
super(title);
|
super(id, file, title, encoding, language);
|
||||||
if (file == null) {
|
|
||||||
throw new IllegalArgumentException("Creating book with no file");
|
|
||||||
}
|
|
||||||
myId = id;
|
|
||||||
File = file;
|
|
||||||
myEncoding = encoding;
|
|
||||||
myLanguage = language;
|
|
||||||
myIsSaved = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Book(ZLFile file, FormatPlugin plugin) throws BookReadingException {
|
Book(ZLFile file, FormatPlugin plugin) throws BookReadingException {
|
||||||
super(null);
|
super(file, plugin);
|
||||||
if (file == null) {
|
|
||||||
throw new IllegalArgumentException("Creating book with no file");
|
|
||||||
}
|
|
||||||
myId = -1;
|
|
||||||
File = plugin.realBookFile(file);
|
|
||||||
readMetainfo(plugin);
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean hasSameMetainfoAs(Book other) {
|
|
||||||
return
|
|
||||||
MiscUtil.equals(getTitle(), other.getTitle()) &&
|
|
||||||
MiscUtil.equals(myEncoding, other.myEncoding) &&
|
|
||||||
MiscUtil.equals(myLanguage, other.myLanguage) &&
|
|
||||||
MiscUtil.equals(myAuthors, other.myAuthors) &&
|
|
||||||
MiscUtil.listsEquals(myTags, other.myTags) &&
|
|
||||||
MiscUtil.equals(mySeriesInfo, other.mySeriesInfo) &&
|
|
||||||
MiscUtil.equals(myUids, other.myUids);
|
|
||||||
}
|
|
||||||
|
|
||||||
void merge(Book other, Book base) {
|
|
||||||
if (!MiscUtil.equals(getTitle(), other.getTitle()) &&
|
|
||||||
MiscUtil.equals(getTitle(), base.getTitle())) {
|
|
||||||
setTitle(other.getTitle());
|
|
||||||
}
|
|
||||||
if (!MiscUtil.equals(myEncoding, other.myEncoding) &&
|
|
||||||
MiscUtil.equals(myEncoding, base.myEncoding)) {
|
|
||||||
setEncoding(other.myEncoding);
|
|
||||||
}
|
|
||||||
if (!MiscUtil.equals(myLanguage, other.myLanguage) &&
|
|
||||||
MiscUtil.equals(myLanguage, base.myLanguage)) {
|
|
||||||
setLanguage(other.myLanguage);
|
|
||||||
}
|
|
||||||
if (!MiscUtil.listsEquals(myTags, other.myTags) &&
|
|
||||||
MiscUtil.listsEquals(myTags, base.myTags)) {
|
|
||||||
myTags = other.myTags != null ? new ArrayList<Tag>(other.myTags) : null;
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
if (!MiscUtil.equals(mySeriesInfo, other.mySeriesInfo) &&
|
|
||||||
MiscUtil.equals(mySeriesInfo, base.mySeriesInfo)) {
|
|
||||||
mySeriesInfo = other.mySeriesInfo;
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
if (!MiscUtil.listsEquals(myUids, other.myUids) &&
|
|
||||||
MiscUtil.listsEquals(myUids, base.myUids)) {
|
|
||||||
myUids = other.myUids != null ? new ArrayList<UID>(other.myUids) : null;
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateFrom(Book book) {
|
|
||||||
if (book == null || myId != book.myId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setTitle(book.getTitle());
|
|
||||||
setEncoding(book.myEncoding);
|
|
||||||
setLanguage(book.myLanguage);
|
|
||||||
if (!MiscUtil.equals(myAuthors, book.myAuthors)) {
|
|
||||||
myAuthors = book.myAuthors != null ? new ArrayList<Author>(book.myAuthors) : null;
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
if (!MiscUtil.equals(myTags, book.myTags)) {
|
|
||||||
myTags = book.myTags != null ? new ArrayList<Tag>(book.myTags) : null;
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
if (!MiscUtil.listsEquals(myLabels, book.myLabels)) {
|
|
||||||
myLabels = book.myLabels != null ? new ArrayList<String>(book.myLabels) : null;
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
if (!MiscUtil.equals(mySeriesInfo, book.mySeriesInfo)) {
|
|
||||||
mySeriesInfo = book.mySeriesInfo;
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
if (!MiscUtil.listsEquals(myUids, book.myUids)) {
|
|
||||||
myUids = book.myUids != null ? new ArrayList<UID>(book.myUids) : null;
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
setProgress(book.myProgress);
|
|
||||||
if (HasBookmark != book.HasBookmark) {
|
|
||||||
HasBookmark = book.HasBookmark;
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reloadInfoFromFile() {
|
|
||||||
try {
|
|
||||||
readMetainfo(getPlugin());
|
|
||||||
} catch (BookReadingException e) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public FormatPlugin getPlugin() throws BookReadingException {
|
|
||||||
final FormatPlugin plugin = PluginCollection.Instance().getPlugin(File);
|
|
||||||
if (plugin == null) {
|
|
||||||
throw new BookReadingException("pluginNotFound", File);
|
|
||||||
}
|
|
||||||
return plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
void readMetainfo() throws BookReadingException {
|
|
||||||
readMetainfo(getPlugin());
|
|
||||||
}
|
|
||||||
|
|
||||||
void readMetainfo(FormatPlugin plugin) throws BookReadingException {
|
|
||||||
myEncoding = null;
|
|
||||||
myLanguage = null;
|
|
||||||
setTitle(null);
|
|
||||||
myAuthors = null;
|
|
||||||
myTags = null;
|
|
||||||
mySeriesInfo = null;
|
|
||||||
myUids = null;
|
|
||||||
|
|
||||||
myIsSaved = false;
|
|
||||||
|
|
||||||
plugin.readMetainfo(this);
|
|
||||||
if (myUids == null || myUids.isEmpty()) {
|
|
||||||
plugin.readUids(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isTitleEmpty()) {
|
|
||||||
final String fileName = File.getShortName();
|
|
||||||
final int index = fileName.lastIndexOf('.');
|
|
||||||
setTitle(index > 0 ? fileName.substring(0, index) : fileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void loadLists(BooksDatabase database) {
|
|
||||||
myAuthors = database.listAuthors(myId);
|
|
||||||
myTags = database.listTags(myId);
|
|
||||||
myLabels = database.listLabels(myId);
|
|
||||||
mySeriesInfo = database.getSeriesInfo(myId);
|
|
||||||
myUids = database.listUids(myId);
|
|
||||||
myProgress = database.getProgress(myId);
|
|
||||||
HasBookmark = database.hasVisibleBookmark(myId);
|
|
||||||
myIsSaved = true;
|
|
||||||
if (myUids == null || myUids.isEmpty()) {
|
|
||||||
try {
|
|
||||||
getPlugin().readUids(this);
|
|
||||||
save(database, false);
|
|
||||||
} catch (BookReadingException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Author> authors() {
|
|
||||||
return (myAuthors != null) ? Collections.unmodifiableList(myAuthors) : Collections.<Author>emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
void addAuthorWithNoCheck(Author author) {
|
|
||||||
if (myAuthors == null) {
|
|
||||||
myAuthors = new ArrayList<Author>();
|
|
||||||
}
|
|
||||||
myAuthors.add(author);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeAllAuthors() {
|
|
||||||
if (myAuthors != null) {
|
|
||||||
myAuthors = null;
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addAuthor(Author author) {
|
|
||||||
if (author == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (myAuthors == null) {
|
|
||||||
myAuthors = new ArrayList<Author>();
|
|
||||||
myAuthors.add(author);
|
|
||||||
myIsSaved = false;
|
|
||||||
} else if (!myAuthors.contains(author)) {
|
|
||||||
myAuthors.add(author);
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addAuthor(String name) {
|
|
||||||
addAuthor(name, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addAuthor(String name, String sortKey) {
|
|
||||||
if (name == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String strippedName = name.trim();
|
|
||||||
if (strippedName.length() == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String strippedKey = sortKey != null ? sortKey.trim() : "";
|
|
||||||
if (strippedKey.length() == 0) {
|
|
||||||
int index = strippedName.lastIndexOf(' ');
|
|
||||||
if (index == -1) {
|
|
||||||
strippedKey = strippedName;
|
|
||||||
} else {
|
|
||||||
strippedKey = strippedName.substring(index + 1);
|
|
||||||
while ((index >= 0) && (strippedName.charAt(index) == ' ')) {
|
|
||||||
--index;
|
|
||||||
}
|
|
||||||
strippedName = strippedName.substring(0, index + 1) + ' ' + strippedKey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addAuthor(new Author(strippedName, strippedKey));
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getId() {
|
|
||||||
return myId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setTitle(String title) {
|
|
||||||
if (title == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
title = title.trim();
|
|
||||||
if (title.length() == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!getTitle().equals(title)) {
|
|
||||||
super.setTitle(title);
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public SeriesInfo getSeriesInfo() {
|
|
||||||
return mySeriesInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSeriesInfoWithNoCheck(String name, String index) {
|
|
||||||
mySeriesInfo = SeriesInfo.createSeriesInfo(name, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSeriesInfo(String name, String index) {
|
|
||||||
setSeriesInfo(name, SeriesInfo.createIndex(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSeriesInfo(String name, BigDecimal index) {
|
|
||||||
if (mySeriesInfo == null) {
|
|
||||||
if (name != null) {
|
|
||||||
mySeriesInfo = new SeriesInfo(name, index);
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
} else if (name == null) {
|
|
||||||
mySeriesInfo = null;
|
|
||||||
myIsSaved = false;
|
|
||||||
} else if (!name.equals(mySeriesInfo.Series.getTitle()) || mySeriesInfo.Index != index) {
|
|
||||||
mySeriesInfo = new SeriesInfo(name, index);
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getLanguage() {
|
|
||||||
return myLanguage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLanguage(String language) {
|
|
||||||
if (!MiscUtil.equals(myLanguage, language)) {
|
|
||||||
myLanguage = language;
|
|
||||||
resetSortKey();
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEncoding() {
|
|
||||||
if (myEncoding == null) {
|
|
||||||
try {
|
|
||||||
getPlugin().detectLanguageAndEncoding(this);
|
|
||||||
} catch (BookReadingException e) {
|
|
||||||
}
|
|
||||||
if (myEncoding == null) {
|
|
||||||
setEncoding("utf-8");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return myEncoding;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEncodingNoDetection() {
|
|
||||||
return myEncoding;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEncoding(String encoding) {
|
|
||||||
if (!MiscUtil.equals(myEncoding, encoding)) {
|
|
||||||
myEncoding = encoding;
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Tag> tags() {
|
|
||||||
return myTags != null ? Collections.unmodifiableList(myTags) : Collections.<Tag>emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
void addTagWithNoCheck(Tag tag) {
|
|
||||||
if (myTags == null) {
|
|
||||||
myTags = new ArrayList<Tag>();
|
|
||||||
}
|
|
||||||
myTags.add(tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeAllTags() {
|
|
||||||
if (myTags != null) {
|
|
||||||
myTags = null;
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addTag(Tag tag) {
|
|
||||||
if (tag != null) {
|
|
||||||
if (myTags == null) {
|
|
||||||
myTags = new ArrayList<Tag>();
|
|
||||||
}
|
|
||||||
if (!myTags.contains(tag)) {
|
|
||||||
myTags.add(tag);
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addTag(String tagName) {
|
|
||||||
addTag(Tag.getTag(null, tagName));
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> labels() {
|
|
||||||
return myLabels != null ? Collections.unmodifiableList(myLabels) : Collections.<String>emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
void addLabelWithNoCheck(String label) {
|
|
||||||
if (myLabels == null) {
|
|
||||||
myLabels = new ArrayList<String>();
|
|
||||||
}
|
|
||||||
myLabels.add(label);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addLabel(String label) {
|
|
||||||
if (myLabels == null) {
|
|
||||||
myLabels = new ArrayList<String>();
|
|
||||||
}
|
|
||||||
if (!myLabels.contains(label)) {
|
|
||||||
myLabels.add(label);
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeLabel(String label) {
|
|
||||||
if (myLabels != null && myLabels.remove(label)) {
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<UID> uids() {
|
|
||||||
return myUids != null ? Collections.unmodifiableList(myUids) : Collections.<UID>emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addUid(String type, String id) {
|
|
||||||
addUid(new UID(type, id));
|
|
||||||
}
|
|
||||||
|
|
||||||
void addUidWithNoCheck(UID uid) {
|
|
||||||
if (uid == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (myUids == null) {
|
|
||||||
myUids = new ArrayList<UID>();
|
|
||||||
}
|
|
||||||
myUids.add(uid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addUid(UID uid) {
|
|
||||||
if (uid == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (myUids == null) {
|
|
||||||
myUids = new ArrayList<UID>();
|
|
||||||
}
|
|
||||||
if (!myUids.contains(uid)) {
|
|
||||||
myUids.add(uid);
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean matchesUid(UID uid) {
|
|
||||||
return myUids.contains(uid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RationalNumber getProgress() {
|
|
||||||
return myProgress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProgress(RationalNumber progress) {
|
|
||||||
if (!MiscUtil.equals(myProgress, progress)) {
|
|
||||||
myProgress = progress;
|
|
||||||
myIsSaved = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProgressWithNoCheck(RationalNumber progress) {
|
|
||||||
myProgress = progress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean matches(String pattern) {
|
|
||||||
if (MiscUtil.matchesIgnoreCase(getTitle(), pattern)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (mySeriesInfo != null && MiscUtil.matchesIgnoreCase(mySeriesInfo.Series.getTitle(), pattern)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (myAuthors != null) {
|
|
||||||
for (Author author : myAuthors) {
|
|
||||||
if (MiscUtil.matchesIgnoreCase(author.DisplayName, pattern)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (myTags != null) {
|
|
||||||
for (Tag tag : myTags) {
|
|
||||||
if (MiscUtil.matchesIgnoreCase(tag.Name, pattern)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (MiscUtil.matchesIgnoreCase(File.getLongName(), pattern)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean save(final BooksDatabase database, boolean force) {
|
|
||||||
if (!force && myId != -1 && myIsSaved) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final boolean[] result = new boolean[] { true };
|
|
||||||
database.executeAsTransaction(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
if (myId >= 0) {
|
|
||||||
final FileInfoSet fileInfos = new FileInfoSet(database, File);
|
|
||||||
database.updateBookInfo(myId, fileInfos.getId(File), myEncoding, myLanguage, getTitle());
|
|
||||||
} else {
|
|
||||||
myId = database.insertBookInfo(File, myEncoding, myLanguage, getTitle());
|
|
||||||
if (myId == -1) {
|
|
||||||
result[0] = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (myVisitedHyperlinks != null) {
|
|
||||||
for (String linkId : myVisitedHyperlinks) {
|
|
||||||
database.addVisitedHyperlink(myId, linkId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
database.addBookHistoryEvent(myId, BooksDatabase.HistoryEvent.Added);
|
|
||||||
}
|
|
||||||
|
|
||||||
long index = 0;
|
|
||||||
database.deleteAllBookAuthors(myId);
|
|
||||||
for (Author author : authors()) {
|
|
||||||
database.saveBookAuthorInfo(myId, index++, author);
|
|
||||||
}
|
|
||||||
database.deleteAllBookTags(myId);
|
|
||||||
for (Tag tag : tags()) {
|
|
||||||
database.saveBookTagInfo(myId, tag);
|
|
||||||
}
|
|
||||||
final List<String> labelsInDb = database.listLabels(myId);
|
|
||||||
for (String label : labelsInDb) {
|
|
||||||
if (myLabels == null || !myLabels.contains(label)) {
|
|
||||||
database.removeLabel(myId, label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (myLabels != null) {
|
|
||||||
for (String label : myLabels) {
|
|
||||||
database.setLabel(myId, label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
database.saveBookSeriesInfo(myId, mySeriesInfo);
|
|
||||||
database.deleteAllBookUids(myId);
|
|
||||||
for (UID uid : uids()) {
|
|
||||||
database.saveBookUid(myId, uid);
|
|
||||||
}
|
|
||||||
if (myProgress != null) {
|
|
||||||
database.saveBookProgress(myId, myProgress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (result[0]) {
|
|
||||||
myIsSaved = true;
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Set<String> myVisitedHyperlinks;
|
|
||||||
private void initHyperlinkSet(BooksDatabase database) {
|
|
||||||
if (myVisitedHyperlinks == null) {
|
|
||||||
myVisitedHyperlinks = new TreeSet<String>();
|
|
||||||
if (myId != -1) {
|
|
||||||
myVisitedHyperlinks.addAll(database.loadVisitedHyperlinks(myId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isHyperlinkVisited(BooksDatabase database, String linkId) {
|
|
||||||
initHyperlinkSet(database);
|
|
||||||
return myVisitedHyperlinks.contains(linkId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void markHyperlinkAsVisited(BooksDatabase database, String linkId) {
|
|
||||||
initHyperlinkSet(database);
|
|
||||||
if (!myVisitedHyperlinks.contains(linkId)) {
|
|
||||||
myVisitedHyperlinks.add(linkId);
|
|
||||||
if (myId != -1) {
|
|
||||||
database.addVisitedHyperlink(myId, linkId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return File.getShortName().hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!(o instanceof Book)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final Book obook = ((Book)o);
|
|
||||||
final ZLFile ofile = obook.File;
|
|
||||||
if (File.equals(ofile)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!File.getShortName().equals(ofile.getShortName())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (myUids == null || obook.myUids == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (UID uid : obook.myUids) {
|
|
||||||
if (myUids.contains(uid)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new StringBuilder("Book[")
|
|
||||||
.append(File.getPath())
|
|
||||||
.append(", ")
|
|
||||||
.append(myId)
|
|
||||||
.append(", ")
|
|
||||||
.append(getTitle())
|
|
||||||
.append("]")
|
|
||||||
.toString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
package org.geometerplus.fbreader.formats;
|
package org.geometerplus.fbreader.formats;
|
||||||
|
|
||||||
import org.geometerplus.fbreader.book.Book;
|
import org.geometerplus.fbreader.book.AbstractBook;
|
||||||
|
|
||||||
public class ComicBookPlugin extends ExternalFormatPlugin {
|
public class ComicBookPlugin extends ExternalFormatPlugin {
|
||||||
public ComicBookPlugin() {
|
public ComicBookPlugin() {
|
||||||
|
@ -32,7 +32,7 @@ public class ComicBookPlugin extends ExternalFormatPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readMetainfo(Book book) {
|
public void readMetainfo(AbstractBook book) {
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
package org.geometerplus.fbreader.formats;
|
package org.geometerplus.fbreader.formats;
|
||||||
|
|
||||||
import org.geometerplus.fbreader.book.Book;
|
import org.geometerplus.fbreader.book.AbstractBook;
|
||||||
|
|
||||||
public class DjVuPlugin extends ExternalFormatPlugin {
|
public class DjVuPlugin extends ExternalFormatPlugin {
|
||||||
public DjVuPlugin() {
|
public DjVuPlugin() {
|
||||||
|
@ -32,7 +32,7 @@ public class DjVuPlugin extends ExternalFormatPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readMetainfo(Book book) {
|
public void readMetainfo(AbstractBook book) {
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ package org.geometerplus.fbreader.formats;
|
||||||
import org.geometerplus.zlibrary.core.encodings.AutoEncodingCollection;
|
import org.geometerplus.zlibrary.core.encodings.AutoEncodingCollection;
|
||||||
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
||||||
|
|
||||||
import org.geometerplus.fbreader.book.Book;
|
import org.geometerplus.fbreader.book.AbstractBook;
|
||||||
import org.geometerplus.fbreader.book.BookUtil;
|
import org.geometerplus.fbreader.book.BookUtil;
|
||||||
|
|
||||||
public abstract class ExternalFormatPlugin extends FormatPlugin {
|
public abstract class ExternalFormatPlugin extends FormatPlugin {
|
||||||
|
@ -48,7 +48,7 @@ public abstract class ExternalFormatPlugin extends FormatPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void detectLanguageAndEncoding(Book book) {
|
public void detectLanguageAndEncoding(AbstractBook book) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -57,7 +57,7 @@ public abstract class ExternalFormatPlugin extends FormatPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readUids(Book book) {
|
public void readUids(AbstractBook book) {
|
||||||
if (book.uids().isEmpty()) {
|
if (book.uids().isEmpty()) {
|
||||||
book.addUid(BookUtil.createUid(book.File, "SHA-256"));
|
book.addUid(BookUtil.createUid(book.File, "SHA-256"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
||||||
import org.geometerplus.zlibrary.core.image.ZLImage;
|
import org.geometerplus.zlibrary.core.image.ZLImage;
|
||||||
import org.geometerplus.zlibrary.core.resources.ZLResource;
|
import org.geometerplus.zlibrary.core.resources.ZLResource;
|
||||||
|
|
||||||
import org.geometerplus.fbreader.book.Book;
|
import org.geometerplus.fbreader.book.AbstractBook;
|
||||||
import org.geometerplus.fbreader.bookmodel.BookReadingException;
|
import org.geometerplus.fbreader.bookmodel.BookReadingException;
|
||||||
|
|
||||||
public abstract class FormatPlugin {
|
public abstract class FormatPlugin {
|
||||||
|
@ -49,12 +49,12 @@ public abstract class FormatPlugin {
|
||||||
public ZLFile realBookFile(ZLFile file) throws BookReadingException {
|
public ZLFile realBookFile(ZLFile file) throws BookReadingException {
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
public List<FileEncryptionInfo> readEncryptionInfos(Book book) {
|
public List<FileEncryptionInfo> readEncryptionInfos(AbstractBook book) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
public abstract void readMetainfo(Book book) throws BookReadingException;
|
public abstract void readMetainfo(AbstractBook book) throws BookReadingException;
|
||||||
public abstract void readUids(Book book) throws BookReadingException;
|
public abstract void readUids(AbstractBook book) throws BookReadingException;
|
||||||
public abstract void detectLanguageAndEncoding(Book book) throws BookReadingException;
|
public abstract void detectLanguageAndEncoding(AbstractBook book) throws BookReadingException;
|
||||||
public abstract ZLImage readCover(ZLFile file);
|
public abstract ZLImage readCover(ZLFile file);
|
||||||
public abstract String readAnnotation(ZLFile file);
|
public abstract String readAnnotation(ZLFile file);
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
||||||
import org.geometerplus.zlibrary.core.image.*;
|
import org.geometerplus.zlibrary.core.image.*;
|
||||||
import org.geometerplus.zlibrary.text.model.CachedCharStorageException;
|
import org.geometerplus.zlibrary.text.model.CachedCharStorageException;
|
||||||
|
|
||||||
import org.geometerplus.fbreader.book.Book;
|
import org.geometerplus.fbreader.book.AbstractBook;
|
||||||
import org.geometerplus.fbreader.book.BookUtil;
|
import org.geometerplus.fbreader.book.BookUtil;
|
||||||
import org.geometerplus.fbreader.bookmodel.BookModel;
|
import org.geometerplus.fbreader.bookmodel.BookModel;
|
||||||
import org.geometerplus.fbreader.bookmodel.BookReadingException;
|
import org.geometerplus.fbreader.bookmodel.BookReadingException;
|
||||||
|
@ -51,7 +51,7 @@ public class NativeFormatPlugin extends BuiltinFormatPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
synchronized public void readMetainfo(Book book) throws BookReadingException {
|
synchronized public void readMetainfo(AbstractBook book) throws BookReadingException {
|
||||||
final int code = readMetainfoNative(book);
|
final int code = readMetainfoNative(book);
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
throw new BookReadingException(
|
throw new BookReadingException(
|
||||||
|
@ -62,34 +62,34 @@ public class NativeFormatPlugin extends BuiltinFormatPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private native int readMetainfoNative(Book book);
|
private native int readMetainfoNative(AbstractBook book);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<FileEncryptionInfo> readEncryptionInfos(Book book) {
|
public List<FileEncryptionInfo> readEncryptionInfos(AbstractBook book) {
|
||||||
final FileEncryptionInfo[] infos = readEncryptionInfosNative(book);
|
final FileEncryptionInfo[] infos = readEncryptionInfosNative(book);
|
||||||
return infos != null
|
return infos != null
|
||||||
? Arrays.<FileEncryptionInfo>asList(infos)
|
? Arrays.<FileEncryptionInfo>asList(infos)
|
||||||
: Collections.<FileEncryptionInfo>emptyList();
|
: Collections.<FileEncryptionInfo>emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private native FileEncryptionInfo[] readEncryptionInfosNative(Book book);
|
private native FileEncryptionInfo[] readEncryptionInfosNative(AbstractBook book);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
synchronized public void readUids(Book book) throws BookReadingException {
|
synchronized public void readUids(AbstractBook book) throws BookReadingException {
|
||||||
readUidsNative(book);
|
readUidsNative(book);
|
||||||
if (book.uids().isEmpty()) {
|
if (book.uids().isEmpty()) {
|
||||||
book.addUid(BookUtil.createUid(book.File, "SHA-256"));
|
book.addUid(BookUtil.createUid(book.File, "SHA-256"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private native boolean readUidsNative(Book book);
|
private native boolean readUidsNative(AbstractBook book);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void detectLanguageAndEncoding(Book book) {
|
public void detectLanguageAndEncoding(AbstractBook book) {
|
||||||
detectLanguageAndEncodingNative(book);
|
detectLanguageAndEncodingNative(book);
|
||||||
}
|
}
|
||||||
|
|
||||||
public native void detectLanguageAndEncodingNative(Book book);
|
public native void detectLanguageAndEncodingNative(AbstractBook book);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
synchronized public void readModel(BookModel model) throws BookReadingException {
|
synchronized public void readModel(BookModel model) throws BookReadingException {
|
||||||
|
|
|
@ -23,7 +23,7 @@ import org.pdfparse.model.PDFDocInfo;
|
||||||
import org.pdfparse.model.PDFDocument;
|
import org.pdfparse.model.PDFDocument;
|
||||||
|
|
||||||
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
||||||
import org.geometerplus.fbreader.book.Book;
|
import org.geometerplus.fbreader.book.AbstractBook;
|
||||||
import org.geometerplus.fbreader.bookmodel.BookReadingException;
|
import org.geometerplus.fbreader.bookmodel.BookReadingException;
|
||||||
|
|
||||||
public class PDFPlugin extends ExternalFormatPlugin {
|
public class PDFPlugin extends ExternalFormatPlugin {
|
||||||
|
@ -37,7 +37,7 @@ public class PDFPlugin extends ExternalFormatPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readMetainfo(Book book) {
|
public void readMetainfo(AbstractBook book) {
|
||||||
final ZLFile file = book.File;
|
final ZLFile file = book.File;
|
||||||
if (file != file.getPhysicalFile()) {
|
if (file != file.getPhysicalFile()) {
|
||||||
// TODO: throw BookReadingException
|
// TODO: throw BookReadingException
|
||||||
|
|
|
@ -28,7 +28,7 @@ import org.geometerplus.zlibrary.core.encodings.AutoEncodingCollection;
|
||||||
|
|
||||||
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
||||||
|
|
||||||
import org.geometerplus.fbreader.book.Book;
|
import org.geometerplus.fbreader.book.AbstractBook;
|
||||||
import org.geometerplus.fbreader.bookmodel.BookModel;
|
import org.geometerplus.fbreader.bookmodel.BookModel;
|
||||||
import org.geometerplus.fbreader.bookmodel.BookReadingException;
|
import org.geometerplus.fbreader.bookmodel.BookReadingException;
|
||||||
import org.geometerplus.fbreader.formats.NativeFormatPlugin;
|
import org.geometerplus.fbreader.formats.NativeFormatPlugin;
|
||||||
|
@ -103,7 +103,7 @@ public class FB2NativePlugin extends NativeFormatPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void detectLanguageAndEncoding(Book book) {
|
public void detectLanguageAndEncoding(AbstractBook book) {
|
||||||
book.setEncoding("auto");
|
book.setEncoding("auto");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ import org.geometerplus.zlibrary.core.encodings.EncodingCollection;
|
||||||
import org.geometerplus.zlibrary.core.encodings.AutoEncodingCollection;
|
import org.geometerplus.zlibrary.core.encodings.AutoEncodingCollection;
|
||||||
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
||||||
|
|
||||||
import org.geometerplus.fbreader.book.Book;
|
import org.geometerplus.fbreader.book.AbstractBook;
|
||||||
import org.geometerplus.fbreader.bookmodel.BookModel;
|
import org.geometerplus.fbreader.bookmodel.BookModel;
|
||||||
import org.geometerplus.fbreader.bookmodel.BookReadingException;
|
import org.geometerplus.fbreader.bookmodel.BookReadingException;
|
||||||
import org.geometerplus.fbreader.formats.NativeFormatPlugin;
|
import org.geometerplus.fbreader.formats.NativeFormatPlugin;
|
||||||
|
@ -60,7 +60,7 @@ public class OEBNativePlugin extends NativeFormatPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void detectLanguageAndEncoding(Book book) {
|
public void detectLanguageAndEncoding(AbstractBook book) {
|
||||||
book.setEncoding("auto");
|
book.setEncoding("auto");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue