Mercury-IM/domain/src/main/java/org/mercury_im/messenger/xmpp/MercuryConnection.java

105 lines
3.2 KiB
Java

package org.mercury_im.messenger.xmpp;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.XMPPConnection;
import org.mercury_im.messenger.data.repository.AccountRepository;
import org.mercury_im.messenger.entity.Account;
import org.mercury_im.messenger.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;
import io.reactivex.Observable;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.subjects.BehaviorSubject;
public class MercuryConnection {
private static final Logger LOGGER = Logger.getLogger("MercuryConnection");
private static final XmppConnectionFactory connectionFactory = new XmppConnectionFactory();
private final CompositeDisposable disposable = new CompositeDisposable();
private final AccountRepository accountRepository;
private Account account;
private XMPPConnection connection;
private BehaviorSubject<Boolean> enabled = BehaviorSubject.create();
private BehaviorSubject<ConnectionState> state = BehaviorSubject.createDefault(ConnectionState.closed);
public MercuryConnection(AccountRepository accountRepository, Account account) {
this.accountRepository = accountRepository;
this.account = account;
this.connection = connectionFactory.createConnection(account);
observeAccountAndConnection();
}
public Observable<ConnectionState> getState() {
return state;
}
private void observeAccountAndConnection() {
observeAccount();
observeConnection();
}
private void observeAccount() {
disposable.add(accountRepository.observeAccount(account.getId())
.filter(Optional::isPresent)
.map(Optional::getItem)
.subscribe(this::setAccount));
}
private void observeConnection() {
connection.addConnectionListener(new ConnectionListener() {
@Override
public void connected(XMPPConnection connection) {
LOGGER.log(Level.FINER, "connected");
state.onNext(ConnectionState.connected);
}
@Override
public void authenticated(XMPPConnection connection, boolean resumed) {
LOGGER.log(Level.FINER, "authenticated. resumed? " + resumed);
state.onNext(ConnectionState.authenticated);
}
@Override
public void connectionClosed() {
LOGGER.log(Level.FINER, "connectionClosed");
state.onNext(ConnectionState.closed);
}
@Override
public void connectionClosedOnError(Exception e) {
LOGGER.log(Level.WARNING, "connectionClosedOnError");
state.onNext(ConnectionState.closedOnError);
}
});
}
private void setAccount(Account account) {
this.account = account;
enabled.onNext(account.isEnabled());
}
public Account getAccount() {
return account;
}
public XMPPConnection getConnection() {
return connection;
}
public void dispose() {
disposable.dispose();
}
public enum ConnectionState {
connected,
authenticated,
closedOnError,
closed
}
}