1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2025-09-11 18:19:38 +02:00

Initial commit

This commit is contained in:
Paul Schaub 2020-02-08 17:56:24 +01:00
parent 9d626bf787
commit 0d90e6535e
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
16 changed files with 551 additions and 0 deletions

View file

@ -0,0 +1,7 @@
dependencies {
implementation project(":smack-core")
implementation project(":smack-tcp")
implementation project(":smack-im")
implementation project(":smack-extensions")
implementation project(":smack-experimental")
}

View file

@ -0,0 +1,34 @@
package org.jivesoftware.smackx.messenger;
import java.util.UUID;
public class AccountRecord {
private final UUID accountId;
private final String username;
private final String password;
private final String serviceName;
public AccountRecord(UUID accountId, String username, String password, String serviceName) {
this.accountId = accountId;
this.username = username;
this.password = password;
this.serviceName = serviceName;
}
public UUID getAccountId() {
return accountId;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public String getServiceName() {
return serviceName;
}
}

View file

@ -0,0 +1,100 @@
package org.jivesoftware.smackx.messenger;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.jivesoftware.smack.ReconnectionManager;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smackx.caps.EntityCapsManager;
import org.jivesoftware.smackx.carbons.CarbonManager;
import org.jivesoftware.smackx.csi.ClientStateIndicationManager;
import org.jivesoftware.smackx.iqversion.VersionManager;
import org.jivesoftware.smackx.messenger.connection.ConnectionFactory;
import org.jivesoftware.smackx.messenger.connection.XmppTcpConnectionFactory;
import org.jivesoftware.smackx.messenger.csi.ClientStateListener;
import org.jivesoftware.smackx.messenger.store.MessengerStore;
import org.jivesoftware.smackx.messenger.store.roster.RosterStoreAdapter;
import org.jivesoftware.smackx.sid.StableUniqueStanzaIdManager;
import org.jxmpp.stringprep.XmppStringprepException;
public class Messenger implements ClientStateListener {
private final Map<UUID, XmppAccount> accounts = new ConcurrentHashMap<>();
private final MessengerStore messengerStore;
private ConnectionFactory connectionFactory = new XmppTcpConnectionFactory();
public Messenger(MessengerStore store) {
this.messengerStore = store;
EntityCapsManager.setPersistentCache(store);
setGlobalDefaults();
}
private void setGlobalDefaults() {
ReconnectionManager.setEnabledPerDefault(true);
StableUniqueStanzaIdManager.setEnabledByDefault(true);
VersionManager.setAutoAppendSmackVersion(false);
}
public XmppAccount addAccount(UUID accountId, String username, String password, String serviceName)
throws XmppStringprepException {
XMPPConnection connection = connectionFactory.createConnection(username, password, serviceName);
XmppAccount xmppAccount = new XmppAccount(accountId, connection);
accounts.put(accountId, xmppAccount);
offlineAccountSetup(xmppAccount);
return xmppAccount;
}
private void offlineAccountSetup(XmppAccount account) {
Roster.getInstanceFor(account.getConnection()).setRosterStore(
new RosterStoreAdapter(account.getAccountId(), messengerStore));
}
private void onlineAccountSetup(XmppAccount account)
throws InterruptedException, XMPPException, SmackException {
if (CarbonManager.getInstanceFor(account.getConnection()).isSupportedByServer()) {
CarbonManager.getInstanceFor(account.getConnection()).enableCarbons();
}
}
@Override
public synchronized void onClientInForeground() {
for (XmppAccount connection : accounts.values()) {
trySetCsiActive(connection);
}
}
private void trySetCsiActive(XmppAccount connection) {
try {
ClientStateIndicationManager.active(connection.getConnection());
} catch (SmackException.NotConnectedException | InterruptedException e) {
e.printStackTrace();
}
}
@Override
public synchronized void onClientInBackground() {
for (XmppAccount connection : accounts.values()) {
trySetCsiInactive(connection);
}
}
private void trySetCsiInactive(XmppAccount connection) {
try {
ClientStateIndicationManager.inactive(connection.getConnection());
} catch (SmackException.NotConnectedException | InterruptedException e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,36 @@
package org.jivesoftware.smackx.messenger;
import java.io.IOException;
import java.util.UUID;
import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
public class XmppAccount {
private final UUID accountId;
private final XMPPConnection connection;
public XmppAccount(UUID accountId, XMPPConnection connection) {
this.connection = connection;
this.accountId = accountId;
}
public XMPPConnection getConnection() {
return connection;
}
public UUID getAccountId() {
return accountId;
}
public void login() throws InterruptedException, XMPPException, SmackException, IOException {
((AbstractXMPPConnection) getConnection()).connect().login();
}
public boolean isLoggedIn() {
return getConnection().isAuthenticated();
}
}

View file

@ -0,0 +1,10 @@
package org.jivesoftware.smackx.messenger.connection;
import org.jivesoftware.smack.XMPPConnection;
import org.jxmpp.stringprep.XmppStringprepException;
public interface ConnectionFactory {
XMPPConnection createConnection(String username, String password, String serviceName) throws XmppStringprepException;
}

View file

@ -0,0 +1,22 @@
package org.jivesoftware.smackx.messenger.connection;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jxmpp.stringprep.XmppStringprepException;
public class XmppTcpConnectionFactory implements ConnectionFactory {
@Override
public XMPPConnection createConnection(String username, String password, String serviceName) throws XmppStringprepException {
XMPPTCPConnectionConfiguration configuration = XMPPTCPConnectionConfiguration.builder()
.setConnectTimeout(60 * 1000)
.setHost(serviceName)
.setUsernameAndPassword(username, password)
.build();
XMPPTCPConnection connection = new XMPPTCPConnection(configuration);
return connection;
}
}

View file

@ -0,0 +1,7 @@
package org.jivesoftware.smackx.messenger.csi;
public interface ClientStateListener {
void onClientInForeground();
void onClientInBackground();
}

View file

@ -0,0 +1,105 @@
package org.jivesoftware.smackx.messenger.store;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.jivesoftware.smack.roster.packet.RosterPacket;
import org.jivesoftware.smack.roster.rosterstore.DirectoryRosterStore;
import org.jivesoftware.smackx.caps.cache.SimpleDirectoryPersistentCache;
import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
import org.jivesoftware.smackx.messenger.AccountRecord;
import org.jxmpp.jid.Jid;
public class FilebasedMessengerStore implements MessengerStore {
private final File storeBaseDir;
private final Map<UUID, DirectoryRosterStore> rosterStoreMap = new ConcurrentHashMap<>();
private final SimpleDirectoryPersistentCache entityCapsCache;
private final Map<UUID, AccountRecord> accounts = new ConcurrentHashMap<>();
public FilebasedMessengerStore(File storeBaseDir) {
this.storeBaseDir = storeBaseDir;
entityCapsCache = new SimpleDirectoryPersistentCache(new File(storeBaseDir, "entityCaps"));
}
private DirectoryRosterStore getRosterStore(UUID accountId) {
DirectoryRosterStore store = rosterStoreMap.get(accountId);
if (store == null) {
File accountDir = new File(storeBaseDir, accountId.toString());
File rosterDir = new File(accountDir, "roster");
store = DirectoryRosterStore.open(rosterDir);
if (store == null) {
store = DirectoryRosterStore.init(rosterDir);
}
rosterStoreMap.put(accountId, store);
}
return store;
}
@Override
public void addDiscoverInfoByNodePersistent(String nodeVer, DiscoverInfo info) {
entityCapsCache.addDiscoverInfoByNodePersistent(nodeVer, info);
}
@Override
public DiscoverInfo lookup(String nodeVer) {
return entityCapsCache.lookup(nodeVer);
}
@Override
public void emptyCache() {
entityCapsCache.emptyCache();
}
@Override
public List<AccountRecord> getAllAccounts() {
return new ArrayList<>(accounts.values());
}
@Override
public AccountRecord getAccount(UUID accountId) {
return accounts.get(accountId);
}
@Override
public List<RosterPacket.Item> getEntries(UUID accountId) {
return getRosterStore(accountId).getEntries();
}
@Override
public RosterPacket.Item getEntry(UUID accountId, Jid bareJid) {
return getRosterStore(accountId).getEntry(bareJid);
}
@Override
public String getRosterVersion(UUID accountId) {
return getRosterStore(accountId).getRosterVersion();
}
@Override
public boolean addEntry(UUID accountId, RosterPacket.Item item, String version) {
return getRosterStore(accountId).addEntry(item, version);
}
@Override
public boolean resetEntries(UUID accountId, Collection<RosterPacket.Item> items, String version) {
return getRosterStore(accountId).resetEntries(items, version);
}
@Override
public boolean removeEntry(UUID accountId, Jid bareJid, String version) {
return getRosterStore(accountId).removeEntry(bareJid, version);
}
@Override
public void resetStore(UUID accountId) {
getRosterStore(accountId).resetStore();
}
}

View file

@ -0,0 +1,9 @@
package org.jivesoftware.smackx.messenger.store;
import org.jivesoftware.smackx.caps.cache.EntityCapsPersistentCache;
import org.jivesoftware.smackx.messenger.store.account.AccountStore;
import org.jivesoftware.smackx.messenger.store.roster.GlobalRosterStore;
public interface MessengerStore extends EntityCapsPersistentCache, AccountStore, GlobalRosterStore {
}

View file

@ -0,0 +1,13 @@
package org.jivesoftware.smackx.messenger.store.account;
import java.util.List;
import java.util.UUID;
import org.jivesoftware.smackx.messenger.AccountRecord;
public interface AccountStore {
List<AccountRecord> getAllAccounts();
AccountRecord getAccount(UUID accountId);
}

View file

@ -0,0 +1,26 @@
package org.jivesoftware.smackx.messenger.store.roster;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
import org.jivesoftware.smack.roster.packet.RosterPacket;
import org.jxmpp.jid.Jid;
public interface GlobalRosterStore {
List<RosterPacket.Item> getEntries(UUID accountId);
RosterPacket.Item getEntry(UUID accountId, Jid bareJid);
String getRosterVersion(UUID accountId);
boolean addEntry(UUID accountId, RosterPacket.Item item, String version);
boolean resetEntries(UUID accountId, Collection<RosterPacket.Item> items, String version);
boolean removeEntry(UUID accountId, Jid bareJid, String version);
void resetStore(UUID accountId);
}

View file

@ -0,0 +1,57 @@
package org.jivesoftware.smackx.messenger.store.roster;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
import org.jivesoftware.smack.roster.packet.RosterPacket;
import org.jivesoftware.smack.roster.rosterstore.RosterStore;
import org.jivesoftware.smackx.messenger.store.roster.GlobalRosterStore;
import org.jxmpp.jid.Jid;
public class RosterStoreAdapter implements RosterStore {
private final GlobalRosterStore store;
private final UUID accountId;
public RosterStoreAdapter(UUID accountId, GlobalRosterStore globalRosterStore) {
this.store = globalRosterStore;
this.accountId = accountId;
}
@Override
public List<RosterPacket.Item> getEntries() {
return store.getEntries(accountId);
}
@Override
public RosterPacket.Item getEntry(Jid bareJid) {
return store.getEntry(accountId, bareJid);
}
@Override
public String getRosterVersion() {
return store.getRosterVersion(accountId);
}
@Override
public boolean addEntry(RosterPacket.Item item, String version) {
return store.addEntry(accountId, item, version);
}
@Override
public boolean resetEntries(Collection<RosterPacket.Item> items, String version) {
return store.resetEntries(accountId, items, version);
}
@Override
public boolean removeEntry(Jid bareJid, String version) {
return store.removeEntry(accountId, bareJid, version);
}
@Override
public void resetStore() {
store.resetStore(accountId);
}
}