1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-04 18:29:23 +02:00

move code moved from Library to BookCollection

This commit is contained in:
Nikolay Pultsin 2013-01-09 07:54:35 +00:00
parent d2dd11cb45
commit 071a3d8787
3 changed files with 110 additions and 58 deletions

View file

@ -36,19 +36,27 @@ public class LibraryService extends Service {
} }
final BookCollection collection = new BookCollection(database); final BookCollection collection = new BookCollection(database);
final long start = System.currentTimeMillis(); final long start = System.currentTimeMillis();
collection.addChangeListener(new BookCollection.ChangeListener() { collection.addListener(new BookCollection.Listener() {
public void onCollectionChanged(Code code, Book book) { public void onBookEvent(BookEvent event, Book book) {
switch (code) { switch (event) {
case BookAdded: case Added:
System.err.println("Added " + book.getTitle()); System.err.println("Added " + book.getTitle());
break; break;
case BuildStarted: }
}
public void onBuildEvent(BuildEvent event) {
switch (event) {
case Started:
System.err.println("Build started"); System.err.println("Build started");
break; break;
case BuildSucceeded: case Succeeded:
System.err.println("Build succeeded"); System.err.println("Build succeeded");
break; break;
case BuildCompleted: case Failed:
System.err.println("Build failed");
break;
case Completed:
System.err.println("Build completed with " + collection.size() + " books in " + (System.currentTimeMillis() - start) + " milliseconds"); System.err.println("Build completed with " + collection.size() + " books in " + (System.currentTimeMillis() - start) + " milliseconds");
break; break;
} }

View file

@ -29,39 +29,54 @@ import org.geometerplus.fbreader.Paths;
import org.geometerplus.fbreader.bookmodel.BookReadingException; import org.geometerplus.fbreader.bookmodel.BookReadingException;
public class BookCollection { public class BookCollection {
private final List<ChangeListener> myListeners = Collections.synchronizedList(new LinkedList<ChangeListener>()); private final List<Listener> myListeners = Collections.synchronizedList(new LinkedList<Listener>());
public interface ChangeListener { public interface Listener {
public enum Code { public enum BookEvent {
BookAdded, Added,
BookRemoved, Updated,
BuildStarted, Removed
BuildNotStarted,
BuildSucceeded,
BuildCompleted
} }
void onCollectionChanged(Code code, Book book); public enum BuildEvent {
Started,
NotStarted,
Succeeded,
Failed,
Completed
}
void onBookEvent(BookEvent event, Book book);
void onBuildEvent(BuildEvent event);
} }
public void addChangeListener(ChangeListener listener) { public void addListener(Listener listener) {
myListeners.add(listener); myListeners.add(listener);
} }
public void removeChangeListener(ChangeListener listener) { public void removeListener(Listener listener) {
myListeners.remove(listener); myListeners.remove(listener);
} }
protected void fireModelChangedEvent(ChangeListener.Code code, Book book) { protected void fireBookEvent(Listener.BookEvent event, Book book) {
synchronized (myListeners) { synchronized (myListeners) {
for (ChangeListener l : myListeners) { for (Listener l : myListeners) {
l.onCollectionChanged(code, book); l.onBookEvent(event, book);
}
}
}
protected void fireBuildEvent(Listener.BuildEvent event) {
synchronized (myListeners) {
for (Listener l : myListeners) {
l.onBuildEvent(event);
} }
} }
} }
private final BooksDatabase myDatabase; private final BooksDatabase myDatabase;
private final Map<ZLFile,Book> myBooks = private final Map<ZLFile,Book> myBooksByFile =
Collections.synchronizedMap(new HashMap<ZLFile,Book>()); Collections.synchronizedMap(new LinkedHashMap<ZLFile,Book>());
private final Map<Long,Book> myBooksById =
Collections.synchronizedMap(new HashMap<Long,Book>());
private volatile boolean myBuildStarted = false; private volatile boolean myBuildStarted = false;
public BookCollection(BooksDatabase db) { public BookCollection(BooksDatabase db) {
@ -69,19 +84,27 @@ public class BookCollection {
} }
public int size() { public int size() {
return myBooks.size(); return myBooksByFile.size();
} }
private void addBook(Book book) { private void addBook(Book book) {
if (book == null || myBooks.containsKey(book.File)) { if (book == null || myBooksByFile.containsKey(book.File)) {
return; return;
} }
myBooks.put(book.File, book); myBooksByFile.put(book.File, book);
fireModelChangedEvent(ChangeListener.Code.BookAdded, book); addBookById(book);
fireBookEvent(Listener.BookEvent.Added, book);
}
private void addBookById(Book book) {
final long id = book.getId();
if (id != -1) {
myBooksById.put(id, book);
}
} }
public void removeBook(Book book, boolean deleteFromDisk) { public void removeBook(Book book, boolean deleteFromDisk) {
myBooks.remove(book.File); myBooksByFile.remove(book.File);
final List<Long> ids = myDatabase.loadRecentBookIds(); final List<Long> ids = myDatabase.loadRecentBookIds();
if (ids.remove(book.getId())) { if (ids.remove(book.getId())) {
myDatabase.saveRecentBookIds(ids); myDatabase.saveRecentBookIds(ids);
@ -90,12 +113,12 @@ public class BookCollection {
if (deleteFromDisk) { if (deleteFromDisk) {
book.File.getPhysicalFile().delete(); book.File.getPhysicalFile().delete();
} }
fireModelChangedEvent(ChangeListener.Code.BookRemoved, book); fireBookEvent(Listener.BookEvent.Removed, book);
} }
public List<Book> books() { public List<Book> books() {
synchronized (myBooks) { synchronized (myBooksByFile) {
return new ArrayList<Book>(myBooks.values()); return new ArrayList<Book>(myBooksByFile.values());
} }
} }
@ -104,9 +127,29 @@ public class BookCollection {
return recentIds.size() > index ? Book.getById(recentIds.get(index)) : null; return recentIds.size() > index ? Book.getById(recentIds.get(index)) : null;
} }
public void addBookToRecentList(Book book) {
final List<Long> ids = myDatabase.loadRecentBookIds();
final Long bookId = book.getId();
ids.remove(bookId);
ids.add(0, bookId);
if (ids.size() > 12) {
ids.remove(12);
}
myDatabase.saveRecentBookIds(ids);
}
public void setBookFavorite(Book book, boolean favorite) {
if (favorite) {
myDatabase.addToFavorites(book.getId());
} else {
myDatabase.removeFromFavorites(book.getId());
}
fireBookEvent(Listener.BookEvent.Updated, book);
}
public synchronized void startBuild() { public synchronized void startBuild() {
if (myBuildStarted) { if (myBuildStarted) {
fireModelChangedEvent(ChangeListener.Code.BuildNotStarted, null); fireBuildEvent(Listener.BuildEvent.NotStarted);
return; return;
} }
myBuildStarted = true; myBuildStarted = true;
@ -114,11 +157,13 @@ public class BookCollection {
final Thread builder = new Thread("Library.build") { final Thread builder = new Thread("Library.build") {
public void run() { public void run() {
try { try {
fireModelChangedEvent(ChangeListener.Code.BuildStarted, null); fireBuildEvent(Listener.BuildEvent.Started);
build(); build();
fireModelChangedEvent(ChangeListener.Code.BuildSucceeded, null); fireBuildEvent(Listener.BuildEvent.Succeeded);
} catch (Throwable t) {
fireBuildEvent(Listener.BuildEvent.Failed);
} finally { } finally {
fireModelChangedEvent(ChangeListener.Code.BuildCompleted, null); fireBuildEvent(Listener.BuildEvent.Completed);
myBuildStarted = false; myBuildStarted = false;
} }
} }
@ -213,7 +258,7 @@ public class BookCollection {
} }
} else { } else {
//myRootTree.removeBook(book, true); //myRootTree.removeBook(book, true);
//fireModelChangedEvent(ChangeListener.Code.BookRemoved); //fireBookEvent(Listener.BookEvent.Removed);
orphanedBooks.add(book); orphanedBooks.add(book);
} }
} }
@ -259,6 +304,7 @@ public class BookCollection {
public void run() { public void run() {
for (Book book : newBooks) { for (Book book : newBooks) {
book.save(); book.save();
addBookById(book);
} }
} }
}); });

View file

@ -101,20 +101,25 @@ public final class Library {
public Library(BooksDatabase db) { public Library(BooksDatabase db) {
myDatabase = db; myDatabase = db;
myCollection = new BookCollection(db); myCollection = new BookCollection(db);
myCollection.addChangeListener(new BookCollection.ChangeListener() { myCollection.addListener(new BookCollection.Listener() {
public void onCollectionChanged(Code code, Book book) { public void onBookEvent(BookEvent event, Book book) {
switch (code) { switch (event) {
case BookAdded: case Added:
addBookToLibraryWithNoCheck(book); addBookToLibrary(book);
if (myCollection.size() % 16 == 0) { if (myCollection.size() % 16 == 0) {
Library.this.fireModelChangedEvent(ChangeListener.Code.BookAdded); Library.this.fireModelChangedEvent(ChangeListener.Code.BookAdded);
} }
break; break;
case BuildStarted: }
}
public void onBuildEvent(BuildEvent event) {
switch (event) {
case Started:
Library.this.fireModelChangedEvent(ChangeListener.Code.StatusChanged); Library.this.fireModelChangedEvent(ChangeListener.Code.StatusChanged);
setStatus(myStatusMask | STATUS_LOADING); setStatus(myStatusMask | STATUS_LOADING);
break; break;
case BuildCompleted: case Completed:
Library.this.fireModelChangedEvent(ChangeListener.Code.BookAdded); Library.this.fireModelChangedEvent(ChangeListener.Code.BookAdded);
setStatus(myStatusMask & ~STATUS_LOADING); setStatus(myStatusMask & ~STATUS_LOADING);
break; break;
@ -179,7 +184,7 @@ public final class Library {
} }
} }
private synchronized void addBookToLibraryWithNoCheck(Book book) { private synchronized void addBookToLibrary(Book book) {
final String xml = BookSerializerUtil.serialize(book); final String xml = BookSerializerUtil.serialize(book);
book = BookSerializerUtil.deserialize(xml); book = BookSerializerUtil.deserialize(xml);
@ -265,7 +270,7 @@ public final class Library {
removeFromTree(ROOT_BY_SERIES, book); removeFromTree(ROOT_BY_SERIES, book);
removeFromTree(ROOT_BY_AUTHOR, book); removeFromTree(ROOT_BY_AUTHOR, book);
removeFromTree(ROOT_BY_TAG, book); removeFromTree(ROOT_BY_TAG, book);
addBookToLibraryWithNoCheck(book); addBookToLibrary(book);
fireModelChangedEvent(ChangeListener.Code.BookAdded); fireModelChangedEvent(ChangeListener.Code.BookAdded);
} }
@ -336,14 +341,7 @@ public final class Library {
} }
public void addBookToRecentList(Book book) { public void addBookToRecentList(Book book) {
final List<Long> ids = myDatabase.loadRecentBookIds(); myCollection.addBookToRecentList(book);
final Long bookId = book.getId();
ids.remove(bookId);
ids.add(0, bookId);
if (ids.size() > 12) {
ids.remove(12);
}
myDatabase.saveRecentBookIds(ids);
} }
public boolean isBookInFavorites(Book book) { public boolean isBookInFavorites(Book book) {
@ -365,12 +363,12 @@ public final class Library {
} }
final LibraryTree rootFavorites = getFirstLevelTree(ROOT_FAVORITES); final LibraryTree rootFavorites = getFirstLevelTree(ROOT_FAVORITES);
rootFavorites.getBookSubTree(book, true); rootFavorites.getBookSubTree(book, true);
myDatabase.addToFavorites(book.getId()); myCollection.setBookFavorite(book, true);
} }
public void removeBookFromFavorites(Book book) { public void removeBookFromFavorites(Book book) {
if (getFirstLevelTree(ROOT_FAVORITES).removeBook(book, false)) { if (getFirstLevelTree(ROOT_FAVORITES).removeBook(book, false)) {
myDatabase.removeFromFavorites(book.getId()); myCollection.setBookFavorite(book, false);
fireModelChangedEvent(ChangeListener.Code.BookRemoved); fireModelChangedEvent(ChangeListener.Code.BookRemoved);
} }
} }
@ -400,11 +398,11 @@ public final class Library {
} }
public List<Bookmark> allBookmarks() { public List<Bookmark> allBookmarks() {
return BooksDatabase.Instance().loadAllVisibleBookmarks(); return myDatabase.loadAllVisibleBookmarks();
} }
public List<Bookmark> invisibleBookmarks(Book book) { public List<Bookmark> invisibleBookmarks(Book book) {
final List<Bookmark> list = BooksDatabase.Instance().loadBookmarks(book.getId(), false); final List<Bookmark> list = myDatabase.loadBookmarks(book.getId(), false);
Collections.sort(list, new Bookmark.ByTimeComparator()); Collections.sort(list, new Bookmark.ByTimeComparator());
return list; return list;
} }