Fix EntityCapsStore

This commit is contained in:
Paul Schaub 2019-08-20 01:15:30 +02:00
parent e661ffdf65
commit 4a5ccd879d
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
9 changed files with 70 additions and 25 deletions

View File

View File

@ -8,7 +8,12 @@ import android.content.Intent;
import android.os.Build;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.SmackInitialization;
import org.jivesoftware.smack.im.SmackImInitializer;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.util.PacketParserUtils;
import org.mercury_im.messenger.core.ConnectionCenter;
import org.mercury_im.messenger.core.MercuryConfiguration;
import org.mercury_im.messenger.di.component.AppComponent;
import org.mercury_im.messenger.di.component.DaggerAppComponent;
import org.mercury_im.messenger.di.module.AppModule;
@ -22,6 +27,11 @@ public class MercuryImApplication extends Application {
public static final String TAG = "Mercury-IM";
static {
// Initialize Smack etc.
new MercuryConfiguration();
}
private static MercuryImApplication INSTANCE;
AppComponent appComponent;
@ -34,7 +44,7 @@ public class MercuryImApplication extends Application {
@Override
public void onCreate() {
SmackConfiguration.DEBUG = true;
super.onCreate();
INSTANCE = this;

View File

@ -1,6 +1,7 @@
package org.mercury_im.messenger.core;
import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jivesoftware.smackx.caps.EntityCapsManager;
@ -91,7 +92,11 @@ public class ConnectionCenter {
connection.getRoster().setRosterStore(rosterStore);
if (account.getEnabled()) {
LOGGER.log(Level.INFO, "Connecting...");
connection.connect();
LOGGER.log(Level.INFO, "Connected!");
} else {
LOGGER.log(Level.INFO, "Account not enabled. Skip.");
}
}

View File

@ -1,83 +1,98 @@
package org.mercury_im.messenger.core;
import org.jivesoftware.smack.parsing.SmackParsingException;
import org.jivesoftware.smack.xml.SmackXmlParser;
import org.jivesoftware.smack.util.PacketParserUtils;
import org.jivesoftware.smack.xml.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParserException;
import org.jivesoftware.smackx.caps.cache.EntityCapsPersistentCache;
import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
import org.jivesoftware.smackx.disco.provider.DiscoverInfoProvider;
import org.mercury_im.messenger.persistence.model.EntityCapsModel;
import org.mercury_im.messenger.persistence.repository.EntityCapsRepository;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Inject;
import io.reactivex.SingleObserver;
import io.reactivex.Single;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.observers.DisposableSingleObserver;
import io.reactivex.schedulers.Schedulers;
public class EntityCapsStore implements EntityCapsPersistentCache {
private static final Logger LOGGER = Logger.getLogger(EntityCapsStore.class.getName());
private final EntityCapsRepository entityCapsRepository;
private final Map<String, DiscoverInfo> discoverInfoMap = new HashMap<>();
private final DiscoverInfoProvider provider = new DiscoverInfoProvider();
private final CompositeDisposable disposable = new CompositeDisposable();
private Single<List<EntityCapsModel>> allEntityCaps;
@Inject
public EntityCapsStore(EntityCapsRepository repository) {
this.entityCapsRepository = repository;
populateFromDatabase();
}
private void populateFromDatabase() {
discoverInfoMap.clear();
SingleObserver observer = entityCapsRepository.getAllEntityCaps()
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
allEntityCaps = entityCapsRepository.getAllEntityCaps();
disposable.add(allEntityCaps.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribeWith(new DisposableSingleObserver<List<? extends EntityCapsModel>>() {
@Override
public void onSuccess(List<? extends EntityCapsModel> entityCapsModels) {
discoverInfoMap.clear();
for (EntityCapsModel c : entityCapsModels) {
DiscoverInfo info;
try {
info = provider.parse(
SmackXmlParser.newXmlParser(new StringReader(c.getXml())));
} catch (IOException | XmlPullParserException | SmackParsingException e) {
e.printStackTrace();
continue;
XmlPullParser parser = PacketParserUtils.getParserFor(new StringReader(c.getXml()));
info = (DiscoverInfo) PacketParserUtils.parseIQ(parser);
discoverInfoMap.put(c.getNodeVer(), info);
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "Error parsing EntityCaps: ", e);
}
discoverInfoMap.put(c.getNodeVer(), info);
}
}
@Override
public void onError(Throwable e) {
LOGGER.log(Level.SEVERE, "Error processing Caps update from store.", e);
}
});
}));
}
@Override
public void addDiscoverInfoByNodePersistent(String nodeVer, DiscoverInfo info) {
discoverInfoMap.put(nodeVer, info);
EntityCapsModel model = entityCapsRepository.newEntityCapsModel(nodeVer);
model.setXml(info.toXML().toString());
entityCapsRepository.insertOrReplaceEntityCaps(model);
CharSequence xml = info.toXML();
LOGGER.log(Level.INFO, "Persisting entry:" + xml);
String string = xml.toString();
model.setXml(string);
entityCapsRepository.insertOrReplaceEntityCaps(model)
.subscribeOn(Schedulers.io())
.subscribe();
}
@Override
public DiscoverInfo lookup(String nodeVer) {
return discoverInfoMap.get(nodeVer);
LOGGER.log(Level.INFO, "Looking up caps for " + nodeVer + " in cache...");
DiscoverInfo info = discoverInfoMap.get(nodeVer);
LOGGER.log(Level.INFO, "Entry found: " + (info != null ? info.toXML().toString() : "null"));
return info;
}
@Override
public void emptyCache() {
discoverInfoMap.clear();
entityCapsRepository.deleteAllEntityCaps()
.subscribeOn(Schedulers.io())
.subscribe();
}
}

View File

@ -1,7 +1,15 @@
package org.mercury_im.messenger.core;
import org.jivesoftware.smack.SmackConfiguration;
public class MercuryConfiguration {
static {
SmackConfiguration.DEBUG = true;
// Make sure Smack is initialized.
SmackConfiguration.getVersion();
}
public static final String[] enabledCiphers = {
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",

View File

@ -1,16 +1,13 @@
package org.mercury_im.messenger.persistence.room.dao;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.TypeConverters;
import org.jxmpp.jid.EntityBareJid;
import org.mercury_im.messenger.persistence.model.EntityModel;
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 org.mercury_im.messenger.persistence.room.type_converter.EntityBareJidConverter;
import java.util.List;

View File

@ -36,4 +36,7 @@ public interface EntityCapsDao {
@Delete
Completable delete(RoomEntityCapsModel model);
@Query("DELETE FROM entity_caps")
Completable deleteAllEntityCaps();
}

View File

@ -57,4 +57,9 @@ public class IEntityCapsRepository implements EntityCapsRepository<RoomEntityCap
public Completable deleteOrReplaceEntityCaps(RoomEntityCapsModel entityCaps) {
return dao.delete(entityCaps);
}
@Override
public Completable deleteAllEntityCaps() {
return dao.deleteAllEntityCaps();
}
}

View File

@ -22,4 +22,6 @@ public interface EntityCapsRepository<E extends EntityCapsModel> {
Completable deleteOrReplaceEntityCaps(List<E> entityCaps);
Completable deleteOrReplaceEntityCaps(E entityCaps);
Completable deleteAllEntityCaps();
}