Don't build repositories and data sources dependencies in them

This commit is contained in:
Shinokuni 2020-10-11 22:31:55 +02:00
parent b8219b5dde
commit 9b5dddeff4
7 changed files with 68 additions and 97 deletions

View File

@ -3,17 +3,15 @@ package com.readrops.api.services.freshrss;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.readrops.db.entities.Feed;
import com.readrops.db.entities.Folder;
import com.readrops.db.entities.Item;
import com.readrops.api.services.API;
import com.readrops.api.services.Credentials;
import com.readrops.api.services.SyncResult;
import com.readrops.api.services.SyncType;
import com.readrops.api.services.freshrss.adapters.FreshRSSFeedsAdapter;
import com.readrops.api.services.freshrss.adapters.FreshRSSFoldersAdapter;
import com.readrops.api.services.freshrss.adapters.FreshRSSItemsAdapter;
import com.readrops.api.services.freshrss.json.FreshRSSUserInfo;
import com.readrops.db.entities.Feed;
import com.readrops.db.entities.Folder;
import com.readrops.db.entities.Item;
import com.squareup.moshi.Moshi;
import com.squareup.moshi.Types;
@ -26,17 +24,20 @@ import io.reactivex.Single;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
public class FreshRSSAPI extends API<FreshRSSService> {
public class FreshRSSDataSource {
private static final int MAX_ITEMS = 5000;
public static final String GOOGLE_READ = "user/-/state/com.google/read";
private static final String FEED_PREFIX = "feed/";
public FreshRSSAPI(Credentials credentials) {
super(credentials, FreshRSSService.class, FreshRSSService.END_POINT);
private FreshRSSService api;
public FreshRSSDataSource(FreshRSSService api) {
this.api = api;
}
@Override
protected Moshi buildMoshi() {
return new Moshi.Builder()
.add(Types.newParameterizedType(List.class, Item.class), new FreshRSSItemsAdapter())

View File

@ -2,7 +2,7 @@ package com.readrops.api.services.freshrss.adapters
import android.util.TimingLogger
import com.readrops.db.entities.Item
import com.readrops.api.services.freshrss.FreshRSSAPI.GOOGLE_READ
import com.readrops.api.services.freshrss.FreshRSSDataSource.GOOGLE_READ
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter

View File

@ -8,8 +8,6 @@ import androidx.annotation.Nullable;
import com.readrops.db.entities.Feed;
import com.readrops.db.entities.Folder;
import com.readrops.db.entities.Item;
import com.readrops.api.services.API;
import com.readrops.api.services.Credentials;
import com.readrops.api.services.SyncResult;
import com.readrops.api.services.SyncType;
import com.readrops.api.services.nextcloudnews.adapters.NextNewsFeedsAdapter;
@ -30,15 +28,18 @@ import java.util.Map;
import retrofit2.Response;
public class NextNewsAPI extends API<NextNewsService> {
public class NextNewsDataSource {
private static final String TAG = NextNewsAPI.class.getSimpleName();
private static final String TAG = NextNewsDataSource.class.getSimpleName();
public NextNewsAPI(Credentials credentials) {
super(credentials, NextNewsService.class, NextNewsService.END_POINT);
protected static final int MAX_ITEMS = 5000;
private NextNewsService api;
public NextNewsDataSource(NextNewsService api) {
this.api = api;
}
@Override
protected Moshi buildMoshi() {
return new Moshi.Builder()
.add(new NextNewsFeedsAdapter())

View File

@ -30,26 +30,20 @@ import io.reactivex.Single;
import static com.readrops.app.utils.ReadropsKeys.FEEDS;
public abstract class ARepository<T> {
public abstract class ARepository {
protected Context context;
protected Database database;
protected Account account;
protected T api;
protected SyncResult syncResult;
protected ARepository(@NonNull Context context, @Nullable Account account) {
protected ARepository(Database database, @NonNull Context context, @Nullable Account account) {
this.context = context;
this.database = Database.getInstance(context);
this.database = database;
this.account = account;
api = createAPI();
}
protected abstract T createAPI();
// TODO : replace Single by Completable
public abstract Single<Boolean> login(Account account, boolean insert);
@ -171,20 +165,20 @@ public abstract class ARepository<T> {
context.startService(intent);
}
public static ARepository repositoryFactory(Account account, AccountType accountType, Context context) throws Exception {
public static ARepository repositoryFactory(Account account, AccountType accountType, Context context) {
switch (accountType) {
case LOCAL:
return new LocalFeedRepository(context, account);
return new LocalFeedRepository(null, Database.getInstance(context), context, account);
case NEXTCLOUD_NEWS:
return new NextNewsRepository(context, account);
return new NextNewsRepository(null, Database.getInstance(context), context, account);
case FRESHRSS:
return new FreshRSSRepository(context, account);
return new FreshRSSRepository(null, Database.getInstance(context), context, account);
default:
throw new Exception("account type not supported");
throw new IllegalArgumentException("account type not supported");
}
}
public static ARepository repositoryFactory(Account account, Context context) throws Exception {
public static ARepository repositoryFactory(Account account, Context context) {
return ARepository.repositoryFactory(account, account.getAccountType(), context);
}

View File

@ -7,18 +7,17 @@ import android.util.TimingLogger;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.readrops.api.services.SyncType;
import com.readrops.api.services.freshrss.FreshRSSDataSource;
import com.readrops.api.services.freshrss.FreshRSSSyncData;
import com.readrops.app.utils.FeedInsertionResult;
import com.readrops.app.utils.ParsingResult;
import com.readrops.app.utils.Utils;
import com.readrops.db.Database;
import com.readrops.db.entities.Feed;
import com.readrops.db.entities.Folder;
import com.readrops.db.entities.Item;
import com.readrops.db.entities.account.Account;
import com.readrops.api.services.Credentials;
import com.readrops.api.services.SyncType;
import com.readrops.api.services.freshrss.FreshRSSAPI;
import com.readrops.api.services.freshrss.FreshRSSCredentials;
import com.readrops.api.services.freshrss.FreshRSSSyncData;
import org.joda.time.DateTime;
@ -30,40 +29,30 @@ import io.reactivex.Completable;
import io.reactivex.Observable;
import io.reactivex.Single;
public class FreshRSSRepository extends ARepository<FreshRSSAPI> {
public class FreshRSSRepository extends ARepository {
private static final String TAG = FreshRSSRepository.class.getSimpleName();
public FreshRSSRepository(@NonNull Context context, @Nullable Account account) {
super(context, account);
}
private FreshRSSDataSource dataSource;
@Override
protected FreshRSSAPI createAPI() {
if (account != null)
return new FreshRSSAPI(Credentials.toCredentials(account));
public FreshRSSRepository(FreshRSSDataSource dataSource, Database database, @NonNull Context context, @Nullable Account account) {
super(database, context, account);
return null;
this.dataSource = dataSource;
}
@Override
public Single<Boolean> login(Account account, boolean insert) {
if (api == null)
api = new FreshRSSAPI(Credentials.toCredentials(account));
else
api.setCredentials(Credentials.toCredentials(account));
return api.login(account.getLogin(), account.getPassword())
return dataSource.login(account.getLogin(), account.getPassword())
.flatMap(token -> {
account.setToken(token);
api.setCredentials(new FreshRSSCredentials(token, account.getUrl()));
return api.getWriteToken();
return dataSource.getWriteToken();
})
.flatMap(writeToken -> {
account.setWriteToken(writeToken);
return api.getUserInfo();
return dataSource.getUserInfo();
})
.flatMap(userInfo -> {
account.setDisplayedName(userInfo.getUserName());
@ -100,7 +89,7 @@ public class FreshRSSRepository extends ARepository<FreshRSSAPI> {
syncData.setUnreadItemsIds(database.itemDao().getUnreadChanges(account.getId()));
emitter.onSuccess(syncData);
}).flatMap(syncData1 -> api.sync(syncType, syncData1, account.getWriteToken()))
}).flatMap(syncData1 -> dataSource.sync(syncType, syncData1, account.getWriteToken()))
.flatMapObservable(syncResult -> {
logger.addSplit("server queries");
@ -131,7 +120,7 @@ public class FreshRSSRepository extends ARepository<FreshRSSAPI> {
List<FeedInsertionResult> insertionResults = new ArrayList<>();
for (ParsingResult result : results) {
completableList.add(api.createFeed(account.getWriteToken(), result.getUrl())
completableList.add(dataSource.createFeed(account.getWriteToken(), result.getUrl())
.doOnComplete(() -> {
FeedInsertionResult feedInsertionResult = new FeedInsertionResult();
feedInsertionResult.setParsingResult(result);
@ -159,26 +148,26 @@ public class FreshRSSRepository extends ARepository<FreshRSSAPI> {
Folder folder = feed.getFolderId() == null ? null : database.folderDao().select(feed.getFolderId());
emitter.onSuccess(folder);
}).flatMapCompletable(folder -> api.updateFeed(account.getWriteToken(),
}).flatMapCompletable(folder -> dataSource.updateFeed(account.getWriteToken(),
feed.getUrl(), feed.getName(), folder == null ? null : folder.getRemoteId())
.andThen(super.updateFeed(feed)));
}
@Override
public Completable deleteFeed(Feed feed) {
return api.deleteFeed(account.getWriteToken(), feed.getUrl())
return dataSource.deleteFeed(account.getWriteToken(), feed.getUrl())
.andThen(super.deleteFeed(feed));
}
@Override
public Single<Long> addFolder(Folder folder) {
return api.createFolder(account.getWriteToken(), folder.getName())
return dataSource.createFolder(account.getWriteToken(), folder.getName())
.andThen(super.addFolder(folder));
}
@Override
public Completable updateFolder(Folder folder) {
return api.updateFolder(account.getWriteToken(), folder.getRemoteId(), folder.getName())
return dataSource.updateFolder(account.getWriteToken(), folder.getRemoteId(), folder.getName())
.andThen(Completable.create(emitter -> {
folder.setRemoteId("user/-/label/" + folder.getName());
emitter.onComplete();
@ -188,7 +177,7 @@ public class FreshRSSRepository extends ARepository<FreshRSSAPI> {
@Override
public Completable deleteFolder(Folder folder) {
return api.deleteFolder(account.getWriteToken(), folder.getRemoteId())
return dataSource.deleteFolder(account.getWriteToken(), folder.getRemoteId())
.andThen(super.deleteFolder(folder));
}

View File

@ -9,7 +9,6 @@ import androidx.annotation.Nullable;
import com.readrops.api.localfeed.LocalRSSDataSource;
import com.readrops.api.services.SyncResult;
import com.readrops.api.utils.HttpManager;
import com.readrops.api.utils.LibUtils;
import com.readrops.api.utils.ParseException;
import com.readrops.api.utils.UnknownFormatException;
@ -17,6 +16,7 @@ import com.readrops.app.utils.FeedInsertionResult;
import com.readrops.app.utils.ParsingResult;
import com.readrops.app.utils.SharedPreferencesManager;
import com.readrops.app.utils.Utils;
import com.readrops.db.Database;
import com.readrops.db.entities.Feed;
import com.readrops.db.entities.Item;
import com.readrops.db.entities.account.Account;
@ -34,22 +34,17 @@ import io.reactivex.Single;
import kotlin.Pair;
import okhttp3.Headers;
public class LocalFeedRepository extends ARepository<Void> {
public class LocalFeedRepository extends ARepository {
private static final String TAG = LocalFeedRepository.class.getSimpleName();
private LocalRSSDataSource dataSource;
public LocalFeedRepository(@NonNull Context context, @Nullable Account account) {
super(context, account);
public LocalFeedRepository(LocalRSSDataSource dataSource, Database database, @NonNull Context context, @Nullable Account account) {
super(database, context, account);
syncResult = new SyncResult();
dataSource = new LocalRSSDataSource(HttpManager.getInstance().getOkHttpClient());
}
@Override
protected Void createAPI() {
return null;
this.dataSource = dataSource;
}
@Override

View File

@ -7,16 +7,16 @@ import android.util.TimingLogger;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.readrops.api.services.Credentials;
import com.readrops.api.services.SyncResult;
import com.readrops.api.services.SyncType;
import com.readrops.api.services.nextcloudnews.NextNewsAPI;
import com.readrops.api.services.nextcloudnews.NextNewsDataSource;
import com.readrops.api.services.nextcloudnews.NextNewsSyncData;
import com.readrops.api.services.nextcloudnews.json.NextNewsUser;
import com.readrops.api.utils.UnknownFormatException;
import com.readrops.app.utils.FeedInsertionResult;
import com.readrops.app.utils.ParsingResult;
import com.readrops.app.utils.Utils;
import com.readrops.db.Database;
import com.readrops.db.entities.Feed;
import com.readrops.db.entities.Folder;
import com.readrops.db.entities.Item;
@ -33,31 +33,22 @@ import io.reactivex.Completable;
import io.reactivex.Observable;
import io.reactivex.Single;
public class NextNewsRepository extends ARepository<NextNewsAPI> {
public class NextNewsRepository extends ARepository {
private static final String TAG = NextNewsRepository.class.getSimpleName();
public NextNewsRepository(@NonNull Context context, @Nullable Account account) {
super(context, account);
}
private NextNewsDataSource dataSource;
@Override
protected NextNewsAPI createAPI() {
if (account != null)
return new NextNewsAPI(Credentials.toCredentials(account));
public NextNewsRepository(NextNewsDataSource dataSource, Database database, @NonNull Context context, @Nullable Account account) {
super(database, context, account);
return null;
this.dataSource = dataSource;
}
@Override
public Single<Boolean> login(Account account, boolean insert) {
return Single.<NextNewsUser>create(emitter -> {
if (api == null)
api = new NextNewsAPI(Credentials.toCredentials(account));
else
api.setCredentials(Credentials.toCredentials(account));
NextNewsUser user = api.login();
NextNewsUser user = dataSource.login();
if (user != null) {
emitter.onSuccess(user);
@ -101,7 +92,7 @@ public class NextNewsRepository extends ARepository<NextNewsAPI> {
}
TimingLogger timings = new TimingLogger(TAG, "nextcloud news " + syncType.name().toLowerCase());
SyncResult result = api.sync(syncType, syncData);
SyncResult result = dataSource.sync(syncType, syncData);
timings.addSplit("server queries");
if (!result.isError()) {
@ -141,11 +132,11 @@ public class NextNewsRepository extends ARepository<NextNewsAPI> {
FeedInsertionResult insertionResult = new FeedInsertionResult();
try {
List<Feed> nextNewsFeeds = api.createFeed(result.getUrl(), 0);
List<Feed> nextNewsFeeds = dataSource.createFeed(result.getUrl(), 0);
if (nextNewsFeeds != null) {
List<Feed> newFeeds = insertFeeds(nextNewsFeeds, true);
// there is always only one object in the list, see nextcloud news api doc
// there is always only one object in the list, see nextcloud news dataSource doc
insertionResult.setFeed(newFeeds.get(0));
} else
insertionResult.setInsertionError(FeedInsertionResult.FeedInsertionError.UNKNOWN_ERROR);
@ -180,7 +171,7 @@ public class NextNewsRepository extends ARepository<NextNewsAPI> {
feed.setRemoteFolderId(String.valueOf(0)); // 0 for no folder
try {
if (api.renameFeed(feed) && api.changeFeedFolder(feed)) {
if (dataSource.renameFeed(feed) && dataSource.changeFeedFolder(feed)) {
emitter.onComplete();
} else
emitter.onError(new Exception("Unknown error when updating feed"));
@ -194,7 +185,7 @@ public class NextNewsRepository extends ARepository<NextNewsAPI> {
public Completable deleteFeed(Feed feed) {
return Completable.create(emitter -> {
try {
if (api.deleteFeed(Integer.parseInt(feed.getRemoteId()))) {
if (dataSource.deleteFeed(Integer.parseInt(feed.getRemoteId()))) {
emitter.onComplete();
} else
emitter.onError(new Exception("Unknown error"));
@ -210,7 +201,7 @@ public class NextNewsRepository extends ARepository<NextNewsAPI> {
public Single<Long> addFolder(Folder folder) {
return Single.<Folder>create(emitter -> {
try {
List<Folder> folders = api.createFolder(folder);
List<Folder> folders = dataSource.createFolder(folder);
if (folders != null) {
Folder nextNewsFolder = folders.get(0); // always only one item returned by the server, see doc
@ -229,7 +220,7 @@ public class NextNewsRepository extends ARepository<NextNewsAPI> {
public Completable updateFolder(Folder folder) {
return Completable.create(emitter -> {
try {
if (api.renameFolder(folder)) {
if (dataSource.renameFolder(folder)) {
emitter.onComplete();
} else
emitter.onError(new Exception("Unknown error"));
@ -246,7 +237,7 @@ public class NextNewsRepository extends ARepository<NextNewsAPI> {
public Completable deleteFolder(Folder folder) {
return Completable.create(emitter -> {
try {
if (api.deleteFolder(folder)) {
if (dataSource.deleteFolder(folder)) {
emitter.onComplete();
} else
emitter.onError(new Exception("Unknown error"));