package org.mercury_im.messenger.data.repository; import org.mercury_im.messenger.data.mapping.GroupChatMapping; import org.mercury_im.messenger.data.model.GroupChatModel; import org.mercury_im.messenger.data.repository.dao.GroupChatDao; import org.mercury_im.messenger.util.Optional; import org.mercury_im.messenger.entity.Account; import org.mercury_im.messenger.entity.chat.GroupChat; import org.mercury_im.messenger.entity.chat.IGroupChat; import org.mercury_im.messenger.util.ThreadUtils; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; import javax.inject.Named; import io.reactivex.Completable; import io.reactivex.Maybe; import io.reactivex.Observable; import io.reactivex.Scheduler; import io.reactivex.Single; import io.requery.Persistable; import io.requery.query.ResultDelegate; import io.requery.reactivex.ReactiveEntityStore; public class XmppGroupChatRepository extends RequeryRepository implements GroupChatRepository { private final GroupChatMapping groupChatMapping; private final GroupChatDao dao; @Inject public XmppGroupChatRepository( ReactiveEntityStore data, @Named(value = ThreadUtils.SCHEDULER_IO) Scheduler subscriberScheduler, @Named(value = ThreadUtils.SCHEDULER_UI) Scheduler observerScheduler, GroupChatMapping groupChatMapping) { super(data, subscriberScheduler, observerScheduler); this.groupChatMapping = groupChatMapping; this.dao = new GroupChatDao(data); } @Override public Single insertGroupChat(GroupChat chat) { return Single.just(chat) .map(groupChatMapping::toModel) .flatMap(dao::insert) .map(model -> groupChatMapping.toEntity(model, chat)) .subscribeOn(subscriberScheduler()) .observeOn(observerScheduler()); } @Override public Observable> observeGroupChat(long chatId) { return dao.get(chatId).observableResult() .map(ResultDelegate::firstOrNull) .map(groupChatMapping::toEntity) .map(Optional::new) .subscribeOn(subscriberScheduler()) .observeOn(observerScheduler()); } @Override public Maybe getGroupChat(long chatId) { return dao.get(chatId).maybe() .map(groupChatMapping::toEntity) .subscribeOn(subscriberScheduler()) .observeOn(observerScheduler()); } @Override public Single getOrCreateGroupChat(Account account, String roomAddress) { return getGroupChatByRoomAddress(account, roomAddress) .switchIfEmpty( Single.just((GroupChat) new IGroupChat() { { setAccount(account); setRoomAddress(roomAddress); } }) .flatMap(this::insertGroupChat)) .subscribeOn(subscriberScheduler()) .observeOn(observerScheduler()); } @Override public Observable> observeGroupChatByRoomAddress(long accountId, String roomAddress) { return dao.get(accountId, roomAddress).observableResult() .map(ResultDelegate::firstOrNull) .map(groupChatMapping::toEntity) .map(Optional::new) .subscribeOn(subscriberScheduler()) .observeOn(observerScheduler()); } @Override public Maybe getGroupChatByRoomAddress(long accountId, String roomAddress) { return dao.get(accountId, roomAddress).maybe() .map(groupChatMapping::toEntity) .subscribeOn(subscriberScheduler()) .observeOn(observerScheduler()); } @Override public Observable> observeAllGroupChats() { return dao.getAll().observableResult() .map(ResultDelegate::toList) .map(list -> { List entities = new ArrayList<>(list.size()); for (GroupChatModel model : list) { entities.add(groupChatMapping.toEntity(model)); } return entities; }) .subscribeOn(subscriberScheduler()) .observeOn(observerScheduler()); } @Override public Single updateGroupChat(GroupChat chat) { return dao.get(chat.getId()).maybe().toSingle() .map(model -> groupChatMapping.toModel(chat, model)) .flatMap(data()::update) .map(model -> groupChatMapping.toEntity(model, chat)) .subscribeOn(subscriberScheduler()) .observeOn(observerScheduler()); } @Override public Single upsertGroupChat(GroupChat chat) { return dao.get(chat.getId()).maybe() .switchIfEmpty(Single.just(chat).map(groupChatMapping::toModel) .flatMap(dao::insert)) .map(model -> groupChatMapping.toModel(chat, model)) .flatMap(data()::update) .map(model -> groupChatMapping.toEntity(model, chat)) .subscribeOn(subscriberScheduler()) .observeOn(observerScheduler()); } @Override public Completable deleteGroupChat(GroupChat chat) { return dao.delete(chat.getId()).ignoreElement() .subscribeOn(subscriberScheduler()) .observeOn(observerScheduler()); } }