mirror of
https://codeberg.org/Mercury-IM/Mercury-IM
synced 2024-06-15 16:14:52 +02:00
129 lines
4.2 KiB
Java
129 lines
4.2 KiB
Java
package org.mercury_im.messenger.usecase;
|
|
|
|
import org.jivesoftware.smack.AbstractXMPPConnection;
|
|
import org.jivesoftware.smack.SmackException;
|
|
import org.jivesoftware.smack.XMPPException;
|
|
import org.jivesoftware.smack.sasl.SASLErrorException;
|
|
import org.mercury_im.messenger.Messenger;
|
|
import org.mercury_im.messenger.data.repository.AccountRepository;
|
|
import org.mercury_im.messenger.entity.Account;
|
|
import org.mercury_im.messenger.entity.IAccount;
|
|
import org.mercury_im.messenger.xmpp.MercuryConnection;
|
|
|
|
import java.io.IOException;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
|
|
import io.reactivex.Completable;
|
|
import io.reactivex.Single;
|
|
import io.reactivex.disposables.CompositeDisposable;
|
|
import io.reactivex.schedulers.Schedulers;
|
|
|
|
public class AddAccount {
|
|
|
|
private static final Logger LOGGER = Logger.getLogger(AddAccount.class.getName());
|
|
|
|
public enum ConnectionResult {
|
|
success,
|
|
credential_error,
|
|
server_error,
|
|
other_error
|
|
}
|
|
|
|
private Account account;
|
|
private MercuryConnection connection;
|
|
|
|
private final AccountRepository accountRepository;
|
|
private final Messenger messenger;
|
|
|
|
private final CompositeDisposable disposable = new CompositeDisposable();
|
|
|
|
public AddAccount(AccountRepository accountRepository, Messenger messenger) {
|
|
this.accountRepository = accountRepository;
|
|
this.messenger = messenger;
|
|
this.account = new IAccount();
|
|
}
|
|
|
|
public AddAccount setAddress(String address) {
|
|
this.account.setAddress(address);
|
|
return this;
|
|
}
|
|
|
|
public AddAccount setPassword(String password) {
|
|
this.account.setPassword(password);
|
|
return this;
|
|
}
|
|
|
|
public Completable execute() {
|
|
return loginAndStoreAccountIfSuccessful();
|
|
}
|
|
|
|
public Completable loginAndStoreAccountIfSuccessful() {
|
|
return logIntoAccount()
|
|
.andThen(insertEnabledAccountIntoDatabase()).ignoreElement()
|
|
.andThen(addConnectionToMessenger());
|
|
}
|
|
|
|
private Single<Account> insertEnabledAccountIntoDatabase() {
|
|
account.setEnabled(true);
|
|
return accountRepository.upsertAccount(account)
|
|
.map(this::updateAccount);
|
|
}
|
|
|
|
private Completable addConnectionToMessenger() {
|
|
return Completable.fromAction(() -> messenger.addConnection(connection));
|
|
}
|
|
|
|
private Account updateAccount(Account account) {
|
|
this.account = account;
|
|
updateAccountIdInConnection(account);
|
|
return account;
|
|
}
|
|
|
|
private void updateAccountIdInConnection(Account account) {
|
|
if (connection != null) {
|
|
connection.getAccount().setId(account.getId());
|
|
}
|
|
}
|
|
|
|
private Completable logIntoAccount() {
|
|
return Completable.fromAction(
|
|
() -> {
|
|
getOrCreateConnection();
|
|
doAuthenticateIfNecessary();
|
|
})
|
|
.subscribeOn(Schedulers.io());
|
|
}
|
|
|
|
private void getOrCreateConnection() {
|
|
connection = messenger.getConnection(account);
|
|
if (connection == null) {
|
|
connection = new MercuryConnection(account);
|
|
}
|
|
}
|
|
|
|
private ConnectionResult authenticateIfNecessary() {
|
|
try {
|
|
doAuthenticateIfNecessary();
|
|
return ConnectionResult.success;
|
|
} catch (SASLErrorException e) {
|
|
LOGGER.log(Level.WARNING, "SASL Error while connecting to account " + account.getAddress(), e);
|
|
return ConnectionResult.credential_error;
|
|
} catch (SmackException.ConnectionException e) {
|
|
LOGGER.log(Level.WARNING, "Connectivity error while connecting to account " + account.getAddress(), e);
|
|
return ConnectionResult.server_error;
|
|
}
|
|
catch (IOException | XMPPException | SmackException | InterruptedException e) {
|
|
LOGGER.log(Level.WARNING, "Error connecting to account " + account.getAddress(), e);
|
|
return ConnectionResult.other_error;
|
|
}
|
|
}
|
|
|
|
private void doAuthenticateIfNecessary()
|
|
throws InterruptedException, XMPPException, SmackException, IOException {
|
|
if (!connection.getConnection().isAuthenticated()) {
|
|
((AbstractXMPPConnection) connection.getConnection()).connect().login();
|
|
}
|
|
}
|
|
}
|