package org.bspeice.minimalbible.activities.downloader.manager; import android.os.Handler; import org.bspeice.minimalbible.MinimalBible; import org.crosswire.jsword.book.Book; import org.crosswire.jsword.book.install.Installer; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.inject.Inject; import javax.inject.Singleton; import rx.Observable; import rx.android.schedulers.AndroidSchedulers; /** * Handle refreshing the list of books available as needed */ @Singleton public class RefreshManager { @Inject DownloadManager downloadManager; /** * Cached copy of modules that are available so we don't refresh for everyone who requests it. */ private Observable>> availableModules; private boolean refreshComplete; public RefreshManager() { MinimalBible.getApplication().inject(this); refreshModules(); } /** * Do the work of kicking off the AsyncTask to refresh books, and make sure we know * when it's done. */ private void refreshModules() { if (availableModules == null) { Handler backgroundHandler = new Handler(); availableModules = Observable.from(downloadManager.getInstallers().values()) .map(installer -> { Map> map = new HashMap>(); map.put(installer, installer.getBooks()); return map; }).observeOn(AndroidSchedulers.handlerThread(backgroundHandler)) .cache(); // Set refresh complete when it is. availableModules.subscribeOn(AndroidSchedulers.handlerThread(backgroundHandler)) .subscribe(null, null, () -> refreshComplete = true); } } /** * Get the cached book list * @return The cached book list, or null */ public List getBookList() { List availableList = new ArrayList<>(); availableModules.reduce(availableList, (books, installerListMap) -> { for (List l : installerListMap.values()) { books.addAll(l); } return books; }); return availableList; } /** * Find the installer that a Book comes from. * @param b The book to search for * @return The Installer that should be used for this book. */ public Observable installerFromBook(Book b) { return availableModules.filter(installerListMap -> { for (List element : installerListMap.values()) { if (element.contains(b)) { return true; } } return false; }) .take(1) .map(element -> element.entrySet().iterator().next().getKey()); } }