mirror of https://github.com/kurisufriend/Clover
parent
a91cc5155c
commit
7ef0243922
@ -0,0 +1,189 @@ |
||||
/* |
||||
* Clover - 4chan browser https://github.com/Floens/Clover/
|
||||
* Copyright (C) 2014 Floens |
||||
* |
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
package org.floens.chan.core.repository; |
||||
|
||||
import android.util.Pair; |
||||
|
||||
import org.floens.chan.core.database.DatabaseBoardManager; |
||||
import org.floens.chan.core.database.DatabaseManager; |
||||
import org.floens.chan.core.model.orm.Board; |
||||
import org.floens.chan.core.site.Site; |
||||
import org.floens.chan.utils.Time; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Observable; |
||||
import java.util.Observer; |
||||
|
||||
import javax.inject.Inject; |
||||
import javax.inject.Singleton; |
||||
|
||||
@Singleton |
||||
public class BoardRepository implements Observer { |
||||
private final DatabaseManager databaseManager; |
||||
private final DatabaseBoardManager databaseBoardManager; |
||||
|
||||
private final SiteRepository siteRepository; |
||||
private final SiteRepository.Sites allSites; |
||||
|
||||
private SitesBoards allBoards = new SitesBoards(); |
||||
private SitesBoards savedBoards = new SitesBoards(); |
||||
|
||||
@Inject |
||||
public BoardRepository(DatabaseManager databaseManager, SiteRepository siteRepository) { |
||||
this.databaseManager = databaseManager; |
||||
databaseBoardManager = databaseManager.getDatabaseBoardManager(); |
||||
|
||||
this.siteRepository = siteRepository; |
||||
|
||||
allSites = this.siteRepository.all(); |
||||
allSites.addObserver(this); |
||||
} |
||||
|
||||
public void initialize() { |
||||
updateObservablesSync(); |
||||
} |
||||
|
||||
@Override |
||||
public void update(Observable o, Object arg) { |
||||
if (o == allSites) { |
||||
updateObservablesAsync(); |
||||
} |
||||
} |
||||
|
||||
public void updateAvailableBoardsForSite(Site site, List<Board> availableBoards) { |
||||
databaseManager.runTask(databaseBoardManager.createAll(site, availableBoards)); |
||||
} |
||||
|
||||
public Board getFromCode(Site site, String code) { |
||||
for (SiteBoards siteBoards : allBoards.get()) { |
||||
if (siteBoards.site.id() == site.id()) { |
||||
for (Board board : siteBoards.boards) { |
||||
if (board.code.equals(code)) { |
||||
return board; |
||||
} |
||||
|
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
public SitesBoards getAll() { |
||||
return allBoards; |
||||
} |
||||
|
||||
public SitesBoards getSaved() { |
||||
return savedBoards; |
||||
} |
||||
|
||||
public List<Board> getSiteBoards(Site site) { |
||||
for (SiteBoards item : allBoards.siteBoards) { |
||||
if (item.site.id() == site.id()) { |
||||
return item.boards; |
||||
} |
||||
} |
||||
return new ArrayList<>(); |
||||
} |
||||
|
||||
public List<Board> getSiteSavedBoards(Site site) { |
||||
for (SiteBoards item : savedBoards.siteBoards) { |
||||
if (item.site.id() == site.id()) { |
||||
return item.boards; |
||||
} |
||||
} |
||||
return new ArrayList<>(); |
||||
} |
||||
|
||||
public void updateBoardOrders(List<Board> boards) { |
||||
databaseManager.runTaskAsync(databaseBoardManager.updateOrders(boards), |
||||
(e) -> updateObservablesAsync()); |
||||
} |
||||
|
||||
public void setSaved(Board board, boolean saved) { |
||||
board.saved = saved; |
||||
databaseManager.runTaskAsync(databaseBoardManager.updateIncludingUserFields(board), |
||||
(e) -> updateObservablesAsync()); |
||||
} |
||||
|
||||
public void setAllSaved(List<Board> boards, boolean saved) { |
||||
for (Board board : boards) { |
||||
board.saved = saved; |
||||
} |
||||
databaseManager.runTaskAsync(databaseBoardManager.updateIncludingUserFields(boards), |
||||
(e) -> updateObservablesAsync()); |
||||
} |
||||
|
||||
private void updateObservablesSync() { |
||||
long start = Time.startTiming(); |
||||
updateWith(databaseManager.runTask( |
||||
databaseBoardManager.getBoardsForAllSitesOrdered(allSites.getAll()))); |
||||
Time.endTiming("BoardRepository.updateObservablesSync", start); |
||||
} |
||||
|
||||
private void updateObservablesAsync() { |
||||
databaseManager.runTaskAsync( |
||||
databaseBoardManager.getBoardsForAllSitesOrdered(allSites.getAll()), |
||||
this::updateWith); |
||||
} |
||||
|
||||
private void updateWith(List<Pair<Site, List<Board>>> databaseData) { |
||||
List<SiteBoards> all = new ArrayList<>(); |
||||
List<SiteBoards> saved = new ArrayList<>(); |
||||
for (Pair<Site, List<Board>> item : databaseData) { |
||||
all.add(new SiteBoards(item.first, item.second)); |
||||
|
||||
List<Board> savedBoards = new ArrayList<>(); |
||||
for (Board board : item.second) { |
||||
if (board.saved) savedBoards.add(board); |
||||
} |
||||
saved.add(new SiteBoards(item.first, savedBoards)); |
||||
} |
||||
|
||||
allBoards.set(all); |
||||
savedBoards.set(saved); |
||||
|
||||
allBoards.notifyObservers(); |
||||
savedBoards.notifyObservers(); |
||||
} |
||||
|
||||
public class SitesBoards extends Observable { |
||||
private List<SiteBoards> siteBoards = new ArrayList<>(); |
||||
|
||||
public void set(List<SiteBoards> siteBoards) { |
||||
this.siteBoards = siteBoards; |
||||
setChanged(); |
||||
} |
||||
|
||||
public List<SiteBoards> get() { |
||||
return siteBoards; |
||||
} |
||||
} |
||||
|
||||
public class SiteBoards { |
||||
public final Site site; |
||||
public final List<Board> boards; |
||||
|
||||
public SiteBoards(Site site, List<Board> boards) { |
||||
this.site = site; |
||||
this.boards = boards; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,249 @@ |
||||
package org.floens.chan.core.repository; |
||||
|
||||
import android.util.Pair; |
||||
import android.util.SparseArray; |
||||
|
||||
import org.floens.chan.core.database.DatabaseManager; |
||||
import org.floens.chan.core.model.json.site.SiteConfig; |
||||
import org.floens.chan.core.model.orm.SiteModel; |
||||
import org.floens.chan.core.settings.json.JsonSettings; |
||||
import org.floens.chan.core.site.Site; |
||||
import org.floens.chan.core.site.SiteRegistry; |
||||
import org.floens.chan.core.site.sites.chan4.Chan4; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.Observable; |
||||
|
||||
import javax.inject.Inject; |
||||
import javax.inject.Singleton; |
||||
|
||||
@Singleton |
||||
public class SiteRepository { |
||||
private DatabaseManager databaseManager; |
||||
|
||||
private Sites sitesObservable = new Sites(); |
||||
|
||||
// Shortcut
|
||||
private static SiteRepository instance; |
||||
|
||||
public static Site forId(int id) { |
||||
return instance.sitesObservable.forId(id); |
||||
} |
||||
|
||||
@Inject |
||||
public SiteRepository(DatabaseManager databaseManager) { |
||||
instance = this; |
||||
this.databaseManager = databaseManager; |
||||
} |
||||
|
||||
public Sites all() { |
||||
return sitesObservable; |
||||
} |
||||
|
||||
public SiteModel byId(int id) { |
||||
return databaseManager.runTask(databaseManager.getDatabaseSiteManager() |
||||
.byId(id)); |
||||
} |
||||
|
||||
public void setId(SiteModel siteModel, int id) { |
||||
databaseManager.runTask(databaseManager.getDatabaseSiteManager() |
||||
.updateId(siteModel, id)); |
||||
} |
||||
|
||||
public void updateSiteUserSettingsAsync(SiteModel siteModel, JsonSettings jsonSettings) { |
||||
siteModel.storeUserSettings(jsonSettings); |
||||
databaseManager.runTaskAsync(databaseManager.getDatabaseSiteManager() |
||||
.update(siteModel)); |
||||
} |
||||
|
||||
public Map<Integer, Integer> getOrdering() { |
||||
return databaseManager.runTask(databaseManager.getDatabaseSiteManager().getOrdering()); |
||||
} |
||||
|
||||
public void updateSiteOrderingAsync(List<Site> sites) { |
||||
List<Integer> ids = new ArrayList<>(sites.size()); |
||||
for (Site site : sites) { |
||||
ids.add(site.id()); |
||||
} |
||||
|
||||
databaseManager.runTaskAsync( |
||||
databaseManager.getDatabaseSiteManager().updateOrdering(ids), |
||||
(r) -> { |
||||
sitesObservable.wasReordered(); |
||||
sitesObservable.notifyObservers(); |
||||
}); |
||||
} |
||||
|
||||
public void initialize() { |
||||
List<Site> sites = new ArrayList<>(); |
||||
|
||||
List<SiteModel> models = databaseManager.runTask( |
||||
databaseManager.getDatabaseSiteManager().getAll()); |
||||
|
||||
for (SiteModel siteModel : models) { |
||||
SiteConfigSettingsHolder holder = instantiateSiteFromModel(siteModel); |
||||
|
||||
Site site = holder.site; |
||||
SiteConfig config = holder.config; |
||||
JsonSettings settings = holder.settings; |
||||
|
||||
site.initialize(siteModel.id, config, settings); |
||||
|
||||
sites.add(site); |
||||
} |
||||
|
||||
sitesObservable.addAll(sites); |
||||
|
||||
for (Site site : sites) { |
||||
site.postInitialize(); |
||||
} |
||||
|
||||
sitesObservable.notifyObservers(); |
||||
} |
||||
|
||||
// Called before #initialize to add the old 4chan site when the database was upgraded from
|
||||
// an older version. It only adds the model to the database with id 0.
|
||||
public void addLegacySite() { |
||||
Site site = new Chan4(); |
||||
|
||||
SiteConfig config = new SiteConfig(); |
||||
config.classId = SiteRegistry.SITE_CLASSES.indexOfValue(site.getClass()); |
||||
config.external = false; |
||||
|
||||
SiteModel model = createFromClass(config, new JsonSettings()); |
||||
setId(model, 0); |
||||
} |
||||
|
||||
public Site createFromClass(Class<? extends Site> siteClass) { |
||||
Site site = instantiateSiteClass(siteClass); |
||||
|
||||
SiteConfig config = new SiteConfig(); |
||||
JsonSettings settings = new JsonSettings(); |
||||
|
||||
config.classId = SiteRegistry.SITE_CLASSES.indexOfValue(site.getClass()); |
||||
config.external = false; |
||||
|
||||
SiteModel model = createFromClass(config, settings); |
||||
|
||||
site.initialize(model.id, config, settings); |
||||
|
||||
sitesObservable.add(site); |
||||
|
||||
site.postInitialize(); |
||||
|
||||
sitesObservable.notifyObservers(); |
||||
|
||||
return site; |
||||
} |
||||
|
||||
private SiteModel createFromClass(SiteConfig config, JsonSettings userSettings) { |
||||
SiteModel siteModel = new SiteModel(); |
||||
siteModel.storeConfig(config); |
||||
siteModel.storeUserSettings(userSettings); |
||||
databaseManager.runTask(databaseManager.getDatabaseSiteManager().add(siteModel)); |
||||
|
||||
return siteModel; |
||||
} |
||||
|
||||
private SiteConfigSettingsHolder instantiateSiteFromModel(SiteModel siteModel) { |
||||
Pair<SiteConfig, JsonSettings> configFields = siteModel.loadConfigFields(); |
||||
SiteConfig config = configFields.first; |
||||
JsonSettings settings = configFields.second; |
||||
|
||||
return new SiteConfigSettingsHolder( |
||||
instantiateSiteClass(config.classId), |
||||
config, |
||||
settings); |
||||
} |
||||
|
||||
private Site instantiateSiteClass(int classId) { |
||||
Class<? extends Site> clazz = SiteRegistry.SITE_CLASSES.get(classId); |
||||
if (clazz == null) { |
||||
throw new IllegalArgumentException("Unknown class id"); |
||||
} |
||||
return instantiateSiteClass(clazz); |
||||
} |
||||
|
||||
private Site instantiateSiteClass(Class<? extends Site> clazz) { |
||||
Site site; |
||||
try { |
||||
site = clazz.newInstance(); |
||||
} catch (InstantiationException e) { |
||||
throw new IllegalArgumentException(); |
||||
} catch (IllegalAccessException e) { |
||||
throw new IllegalArgumentException(); |
||||
} |
||||
return site; |
||||
} |
||||
|
||||
public class Sites extends Observable { |
||||
private List<Site> sites = Collections.unmodifiableList(new ArrayList<>()); |
||||
private SparseArray<Site> sitesById = new SparseArray<>(); |
||||
|
||||
public Site forId(int id) { |
||||
Site s = sitesById.get(id); |
||||
if (s == null) { |
||||
throw new IllegalArgumentException("No site with id (" + id + ")"); |
||||
} |
||||
return s; |
||||
} |
||||
|
||||
public List<Site> getAll() { |
||||
return new ArrayList<>(sites); |
||||
} |
||||
|
||||
public List<Site> getAllInOrder() { |
||||
Map<Integer, Integer> ordering = getOrdering(); |
||||
|
||||
List<Site> ordered = new ArrayList<>(sites); |
||||
Collections.sort(ordered, |
||||
(lhs, rhs) -> ordering.get(lhs.id()) - ordering.get(rhs.id())); |
||||
|
||||
return ordered; |
||||
} |
||||
|
||||
private void addAll(List<Site> all) { |
||||
List<Site> copy = new ArrayList<>(sites); |
||||
copy.addAll(all); |
||||
resetSites(copy); |
||||
setChanged(); |
||||
} |
||||
|
||||
private void add(Site site) { |
||||
List<Site> copy = new ArrayList<>(sites); |
||||
copy.add(site); |
||||
resetSites(copy); |
||||
setChanged(); |
||||
} |
||||
|
||||
// We don't keep the order ourselves here, that's the task of listeners. Do notify the
|
||||
// listeners.
|
||||
private void wasReordered() { |
||||
setChanged(); |
||||
} |
||||
|
||||
private void resetSites(List<Site> newSites) { |
||||
sites = Collections.unmodifiableList(newSites); |
||||
SparseArray<Site> byId = new SparseArray<>(newSites.size()); |
||||
for (Site newSite : newSites) { |
||||
byId.put(newSite.id(), newSite); |
||||
} |
||||
sitesById = byId; |
||||
} |
||||
} |
||||
|
||||
private class SiteConfigSettingsHolder { |
||||
Site site; |
||||
SiteConfig config; |
||||
JsonSettings settings; |
||||
|
||||
public SiteConfigSettingsHolder(Site site, SiteConfig config, JsonSettings settings) { |
||||
this.site = site; |
||||
this.config = config; |
||||
this.settings = settings; |
||||
} |
||||
} |
||||
} |
@ -1,63 +0,0 @@ |
||||
package org.floens.chan.core.site; |
||||
|
||||
import org.floens.chan.core.database.DatabaseManager; |
||||
import org.floens.chan.core.model.json.site.SiteConfig; |
||||
import org.floens.chan.core.model.orm.SiteModel; |
||||
import org.floens.chan.core.settings.json.JsonSettings; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import javax.inject.Inject; |
||||
|
||||
public class SiteRepository { |
||||
private DatabaseManager databaseManager; |
||||
|
||||
@Inject |
||||
public SiteRepository(DatabaseManager databaseManager) { |
||||
this.databaseManager = databaseManager; |
||||
} |
||||
|
||||
public List<SiteModel> all() { |
||||
return databaseManager.runTask(databaseManager.getDatabaseSiteManager().getAll()); |
||||
} |
||||
|
||||
public SiteModel byId(int id) { |
||||
return databaseManager.runTask(databaseManager.getDatabaseSiteManager() |
||||
.byId(id)); |
||||
} |
||||
|
||||
public SiteModel create(SiteConfig config, JsonSettings userSettings) { |
||||
SiteModel siteModel = new SiteModel(); |
||||
siteModel.storeConfig(config); |
||||
siteModel.storeUserSettings(userSettings); |
||||
databaseManager.runTask(databaseManager.getDatabaseSiteManager().add(siteModel)); |
||||
return siteModel; |
||||
} |
||||
|
||||
public void setId(SiteModel siteModel, int id) { |
||||
databaseManager.runTask(databaseManager.getDatabaseSiteManager() |
||||
.updateId(siteModel, id)); |
||||
} |
||||
|
||||
public void updateSiteUserSettingsAsync(SiteModel siteModel, JsonSettings jsonSettings) { |
||||
siteModel.storeUserSettings(jsonSettings); |
||||
databaseManager.runTaskAsync(databaseManager.getDatabaseSiteManager() |
||||
.update(siteModel)); |
||||
} |
||||
|
||||
public Map<Integer, Integer> getOrdering() { |
||||
return databaseManager.runTask(databaseManager.getDatabaseSiteManager().getOrdering()); |
||||
} |
||||
|
||||
public void updateSiteOrderingAsync(List<Site> sites, Runnable done) { |
||||
List<Integer> ids = new ArrayList<>(sites.size()); |
||||
for (Site site : sites) { |
||||
ids.add(site.id()); |
||||
} |
||||
|
||||
databaseManager.runTaskAsync(databaseManager.getDatabaseSiteManager().updateOrdering(ids), |
||||
result -> done.run()); |
||||
} |
||||
} |
@ -1,35 +0,0 @@ |
||||
package org.floens.chan.core.site; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
public class Sites { |
||||
private static List<Site> ALL_SITES = Collections.unmodifiableList(new ArrayList<Site>()); |
||||
|
||||
/** |
||||
* Return all sites known in the system. |
||||
* <p>This list is immutable. Changes to the known sites cause this function to return a new immutable list |
||||
* with the site changes. |
||||
* |
||||
* @return list of sites known in the system. |
||||
*/ |
||||
public static List<Site> allSites() { |
||||
return ALL_SITES; |
||||
} |
||||
|
||||
public static Site forId(int id) { |
||||
// TODO: better datastructure
|
||||
for (Site site : ALL_SITES) { |
||||
if (site.id() == id) { |
||||
return site; |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
static void initialize(List<Site> sites) { |
||||
Sites.ALL_SITES = Collections.unmodifiableList(new ArrayList<>(sites)); |
||||
} |
||||
} |
Loading…
Reference in new issue