Mercury-IM/persistence/src/main/java/org/mercury_im/messenger/persistence/repository/RosterRepository.java
2019-08-24 23:06:06 +02:00

255 lines
8.9 KiB
Java

package org.mercury_im.messenger.persistence.repository;
import org.jxmpp.jid.EntityBareJid;
import org.mercury_im.messenger.persistence.model.AccountModel;
import org.mercury_im.messenger.persistence.model.ContactModel;
import org.mercury_im.messenger.persistence.model.EntityModel;
import org.mercury_im.messenger.persistence.model.RosterInformationModel;
import java.util.List;
import io.reactivex.Completable;
import io.reactivex.Maybe;
import io.reactivex.Observable;
import io.reactivex.Single;
import io.reactivex.functions.Consumer;
public abstract class RosterRepository<E extends EntityModel, C extends ContactModel, V extends RosterInformationModel> {
/*
ContactModel
*/
/**
* Create a new empty concrete {@link ContactModel}.
* This method is used as a factory method, as the core module will not know about any concrete
* implementations of {@link ContactModel}.
*
* @return new empty {@link ContactModel}
*/
public abstract C newContactModel();
/**
* Return an observable list of {@link ContactModel ContactModels}.
* Note: This method will return all contacts of all accounts.
*
* @return ALL {@link ContactModel ContactModels} currently in the database.
*/
public abstract Observable<List<C>> getAllContacts();
/**
* Return an observable list of all {@link ContactModel ContactModels} that belong to
* the account with the given accountId.
*
* @param accountId ID of the account
* @return all {@link ContactModel ContactModels} of the account
*/
public abstract Observable<List<C>> getAllContactsOfAccount(long accountId);
/**
* Return an observable list of all {@link ContactModel ContactModels} that belong to the
* given {@link AccountModel}.
*
* @param account account
* @return all {@link ContactModel ContactModels} of the account
*/
public Observable<List<C>> getAllContactsOfAccount(AccountModel account) {
return getAllContactsOfAccount(account.getId());
}
/**
* Update or insert an {@link ContactModel}.
* The method returns a {@link Single} which wraps the ID assigned to the {@link ContactModel}.
*
* @param contact contact
* @return single wrapping the contacts ID
*/
public abstract Single<Long> updateOrInsertContact(C contact);
/**
* Return the {@link ContactModel} corresponding to the given ID wrapped in a {@link Maybe}.
*
* @param id ID of the contact
* @return {@link Maybe} wrapping the {@link ContactModel}
*/
public abstract Maybe<C> getContact(long id);
public Maybe<C> getContact(long accountId, EntityBareJid jid) {
return getEntity(accountId, jid).flatMap(this::getContactForEntity);
}
/**
* Return the {@link ContactModel} which belongs to the given entityId, wrapped in a {@link Maybe}.
*
* @param entityId ID of the entity
* @return {@link Maybe} wrapping the {@link ContactModel}.
*/
public abstract Maybe<C> getContactForEntity(long entityId);
public Maybe<C> getContactForEntity(EntityModel entityModel) {
return getContactForEntity(entityModel.getId());
}
/**
* Delete a {@link ContactModel} from the database.
* This method returns a {@link Completable} which will invoke {@link Completable#complete()}
* once the {@link ContactModel} was successfully deleted, or will invoke
* {@link Completable#error(Throwable)} if an error occurs.
*
* @param id ID of the {@link ContactModel}
* @return {@link Completable}
*/
public abstract Completable deleteContact(long id);
/**
* Delete a {@link ContactModel} from the database.
* This method returns a {@link Completable} which will invoke {@link Completable#complete()}
* once the {@link ContactModel} was successfully deleted, or will invoke
* {@link Completable#error(Throwable)} if an error occurs.
*
* @param contact the {@link ContactModel} to be deleted
* @return {@link Completable}
*/
public Completable deleteContact(C contact) {
return deleteContact(contact.getId());
}
public abstract Completable deleteContact(long accountId, EntityBareJid jid);
public abstract Completable deleteAllContacts();
public abstract Completable deleteAllContactsOfAccount(long accountId);
public Completable deleteAllContactsOfAccount(AccountModel account) {
return deleteAllContactsOfAccount(account.getId());
}
public abstract Completable deleteContacts(long[] ids);
public Completable deleteContacts(C[] contacts) {
long[] ids = new long[contacts.length];
for (int i = 0; i < contacts.length; i++) {
ids[i] = contacts[i].getId();
}
return deleteContacts(ids);
}
/*
RosterInformationModel
*/
/**
* Create an empty, concrete implementation of {@link RosterInformationModel}.
* This method is used as a factory method, as the core module may not know about the concrete
* implementation of {@link RosterInformationModel} in use.
*
* @return concrete, empty {@link RosterInformationModel}
*/
public abstract V newRosterInformationModel();
/**
* Return an {@link Observable} wrapping the {@link RosterInformationModel} for the given
* account id.
*
* @param accountId ID of the account
* @return {@link Observable} wrapping the {@link RosterInformationModel}.
*/
public abstract Observable<V> getRosterInformationForAccount(long accountId);
/**
* Return an {@link Observable} wrapping the {@link RosterInformationModel} for the given
* account.
*
* @param account account
* @return {@link Observable} wrapping the {@link RosterInformationModel}.
*/
public Observable<V> getRosterInformationForAccount(AccountModel account) {
return getRosterInformationForAccount(account.getId());
}
public abstract Single<Long> updateRosterInformation(V rosterInformation);
public Single<Long> updateRosterVersionForAccount(long accountID, String rosterVersion) {
V info = newRosterInformationModel();
info.setAccountId(accountID);
info.setRosterVersion(rosterVersion);
return updateRosterInformation(info);
}
public Single<Long> updateRosterVersionForAccount(AccountModel accountModel, String rosterVersion) {
return updateRosterVersionForAccount(accountModel.getId(), rosterVersion);
}
/*
EntityModel
*/
/**
* Create an empty instance of a concrete implementation of the {@link EntityModel} class.
* This method is used as a factory method, as the core module may not know about the concrete
* implementation of {@link EntityModel} in use.
*
* @return new empty concrete implementation object.
*/
public abstract E newEntityModel();
/**
* Return the {@link EntityModel} with the given ID wrapped in a {@link Maybe}.
*
* @param id ID of the {@link EntityModel}
* @return {@link Maybe} wrapping the {@link EntityModel}
*/
public abstract Maybe<E> getEntity(long id);
/**
* Return the {@link EntityModel} which belongs to the given {@link ContactModel}.
* This method returns a {@link Single} instead of a {@link Maybe}, as per definition a
* {@link ContactModel} MUST have a corresponding {@link EntityModel} in the database.
*
* @param contact {@link ContactModel} of which we want to have the {@link EntityModel}
* @return {@link Single} wrapping the {@link EntityModel}
*/
public Single<E> getEntity(C contact) {
return getEntity(contact.getEntityId()).toSingle();
}
/**
* Return the {@link EntityModel} which belongs to the given accountID and jid, wrapped in a
* {@link Maybe}.
*
* @param accountId ID of the {@link AccountModel} to which the {@link EntityModel} points with
* a foreign key
* @param jid {@link EntityBareJid} of the {@link EntityModel}
* @return
*/
public abstract Maybe<E> getEntity(long accountId, EntityBareJid jid);
/**
* Return the {@link EntityModel} which has foreign keys pointing to the {@link AccountModel}
* and {@link EntityBareJid}, wrapped in a {@link Maybe}.
*
* @param account {@link AccountModel}
* @param jid {@link EntityBareJid}
* @return
*/
public Maybe<E> getEntity(AccountModel account, EntityBareJid jid) {
return getEntity(account.getId(), jid);
}
public abstract Single<E> getEntityForContact(long contactId);
public Single<E> getEntityForContact(C contact) {
return getEntityForContact(contact.getId());
}
/**
* Insert or replace a {@link EntityModel} in the database.
*
* @param entity {@link EntityModel} which we want to insert or replace in the database
* @return {@link Single} which wraps the ID assigned to the entity
*/
public abstract Single<Long> insertOrReplaceEntity(E entity);
}