Mercury-IM/core-old/src/main/java/org/mercury_im/messenger/core/stores/EntityCapsStore.java

102 lines
4.4 KiB
Java
Raw Normal View History

2019-08-25 17:54:03 +02:00
package org.mercury_im.messenger.core.stores;
2019-08-04 22:36:30 +02:00
2019-08-20 01:15:30 +02:00
import org.jivesoftware.smack.util.PacketParserUtils;
import org.jivesoftware.smack.xml.XmlPullParser;
2019-08-04 22:36:30 +02:00
import org.jivesoftware.smackx.caps.cache.EntityCapsPersistentCache;
import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
import org.mercury_im.messenger.data.model.EntityCapsModel;
import org.mercury_im.messenger.data.repository.XmppEntityCapsRepository;
2019-08-04 22:36:30 +02:00
2019-08-10 21:50:03 +02:00
import java.io.StringReader;
2019-08-04 22:36:30 +02:00
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
2019-08-20 01:15:30 +02:00
import java.util.logging.Level;
import java.util.logging.Logger;
2019-08-04 22:36:30 +02:00
import javax.inject.Inject;
2019-08-20 01:15:30 +02:00
import io.reactivex.disposables.CompositeDisposable;
2019-08-04 22:36:30 +02:00
public class EntityCapsStore implements EntityCapsPersistentCache {
2019-08-20 01:15:30 +02:00
private static final Logger LOGGER = Logger.getLogger(EntityCapsStore.class.getName());
private final XmppEntityCapsRepository entityCapsRepository;
2019-08-04 22:36:30 +02:00
private final Map<String, DiscoverInfo> discoverInfoMap = new HashMap<>();
2019-08-20 01:15:30 +02:00
private final CompositeDisposable disposable = new CompositeDisposable();
2019-08-10 21:50:03 +02:00
2019-08-04 22:36:30 +02:00
@Inject
public EntityCapsStore(XmppEntityCapsRepository entityCapsRepository) {
this.entityCapsRepository = entityCapsRepository;
2019-08-20 01:15:30 +02:00
populateFromDatabase();
2019-08-04 22:36:30 +02:00
}
/*
* Since nodeVers are - if ever - only deleted all at once but added one by one and never
* modified, we can simply determine the set of newly added nodeVers, process those and add
* them to the database.
*/
2019-08-04 22:36:30 +02:00
private void populateFromDatabase() {
disposable.add(entityCapsRepository.getAll()
.subscribe(
entityCapsModels -> {
Map<String, EntityCapsModel> nextEntityCaps = entityCapsModels.toMap(EntityCapsModel.NODE_VER);
// New set of nodeVers
Set<String> nextKeys = nextEntityCaps.keySet();
// Old set of nodeVers
Set<String> previousKeys = discoverInfoMap.keySet();
// Added nodeVers
nextKeys.removeAll(previousKeys);
for (String key : nextKeys) {
// Only add new items. Items itself cannot change, so we don't have to deal
// with changed items.
EntityCapsModel addedModel = nextEntityCaps.get(key);
DiscoverInfo info;
try {
XmlPullParser parser = PacketParserUtils.getParserFor(new StringReader(addedModel.getXml()));
info = (DiscoverInfo) PacketParserUtils.parseIQ(parser);
discoverInfoMap.put(addedModel.getNodeVer(), info);
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "Error parsing EntityCaps: ", e);
}
}
},
error -> LOGGER.log(Level.WARNING, "An error occurred while updating the EntityCaps cache.", error)));
2019-08-04 22:36:30 +02:00
}
@Override
public void addDiscoverInfoByNodePersistent(String nodeVer, DiscoverInfo info) {
EntityCapsModel model = new EntityCapsModel();
model.setNodeVer(nodeVer);
2019-08-20 01:15:30 +02:00
CharSequence xml = info.toXML();
String string = xml.toString();
model.setXml(string);
disposable.add(entityCapsRepository.upsert(model).subscribe(
success -> LOGGER.log(Level.FINE, "Upserted EntityCaps model " + success),
error -> LOGGER.log(Level.WARNING, "An error occurred upserting EntityCaps model", error)
));
2019-08-04 22:36:30 +02:00
}
@Override
public DiscoverInfo lookup(String nodeVer) {
LOGGER.log(Level.FINE, "Looking up caps for " + nodeVer + " in cache...");
2019-08-20 01:15:30 +02:00
DiscoverInfo info = discoverInfoMap.get(nodeVer);
LOGGER.log(Level.FINE, "Entry found: " + (info != null ? info.toXML().toString() : "null"));
2019-08-20 01:15:30 +02:00
return info;
2019-08-04 22:36:30 +02:00
}
@Override
public void emptyCache() {
disposable.add(entityCapsRepository.deleteAll().subscribe(
success -> LOGGER.log(Level.FINE, "EntityCaps table cleared successfully."),
error -> LOGGER.log(Level.WARNING, "An error occurred while clearing EntityCaps table.", error)
));
2019-08-04 22:36:30 +02:00
}
}