From 071a3d8787bef2d0700c56631c1b7a7042febb17 Mon Sep 17 00:00:00 2001 From: Nikolay Pultsin Date: Wed, 9 Jan 2013 07:54:35 +0000 Subject: [PATCH] move code moved from Library to BookCollection --- .../libraryService/LibraryService.java | 22 ++-- .../fbreader/library/BookCollection.java | 106 +++++++++++++----- .../fbreader/library/Library.java | 40 ++++--- 3 files changed, 110 insertions(+), 58 deletions(-) diff --git a/src/org/geometerplus/android/fbreader/libraryService/LibraryService.java b/src/org/geometerplus/android/fbreader/libraryService/LibraryService.java index f2f109508..b9fc8320f 100644 --- a/src/org/geometerplus/android/fbreader/libraryService/LibraryService.java +++ b/src/org/geometerplus/android/fbreader/libraryService/LibraryService.java @@ -36,19 +36,27 @@ public class LibraryService extends Service { } final BookCollection collection = new BookCollection(database); final long start = System.currentTimeMillis(); - collection.addChangeListener(new BookCollection.ChangeListener() { - public void onCollectionChanged(Code code, Book book) { - switch (code) { - case BookAdded: + collection.addListener(new BookCollection.Listener() { + public void onBookEvent(BookEvent event, Book book) { + switch (event) { + case Added: System.err.println("Added " + book.getTitle()); break; - case BuildStarted: + } + } + + public void onBuildEvent(BuildEvent event) { + switch (event) { + case Started: System.err.println("Build started"); break; - case BuildSucceeded: + case Succeeded: System.err.println("Build succeeded"); 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"); break; } diff --git a/src/org/geometerplus/fbreader/library/BookCollection.java b/src/org/geometerplus/fbreader/library/BookCollection.java index 2820a682d..242095745 100644 --- a/src/org/geometerplus/fbreader/library/BookCollection.java +++ b/src/org/geometerplus/fbreader/library/BookCollection.java @@ -29,39 +29,54 @@ import org.geometerplus.fbreader.Paths; import org.geometerplus.fbreader.bookmodel.BookReadingException; public class BookCollection { - private final List myListeners = Collections.synchronizedList(new LinkedList()); + private final List myListeners = Collections.synchronizedList(new LinkedList()); - public interface ChangeListener { - public enum Code { - BookAdded, - BookRemoved, - BuildStarted, - BuildNotStarted, - BuildSucceeded, - BuildCompleted + public interface Listener { + public enum BookEvent { + Added, + Updated, + Removed } - 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); } - public void removeChangeListener(ChangeListener listener) { + public void removeListener(Listener listener) { myListeners.remove(listener); } - protected void fireModelChangedEvent(ChangeListener.Code code, Book book) { + protected void fireBookEvent(Listener.BookEvent event, Book book) { synchronized (myListeners) { - for (ChangeListener l : myListeners) { - l.onCollectionChanged(code, book); + for (Listener l : myListeners) { + 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 Map myBooks = - Collections.synchronizedMap(new HashMap()); + private final Map myBooksByFile = + Collections.synchronizedMap(new LinkedHashMap()); + private final Map myBooksById = + Collections.synchronizedMap(new HashMap()); private volatile boolean myBuildStarted = false; public BookCollection(BooksDatabase db) { @@ -69,19 +84,27 @@ public class BookCollection { } public int size() { - return myBooks.size(); + return myBooksByFile.size(); } private void addBook(Book book) { - if (book == null || myBooks.containsKey(book.File)) { + if (book == null || myBooksByFile.containsKey(book.File)) { return; } - myBooks.put(book.File, book); - fireModelChangedEvent(ChangeListener.Code.BookAdded, book); + myBooksByFile.put(book.File, 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) { - myBooks.remove(book.File); + myBooksByFile.remove(book.File); final List ids = myDatabase.loadRecentBookIds(); if (ids.remove(book.getId())) { myDatabase.saveRecentBookIds(ids); @@ -90,12 +113,12 @@ public class BookCollection { if (deleteFromDisk) { book.File.getPhysicalFile().delete(); } - fireModelChangedEvent(ChangeListener.Code.BookRemoved, book); + fireBookEvent(Listener.BookEvent.Removed, book); } public List books() { - synchronized (myBooks) { - return new ArrayList(myBooks.values()); + synchronized (myBooksByFile) { + return new ArrayList(myBooksByFile.values()); } } @@ -104,9 +127,29 @@ public class BookCollection { return recentIds.size() > index ? Book.getById(recentIds.get(index)) : null; } + public void addBookToRecentList(Book book) { + final List 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() { if (myBuildStarted) { - fireModelChangedEvent(ChangeListener.Code.BuildNotStarted, null); + fireBuildEvent(Listener.BuildEvent.NotStarted); return; } myBuildStarted = true; @@ -114,11 +157,13 @@ public class BookCollection { final Thread builder = new Thread("Library.build") { public void run() { try { - fireModelChangedEvent(ChangeListener.Code.BuildStarted, null); + fireBuildEvent(Listener.BuildEvent.Started); build(); - fireModelChangedEvent(ChangeListener.Code.BuildSucceeded, null); + fireBuildEvent(Listener.BuildEvent.Succeeded); + } catch (Throwable t) { + fireBuildEvent(Listener.BuildEvent.Failed); } finally { - fireModelChangedEvent(ChangeListener.Code.BuildCompleted, null); + fireBuildEvent(Listener.BuildEvent.Completed); myBuildStarted = false; } } @@ -213,7 +258,7 @@ public class BookCollection { } } else { //myRootTree.removeBook(book, true); - //fireModelChangedEvent(ChangeListener.Code.BookRemoved); + //fireBookEvent(Listener.BookEvent.Removed); orphanedBooks.add(book); } } @@ -259,6 +304,7 @@ public class BookCollection { public void run() { for (Book book : newBooks) { book.save(); + addBookById(book); } } }); diff --git a/src/org/geometerplus/fbreader/library/Library.java b/src/org/geometerplus/fbreader/library/Library.java index 8e179f502..320490c2a 100644 --- a/src/org/geometerplus/fbreader/library/Library.java +++ b/src/org/geometerplus/fbreader/library/Library.java @@ -101,20 +101,25 @@ public final class Library { public Library(BooksDatabase db) { myDatabase = db; myCollection = new BookCollection(db); - myCollection.addChangeListener(new BookCollection.ChangeListener() { - public void onCollectionChanged(Code code, Book book) { - switch (code) { - case BookAdded: - addBookToLibraryWithNoCheck(book); + myCollection.addListener(new BookCollection.Listener() { + public void onBookEvent(BookEvent event, Book book) { + switch (event) { + case Added: + addBookToLibrary(book); if (myCollection.size() % 16 == 0) { Library.this.fireModelChangedEvent(ChangeListener.Code.BookAdded); } break; - case BuildStarted: + } + } + + public void onBuildEvent(BuildEvent event) { + switch (event) { + case Started: Library.this.fireModelChangedEvent(ChangeListener.Code.StatusChanged); setStatus(myStatusMask | STATUS_LOADING); break; - case BuildCompleted: + case Completed: Library.this.fireModelChangedEvent(ChangeListener.Code.BookAdded); setStatus(myStatusMask & ~STATUS_LOADING); 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); book = BookSerializerUtil.deserialize(xml); @@ -265,7 +270,7 @@ public final class Library { removeFromTree(ROOT_BY_SERIES, book); removeFromTree(ROOT_BY_AUTHOR, book); removeFromTree(ROOT_BY_TAG, book); - addBookToLibraryWithNoCheck(book); + addBookToLibrary(book); fireModelChangedEvent(ChangeListener.Code.BookAdded); } @@ -336,14 +341,7 @@ public final class Library { } public void addBookToRecentList(Book book) { - final List 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); + myCollection.addBookToRecentList(book); } public boolean isBookInFavorites(Book book) { @@ -365,12 +363,12 @@ public final class Library { } final LibraryTree rootFavorites = getFirstLevelTree(ROOT_FAVORITES); rootFavorites.getBookSubTree(book, true); - myDatabase.addToFavorites(book.getId()); + myCollection.setBookFavorite(book, true); } public void removeBookFromFavorites(Book book) { if (getFirstLevelTree(ROOT_FAVORITES).removeBook(book, false)) { - myDatabase.removeFromFavorites(book.getId()); + myCollection.setBookFavorite(book, false); fireModelChangedEvent(ChangeListener.Code.BookRemoved); } } @@ -400,11 +398,11 @@ public final class Library { } public List allBookmarks() { - return BooksDatabase.Instance().loadAllVisibleBookmarks(); + return myDatabase.loadAllVisibleBookmarks(); } public List invisibleBookmarks(Book book) { - final List list = BooksDatabase.Instance().loadBookmarks(book.getId(), false); + final List list = myDatabase.loadBookmarks(book.getId(), false); Collections.sort(list, new Bookmark.ByTimeComparator()); return list; }