Mercury-IM/core/src/main/java/org/mercury_im/messenger/core/RosterStore.java

197 lines
6.9 KiB
Java
Raw Normal View History

2019-08-12 17:05:30 +02:00
package org.mercury_im.messenger.core;
import org.jivesoftware.smack.roster.packet.RosterPacket;
import org.jxmpp.jid.Jid;
import org.mercury_im.messenger.persistence.model.ContactModel;
import org.mercury_im.messenger.persistence.model.EntityModel;
2019-08-19 02:36:31 +02:00
import org.mercury_im.messenger.persistence.model.RosterInformationModel;
import org.mercury_im.messenger.persistence.repository.RosterRepository;
2019-08-12 17:05:30 +02:00
2019-08-19 02:36:31 +02:00
import java.util.ArrayList;
2019-08-12 17:05:30 +02:00
import java.util.Collection;
2019-08-19 02:36:31 +02:00
import java.util.HashMap;
2019-08-12 17:05:30 +02:00
import java.util.List;
2019-08-19 02:36:31 +02:00
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
2019-08-12 17:05:30 +02:00
import javax.inject.Inject;
2019-08-19 02:36:31 +02:00
import io.reactivex.disposables.CompositeDisposable;
2019-08-12 17:05:30 +02:00
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
public class RosterStore implements org.jivesoftware.smack.roster.rosterstore.RosterStore {
2019-08-19 02:36:31 +02:00
private static final Logger LOGGER = Logger.getLogger(RosterStore.class.getName());
2019-08-12 17:05:30 +02:00
2019-08-19 02:36:31 +02:00
private final RosterRepository rosterRepository;
2019-08-12 17:05:30 +02:00
private long accountId;
2019-08-19 02:36:31 +02:00
private CompositeDisposable disposable = null;
private final Map<Jid, RosterPacket.Item> itemMap = new HashMap<>();
private String rosterVersion;
2019-08-12 17:05:30 +02:00
@Inject
2019-08-19 02:36:31 +02:00
public RosterStore(RosterRepository rosterRepository) {
this.rosterRepository = rosterRepository;
}
2019-08-12 17:05:30 +02:00
2019-08-19 02:36:31 +02:00
public void subscribe() {
LOGGER.log(Level.INFO, "Subscribing...");
if (disposable != null) {
return;
}
disposable = new CompositeDisposable();
disposable.add(rosterRepository.getAllContactsOfAccount(accountId)
2019-08-12 17:05:30 +02:00
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
2019-08-19 02:36:31 +02:00
.subscribe((Consumer<List<? extends ContactModel>>) o -> {
itemMap.clear();
for (ContactModel c : o) {
rosterRepository.getEntityForContact(c.getId()).subscribeOn(Schedulers.io())
.subscribe((Consumer<EntityModel>) o1 -> itemMap.put(o1.getJid(), fromModel(c)));
LOGGER.log(Level.INFO, "Populate itemMap with " + o.size() + " items");
}
}));
disposable.add(rosterRepository.getRosterInformationForAccount(accountId)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.subscribe((Consumer<RosterInformationModel>) s -> {
LOGGER.log(Level.INFO, "Set rosterVer = " + s.getRosterVersion());
rosterVersion = s.getRosterVersion();
}));
}
public void unsubscribe() {
if (disposable == null) {
return;
}
disposable.dispose();
disposable = null;
2019-08-12 17:05:30 +02:00
}
public void setAccountId(long accountId) {
this.accountId = accountId;
}
@Override
public List<RosterPacket.Item> getEntries() {
2019-08-19 02:36:31 +02:00
return new ArrayList<>(itemMap.values());
2019-08-12 17:05:30 +02:00
}
@Override
public RosterPacket.Item getEntry(Jid bareJid) {
2019-08-19 02:36:31 +02:00
return itemMap.get(bareJid);
2019-08-12 17:05:30 +02:00
}
@Override
public String getRosterVersion() {
2019-08-19 02:36:31 +02:00
return rosterVersion != null ? rosterVersion : "";
2019-08-12 17:05:30 +02:00
}
@Override
public boolean addEntry(RosterPacket.Item item, String version) {
2019-08-19 02:36:31 +02:00
LOGGER.log(Level.INFO, "Add entry " + item.toXML().toString());
// Update database
ContactModel contact = toModel(item);
rosterRepository.updateOrInsertContact(contact)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.subscribe();
rosterRepository.updateRosterVersionForAccount(accountId, version)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.subscribe();
return true;
2019-08-12 17:05:30 +02:00
}
@Override
public boolean resetEntries(Collection<RosterPacket.Item> items, String version) {
2019-08-19 02:36:31 +02:00
// Update database
for (RosterPacket.Item item : items) {
rosterRepository.updateOrInsertContact(toModel(item))
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.subscribe();
}
rosterRepository.updateRosterVersionForAccount(accountId, version)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.subscribe();
return true;
2019-08-12 17:05:30 +02:00
}
@Override
public boolean removeEntry(Jid bareJid, String version) {
2019-08-19 02:36:31 +02:00
rosterRepository.deleteContact(accountId, bareJid.asEntityBareJidOrThrow())
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.subscribe();
rosterRepository.updateRosterVersionForAccount(accountId, version)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.subscribe();
return true;
2019-08-12 17:05:30 +02:00
}
@Override
public void resetStore() {
2019-08-19 02:36:31 +02:00
rosterRepository.deleteAllContactsOfAccount(accountId)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.subscribe();
rosterRepository.updateRosterVersionForAccount(accountId, "")
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.subscribe();
2019-08-12 17:05:30 +02:00
}
public RosterPacket.Item fromModel(ContactModel contactModel) {
2019-08-19 02:36:31 +02:00
RosterPacket.Item item = new RosterPacket.Item(
contactModel.getEntity().getJid(),
contactModel.getRosterName());
if (contactModel.getDirection() != null) {
item.setItemType(convert(contactModel.getDirection()));
}
item.setApproved(contactModel.isApproved());
item.setSubscriptionPending(contactModel.isSubscriptionPending());
2019-08-12 17:05:30 +02:00
return item;
}
public ContactModel toModel(RosterPacket.Item item) {
2019-08-19 02:36:31 +02:00
ContactModel contact = rosterRepository.newContactModel();
contact.setAccountId(accountId);
2019-08-12 17:05:30 +02:00
2019-08-19 02:36:31 +02:00
ContactModel attributes = rosterRepository.newContactModel();
2019-08-12 17:05:30 +02:00
attributes.setRosterName(item.getName());
2019-08-19 02:36:31 +02:00
if (item.getItemType() != null) {
attributes.setDirection(convert(item.getItemType()));
}
2019-08-12 17:05:30 +02:00
attributes.setApproved(item.isApproved());
attributes.setSubscriptionPending(item.isSubscriptionPending());
2019-08-19 02:36:31 +02:00
EntityModel entity = rosterRepository.newEntityModel();
entity.setAccountId(accountId);
2019-08-12 17:05:30 +02:00
entity.setJid(item.getJid().asEntityBareJidOrThrow());
contact.setEntity(entity);
return contact;
}
2019-08-19 02:36:31 +02:00
public ContactModel.DIRECTION convert(RosterPacket.ItemType type) {
return ContactModel.DIRECTION.valueOf(type.toString());
2019-08-12 17:05:30 +02:00
}
2019-08-19 02:36:31 +02:00
public RosterPacket.ItemType convert(ContactModel.DIRECTION direction) {
2019-08-12 17:05:30 +02:00
return RosterPacket.ItemType.fromString(direction.toString());
}
}