Delete old core-old module
This commit is contained in:
parent
fc754aa076
commit
5e47b39c5e
|
@ -1 +0,0 @@
|
|||
/build
|
|
@ -1,44 +0,0 @@
|
|||
apply plugin: 'java-library'
|
||||
|
||||
// Add the generated folder to the source directories so that we can work with generated classes
|
||||
// This is apparently necessary for use with requery.
|
||||
sourceSets {
|
||||
main.java.srcDirs += "${buildDir}/generated/sources/annotationProcessor/java/main/"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
api project(':entity')
|
||||
|
||||
// Smack
|
||||
// Not all of those are needed, but it may be a good idea to define those versions explicitly
|
||||
api "org.igniterealtime.smack:smack-core:$smackCoreVersion"
|
||||
api "org.igniterealtime.smack:smack-experimental:$smackExperimentalVersion"
|
||||
api "org.igniterealtime.smack:smack-extensions:$smackExtensionsVersion"
|
||||
api "org.igniterealtime.smack:smack-im:$smackImVersion"
|
||||
api "org.igniterealtime.smack:smack-tcp:$smackTcpVersion"
|
||||
|
||||
// api "org.igniterealtime.smack:smack-omemo:$smackOmemoVersion"
|
||||
// api "org.igniterealtime.smack:smack-omemo-signal:$smackOmemoSignalVersion"
|
||||
// api "org.igniterealtime.smack:smack-openpgp:$smackOpenpgpVersion"
|
||||
// api "org.igniterealtime.smack:smack-resolver-minidns:$smackResolverMiniDnsVersion"
|
||||
|
||||
|
||||
// RxJava2
|
||||
api "io.reactivex.rxjava2:rxjava:$rxJava2Version"
|
||||
|
||||
// Dagger 2 for dependency injection
|
||||
implementation "com.google.dagger:dagger:$daggerVersion"
|
||||
annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion"
|
||||
|
||||
// Requery ORM
|
||||
api "io.requery:requery:$requeryVersion"
|
||||
annotationProcessor "io.requery:requery-processor:$requeryVersion"
|
||||
|
||||
// JUnit for testing
|
||||
testImplementation "junit:junit:$junitVersion"
|
||||
compile project(path: ':data')
|
||||
}
|
||||
|
||||
sourceCompatibility = "8"
|
||||
targetCompatibility = "8"
|
|
@ -1,18 +0,0 @@
|
|||
package org.mercury_im.domain.data.util;
|
||||
|
||||
import org.mercury_im.messenger.entity.contact.Peer;
|
||||
|
||||
public class ContactNameUtil {
|
||||
|
||||
public static String displayableNameFrom(Peer contact) {
|
||||
if (contact == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (contact.getName() != null) {
|
||||
return contact.getName();
|
||||
}
|
||||
|
||||
return contact.getAddress();
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package org.mercury_im.messenger.core;
|
||||
|
||||
|
||||
import org.mercury_im.messenger.xmpp.util.ChatAndPossiblyContact;
|
||||
|
||||
public interface NotificationManager {
|
||||
|
||||
int chatMessageReceived(ChatAndPossiblyContact chatAndPossiblyContact, String body);
|
||||
|
||||
}
|
|
@ -1,245 +0,0 @@
|
|||
package org.mercury_im.messenger.core.centers;
|
||||
|
||||
import org.jivesoftware.smack.AbstractXMPPConnection;
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
|
||||
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
|
||||
import org.jivesoftware.smackx.caps.EntityCapsManager;
|
||||
import org.jivesoftware.smackx.csi.ClientStateIndicationManager;
|
||||
import org.jivesoftware.smackx.mam.MamManager;
|
||||
import org.mercury_im.messenger.core.connection.MercuryConfiguration;
|
||||
import org.mercury_im.messenger.core.connection.MercuryConnection;
|
||||
import org.mercury_im.messenger.xmpp.model.AccountModel;
|
||||
import org.mercury_im.messenger.xmpp.model.ChatModel;
|
||||
import org.mercury_im.messenger.xmpp.repository.RequeryAccountRepository;
|
||||
import org.mercury_im.messenger.xmpp.repository.RosterRepository;
|
||||
import org.mercury_im.messenger.core.stores.EntityCapsStore;
|
||||
import org.mercury_im.messenger.core.stores.PlainMessageStore;
|
||||
import org.mercury_im.messenger.core.stores.RosterStore;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
@Singleton
|
||||
public class ConnectionCenter {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(ConnectionCenter.class.getName());
|
||||
|
||||
// Injected
|
||||
private final RequeryAccountRepository accountRepository;
|
||||
private final RosterRepository rosterRepository;
|
||||
private final PlainMessageStore messageStore;
|
||||
private final EntityCapsStore entityCapsStore;
|
||||
|
||||
// Connections
|
||||
private final Map<Long, MercuryConnection> connectionMap =
|
||||
Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
// Disposable for rx
|
||||
private final CompositeDisposable disposable = new CompositeDisposable();
|
||||
|
||||
private final AtomicBoolean isConnectionCenterStarted = new AtomicBoolean(false);
|
||||
|
||||
@Inject
|
||||
public ConnectionCenter(EntityCapsStore capsStore,
|
||||
PlainMessageStore messageStore,
|
||||
RequeryAccountRepository accountRepository,
|
||||
RosterRepository rosterRepository) {
|
||||
LOGGER.log(Level.INFO, "ConnectionCenter initialized");
|
||||
this.entityCapsStore = capsStore;
|
||||
this.messageStore = messageStore;
|
||||
this.accountRepository = accountRepository;
|
||||
this.rosterRepository = rosterRepository;
|
||||
|
||||
EntityCapsManager.setPersistentCache(capsStore);
|
||||
startUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start up the center by subscribing to changes of the {@link AccountModel accounts} in the
|
||||
* database. For each new {@link AccountModel} it creates a {@link MercuryConnection} and
|
||||
* stores it in the {@link #connectionMap}.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public synchronized void startUp() {
|
||||
|
||||
if (isConnectionCenterStarted.getAndSet(true)) {
|
||||
// already started.
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise subscribe to accounts and create connections.
|
||||
Disposable allAccounts = accountRepository.getAll()
|
||||
.observeOn(Schedulers.newThread())
|
||||
.subscribe(accounts -> {
|
||||
LOGGER.log(Level.INFO, "Accounts changed.");
|
||||
Set<Long> accountIds = new HashSet<>();
|
||||
|
||||
// Add missing connections to the map
|
||||
for (AccountModel account : accounts.toList()) {
|
||||
accountIds.add(account.getId());
|
||||
if (connectionMap.get(account.getId()) != null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LOGGER.log(Level.INFO, "Add new connection " + account.getJid().toString() + " to ConnectionCenter list.");
|
||||
MercuryConnection connection = createConnection(account);
|
||||
connectionMap.put(account.getId(), connection);
|
||||
|
||||
// initialize new connection
|
||||
initializeConnection(connection);
|
||||
}
|
||||
|
||||
// Remove unwanted connections from the map
|
||||
for (long connectionId : connectionMap.keySet()) {
|
||||
if (!accountIds.contains(connectionId)) {
|
||||
LOGGER.log(Level.INFO, "Connection " + connectionId + " was deleted.");
|
||||
AbstractXMPPConnection con =
|
||||
(AbstractXMPPConnection) connectionMap.get(connectionId).getConnection();
|
||||
con.disconnect();
|
||||
connectionMap.remove(connectionId);
|
||||
}
|
||||
}
|
||||
|
||||
for (AccountModel account : accounts) {
|
||||
MercuryConnection connection = connectionMap.get(account.getId());
|
||||
if (account.isEnabled()) {
|
||||
if (connection.getConnection().isConnected()) {
|
||||
continue;
|
||||
}
|
||||
LOGGER.log(Level.INFO, "Connecting connection " + account.getId() + " (" + account.getJid().toString() + ")");
|
||||
connection.connect();
|
||||
LOGGER.log(Level.INFO, "Connected!");
|
||||
} else {
|
||||
if (!connection.getConnection().isConnected()) {
|
||||
continue;
|
||||
}
|
||||
LOGGER.log(Level.INFO, "Account " + account.getJid() + " (" + account.getJid().toString() + ") not enabled. Disable.");
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
disposable.add(allAccounts);
|
||||
}
|
||||
|
||||
public MercuryConnection getConnection(AccountModel account) {
|
||||
return getConnection(account.getId());
|
||||
}
|
||||
|
||||
public MercuryConnection getConnection(long accountId) {
|
||||
return connectionMap.get(accountId);
|
||||
}
|
||||
|
||||
public void putConnection(MercuryConnection connection) {
|
||||
connectionMap.put(connection.getAccountId(), connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link MercuryConnection} with an underlying {@link XMPPTCPConnection}
|
||||
* from the credentials of an {@link AccountModel}.
|
||||
* The new connection will not be connected.
|
||||
*
|
||||
* @param accountModel accountModel
|
||||
*
|
||||
* @return disconnected mercury connection
|
||||
*/
|
||||
public MercuryConnection createConnection(AccountModel accountModel) {
|
||||
LOGGER.log(Level.INFO, "Create Connection for " + accountModel.getJid().toString());
|
||||
XMPPTCPConnectionConfiguration configuration = XMPPTCPConnectionConfiguration.builder()
|
||||
.setHost(accountModel.getJid().getDomain().toString())
|
||||
.setXmppAddressAndPassword(accountModel.getJid(), accountModel.getPassword())
|
||||
.setConnectTimeout(2 * 60 * 1000)
|
||||
.setEnabledSSLCiphers(MercuryConfiguration.enabledCiphers)
|
||||
.setEnabledSSLProtocols(MercuryConfiguration.enabledProtocols)
|
||||
.build();
|
||||
|
||||
AbstractXMPPConnection tcpConnection = new XMPPTCPConnection(configuration);
|
||||
return new MercuryConnection(tcpConnection, accountModel.getId());
|
||||
}
|
||||
|
||||
public void initializeConnection(MercuryConnection connection) {
|
||||
// Register roster store
|
||||
RosterStore rosterStore = new RosterStore(rosterRepository, accountRepository);
|
||||
rosterStore.setAccountId(connection.getAccountId());
|
||||
rosterStore.subscribe();
|
||||
connection.getRoster().setRosterStore(rosterStore);
|
||||
|
||||
// Register message store
|
||||
messageStore.registerForMercuryConnection(connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Client State Indication status to active.
|
||||
*
|
||||
* @see <a href="https://xmpp.org/extensions/xep-0352.html">XEP-0352: Client State Indication</a>
|
||||
*/
|
||||
public void clientStateActive() {
|
||||
LOGGER.log(Level.INFO, "CSI: App is going to foreground -> active");
|
||||
for (MercuryConnection mercuryConnection : connectionMap.values()) {
|
||||
XMPPConnection connection = mercuryConnection.getConnection();
|
||||
if (connection.isConnected() && ClientStateIndicationManager.isSupported(connection)) {
|
||||
try {
|
||||
ClientStateIndicationManager.active(mercuryConnection.getConnection());
|
||||
} catch (SmackException.NotConnectedException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Client State Indication status to inactive.
|
||||
*
|
||||
* @see <a href="https://xmpp.org/extensions/xep-0352.html">XEP-0352: Client State Indication</a>
|
||||
*/
|
||||
public void clientStateInactive() {
|
||||
LOGGER.log(Level.INFO, "CSI: App is going to background -> inactive");
|
||||
for (MercuryConnection mercuryConnection : connectionMap.values()) {
|
||||
XMPPConnection connection = mercuryConnection.getConnection();
|
||||
if (connection.isConnected() && ClientStateIndicationManager.isSupported(connection)) {
|
||||
try {
|
||||
ClientStateIndicationManager.inactive(connection);
|
||||
} catch (SmackException.NotConnectedException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void requestMamMessagesFor(ChatModel chat) {
|
||||
|
||||
MercuryConnection connection = connectionMap.get(chat.getPeer().getAccount().getId());
|
||||
if (connection == null) return;
|
||||
MamManager mamManager = MamManager.getInstanceFor(connection.getConnection());
|
||||
MamManager.MamQuery query;
|
||||
//if (chat.getEarliestMamMessageId() == null) {
|
||||
try {
|
||||
query = mamManager.queryMostRecentPage(chat.getPeer().getJid(), 100);
|
||||
messageStore.handleMamResult(chat.getPeer().getAccount().getId(), chat.getPeer().getJid(), query);
|
||||
} catch (SmackException.NoResponseException | XMPPException.XMPPErrorException | SmackException.NotConnectedException | SmackException.NotLoggedInException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
//} else {
|
||||
//MamManager.MamQueryArgs queryArgs = MamManager.MamQueryArgs.builder()
|
||||
// .beforeUid()
|
||||
// .build();
|
||||
//query = mamManager.queryArchive()
|
||||
//}
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
package org.mercury_im.messenger.core.centers;
|
||||
|
||||
public class ContactCenter {
|
||||
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package org.mercury_im.messenger.core.centers;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class MessageCenter {
|
||||
|
||||
private final ConnectionCenter connectionCenter;
|
||||
|
||||
@Inject
|
||||
public MessageCenter(ConnectionCenter connectionCenter) {
|
||||
this.connectionCenter = connectionCenter;
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
package org.mercury_im.messenger.core.connection;
|
||||
|
||||
/**
|
||||
* {@link MercuryConnection} modeled as a finite state machine.
|
||||
* Below enums represent the states of the machine.
|
||||
*/
|
||||
public enum ConnectionState {
|
||||
|
||||
/**
|
||||
* Connection is disconnected.
|
||||
* This is the initial state of the machine.
|
||||
*/
|
||||
DISCONNECTED,
|
||||
|
||||
/**
|
||||
* The connection is in the process of connecting to the server.
|
||||
* This state can be reached by issuing a connect() call from within the {@link #DISCONNECTED}
|
||||
* state.
|
||||
*/
|
||||
CONNECTING,
|
||||
|
||||
/**
|
||||
* The connection is successfully connected to the server and the stream has been initiated.
|
||||
*/
|
||||
CONNECTED,
|
||||
|
||||
/**
|
||||
* THe connection is authenticated.
|
||||
* In this state the connection is ready to send and receive stanzas.
|
||||
*/
|
||||
AUTHENTICATED,
|
||||
|
||||
/**
|
||||
* The connection is in the process of shutting down.
|
||||
*/
|
||||
DISCONNECTING,
|
||||
|
||||
/**
|
||||
* The device doesn't have usable network connectivity.
|
||||
*/
|
||||
WAITING_FOR_NETWORK,
|
||||
|
||||
/**
|
||||
* The connection already (unsuccessfully) tried to connect, but failed due to lack of network
|
||||
* connectivity and is now waiting to retry connecting.
|
||||
*/
|
||||
WAITING_FOR_RETRY
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
package org.mercury_im.messenger.core.connection;
|
||||
|
||||
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",
|
||||
"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
|
||||
"TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
|
||||
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",
|
||||
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
|
||||
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",
|
||||
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA"
|
||||
};
|
||||
|
||||
public static final String[] enabledProtocols = {
|
||||
"TLSv1.2",
|
||||
"TLSv1.3"
|
||||
};
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
package org.mercury_im.messenger.core.connection;
|
||||
|
||||
import org.jivesoftware.smack.AbstractXMPPConnection;
|
||||
import org.jivesoftware.smack.ConnectionListener;
|
||||
import org.jivesoftware.smack.ReconnectionManager;
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.chat2.ChatManager;
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.smack.roster.Roster;
|
||||
import org.jivesoftware.smackx.carbons.CarbonManager;
|
||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||
import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
|
||||
import org.jivesoftware.smackx.iqversion.VersionManager;
|
||||
import org.jivesoftware.smackx.mam.MamManager;
|
||||
import org.jivesoftware.smackx.sid.StableUniqueStanzaIdManager;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import io.reactivex.subjects.BehaviorSubject;
|
||||
|
||||
public class MercuryConnection {
|
||||
|
||||
public static final String TAG = "Mercury";
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(MercuryConnection.class.getName());
|
||||
|
||||
private final AbstractXMPPConnection mConnection;
|
||||
private final long mAccountId;
|
||||
|
||||
// Managers
|
||||
private final ReconnectionManager mReconnectionManager;
|
||||
private final Roster mRoster;
|
||||
private final ChatManager mChatManager;
|
||||
private final CarbonManager mCarbonManager;
|
||||
private final StableUniqueStanzaIdManager mStanzaIdManager;
|
||||
private final ServiceDiscoveryManager mServiceDiscoveryManager;
|
||||
private final MamManager mMamManager;
|
||||
private final VersionManager mVersionManager;
|
||||
|
||||
private BehaviorSubject<ConnectionState> mState = BehaviorSubject.createDefault(ConnectionState.DISCONNECTED);
|
||||
|
||||
|
||||
public MercuryConnection(AbstractXMPPConnection connection, long accountId) {
|
||||
mConnection = connection;
|
||||
mConnection.addConnectionListener(mConnectionListener);
|
||||
mAccountId = accountId;
|
||||
|
||||
mReconnectionManager = ReconnectionManager.getInstanceFor(connection);
|
||||
mReconnectionManager.enableAutomaticReconnection();
|
||||
mReconnectionManager.abortPossiblyRunningReconnection();
|
||||
|
||||
mRoster = Roster.getInstanceFor(connection);
|
||||
mRoster.setRosterLoadedAtLogin(true);
|
||||
|
||||
mChatManager = ChatManager.getInstanceFor(connection);
|
||||
mCarbonManager = CarbonManager.getInstanceFor(connection);
|
||||
|
||||
mStanzaIdManager = StableUniqueStanzaIdManager.getInstanceFor(connection);
|
||||
mStanzaIdManager.enable();
|
||||
|
||||
mServiceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(connection);
|
||||
mServiceDiscoveryManager.setIdentity(new DiscoverInfo.Identity("client", "Mercury", "phone"));
|
||||
|
||||
mVersionManager = VersionManager.getInstanceFor(connection);
|
||||
mVersionManager.setVersion("Mercury", "0.0.1-stealth", "Android");
|
||||
VersionManager.setAutoAppendSmackVersion(false);
|
||||
|
||||
mMamManager = MamManager.getInstanceFor(connection);
|
||||
}
|
||||
|
||||
public void connect() throws InterruptedException, XMPPException, SmackException, IOException {
|
||||
LOGGER.log(Level.INFO, "Connecting...");
|
||||
mState.onNext(ConnectionState.CONNECTING);
|
||||
AbstractXMPPConnection con = (AbstractXMPPConnection) getConnection();
|
||||
|
||||
con.connect().login();
|
||||
}
|
||||
|
||||
public void disconnect() throws SmackException.NotConnectedException {
|
||||
AbstractXMPPConnection con = (AbstractXMPPConnection) getConnection();
|
||||
mState.onNext(ConnectionState.DISCONNECTING);
|
||||
|
||||
con.disconnect(new Presence(Presence.Type.unavailable));
|
||||
|
||||
mState.onNext(ConnectionState.DISCONNECTED);
|
||||
}
|
||||
|
||||
public XMPPConnection getConnection() {
|
||||
return mConnection;
|
||||
}
|
||||
|
||||
public long getAccountId() {
|
||||
return mAccountId;
|
||||
}
|
||||
|
||||
public Roster getRoster() {
|
||||
return mRoster;
|
||||
}
|
||||
|
||||
|
||||
private final ConnectionListener mConnectionListener = new ConnectionListener() {
|
||||
|
||||
@Override
|
||||
public void connected(XMPPConnection connection) {
|
||||
mState.onNext(ConnectionState.CONNECTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void authenticated(XMPPConnection connection, boolean resumed) {
|
||||
mState.onNext(ConnectionState.AUTHENTICATED);
|
||||
LOGGER.info("Connection " + getAccountId() + " authenticated (" + (resumed ? "resumed" : "initially") + ")");
|
||||
if (!resumed) {
|
||||
LOGGER.info("Enabling carbons!");
|
||||
mCarbonManager.enableCarbonsAsync(exception -> {
|
||||
LOGGER.severe("Could not enable carbons for connection " + mAccountId + ".");
|
||||
exception.printStackTrace();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionClosed() {
|
||||
mState.onNext(ConnectionState.DISCONNECTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionClosedOnError(Exception e) {
|
||||
mState.onNext(ConnectionState.DISCONNECTED);
|
||||
}
|
||||
};
|
||||
|
||||
public BehaviorSubject<ConnectionState> getState() {
|
||||
return mState;
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
package org.mercury_im.messenger.core.di;
|
||||
|
||||
import org.mercury_im.messenger.core.NotificationManager;
|
||||
import org.mercury_im.messenger.core.centers.ConnectionCenter;
|
||||
import org.mercury_im.messenger.core.stores.EntityCapsStore;
|
||||
import org.mercury_im.messenger.core.stores.PlainMessageStore;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
@Module
|
||||
public class CenterModule {
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
static ConnectionCenter provideConnectionCenter(EntityCapsStore capsStore,
|
||||
PlainMessageStore messageStore,
|
||||
AccountRepository accountRepository,
|
||||
RosterRepository rosterRepository) {
|
||||
return new ConnectionCenter(capsStore, messageStore, accountRepository, rosterRepository);
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
static EntityCapsStore providerEntityCapsStore(EntityCapsRepository entityCapsRepository) {
|
||||
return new EntityCapsStore(entityCapsRepository);
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
static PlainMessageStore provideMessageStore(RosterRepository rosterRepository,
|
||||
ChatRepository chatRepository,
|
||||
MessageRepository messageRepository,
|
||||
NotificationManager notificationManager) {
|
||||
return new PlainMessageStore(rosterRepository, chatRepository, messageRepository, notificationManager);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
package org.mercury_im.messenger.core.di;
|
||||
|
||||
import org.mercury_im.messenger.xmpp.di.RequeryModule;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import dagger.Component;
|
||||
|
||||
@Singleton
|
||||
@Component(modules = {
|
||||
CenterModule.class,
|
||||
RequeryModule.class
|
||||
})
|
||||
public interface XmppComponent {
|
||||
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
package org.mercury_im.messenger.core.stores;
|
||||
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.jivesoftware.smack.xml.XmlPullParser;
|
||||
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;
|
||||
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
|
||||
public class EntityCapsStore implements EntityCapsPersistentCache {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(EntityCapsStore.class.getName());
|
||||
|
||||
private final XmppEntityCapsRepository entityCapsRepository;
|
||||
private final Map<String, DiscoverInfo> discoverInfoMap = new HashMap<>();
|
||||
|
||||
private final CompositeDisposable disposable = new CompositeDisposable();
|
||||
|
||||
@Inject
|
||||
public EntityCapsStore(XmppEntityCapsRepository entityCapsRepository) {
|
||||
this.entityCapsRepository = entityCapsRepository;
|
||||
populateFromDatabase();
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
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)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDiscoverInfoByNodePersistent(String nodeVer, DiscoverInfo info) {
|
||||
EntityCapsModel model = new EntityCapsModel();
|
||||
model.setNodeVer(nodeVer);
|
||||
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)
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DiscoverInfo lookup(String nodeVer) {
|
||||
LOGGER.log(Level.FINE, "Looking up caps for " + nodeVer + " in cache...");
|
||||
DiscoverInfo info = discoverInfoMap.get(nodeVer);
|
||||
LOGGER.log(Level.FINE, "Entry found: " + (info != null ? info.toXML().toString() : "null"));
|
||||
return info;
|
||||
}
|
||||
|
||||
@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)
|
||||
));
|
||||
}
|
||||
}
|
|
@ -1,202 +0,0 @@
|
|||
package org.mercury_im.messenger.core.stores;
|
||||
|
||||
import org.jivesoftware.smack.chat2.Chat;
|
||||
import org.jivesoftware.smack.chat2.ChatManager;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smackx.carbons.CarbonManager;
|
||||
import org.jivesoftware.smackx.carbons.packet.CarbonExtension;
|
||||
import org.jivesoftware.smackx.delay.DelayInformationManager;
|
||||
import org.jivesoftware.smackx.delay.packet.DelayInformation;
|
||||
import org.jivesoftware.smackx.mam.MamManager;
|
||||
import org.jivesoftware.smackx.sid.element.OriginIdElement;
|
||||
import org.jivesoftware.smackx.sid.element.StanzaIdElement;
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.mercury_im.messenger.core.NotificationManager;
|
||||
import org.mercury_im.messenger.core.connection.MercuryConnection;
|
||||
import org.mercury_im.messenger.xmpp.model.ChatModel;
|
||||
import org.mercury_im.messenger.xmpp.model.ContactModel;
|
||||
import org.mercury_im.messenger.xmpp.model.EntityModel;
|
||||
import org.mercury_im.messenger.xmpp.model.LastChatMessageRelation;
|
||||
import org.mercury_im.messenger.xmpp.model.MessageModel;
|
||||
import org.mercury_im.messenger.xmpp.repository.ChatRepository;
|
||||
import org.mercury_im.messenger.xmpp.repository.MessageRepository;
|
||||
import org.mercury_im.messenger.xmpp.repository.RosterRepository;
|
||||
import org.mercury_im.messenger.xmpp.util.ChatAndPossiblyContact;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import io.reactivex.Completable;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
public class PlainMessageStore {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(PlainMessageStore.class.getName());
|
||||
private static final CompositeDisposable disposable = new CompositeDisposable();
|
||||
|
||||
private final RosterRepository rosterRepository;
|
||||
private final ChatRepository chatRepository;
|
||||
private final MessageRepository messageRepository;
|
||||
|
||||
private final NotificationManager notificationManager;
|
||||
|
||||
public PlainMessageStore(RosterRepository rosterRepository, ChatRepository chatRepository, MessageRepository messageRepository, NotificationManager notificationManager) {
|
||||
this.rosterRepository = rosterRepository;
|
||||
this.chatRepository = chatRepository;
|
||||
this.messageRepository = messageRepository;
|
||||
this.notificationManager = notificationManager;
|
||||
}
|
||||
|
||||
public void handleIncomingMessage(long accountId, EntityBareJid from, Message message, Chat chat) {
|
||||
if (message.getBody() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Completable.fromAction(() -> {
|
||||
EntityModel entityModel = rosterRepository.getOrCreateEntity(accountId, from)
|
||||
.blockingGet();
|
||||
ContactModel contactModel = rosterRepository.getContact(accountId, entityModel.getJid()).blockingFirst().firstOrNull();
|
||||
ChatModel chatModel = chatRepository.getChatWith(entityModel).blockingFirst().firstOr(() -> {
|
||||
ChatModel freshChatModel = new ChatModel();
|
||||
freshChatModel.setPeer(entityModel);
|
||||
freshChatModel.setDisplayed(true);
|
||||
return freshChatModel;
|
||||
});
|
||||
|
||||
chatModel = chatRepository.upsert(chatModel).blockingGet();
|
||||
|
||||
MessageModel messageModel = setCommonMessageAttributes(message, chatModel);
|
||||
messageModel.setSender(from);
|
||||
messageModel.setIncoming(true);
|
||||
|
||||
final ChatModel fChatModel = chatModel;
|
||||
disposable.add(messageRepository.insert(messageModel)
|
||||
.subscribe(insertedMessageModel -> {
|
||||
if (message.getBody() != null) {
|
||||
notificationManager.chatMessageReceived(new ChatAndPossiblyContact(fChatModel, contactModel), message.getBody());
|
||||
}
|
||||
|
||||
LastChatMessageRelation lastMessage = new LastChatMessageRelation();
|
||||
lastMessage.setChat(fChatModel);
|
||||
lastMessage.setMessage(insertedMessageModel);
|
||||
}));
|
||||
}).subscribeOn(Schedulers.io())
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
public void handleOutgoingMessage(long accountId, EntityBareJid to, Message message, Chat chat) {
|
||||
MessageModel model = setCommonMessageAttributes(message, null);
|
||||
EntityModel entityModel = rosterRepository.getOrCreateEntity(accountId, to).blockingGet();
|
||||
|
||||
model.setIncoming(false);
|
||||
model.setTimestamp(new Date());
|
||||
model.setSender(entityModel.getAccount().getJid());
|
||||
model.setRecipient(to);
|
||||
|
||||
ChatModel chatModel = chatRepository.getChatWith(entityModel).blockingFirst().firstOr(() -> {
|
||||
ChatModel freshChatModel = new ChatModel();
|
||||
freshChatModel.setPeer(entityModel);
|
||||
freshChatModel.setDisplayed(true);
|
||||
return freshChatModel;
|
||||
});
|
||||
|
||||
model.setChat(chatModel);
|
||||
|
||||
disposable.add(messageRepository.upsert(model)
|
||||
.subscribe(messageId ->
|
||||
LOGGER.log(Level.INFO, "Inserted outgoing message " + messageId)));
|
||||
}
|
||||
|
||||
public void handleCarbonCopy(long accountId, CarbonExtension.Direction direction, Message carbonCopy, Message wrappingMessage) {
|
||||
if (carbonCopy.getBody() == null) {
|
||||
return;
|
||||
}
|
||||
MessageModel messageModel = new MessageModel();
|
||||
messageModel.setSender(carbonCopy.getFrom() != null ? carbonCopy.getFrom().asEntityBareJidIfPossible() : null);
|
||||
messageModel.setRecipient(carbonCopy.getTo() != null ? carbonCopy.getTo().asEntityBareJidIfPossible() : null);
|
||||
|
||||
messageModel.setIncoming(direction == CarbonExtension.Direction.received);
|
||||
|
||||
messageModel.setBody(carbonCopy.getBody());
|
||||
messageModel.setTimestamp(new Date());
|
||||
|
||||
disposable.add(messageRepository.upsert(messageModel)
|
||||
.subscribe(messageId ->
|
||||
LOGGER.log(Level.INFO, "Inserted carbon message " + messageId)));
|
||||
}
|
||||
|
||||
public void registerForMercuryConnection(MercuryConnection connection) {
|
||||
ChatManager chatManager = ChatManager.getInstanceFor(connection.getConnection());
|
||||
CarbonManager carbonManager = CarbonManager.getInstanceFor(connection.getConnection());
|
||||
|
||||
// Add account ID to
|
||||
chatManager.addIncomingListener((from, message, chat) ->
|
||||
PlainMessageStore.this.handleIncomingMessage(
|
||||
connection.getAccountId(), from, message, chat));
|
||||
|
||||
chatManager.addOutgoingListener((to, message, chat) ->
|
||||
PlainMessageStore.this.handleOutgoingMessage(
|
||||
connection.getAccountId(), to, message, chat));
|
||||
|
||||
carbonManager.addCarbonCopyReceivedListener((direction, carbonCopy, wrappingMessage) ->
|
||||
PlainMessageStore.this.handleCarbonCopy(
|
||||
connection.getAccountId(), direction, carbonCopy, wrappingMessage));
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
disposable.clear();
|
||||
}
|
||||
|
||||
public void handleMamResult(long accountId, EntityBareJid peerJid, MamManager.MamQuery query) {
|
||||
List<MessageModel> messageModels = new ArrayList<>();
|
||||
for (Message message : query.getMessages()) {
|
||||
Date date = new Date();
|
||||
DelayInformation delay = DelayInformation.from(message);
|
||||
if (delay != null) {
|
||||
date = delay.getStamp();
|
||||
}
|
||||
|
||||
MessageModel messageModel = new MessageModel();
|
||||
messageModel.setBody(message.getBody());
|
||||
messageModel.setSender(message.getFrom().asEntityBareJidOrThrow());
|
||||
messageModel.setRecipient(message.getTo().asEntityBareJidOrThrow());
|
||||
messageModel.setIncoming(peerJid.equals(message.getFrom().asEntityBareJidOrThrow()));
|
||||
messageModel.setTimestamp(date);
|
||||
messageModels.add(messageModel);
|
||||
}
|
||||
|
||||
disposable.add(messageRepository.upsert(messageModels).subscribe());
|
||||
}
|
||||
|
||||
private MessageModel incomingMessageToModel(Message message, ChatModel chat) {
|
||||
MessageModel model = setCommonMessageAttributes(message, chat);
|
||||
model.setIncoming(true);
|
||||
return model;
|
||||
}
|
||||
|
||||
private MessageModel setCommonMessageAttributes(Message message, ChatModel chat) {
|
||||
MessageModel model = new MessageModel();
|
||||
|
||||
model.setBody(message.getBody());
|
||||
Date timestamp = DelayInformationManager.getDelayTimestamp(message);
|
||||
model.setTimestamp(timestamp == null ? new Date() : timestamp);
|
||||
model.setThread(message.getThread());
|
||||
model.setLegacyId(message.getStanzaId());
|
||||
model.setChat(chat);
|
||||
model.setRecipient(message.getTo().asEntityBareJidOrThrow());
|
||||
model.setSender(message.getFrom() != null ? message.getFrom().asEntityBareJidIfPossible() : null);
|
||||
OriginIdElement originId = OriginIdElement.getOriginId(message);
|
||||
model.setOriginId(originId != null ? originId.getId() : null);
|
||||
StanzaIdElement stanzaId = StanzaIdElement.getStanzaId(message);
|
||||
model.setStanzaId(stanzaId != null ? stanzaId.getId() : null);
|
||||
model.setStanzaIdBy(stanzaId != null ? JidCreate.entityBareFromOrThrowUnchecked(stanzaId.getBy()) : null);
|
||||
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
|
@ -1,217 +0,0 @@
|
|||
package org.mercury_im.messenger.core.stores;
|
||||
|
||||
import org.jivesoftware.smack.roster.packet.RosterPacket;
|
||||
import org.jxmpp.jid.Jid;
|
||||
import org.mercury_im.messenger.xmpp.model.AccountModel;
|
||||
import org.mercury_im.messenger.xmpp.model.ContactModel;
|
||||
import org.mercury_im.messenger.xmpp.model.EntityModel;
|
||||
import org.mercury_im.messenger.xmpp.repository.RequeryAccountRepository;
|
||||
import org.mercury_im.messenger.xmpp.repository.RosterRepository;
|
||||
import org.mercury_im.messenger.xmpp.enums.SubscriptionDirection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
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.disposables.CompositeDisposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
public class RosterStore implements org.jivesoftware.smack.roster.rosterstore.RosterStore {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(RosterStore.class.getName());
|
||||
|
||||
private final RosterRepository rosterRepository;
|
||||
private final RequeryAccountRepository accountRepository;
|
||||
private AccountModel account;
|
||||
private CompositeDisposable disposable = null;
|
||||
|
||||
private final Map<Jid, RosterPacket.Item> itemMap = new HashMap<>();
|
||||
private String rosterVersion;
|
||||
|
||||
@Inject
|
||||
public RosterStore(RosterRepository rosterRepository, RequeryAccountRepository accountRepository) {
|
||||
this.rosterRepository = rosterRepository;
|
||||
this.accountRepository = accountRepository;
|
||||
}
|
||||
|
||||
public void subscribe() {
|
||||
LOGGER.log(Level.INFO, "Subscribing...");
|
||||
if (disposable != null) {
|
||||
return;
|
||||
}
|
||||
disposable = new CompositeDisposable();
|
||||
|
||||
disposable.add(rosterRepository.getAllContactsOfAccount(account)
|
||||
.observeOn(Schedulers.computation())
|
||||
.subscribe(contactsList -> {
|
||||
itemMap.clear();
|
||||
for (ContactModel contactModel : contactsList) {
|
||||
itemMap.put(contactModel.getEntity().getJid(), fromModel(contactModel));
|
||||
LOGGER.log(Level.INFO, "Populate itemMap with " + contactsList.toList().size() + " items");
|
||||
|
||||
}
|
||||
},
|
||||
error -> LOGGER.log(Level.WARNING, "An error occurred while updating roster cache", error)));
|
||||
|
||||
disposable.add(rosterRepository.getRosterVersion(account)
|
||||
.observeOn(Schedulers.computation())
|
||||
.subscribe(
|
||||
result -> setRosterVersion(result),
|
||||
error -> LOGGER.log(Level.WARNING, "An error occurred updating cached roster version", error)));
|
||||
}
|
||||
|
||||
public void unsubscribe() {
|
||||
if (disposable == null) {
|
||||
return;
|
||||
}
|
||||
disposable.dispose();
|
||||
disposable = null;
|
||||
}
|
||||
|
||||
public void setAccountId(long accountId) {
|
||||
this.account = accountRepository.getAccount(accountId)
|
||||
.doOnSubscribe(subscribe -> LOGGER.log(Level.FINE, "Fetching account " + accountId))
|
||||
.blockingFirst().first();
|
||||
}
|
||||
|
||||
private void setRosterVersion(String rosterVersion) {
|
||||
this.rosterVersion = rosterVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RosterPacket.Item> getEntries() {
|
||||
return new ArrayList<>(itemMap.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RosterPacket.Item getEntry(Jid bareJid) {
|
||||
return itemMap.get(bareJid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRosterVersion() {
|
||||
return rosterVersion != null ? rosterVersion : "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addEntry(RosterPacket.Item item, String version) {
|
||||
LOGGER.log(Level.INFO, "Add entry " + item.toXML().toString());
|
||||
// Update database
|
||||
ContactModel contact = toModel(item);
|
||||
disposable.add(rosterRepository.upsertContact(contact)
|
||||
.subscribe(
|
||||
success -> LOGGER.log(Level.FINE, "Upserted contact model " + success + " successfully"),
|
||||
error -> LOGGER.log(Level.WARNING, "An error occurred upserting contact " + contact, error)
|
||||
));
|
||||
disposable.add(rosterRepository.updateRosterVersion(account, version)
|
||||
.subscribe(
|
||||
success -> LOGGER.log(Level.FINE, "Upserted roster version to " + rosterVersion + " successfully"),
|
||||
error -> LOGGER.log(Level.WARNING, "An error occurred upserting roster version", error)
|
||||
));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetEntries(Collection<RosterPacket.Item> items, String version) {
|
||||
LOGGER.log(Level.INFO, "Reset Entries: " + Arrays.toString(items.toArray()));
|
||||
// Update database
|
||||
// TODO: Delete other contacts
|
||||
for (RosterPacket.Item item : items) {
|
||||
ContactModel model = toModel(item);
|
||||
disposable.add(rosterRepository.upsertContact(model)
|
||||
.subscribe(
|
||||
success -> LOGGER.log(Level.FINE, "Upserted contact model " + success + " successfully"),
|
||||
error -> LOGGER.log(Level.WARNING, "An error occurred upserting contact " + model, error)
|
||||
));
|
||||
}
|
||||
|
||||
disposable.add(rosterRepository.updateRosterVersion(account, version)
|
||||
.subscribe(
|
||||
success -> LOGGER.log(Level.FINE, "Upserted roster version to " + rosterVersion + " successfully"),
|
||||
error -> LOGGER.log(Level.WARNING, "An error occurred upserting roster version", error)
|
||||
));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeEntry(Jid bareJid, String version) {
|
||||
LOGGER.log(Level.INFO, "Remove entry " + bareJid.toString());
|
||||
|
||||
disposable.add(rosterRepository.deleteContact(account.getId(), bareJid.asEntityBareJidOrThrow())
|
||||
.subscribe(
|
||||
() -> LOGGER.log(Level.FINE, "Deletion of contact " + bareJid.toString() + " successful"),
|
||||
error -> LOGGER.log(Level.WARNING, "An error occurred deleting contact " + bareJid.toString(), error)
|
||||
));
|
||||
disposable.add(rosterRepository.updateRosterVersion(account, version)
|
||||
.subscribe(
|
||||
success -> LOGGER.log(Level.FINE, "Upserted roster version to " + rosterVersion + " successfully"),
|
||||
error -> LOGGER.log(Level.WARNING, "An error occurred upserting roster version", error)
|
||||
));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetStore() {
|
||||
LOGGER.log(Level.INFO, "Reset Store");
|
||||
|
||||
disposable.add(rosterRepository.deleteAllContactsOfAccount(account)
|
||||
.subscribe(
|
||||
success -> LOGGER.log(Level.FINE, "Successfully reset store."),
|
||||
error -> LOGGER.log(Level.WARNING, "An error occurred resetting store", error)
|
||||
));
|
||||
disposable.add(rosterRepository.updateRosterVersion(account, "")
|
||||
.subscribe(
|
||||
success -> LOGGER.log(Level.FINE, "Successfully reset roster version"),
|
||||
error -> LOGGER.log(Level.WARNING, "An error occurred resetting roster version", error)
|
||||
));
|
||||
}
|
||||
|
||||
public RosterPacket.Item fromModel(ContactModel contactModel) {
|
||||
RosterPacket.Item item = new RosterPacket.Item(
|
||||
contactModel.getEntity().getJid(),
|
||||
contactModel.getRostername());
|
||||
if (contactModel.getSub_direction() != null) {
|
||||
item.setItemType(convert(contactModel.getSub_direction()));
|
||||
}
|
||||
item.setApproved(contactModel.isSub_approved());
|
||||
item.setSubscriptionPending(contactModel.isSub_pending());
|
||||
return item;
|
||||
}
|
||||
|
||||
public ContactModel toModel(RosterPacket.Item item) {
|
||||
ContactModel contact = new ContactModel();
|
||||
|
||||
contact.setRostername(item.getName());
|
||||
if (item.getItemType() != null) {
|
||||
contact.setSub_direction(convert(item.getItemType()));
|
||||
}
|
||||
contact.setSub_approved(item.isApproved());
|
||||
contact.setSub_pending(item.isSubscriptionPending());
|
||||
|
||||
EntityModel entity = new EntityModel();
|
||||
entity.setAccount(account);
|
||||
entity.setJid(item.getJid().asEntityBareJidOrThrow());
|
||||
|
||||
contact.setEntity(entity);
|
||||
|
||||
return contact;
|
||||
}
|
||||
|
||||
public SubscriptionDirection convert(RosterPacket.ItemType type) {
|
||||
return SubscriptionDirection.valueOf(type.toString());
|
||||
|
||||
}
|
||||
|
||||
public RosterPacket.ItemType convert(SubscriptionDirection direction) {
|
||||
return RosterPacket.ItemType.fromString(direction.toString());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue