264 lines
9.4 KiB
Java
264 lines
9.4 KiB
Java
package org.mercury_im.messenger.persistence.room.repository;
|
|
|
|
import android.util.Log;
|
|
|
|
import org.jxmpp.jid.EntityBareJid;
|
|
import org.mercury_im.messenger.persistence.repository.RosterRepository;
|
|
import org.mercury_im.messenger.persistence.room.dao.ContactDao;
|
|
import org.mercury_im.messenger.persistence.room.dao.EntityDao;
|
|
import org.mercury_im.messenger.persistence.room.dao.RosterInformationDao;
|
|
import org.mercury_im.messenger.persistence.room.model.RoomContactModel;
|
|
import org.mercury_im.messenger.persistence.room.model.RoomEntityModel;
|
|
import org.mercury_im.messenger.persistence.room.model.RoomRosterInformationModel;
|
|
|
|
import java.util.List;
|
|
|
|
import javax.inject.Inject;
|
|
|
|
import io.reactivex.Completable;
|
|
import io.reactivex.Maybe;
|
|
import io.reactivex.Observable;
|
|
import io.reactivex.Single;
|
|
|
|
import static org.mercury_im.messenger.persistence.room.AppDatabase.TAG;
|
|
|
|
public class IRosterRepository extends RosterRepository<RoomEntityModel, RoomContactModel, RoomRosterInformationModel> {
|
|
|
|
private final EntityDao entityDao;
|
|
|
|
@Override
|
|
public Observable<RoomContactModel> getContact(long accountId, EntityBareJid jid) {
|
|
return contactDao.getContactByJid(accountId, jid);
|
|
}
|
|
|
|
private final ContactDao contactDao;
|
|
private final RosterInformationDao rosterInformationDao;
|
|
|
|
@Inject
|
|
public IRosterRepository(EntityDao entityDao, ContactDao contactDao, RosterInformationDao rosterInformationDao) {
|
|
this.contactDao = contactDao;
|
|
this.entityDao = entityDao;
|
|
this.rosterInformationDao = rosterInformationDao;
|
|
}
|
|
|
|
/*
|
|
RoomContactModel
|
|
*/
|
|
|
|
@Override
|
|
public RoomContactModel newContactModel() {
|
|
return new RoomContactModel();
|
|
}
|
|
|
|
@Override
|
|
public Observable<List<RoomContactModel>> getAllContacts() {
|
|
return contactDao.getAllContacts()
|
|
.flatMap(list -> {
|
|
for (RoomContactModel contact : list) {
|
|
RoomEntityModel entity = getEntityForContact(contact).blockingGet();
|
|
contact.setEntity(entity);
|
|
}
|
|
return Observable.just(list);
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public Observable<List<RoomContactModel>> getAllContactsOfAccount(long accountId) {
|
|
return contactDao.getContactsForAccount(accountId)
|
|
.flatMap(list -> {
|
|
for (RoomContactModel contact : list) {
|
|
RoomEntityModel entity = getEntityForContact(contact).blockingGet();
|
|
contact.setEntity(entity);
|
|
}
|
|
return Observable.just(list);
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public Single<Long> upsertContact(RoomContactModel contact) {
|
|
|
|
return Single.fromCallable(() -> {
|
|
RoomEntityModel existingEntityModel = entityDao
|
|
.getEntityFor(contact.getEntity().getAccountId(), contact.getEntity().getJid())
|
|
.blockingGet();
|
|
if (existingEntityModel == null) {
|
|
// Insert missing entity
|
|
existingEntityModel = (RoomEntityModel) contact.getEntity();
|
|
long entityId = insertEntity(existingEntityModel).blockingGet();
|
|
existingEntityModel.setId(entityId);
|
|
contact.setEntity(existingEntityModel);
|
|
} else {
|
|
contact.getEntity().setId(existingEntityModel.getId());
|
|
contact.setEntityId(existingEntityModel.getId());
|
|
entityDao.update((RoomEntityModel) contact.getEntity())
|
|
.doOnSubscribe(ignore -> Log.v(TAG, "Updating entity " + contact.getEntity()))
|
|
.blockingAwait();
|
|
}
|
|
|
|
RoomContactModel existingContactModel = contactDao.getContactForEntityId(existingEntityModel.getId()).blockingGet();
|
|
if (existingContactModel == null) {
|
|
// Insert missing contact
|
|
existingContactModel = contact;
|
|
return insertContact(existingContactModel).blockingGet();
|
|
} else {
|
|
contact.setId(existingContactModel.getId());
|
|
contactDao.update(contact)
|
|
.doOnSubscribe(ignore -> Log.v(TAG, "Updating contact " + contact))
|
|
.doOnComplete(() -> Log.v(TAG, "Update complete"))
|
|
.blockingAwait();
|
|
}
|
|
|
|
return existingContactModel.getId();
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public Single<Long> insertContact(RoomContactModel contact) {
|
|
return contactDao.insert(contact)
|
|
.map(contactId -> {
|
|
contact.setId(contactId);
|
|
return contactId;
|
|
})
|
|
.doOnSubscribe(ignore -> Log.v(TAG, "Insert " + contact))
|
|
.doAfterSuccess(cid -> Log.v(TAG, "Assigned ID " + cid + " to " + contact));
|
|
|
|
}
|
|
|
|
@Override
|
|
public Single<RoomEntityModel> getEntityForContact(long contactId) {
|
|
Single<RoomEntityModel> s = contactDao.getEntityForContactId(contactId);
|
|
return s;
|
|
}
|
|
|
|
@Override
|
|
public Observable<RoomContactModel> getContact(long contactId) {
|
|
return contactDao.getContact(contactId)
|
|
.map(contact -> {
|
|
contact.setEntity(getEntityForContact(contactId).toMaybe().blockingGet());
|
|
contact.setEntityId(contact.getEntity().getId());
|
|
return contact;
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public Maybe<RoomContactModel> maybeGetContact(long id) {
|
|
return contactDao.maybeGetContact(id)
|
|
// Set the entity
|
|
.zipWith(getEntityForContact(id).toMaybe(),
|
|
(contact, entity) -> {
|
|
contact.setEntity(entity);
|
|
contact.setEntityId(entity.getId());
|
|
return contact;
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public Single<RoomEntityModel> getOrCreateEntityForAccountAndJid(long accountId, EntityBareJid jid) {
|
|
return Single.fromCallable(() -> {
|
|
RoomEntityModel existing = getEntityForAccountAndJid(accountId, jid).blockingGet();
|
|
if (existing == null) {
|
|
existing = newEntityModel();
|
|
existing.setAccountId(accountId);
|
|
existing.setJid(jid);
|
|
existing.setId(insertEntity(existing).blockingGet());
|
|
}
|
|
return existing;
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public Maybe<RoomContactModel> getContactForEntity(long entityId) {
|
|
return contactDao.getContactForEntityId(entityId)
|
|
// Set the entity
|
|
.zipWith(getEntity(entityId),
|
|
(contact, entity) -> {
|
|
contact.setEntity(entity);
|
|
contact.setEntityId(entityId);
|
|
return contact;
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public Completable deleteContact(long id) {
|
|
return contactDao.deleteContact(id);
|
|
}
|
|
|
|
@Override
|
|
public Completable deleteContact(RoomContactModel contact) {
|
|
return contactDao.delete(contact);
|
|
}
|
|
|
|
@Override
|
|
public Completable deleteContact(long accountId, EntityBareJid jid) {
|
|
// Since Room does not support "DELETE x FROM X x INNER JOIN Y...", we have to get the
|
|
// entity for the jid first and then delete by using its entityId
|
|
final Maybe<RoomEntityModel> entity = getEntityForAccountAndJid(accountId, jid.asEntityBareJidOrThrow());
|
|
return entity.flatMapCompletable(entityModel -> contactDao.deleteContactForEntity(entityModel.getId()));
|
|
}
|
|
|
|
@Override
|
|
public Completable deleteAllContacts() {
|
|
return contactDao.deleteAll();
|
|
}
|
|
|
|
@Override
|
|
public Completable deleteAllContactsOfAccount(long accountId) {
|
|
return contactDao.deleteAllForAccount(accountId);
|
|
}
|
|
|
|
@Override
|
|
public Completable deleteContacts(long[] ids) {
|
|
return contactDao.deleteContacts(ids);
|
|
}
|
|
|
|
/*
|
|
RoomRosterInformationModel
|
|
*/
|
|
|
|
@Override
|
|
public RoomRosterInformationModel newRosterInformationModel() {
|
|
return new RoomRosterInformationModel();
|
|
}
|
|
|
|
@Override
|
|
public Observable<RoomRosterInformationModel> getRosterInformationForAccount(long accountId) {
|
|
return rosterInformationDao.getRosterInformation(accountId);
|
|
}
|
|
|
|
@Override
|
|
public Single<Long> updateRosterInformation(RoomRosterInformationModel rosterInformation) {
|
|
return rosterInformationDao.insertRosterInformation(rosterInformation)
|
|
.doOnSubscribe(ignore -> Log.v(TAG, "Insert " + rosterInformation));
|
|
}
|
|
|
|
/*
|
|
RoomEntityModel
|
|
*/
|
|
|
|
@Override
|
|
public RoomEntityModel newEntityModel() {
|
|
return new RoomEntityModel();
|
|
}
|
|
|
|
@Override
|
|
public Maybe<RoomEntityModel> getEntity(long id) {
|
|
return entityDao.getEntity(id);
|
|
}
|
|
|
|
@Override
|
|
public Maybe<RoomEntityModel> getEntityForAccountAndJid(long accountId, EntityBareJid jid) {
|
|
return entityDao.getEntityFor(accountId, jid);
|
|
}
|
|
|
|
public Single<Long> insertEntity(RoomEntityModel entityModel) {
|
|
return entityDao.insert(entityModel)
|
|
.map(entityId -> {
|
|
entityModel.setId(entityId);
|
|
return entityId;
|
|
})
|
|
.doOnSubscribe(ignore -> Log.v(TAG, "Insert " + entityModel))
|
|
.doAfterSuccess(entityId -> Log.v(TAG, "Assign ID " + entityId + " to " + entityModel));
|
|
}
|
|
|
|
}
|