Create smack-im subproject for XMPP-IM

Move Roster and Chat(Manager) code into their own packages within the
new smack-im subproject.

Apply Manager pattern to Roster.

Fixes SMACK-637.
This commit is contained in:
Florian Schmaus 2015-01-22 13:53:50 +01:00
parent e722018808
commit d5b8647d9d
47 changed files with 392 additions and 271 deletions

View File

@ -33,7 +33,7 @@ allprojects {
// build, causing unnecessary rebuilds. // build, causing unnecessary rebuilds.
builtDate = (new java.text.SimpleDateFormat("yyyy-MM-dd")).format(new Date()) builtDate = (new java.text.SimpleDateFormat("yyyy-MM-dd")).format(new Date())
oneLineDesc = 'An Open Source XMPP (Jabber) client library' oneLineDesc = 'An Open Source XMPP (Jabber) client library'
androidProjects = [':smack-tcp',':smack-core', ':smack-resolver-minidns', ':smack-sasl-provided', ':smack-extensions', ':smack-experimental'].collect{ project(it) } androidProjects = [':smack-tcp', ':smack-core', ':smack-im', ':smack-resolver-minidns', ':smack-sasl-provided', ':smack-extensions', ':smack-experimental'].collect{ project(it) }
androidBootClasspath = getAndroidRuntimeJar() androidBootClasspath = getAndroidRuntimeJar()
androidJavadocOffline = getAndroidJavadocOffline() androidJavadocOffline = getAndroidJavadocOffline()
} }

View File

@ -39,7 +39,7 @@ XMPPConnection conn1 = …
// Create a new roster exchange manager on conn1 // Create a new roster exchange manager on conn1
RosterExchangeManager rosterExchangeManager = new RosterExchangeManager(conn1); RosterExchangeManager rosterExchangeManager = new RosterExchangeManager(conn1);
// Send user1's roster to user2 // Send user1's roster to user2
rosterExchangeManager.send(conn1.getRoster(), user2); rosterExchangeManager.send(Roster.getInstanceFor(conn1), user2);
``` ```
Send a roster group Send a roster group
@ -67,7 +67,7 @@ XMPPConnection conn1 = …
// Create a new roster exchange manager on conn1 // Create a new roster exchange manager on conn1
RosterExchangeManager rosterExchangeManager = new RosterExchangeManager(conn1); RosterExchangeManager rosterExchangeManager = new RosterExchangeManager(conn1);
// Send user1's RosterGroups to user2 // Send user1's RosterGroups to user2
for (Iterator it = conn1.getRoster().getGroups(); it.hasNext(); ) for (Iterator it = Roster.getInstanceFor(conn1).getGroups(); it.hasNext(); )
rosterExchangeManager.send((RosterGroup)it.next(), user2); rosterExchangeManager.send((RosterGroup)it.next(), user2);
``` ```
@ -96,7 +96,7 @@ XMPPConnection conn1 = …
// Create a new roster exchange manager on conn1 // Create a new roster exchange manager on conn1
RosterExchangeManager rosterExchangeManager = new RosterExchangeManager(conn1); RosterExchangeManager rosterExchangeManager = new RosterExchangeManager(conn1);
// Send a roster entry (any) to user2 // Send a roster entry (any) to user2
rosterExchangeManager1.send((RosterEntry)conn1.getRoster().getEntries().next(), user2); rosterExchangeManager1.send((RosterEntry)Roster.getInstanceFor(conn1).getEntries().next(), user2);
``` ```
Receive roster entries Receive roster entries
@ -124,7 +124,7 @@ adds the received entries to his roster.
XMPPConnection conn1 = … XMPPConnection conn1 = …
XMPPConnection conn2 = … XMPPConnection conn2 = …
final Roster user2_roster = conn2.getRoster(); final Roster user2_roster = Roster.getInstanceFor(conn2);
// Create a RosterExchangeManager that will help user2 to listen and accept // Create a RosterExchangeManager that will help user2 to listen and accept
the entries received the entries received
@ -156,5 +156,5 @@ rosterExchangeManager2.addRosterListener(rosterExchangeListener);
// Create a RosterExchangeManager that will help user1 to send his roster // Create a RosterExchangeManager that will help user1 to send his roster
RosterExchangeManager rosterExchangeManager1 = new RosterExchangeManager(conn1); RosterExchangeManager rosterExchangeManager1 = new RosterExchangeManager(conn1);
// Send user1's roster to user2 // Send user1's roster to user2
rosterExchangeManager1.send(conn1.getRoster(), user2); rosterExchangeManager1.send(Roster.getInstanceFor(conn1), user2);
``` ```

View File

@ -79,7 +79,7 @@ The roster lets you keep track of the availability (presence) of other users.
Users can be organized into groups such as "Friends" and "Co-workers", and Users can be organized into groups such as "Friends" and "Co-workers", and
then you discover whether each user is online or offline. then you discover whether each user is online or offline.
Retrieve the roster using the `XMPPConnection.getRoster()` method. The roster Retrieve the roster using the `Roster.getInstanceFor(XMPPConnection)` method. The roster
class allows you to find all the roster entries, the groups they belong to, class allows you to find all the roster entries, the groups they belong to,
and the current presence status of each entry. and the current presence status of each entry.

View File

@ -8,7 +8,7 @@ users. A roster also allows you to organize users into groups such as
"Friends" and "Co-workers". Other IM systems refer to the roster as the buddy "Friends" and "Co-workers". Other IM systems refer to the roster as the buddy
list, contact list, etc. list, contact list, etc.
A `Roster` instance is obtained using the `XMPPConnection.getRoster()` method. A `Roster` instance is obtained using the `Roster.getInstanceFor(XMPPConnection)` method.
Roster Entries Roster Entries
-------------- --------------
@ -20,7 +20,7 @@ Every user in a roster is represented by a RosterEntry, which consists of:
* The list of groups in the roster that the entry belongs to. If the roster entry belongs to no groups, it's called an "unfiled entry". The following code snippet prints all entries in the roster: * The list of groups in the roster that the entry belongs to. If the roster entry belongs to no groups, it's called an "unfiled entry". The following code snippet prints all entries in the roster:
``` ```
Roster roster = connection.getRoster(); Roster roster = Roster.getInstanceFor(connection);
Collection<RosterEntry> entries = roster.getEntries(); Collection<RosterEntry> entries = roster.getEntries();
for (RosterEntry entry : entries) { for (RosterEntry entry : entries) {
System.out.println(entry); System.out.println(entry);
@ -63,7 +63,7 @@ out. A normal client would use similar code to update the roster UI with the
changing information. changing information.
``` ```
Roster roster = con.getRoster(); Roster roster = Roster.getInstanceFor(con);
roster.addRosterListener(new RosterListener() { roster.addRosterListener(new RosterListener() {
// Ignored events public void entriesAdded(Collection<String> addresses) {} // Ignored events public void entriesAdded(Collection<String> addresses) {}
public void entriesDeleted(Collection<String> addresses) {} public void entriesDeleted(Collection<String> addresses) {}

View File

@ -1,4 +1,5 @@
include 'smack-core', include 'smack-core',
'smack-im',
'smack-tcp', 'smack-tcp',
'smack-extensions', 'smack-extensions',
'smack-experimental', 'smack-experimental',

View File

@ -34,7 +34,6 @@ import org.jivesoftware.smack.SmackException.ConnectionException;
import org.jivesoftware.smack.XMPPException.StreamErrorException; import org.jivesoftware.smack.XMPPException.StreamErrorException;
import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.ConnectionCreationListener; import org.jivesoftware.smack.ConnectionCreationListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Element; import org.jivesoftware.smack.packet.Element;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
@ -295,8 +294,7 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
* Closes the connection by setting presence to unavailable and closing the * Closes the connection by setting presence to unavailable and closing the
* HTTP client. The shutdown logic will be used during a planned disconnection or when * HTTP client. The shutdown logic will be used during a planned disconnection or when
* dealing with an unexpected disconnection. Unlike {@link #disconnect()} the connection's * dealing with an unexpected disconnection. Unlike {@link #disconnect()} the connection's
* BOSH packet reader and {@link Roster} will not be removed; thus * BOSH packet reader will not be removed; thus connection's state is kept.
* connection's state is kept.
* *
*/ */
@Override @Override

View File

@ -66,7 +66,6 @@ import org.jivesoftware.smack.packet.Mechanisms;
import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.RosterVer;
import org.jivesoftware.smack.packet.Session; import org.jivesoftware.smack.packet.Session;
import org.jivesoftware.smack.packet.StartTls; import org.jivesoftware.smack.packet.StartTls;
import org.jivesoftware.smack.packet.PlainStreamElement; import org.jivesoftware.smack.packet.PlainStreamElement;
@ -75,7 +74,6 @@ import org.jivesoftware.smack.parsing.ParsingExceptionCallback;
import org.jivesoftware.smack.parsing.UnparsablePacket; import org.jivesoftware.smack.parsing.UnparsablePacket;
import org.jivesoftware.smack.provider.PacketExtensionProvider; import org.jivesoftware.smack.provider.PacketExtensionProvider;
import org.jivesoftware.smack.provider.ProviderManager; import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.rosterstore.RosterStore;
import org.jivesoftware.smack.util.DNSUtil; import org.jivesoftware.smack.util.DNSUtil;
import org.jivesoftware.smack.util.PacketParserUtils; import org.jivesoftware.smack.util.PacketParserUtils;
import org.jivesoftware.smack.util.ParserUtils; import org.jivesoftware.smack.util.ParserUtils;
@ -264,8 +262,6 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
private final ExecutorService singleThreadedExecutorService = Executors.newSingleThreadExecutor(new SmackExecutorThreadFactory( private final ExecutorService singleThreadedExecutorService = Executors.newSingleThreadExecutor(new SmackExecutorThreadFactory(
getConnectionCounter(), "Single Threaded Executor")); getConnectionCounter(), "Single Threaded Executor"));
private Roster roster;
/** /**
* The used host to establish the connection to * The used host to establish the connection to
*/ */
@ -380,9 +376,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
* </p> * </p>
* <p> * <p>
* It is possible to log in without sending an initial available presence by using * It is possible to log in without sending an initial available presence by using
* {@link ConnectionConfiguration.Builder#setSendPresence(boolean)}. If this connection is * {@link ConnectionConfiguration.Builder#setSendPresence(boolean)}.
* not interested in loading its roster upon login then use
* {@link ConnectionConfiguration.Builder#setRosterLoadedAtLogin(boolean)}.
* Finally, if you want to not pass a password and instead use a more advanced mechanism * Finally, if you want to not pass a password and instead use a more advanced mechanism
* while using SASL then you may be interested in using * while using SASL then you may be interested in using
* {@link ConnectionConfiguration.Builder#setCallbackHandler(javax.security.auth.callback.CallbackHandler)}. * {@link ConnectionConfiguration.Builder#setCallbackHandler(javax.security.auth.callback.CallbackHandler)}.
@ -527,11 +521,6 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
// eventually load the roster. And we should load the roster before we // eventually load the roster. And we should load the roster before we
// send the initial presence. // send the initial presence.
if (config.isSendPresence() && !resumed) { if (config.isSendPresence() && !resumed) {
if (!isAnonymous()) {
// Make sure that the roster has setup its listeners prior sending the initial presence by calling
// getRoster()
getRoster();
}
sendPacket(new Presence(Presence.Type.available)); sendPacket(new Presence(Presence.Type.available));
} }
} }
@ -603,36 +592,6 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
sendPacketInternal(packet); sendPacketInternal(packet);
} }
@Override
public Roster getRoster() {
if (isAnonymous()) {
throw new IllegalStateException("Anonymous users can't have a roster");
}
// synchronize against login()
synchronized(this) {
if (roster == null) {
roster = new Roster(this);
}
if (!isAuthenticated()) {
return roster;
}
}
// If this is the first time the user has asked for the roster after calling
// login, we want to wait for the server to send back the user's roster. This
// behavior shields API users from having to worry about the fact that roster
// operations are asynchronous, although they'll still have to listen for
// changes to the roster. Note: because of this waiting logic, internal
// Smack code should be wary about calling the getRoster method, and may need to
// access the roster object directly.
// Also only check for rosterIsLoaded is isRosterLoadedAtLogin is set, otherwise the user
// has to manually call Roster.reload() before he can expect a initialized roster.
if (!roster.isLoaded() && config.isRosterLoadedAtLogin()) {
roster.waitUntilLoaded();
}
return roster;
}
/** /**
* Returns the SASLAuthentication manager that is responsible for authenticating with * Returns the SASLAuthentication manager that is responsible for authenticating with
* the server. * the server.
@ -1284,16 +1243,6 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
} }
} }
@Override
public RosterStore getRosterStore() {
return config.getRosterStore();
}
@Override
public boolean isRosterLoadedAtLogin() {
return config.isRosterLoadedAtLogin();
}
protected final void parseFeatures(XmlPullParser parser) throws XmlPullParserException, protected final void parseFeatures(XmlPullParser parser) throws XmlPullParserException,
IOException, SmackException { IOException, SmackException {
streamFeatures.clear(); streamFeatures.clear();
@ -1318,16 +1267,6 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
case Session.ELEMENT: case Session.ELEMENT:
streamFeature = PacketParserUtils.parseSessionFeature(parser); streamFeature = PacketParserUtils.parseSessionFeature(parser);
break; break;
case RosterVer.ELEMENT:
if(namespace.equals(RosterVer.NAMESPACE)) {
streamFeature = RosterVer.INSTANCE;
}
else {
LOGGER.severe("Unknown Roster Versioning Namespace: "
+ namespace
+ ". Roster versioning not enabled");
}
break;
case Compress.Feature.ELEMENT: case Compress.Feature.ELEMENT:
streamFeature = PacketParserUtils.parseCompressionFeature(parser); streamFeature = PacketParserUtils.parseCompressionFeature(parser);
break; break;

View File

@ -19,7 +19,6 @@ package org.jivesoftware.smack;
import org.jivesoftware.smack.packet.Session; import org.jivesoftware.smack.packet.Session;
import org.jivesoftware.smack.proxy.ProxyInfo; import org.jivesoftware.smack.proxy.ProxyInfo;
import org.jivesoftware.smack.rosterstore.RosterStore;
import javax.net.SocketFactory; import javax.net.SocketFactory;
import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HostnameVerifier;
@ -66,8 +65,13 @@ public abstract class ConnectionConfiguration {
private final CharSequence username; private final CharSequence username;
private final String password; private final String password;
private final String resource; private final String resource;
/**
* Initial presence as of RFC 6121 § 4.2
* @see <a href="http://xmpp.org/rfcs/rfc6121.html#presence-initial">RFC 6121 § 4.2 Initial Presence</a>
*/
private final boolean sendPresence; private final boolean sendPresence;
private final boolean rosterLoadedAtLogin;
private final boolean legacySessionDisabled; private final boolean legacySessionDisabled;
private final SecurityMode securityMode; private final SecurityMode securityMode;
@ -83,11 +87,6 @@ public abstract class ConnectionConfiguration {
private final HostnameVerifier hostnameVerifier; private final HostnameVerifier hostnameVerifier;
/**
* Permanent store for the Roster, needed for roster versioning
*/
private final RosterStore rosterStore;
// Holds the proxy information (such as proxyhost, proxyport, username, password etc) // Holds the proxy information (such as proxyhost, proxyport, username, password etc)
protected final ProxyInfo proxy; protected final ProxyInfo proxy;
@ -127,9 +126,7 @@ public abstract class ConnectionConfiguration {
enabledSSLCiphers = builder.enabledSSLCiphers; enabledSSLCiphers = builder.enabledSSLCiphers;
hostnameVerifier = builder.hostnameVerifier; hostnameVerifier = builder.hostnameVerifier;
sendPresence = builder.sendPresence; sendPresence = builder.sendPresence;
rosterLoadedAtLogin = builder.rosterLoadedAtLogin;
legacySessionDisabled = builder.legacySessionDisabled; legacySessionDisabled = builder.legacySessionDisabled;
rosterStore = builder.rosterStore;
debuggerEnabled = builder.debuggerEnabled; debuggerEnabled = builder.debuggerEnabled;
allowNullOrEmptyUsername = builder.allowEmptyOrNullUsername; allowNullOrEmptyUsername = builder.allowEmptyOrNullUsername;
} }
@ -234,17 +231,6 @@ public abstract class ConnectionConfiguration {
return debuggerEnabled; return debuggerEnabled;
} }
/**
* Returns true if the roster will be loaded from the server when logging in. This
* is the common behaviour for clients but sometimes clients may want to differ this
* or just never do it if not interested in rosters.
*
* @return true if the roster will be loaded from the server when logging in.
*/
public boolean isRosterLoadedAtLogin() {
return rosterLoadedAtLogin;
}
/** /**
* Returns true if a {@link Session} will be requested on login if the server * Returns true if a {@link Session} will be requested on login if the server
* supports it. Although this was mandatory on RFC 3921, RFC 6120/6121 don't * supports it. Although this was mandatory on RFC 3921, RFC 6120/6121 don't
@ -282,14 +268,6 @@ public abstract class ConnectionConfiguration {
return this.socketFactory; return this.socketFactory;
} }
/**
* Get the permanent roster store
*/
public RosterStore getRosterStore() {
return rosterStore;
}
/** /**
* An enumeration for TLS security modes that are available when making a connection * An enumeration for TLS security modes that are available when making a connection
* to the XMPP server. * to the XMPP server.
@ -394,9 +372,7 @@ public abstract class ConnectionConfiguration {
private String password; private String password;
private String resource = "Smack"; private String resource = "Smack";
private boolean sendPresence = true; private boolean sendPresence = true;
private boolean rosterLoadedAtLogin = true;
private boolean legacySessionDisabled = false; private boolean legacySessionDisabled = false;
private RosterStore rosterStore;
private ProxyInfo proxy; private ProxyInfo proxy;
private CallbackHandler callbackHandler; private CallbackHandler callbackHandler;
private boolean debuggerEnabled = SmackConfiguration.DEBUG; private boolean debuggerEnabled = SmackConfiguration.DEBUG;
@ -595,19 +571,6 @@ public abstract class ConnectionConfiguration {
return getThis(); return getThis();
} }
/**
* Sets if the roster will be loaded from the server when logging in. This
* is the common behaviour for clients but sometimes clients may want to differ this
* or just never do it if not interested in rosters.
*
* @param rosterLoadedAtLogin if the roster will be loaded from the server when logging in.
* @return a reference to this builder.
*/
public B setRosterLoadedAtLogin(boolean rosterLoadedAtLogin) {
this.rosterLoadedAtLogin = rosterLoadedAtLogin;
return getThis();
}
/** /**
* Sets if an initial available presence will be sent to the server. By default * Sets if an initial available presence will be sent to the server. By default
* an available presence will be sent to the server indicating that this presence * an available presence will be sent to the server indicating that this presence
@ -622,16 +585,6 @@ public abstract class ConnectionConfiguration {
return getThis(); return getThis();
} }
/**
* Set the permanent roster store.
*
* @return a reference to this builder.
*/
public B setRosterStore(RosterStore store) {
rosterStore = store;
return getThis();
}
/** /**
* Sets if the new connection about to be establish is going to be debugged. By * Sets if the new connection about to be establish is going to be debugged. By
* default the value of {@link SmackConfiguration#DEBUG} is used. * default the value of {@link SmackConfiguration#DEBUG} is used.

View File

@ -30,10 +30,8 @@ import java.util.logging.Logger;
import org.jivesoftware.smack.compression.Java7ZlibInputOutputStream; import org.jivesoftware.smack.compression.Java7ZlibInputOutputStream;
import org.jivesoftware.smack.initializer.SmackInitializer; import org.jivesoftware.smack.initializer.SmackInitializer;
import org.jivesoftware.smack.packet.Bind; import org.jivesoftware.smack.packet.Bind;
import org.jivesoftware.smack.packet.RosterPacket;
import org.jivesoftware.smack.provider.BindIQProvider; import org.jivesoftware.smack.provider.BindIQProvider;
import org.jivesoftware.smack.provider.ProviderManager; import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.provider.RosterPacketProvider;
import org.jivesoftware.smack.sasl.core.SASLXOauth2Mechanism; import org.jivesoftware.smack.sasl.core.SASLXOauth2Mechanism;
import org.jivesoftware.smack.sasl.core.SCRAMSHA1Mechanism; import org.jivesoftware.smack.sasl.core.SCRAMSHA1Mechanism;
import org.jivesoftware.smack.util.FileUtils; import org.jivesoftware.smack.util.FileUtils;
@ -140,7 +138,6 @@ public final class SmackInitialization {
SASLAuthentication.registerSASLMechanism(new SCRAMSHA1Mechanism()); SASLAuthentication.registerSASLMechanism(new SCRAMSHA1Mechanism());
SASLAuthentication.registerSASLMechanism(new SASLXOauth2Mechanism()); SASLAuthentication.registerSASLMechanism(new SASLXOauth2Mechanism());
ProviderManager.addIQProvider(RosterPacket.ELEMENT, RosterPacket.NAMESPACE, RosterPacketProvider.INSTANCE);
ProviderManager.addIQProvider(Bind.ELEMENT, Bind.NAMESPACE, new BindIQProvider()); ProviderManager.addIQProvider(Bind.ELEMENT, Bind.NAMESPACE, new BindIQProvider());
SmackConfiguration.smackInitialized = true; SmackConfiguration.smackInitialized = true;

View File

@ -26,7 +26,6 @@ import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.packet.PlainStreamElement; import org.jivesoftware.smack.packet.PlainStreamElement;
import org.jivesoftware.smack.rosterstore.RosterStore;
/** /**
* The abstract XMPPConnection class provides an interface for connections to a XMPP server and * The abstract XMPPConnection class provides an interface for connections to a XMPP server and
@ -167,20 +166,6 @@ public interface XMPPConnection {
*/ */
public void send(PlainStreamElement element) throws NotConnectedException; public void send(PlainStreamElement element) throws NotConnectedException;
/**
* Returns the roster for the user.
* <p>
* This method will never return <code>null</code>, instead if the user has not yet logged into
* the server or is logged in anonymously all modifying methods of the returned roster object
* like {@link Roster#createEntry(String, String, String[])},
* {@link Roster#removeEntry(RosterEntry)} , etc. except adding or removing
* {@link RosterListener}s will throw an IllegalStateException.
*
* @return the user's roster.
* @throws IllegalStateException if the connection is anonymous
*/
public Roster getRoster();
/** /**
* Adds a connection listener to this connection that will be notified when * Adds a connection listener to this connection that will be notified when
* the connection closes or fails. * the connection closes or fails.
@ -438,22 +423,6 @@ public interface XMPPConnection {
*/ */
public FromMode getFromMode(); public FromMode getFromMode();
/**
* Get the permanent roster store.
* @return the permanent roster store or null
*/
public RosterStore getRosterStore();
/**
* Returns true if the roster will be loaded from the server when logging in. This
* is the common behavior for clients but sometimes clients may want to differ this
* or just never do it if not interested in rosters.
*
* @return true if the roster will be loaded from the server when logging in.
* @see <a href="http://xmpp.org/rfcs/rfc6121.html#roster-login">RFC 6121 2.2 - Retrieving the Roster on Login</a>
*/
public boolean isRosterLoadedAtLogin();
/** /**
* Get the feature packet extensions for a given stream feature of the * Get the feature packet extensions for a given stream feature of the
* server, or <code>null</code> if the server doesn't support that feature. * server, or <code>null</code> if the server doesn't support that feature.

View File

@ -52,7 +52,6 @@ import org.jivesoftware.smack.util.XmlStringBuilder;
* the user's current presence status. Second, they are used to subscribe and * the user's current presence status. Second, they are used to subscribe and
* unsubscribe users from the roster. * unsubscribe users from the roster.
* *
* @see RosterPacket
* @author Matt Tucker * @author Matt Tucker
*/ */
public final class Presence extends Packet { public final class Presence extends Packet {

View File

@ -19,5 +19,6 @@
<className>org.jivesoftware.smack.sasl.provided.SASLProvidedSmackInitializer</className> <className>org.jivesoftware.smack.sasl.provided.SASLProvidedSmackInitializer</className>
<className>org.jivesoftware.smack.android.AndroidSmackInitializer</className> <className>org.jivesoftware.smack.android.AndroidSmackInitializer</className>
<className>org.jivesoftware.smack.java7.Java7SmackInitializer</className> <className>org.jivesoftware.smack.java7.Java7SmackInitializer</className>
<className>org.jivesoftware.smack.im.SmackImInitializer</className>
</optionalStartupClasses> </optionalStartupClasses>
</smack> </smack>

View File

@ -49,7 +49,6 @@ public class DummyConnection extends AbstractXMPPConnection {
private boolean reconnect = false; private boolean reconnect = false;
private String connectionID; private String connectionID;
private Roster roster;
private final BlockingQueue<TopLevelStreamElement> queue = new LinkedBlockingQueue<TopLevelStreamElement>(); private final BlockingQueue<TopLevelStreamElement> queue = new LinkedBlockingQueue<TopLevelStreamElement>();
@ -89,7 +88,6 @@ public class DummyConnection extends AbstractXMPPConnection {
protected void shutdown() { protected void shutdown() {
user = null; user = null;
connectionID = null; connectionID = null;
roster = null;
authenticated = false; authenticated = false;
callConnectionClosedListener(); callConnectionClosedListener();
@ -107,17 +105,6 @@ public class DummyConnection extends AbstractXMPPConnection {
return connectionID; return connectionID;
} }
@Override
public Roster getRoster() {
if (isAnonymous()) {
return null;
}
if (roster == null) {
roster = new Roster(this);
}
return roster;
}
@Override @Override
public boolean isSecureConnection() { public boolean isSecureConnection() {
return false; return false;
@ -136,7 +123,6 @@ public class DummyConnection extends AbstractXMPPConnection {
+ config.getServiceName() + config.getServiceName()
+ "/" + "/"
+ (resource != null ? resource : "Test"); + (resource != null ? resource : "Test");
roster = new Roster(this);
authenticated = true; authenticated = true;
} }

View File

@ -7,5 +7,8 @@ Classes and methods that implement support for the various XMPP XEPs
// sourceSet.test of the core subproject // sourceSet.test of the core subproject
dependencies { dependencies {
compile project(':smack-core') compile project(':smack-core')
// Some implementations need APIs provided by smack-im,
// e.g. message delivery receipts the roster
compile project(':smack-im')
testCompile project(':smack-core').sourceSets.test.runtimeClasspath testCompile project(':smack-core').sourceSets.test.runtimeClasspath
} }

View File

@ -17,8 +17,8 @@
package org.jivesoftware.smackx.chatstates; package org.jivesoftware.smackx.chatstates;
import org.jivesoftware.smack.Chat; import org.jivesoftware.smack.chat.Chat;
import org.jivesoftware.smack.ChatMessageListener; import org.jivesoftware.smack.chat.ChatMessageListener;
/** /**
* Events for when the state of a user in a chat changes. * Events for when the state of a user in a chat changes.

View File

@ -20,14 +20,14 @@ package org.jivesoftware.smackx.chatstates;
import java.util.Map; import java.util.Map;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.ChatMessageListener;
import org.jivesoftware.smack.MessageListener; import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.Manager;
import org.jivesoftware.smack.chat.Chat;
import org.jivesoftware.smack.chat.ChatManager;
import org.jivesoftware.smack.chat.ChatManagerListener;
import org.jivesoftware.smack.chat.ChatMessageListener;
import org.jivesoftware.smack.filter.NotFilter; import org.jivesoftware.smack.filter.NotFilter;
import org.jivesoftware.smack.filter.PacketExtensionFilter; import org.jivesoftware.smack.filter.PacketExtensionFilter;
import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.filter.PacketFilter;

View File

@ -29,9 +29,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ChatMessageListener;
import org.jivesoftware.smack.MessageListener; import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.PacketCollector; import org.jivesoftware.smack.PacketCollector;
import org.jivesoftware.smack.PacketListener; import org.jivesoftware.smack.PacketListener;
@ -42,6 +39,9 @@ import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.chat.Chat;
import org.jivesoftware.smack.chat.ChatManager;
import org.jivesoftware.smack.chat.ChatMessageListener;
import org.jivesoftware.smack.filter.AndFilter; import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.FromMatchesFilter; import org.jivesoftware.smack.filter.FromMatchesFilter;
import org.jivesoftware.smack.filter.MessageTypeFilter; import org.jivesoftware.smack.filter.MessageTypeFilter;

View File

@ -36,6 +36,7 @@ import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter; import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
/** /**
@ -147,7 +148,7 @@ public class DeliveryReceiptManager extends Manager {
case disabled: case disabled:
return; return;
case ifIsSubscribed: case ifIsSubscribed:
if (!connection.getRoster().isSubscribedToMyPresence(from)) { if (!Roster.getInstanceFor(connection).isSubscribedToMyPresence(from)) {
return; return;
} }
break; break;

View File

@ -18,9 +18,9 @@
package org.jivesoftware.smackx.xdata.provider; package org.jivesoftware.smackx.xdata.provider;
import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.packet.RosterPacket;
import org.jivesoftware.smack.provider.PacketExtensionProvider; import org.jivesoftware.smack.provider.PacketExtensionProvider;
import org.jivesoftware.smack.provider.RosterPacketProvider; import org.jivesoftware.smack.roster.packet.RosterPacket;
import org.jivesoftware.smack.roster.provider.RosterPacketProvider;
import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.FormField;
import org.jivesoftware.smackx.xdata.packet.DataForm; import org.jivesoftware.smackx.xdata.packet.DataForm;
import org.jivesoftware.smackx.xdatalayout.packet.DataLayout; import org.jivesoftware.smackx.xdatalayout.packet.DataLayout;

11
smack-im/build.gradle Normal file
View File

@ -0,0 +1,11 @@
description = """\
Smack IM.
Classes and methods for XMPP-IM (RFC 6121):
Roster, Chat and other functionality."""
// Note that the test dependencies (junit, ) are inferred from the
// sourceSet.test of the core subproject
dependencies {
compile project(':smack-core')
testCompile project(':smack-core').sourceSets.test.runtimeClasspath
}

View File

@ -15,8 +15,9 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smack; package org.jivesoftware.smack.chat;
import org.jivesoftware.smack.PacketCollector;
import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.StringUtils;

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smack; package org.jivesoftware.smack.chat;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
@ -25,6 +25,11 @@ import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.CopyOnWriteArraySet;
import org.jivesoftware.smack.Manager;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.PacketCollector;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.filter.AndFilter; import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.FlexiblePacketTypeFilter; import org.jivesoftware.smack.filter.FlexiblePacketTypeFilter;

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smack; package org.jivesoftware.smack.chat;
/** /**
* A listener for chat related events. * A listener for chat related events.

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smack; package org.jivesoftware.smack.chat;
import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Message;

View File

@ -0,0 +1,33 @@
/**
*
* Copyright © 2015 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smack.im;
import org.jivesoftware.smack.initializer.UrlInitializer;
public class SmackImInitializer extends UrlInitializer {
@Override
protected String getProvidersUrl() {
return "classpath:org.jivesoftware.smack.im/smackim.providers";
}
@Override
protected String getConfigUrl() {
return "classpath:org.jivesoftware.smack.im/smackim.xml";
}
}

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smack; package org.jivesoftware.smack.roster;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -27,14 +27,23 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.jivesoftware.smack.AbstractConnectionClosedListener;
import org.jivesoftware.smack.ConnectionCreationListener;
import org.jivesoftware.smack.ExceptionCallback;
import org.jivesoftware.smack.Manager;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.SmackException.NotLoggedInException; import org.jivesoftware.smack.SmackException.NotLoggedInException;
import org.jivesoftware.smack.XMPPConnectionRegistry;
import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter; import org.jivesoftware.smack.filter.PacketTypeFilter;
@ -43,12 +52,12 @@ import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.IQ.Type; import org.jivesoftware.smack.packet.IQ.Type;
import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.RosterPacket;
import org.jivesoftware.smack.packet.RosterVer;
import org.jivesoftware.smack.packet.RosterPacket.Item;
import org.jivesoftware.smack.packet.XMPPError; import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.packet.XMPPError.Condition; import org.jivesoftware.smack.packet.XMPPError.Condition;
import org.jivesoftware.smack.rosterstore.RosterStore; import org.jivesoftware.smack.roster.packet.RosterPacket;
import org.jivesoftware.smack.roster.packet.RosterVer;
import org.jivesoftware.smack.roster.packet.RosterPacket.Item;
import org.jivesoftware.smack.roster.rosterstore.RosterStore;
import org.jxmpp.util.XmppStringUtils; import org.jxmpp.util.XmppStringUtils;
/** /**
@ -63,22 +72,55 @@ import org.jxmpp.util.XmppStringUtils;
* </ul> * </ul>
* *
* @author Matt Tucker * @author Matt Tucker
* @see XMPPConnection#getRoster() * @see #getInstanceFor(XMPPConnection)
*/ */
public class Roster { public class Roster extends Manager {
private static final Logger LOGGER = Logger.getLogger(Roster.class.getName()); private static final Logger LOGGER = Logger.getLogger(Roster.class.getName());
static {
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
@Override
public void connectionCreated(XMPPConnection connection) {
getInstanceFor(connection);
}
});
}
private static final Map<XMPPConnection, Roster> INSTANCES = new WeakHashMap<>();
/**
* Returns the roster for the user.
* <p>
* This method will never return <code>null</code>, instead if the user has not yet logged into
* the server or is logged in anonymously all modifying methods of the returned roster object
* like {@link Roster#createEntry(String, String, String[])},
* {@link Roster#removeEntry(RosterEntry)} , etc. except adding or removing
* {@link RosterListener}s will throw an IllegalStateException.
*
* @return the user's roster.
* @throws IllegalStateException if the connection is anonymous
*/
public static synchronized Roster getInstanceFor(XMPPConnection connection) {
Roster roster = INSTANCES.get(connection);
if (roster == null) {
roster = new Roster(connection);
INSTANCES.put(connection, roster);
}
return roster;
}
private static final PacketFilter PRESENCE_PACKET_FILTER = new PacketTypeFilter(Presence.class); private static final PacketFilter PRESENCE_PACKET_FILTER = new PacketTypeFilter(Presence.class);
private static boolean rosterLoadedAtLoginDefault = true;
/** /**
* The default subscription processing mode to use when a Roster is created. By default * The default subscription processing mode to use when a Roster is created. By default
* all subscription requests are automatically accepted. * all subscription requests are automatically accepted.
*/ */
private static SubscriptionMode defaultSubscriptionMode = SubscriptionMode.accept_all; private static SubscriptionMode defaultSubscriptionMode = SubscriptionMode.accept_all;
private final XMPPConnection connection; private RosterStore rosterStore;
private final RosterStore rosterStore;
private final Map<String, RosterGroup> groups = new ConcurrentHashMap<String, RosterGroup>(); private final Map<String, RosterGroup> groups = new ConcurrentHashMap<String, RosterGroup>();
private final Map<String,RosterEntry> entries = new ConcurrentHashMap<String,RosterEntry>(); private final Map<String,RosterEntry> entries = new ConcurrentHashMap<String,RosterEntry>();
private final List<RosterEntry> unfiledEntries = new CopyOnWriteArrayList<RosterEntry>(); private final List<RosterEntry> unfiledEntries = new CopyOnWriteArrayList<RosterEntry>();
@ -91,6 +133,11 @@ public class Roster {
private final PresencePacketListener presencePacketListener = new PresencePacketListener(); private final PresencePacketListener presencePacketListener = new PresencePacketListener();
/**
*
*/
private boolean rosterLoadedAtLogin = rosterLoadedAtLoginDefault;
private SubscriptionMode subscriptionMode = getDefaultSubscriptionMode(); private SubscriptionMode subscriptionMode = getDefaultSubscriptionMode();
/** /**
@ -122,9 +169,8 @@ public class Roster {
* *
* @param connection an XMPP connection. * @param connection an XMPP connection.
*/ */
Roster(final XMPPConnection connection) { private Roster(final XMPPConnection connection) {
this.connection = connection; super(connection);
rosterStore = connection.getRosterStore();
// Note that we use sync packet listeners because RosterListeners should be invoked in the same order as the // Note that we use sync packet listeners because RosterListeners should be invoked in the same order as the
// roster stanzas arrive. // roster stanzas arrive.
@ -143,7 +189,7 @@ public class Roster {
// again if it's an anonymous connection. // again if it's an anonymous connection.
if (connection.isAnonymous()) if (connection.isAnonymous())
return; return;
if (!connection.isRosterLoadedAtLogin()) if (!isRosterLoadedAtLogin())
return; return;
// We are done here if the connection was resumed // We are done here if the connection was resumed
if (resumed) { if (resumed) {
@ -214,6 +260,7 @@ public class Roster {
* @throws NotConnectedException * @throws NotConnectedException
*/ */
public void reload() throws NotLoggedInException, NotConnectedException{ public void reload() throws NotLoggedInException, NotConnectedException{
final XMPPConnection connection = connection();
if (!connection.isAuthenticated()) { if (!connection.isAuthenticated()) {
throw new NotLoggedInException(); throw new NotLoggedInException();
} }
@ -233,7 +280,25 @@ public class Roster {
}); });
} }
public void reloadAndWait() throws NotLoggedInException, NotConnectedException {
reload();
waitUntilLoaded();
}
public boolean setRosterStore(RosterStore rosterStore) {
this.rosterStore = rosterStore;
try {
reload();
}
catch (NotLoggedInException | NotConnectedException e) {
LOGGER.log(Level.FINER, "Could not reload roster", e);
return false;
}
return true;
}
protected boolean waitUntilLoaded() { protected boolean waitUntilLoaded() {
final XMPPConnection connection = connection();
while (!loaded) { while (!loaded) {
long waitTime = connection.getPacketReplyTimeout(); long waitTime = connection.getPacketReplyTimeout();
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
@ -301,6 +366,7 @@ public class Roster {
* @throws IllegalStateException if logged in anonymously * @throws IllegalStateException if logged in anonymously
*/ */
public RosterGroup createGroup(String name) { public RosterGroup createGroup(String name) {
final XMPPConnection connection = connection();
if (connection.isAnonymous()) { if (connection.isAnonymous()) {
throw new IllegalStateException("Anonymous users can't have a roster."); throw new IllegalStateException("Anonymous users can't have a roster.");
} }
@ -327,6 +393,7 @@ public class Roster {
* @throws NotConnectedException * @throws NotConnectedException
*/ */
public void createEntry(String user, String name, String[] groups) throws NotLoggedInException, NoResponseException, XMPPErrorException, NotConnectedException { public void createEntry(String user, String name, String[] groups) throws NotLoggedInException, NoResponseException, XMPPErrorException, NotConnectedException {
final XMPPConnection connection = connection();
if (!connection.isAuthenticated()) { if (!connection.isAuthenticated()) {
throw new NotLoggedInException(); throw new NotLoggedInException();
} }
@ -368,6 +435,7 @@ public class Roster {
* @throws IllegalStateException if connection is not logged in or logged in anonymously * @throws IllegalStateException if connection is not logged in or logged in anonymously
*/ */
public void removeEntry(RosterEntry entry) throws NotLoggedInException, NoResponseException, XMPPErrorException, NotConnectedException { public void removeEntry(RosterEntry entry) throws NotLoggedInException, NoResponseException, XMPPErrorException, NotConnectedException {
final XMPPConnection connection = connection();
if (!connection.isAuthenticated()) { if (!connection.isAuthenticated()) {
throw new NotLoggedInException(); throw new NotLoggedInException();
} }
@ -723,6 +791,33 @@ public class Roster {
} }
} }
/**
* Sets if the roster will be loaded from the server when logging in. This
* is the common behaviour for clients but sometimes clients may want to differ this
* or just never do it if not interested in rosters.
*
* @param rosterLoadedAtLogin if the roster will be loaded from the server when logging in.
*/
public void setRosterLoadedAtLogin(boolean rosterLoadedAtLogin) {
this.rosterLoadedAtLogin = rosterLoadedAtLogin;
}
/**
* Returns true if the roster will be loaded from the server when logging in. This
* is the common behavior for clients but sometimes clients may want to differ this
* or just never do it if not interested in rosters.
*
* @return true if the roster will be loaded from the server when logging in.
* @see <a href="http://xmpp.org/rfcs/rfc6121.html#roster-login">RFC 6121 2.2 - Retrieving the Roster on Login</a>
*/
public boolean isRosterLoadedAtLogin() {
return rosterLoadedAtLogin;
}
RosterStore getRosterStore() {
return rosterStore;
}
/** /**
* Returns the key to use in the presenceMap and entries Map for a fully qualified XMPP ID. * Returns the key to use in the presenceMap and entries Map for a fully qualified XMPP ID.
* The roster can contain any valid address format such us "domain/resource", * The roster can contain any valid address format such us "domain/resource",
@ -921,7 +1016,7 @@ public class Roster {
} }
private boolean isRosterVersioningSupported() { private boolean isRosterVersioningSupported() {
return connection.hasFeature(RosterVer.ELEMENT, RosterVer.NAMESPACE); return connection().hasFeature(RosterVer.ELEMENT, RosterVer.NAMESPACE);
} }
/** /**
@ -973,6 +1068,7 @@ public class Roster {
} }
public void processPacket(Packet packet) throws NotConnectedException { public void processPacket(Packet packet) throws NotConnectedException {
final XMPPConnection connection = connection();
Presence presence = (Presence) packet; Presence presence = (Presence) packet;
String from = presence.getFrom(); String from = presence.getFrom();
String key = getMapKey(from); String key = getMapKey(from);
@ -1078,6 +1174,7 @@ public class Roster {
@Override @Override
public void processPacket(Packet packet) { public void processPacket(Packet packet) {
final XMPPConnection connection = connection();
LOGGER.fine("RosterResultListener received stanza"); LOGGER.fine("RosterResultListener received stanza");
Collection<String> addedEntries = new ArrayList<String>(); Collection<String> addedEntries = new ArrayList<String>();
Collection<String> updatedEntries = new ArrayList<String>(); Collection<String> updatedEntries = new ArrayList<String>();
@ -1153,6 +1250,7 @@ public class Roster {
@Override @Override
public IQ handleIQRequest(IQ iqRequest) { public IQ handleIQRequest(IQ iqRequest) {
final XMPPConnection connection = connection();
RosterPacket rosterPacket = (RosterPacket) iqRequest; RosterPacket rosterPacket = (RosterPacket) iqRequest;
// Roster push (RFC 6121, 2.1.6) // Roster push (RFC 6121, 2.1.6)

View File

@ -15,16 +15,17 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smack; package org.jivesoftware.smack.roster;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.RosterPacket; import org.jivesoftware.smack.roster.packet.RosterPacket;
/** /**

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smack; package org.jivesoftware.smack.roster;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
@ -23,11 +23,13 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;
import org.jivesoftware.smack.PacketCollector;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.RosterPacket; import org.jivesoftware.smack.roster.packet.RosterPacket;
import org.jxmpp.util.XmppStringUtils; import org.jxmpp.util.XmppStringUtils;
/** /**

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smack; package org.jivesoftware.smack.roster;
import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.Presence;

View File

@ -15,8 +15,10 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smack.packet; package org.jivesoftware.smack.roster.packet;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smack.util.XmlStringBuilder;
import java.util.ArrayList; import java.util.ArrayList;

View File

@ -14,8 +14,9 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smack.packet; package org.jivesoftware.smack.roster.packet;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smack.util.XmlStringBuilder;
public class RosterVer implements PacketExtension { public class RosterVer implements PacketExtension {

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright © 2003-2007 Jive Software, 2014 Florian Schmaus * Copyright © 2003-2007 Jive Software, 2014-2015 Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -14,12 +14,13 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smack.provider; package org.jivesoftware.smack.roster.provider;
import java.io.IOException; import java.io.IOException;
import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.packet.RosterPacket; import org.jivesoftware.smack.provider.IQProvider;
import org.jivesoftware.smack.roster.packet.RosterPacket;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
@ -27,9 +28,6 @@ public class RosterPacketProvider extends IQProvider<RosterPacket> {
public static final RosterPacketProvider INSTANCE = new RosterPacketProvider(); public static final RosterPacketProvider INSTANCE = new RosterPacketProvider();
private RosterPacketProvider() {
}
@Override @Override
public RosterPacket parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException, public RosterPacket parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException,
SmackException { SmackException {

View File

@ -0,0 +1,35 @@
/**
*
* Copyright © 2015 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smack.roster.provider;
import java.io.IOException;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.provider.PacketExtensionProvider;
import org.jivesoftware.smack.roster.packet.RosterVer;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
public class RosterVerStreamFeatureProvider extends PacketExtensionProvider<RosterVer> {
@Override
public RosterVer parse(XmlPullParser parser, int initialDepth)
throws XmlPullParserException, IOException, SmackException {
return RosterVer.INSTANCE;
}
}

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smack.rosterstore; package org.jivesoftware.smack.roster.rosterstore;
import java.io.File; import java.io.File;
import java.io.FileFilter; import java.io.FileFilter;
@ -26,8 +26,8 @@ import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.jivesoftware.smack.packet.RosterPacket; import org.jivesoftware.smack.roster.packet.RosterPacket;
import org.jivesoftware.smack.packet.RosterPacket.Item; import org.jivesoftware.smack.roster.packet.RosterPacket.Item;
import org.jivesoftware.smack.util.FileUtils; import org.jivesoftware.smack.util.FileUtils;
import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jivesoftware.smack.util.stringencoder.Base32; import org.jivesoftware.smack.util.stringencoder.Base32;

View File

@ -14,11 +14,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smack.rosterstore; package org.jivesoftware.smack.roster.rosterstore;
import java.util.Collection; import java.util.Collection;
import org.jivesoftware.smack.packet.RosterPacket; import org.jivesoftware.smack.roster.packet.RosterPacket;
/** /**
* This is an interface for persistent roster store needed to implement * This is an interface for persistent roster store needed to implement
@ -29,13 +29,13 @@ public interface RosterStore {
/** /**
* This method returns a collection of all roster items contained in this store. * This method returns a collection of all roster items contained in this store.
* @return List of {@link org.jivesoftware.smack.RosterEntry} * @return List of {@link org.jivesoftware.smack.roster.RosterEntry}
*/ */
public Collection<RosterPacket.Item> getEntries(); public Collection<RosterPacket.Item> getEntries();
/** /**
* This method returns the roster item in this store for the given JID. * This method returns the roster item in this store for the given JID.
* @param bareJid The bare JID of the RosterEntry * @param bareJid The bare JID of the RosterEntry
* @return The {@link org.jivesoftware.smack.RosterEntry} which belongs to that user * @return The {@link org.jivesoftware.smack.roster.RosterEntry} which belongs to that user
*/ */
public RosterPacket.Item getEntry(String bareJid); public RosterPacket.Item getEntry(String bareJid);
/** /**

View File

@ -0,0 +1,16 @@
<?xml version="1.0"?>
<smackProviders>
<iqProvider>
<elementName>query</elementName>
<namespace>jabber:iq:roster</namespace>
<className>org.jivesoftware.smack.roster.provider.RosterPacketProvider</className>
</iqProvider>
<streamFeatureProvider>
<elementName>ver</elementName>
<namespace>urn:xmpp:features:rosterver</namespace>
<className>org.jivesoftware.smack.roster.provider.RosterVerStreamFeatureProvider</className>
</streamFeatureProvider>
</smackProviders>

View File

@ -0,0 +1,5 @@
<smack>
<startupClasses>
<className>org.jivesoftware.smack.roster.Roster</className>
</startupClasses>
</smack>

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smack; package org.jivesoftware.smack.chat;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
@ -23,7 +23,8 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import org.jivesoftware.smack.ChatManager.MatchMode; import org.jivesoftware.smack.DummyConnection;
import org.jivesoftware.smack.chat.ChatManager.MatchMode;
import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Message.Type; import org.jivesoftware.smack.packet.Message.Type;
import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Packet;

View File

@ -0,0 +1,25 @@
/**
*
* Copyright 2015 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smack.im;
public class InitSmackIm {
static {
(new SmackImInitializer()).initialize();
}
}

View File

@ -0,0 +1,34 @@
/**
*
* Copyright 2015 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smack.im;
import static org.junit.Assert.assertTrue;
import java.util.List;
import org.junit.Test;
public class SmackImInitializerTest {
@Test
public void testExtensionInitializer() {
SmackImInitializer initializer = new SmackImInitializer();
List<Exception> exceptions = initializer.initialize();
assertTrue(exceptions.size() == 0);
}
}

View File

@ -14,12 +14,12 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smack.tcp; package org.jivesoftware.smack.roster;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import org.jivesoftware.smack.Roster; import org.jivesoftware.smack.DummyConnection;
import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.XMPPException;
import org.junit.Before; import org.junit.Before;
@ -32,16 +32,16 @@ import org.junit.Test;
*/ */
public class RosterOfflineTest { public class RosterOfflineTest {
XMPPTCPConnection connection; DummyConnection connection;
Roster roster; Roster roster;
@Before @Before
public void setup() throws XMPPException, SmackException { public void setup() throws XMPPException, SmackException {
this.connection = new XMPPTCPConnection("user", "pass", "example.org"); this.connection = new DummyConnection();
assertFalse(connection.isConnected()); assertFalse(connection.isConnected());
roster = connection.getRoster(); roster = Roster.getInstanceFor(connection);
assertNotNull(roster); assertNotNull(roster);
} }

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smack; package org.jivesoftware.smack.roster;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
@ -30,15 +30,20 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import org.jivesoftware.smack.DummyConnection;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.im.InitSmackIm;
import org.jivesoftware.smack.packet.ErrorIQ; import org.jivesoftware.smack.packet.ErrorIQ;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.RosterPacket;
import org.jivesoftware.smack.packet.IQ.Type; import org.jivesoftware.smack.packet.IQ.Type;
import org.jivesoftware.smack.packet.RosterPacket.Item;
import org.jivesoftware.smack.packet.RosterPacket.ItemType;
import org.jivesoftware.smack.packet.XMPPError.Condition; import org.jivesoftware.smack.packet.XMPPError.Condition;
import org.jivesoftware.smack.roster.packet.RosterPacket;
import org.jivesoftware.smack.roster.packet.RosterPacket.Item;
import org.jivesoftware.smack.roster.packet.RosterPacket.ItemType;
import org.jivesoftware.smack.test.util.TestUtils; import org.jivesoftware.smack.test.util.TestUtils;
import org.jivesoftware.smack.test.util.WaitForPacketListener; import org.jivesoftware.smack.test.util.WaitForPacketListener;
import org.jivesoftware.smack.util.PacketParserUtils; import org.jivesoftware.smack.util.PacketParserUtils;
@ -54,7 +59,7 @@ import org.xmlpull.v1.XmlPullParser;
* @see <a href="http://xmpp.org/rfcs/rfc3921.html#roster">Roster Management</a> * @see <a href="http://xmpp.org/rfcs/rfc3921.html#roster">Roster Management</a>
* @author Guenther Niess * @author Guenther Niess
*/ */
public class RosterTest { public class RosterTest extends InitSmackIm {
private DummyConnection connection; private DummyConnection connection;
private Roster roster; private Roster roster;
@ -62,14 +67,11 @@ public class RosterTest {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
// Uncomment this to enable debug output
//SmackConfiguration.DEBUG = true;
connection = new DummyConnection(); connection = new DummyConnection();
connection.connect(); connection.connect();
connection.login(); connection.login();
rosterListener = new TestRosterListener(); rosterListener = new TestRosterListener();
roster = connection.getRoster(); roster = Roster.getInstanceFor(connection);
roster.addRosterListener(rosterListener); roster.addRosterListener(rosterListener);
connection.setPacketReplyTimeout(1000 * 60 * 5); connection.setPacketReplyTimeout(1000 * 60 * 5);
} }
@ -77,8 +79,8 @@ public class RosterTest {
@After @After
public void tearDown() throws Exception { public void tearDown() throws Exception {
if (connection != null) { if (connection != null) {
if (rosterListener != null && connection.getRoster() != null) { if (rosterListener != null) {
connection.getRoster().removeRosterListener(rosterListener); roster.removeRosterListener(rosterListener);
rosterListener = null; rosterListener = null;
} }
connection.disconnect(); connection.disconnect();
@ -381,7 +383,7 @@ public class RosterTest {
assertEquals(requestId, errorIQ.getPacketID()); assertEquals(requestId, errorIQ.getPacketID());
assertEquals(Condition.service_unavailable, errorIQ.getError().getCondition()); assertEquals(Condition.service_unavailable, errorIQ.getError().getCondition());
assertNull("Contact was added to roster", connection.getRoster().getEntry("spam@example.com")); assertNull("Contact was added to roster", Roster.getInstanceFor(connection).getEntry("spam@example.com"));
} }
/** /**

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smack; package org.jivesoftware.smack.roster;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
@ -26,16 +26,19 @@ import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import org.jivesoftware.smack.DummyConnection;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.ConnectionConfiguration.Builder; import org.jivesoftware.smack.ConnectionConfiguration.Builder;
import org.jivesoftware.smack.RosterTest.TestRosterListener;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.IQ.Type; import org.jivesoftware.smack.packet.IQ.Type;
import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.RosterPacket; import org.jivesoftware.smack.roster.RosterTest.TestRosterListener;
import org.jivesoftware.smack.packet.RosterPacket.Item; import org.jivesoftware.smack.roster.packet.RosterPacket;
import org.jivesoftware.smack.packet.RosterPacket.ItemType; import org.jivesoftware.smack.roster.packet.RosterPacket.Item;
import org.jivesoftware.smack.rosterstore.DirectoryRosterStore; import org.jivesoftware.smack.roster.packet.RosterPacket.ItemType;
import org.jivesoftware.smack.rosterstore.RosterStore; import org.jivesoftware.smack.roster.rosterstore.DirectoryRosterStore;
import org.jivesoftware.smack.roster.rosterstore.RosterStore;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
@ -66,12 +69,12 @@ public class RosterVersioningTest {
populateStore(store); populateStore(store);
Builder<?, ?> builder = DummyConnection.getDummyConfigurationBuilder(); Builder<?, ?> builder = DummyConnection.getDummyConfigurationBuilder();
builder.setRosterStore(store);
connection = new DummyConnection(builder.build()); connection = new DummyConnection(builder.build());
connection.connect(); connection.connect();
connection.login(); connection.login();
rosterListener = new TestRosterListener(); rosterListener = new TestRosterListener();
roster = connection.getRoster(); roster = Roster.getInstanceFor(connection);
roster.setRosterStore(store);
roster.addRosterListener(rosterListener); roster.addRosterListener(rosterListener);
roster.reload(); roster.reload();
} }
@ -152,13 +155,13 @@ public class RosterVersioningTest {
assertTrue("Expected to get a RosterPacket ", false); assertTrue("Expected to get a RosterPacket ", false);
} }
Roster roster = connection.getRoster(); Roster roster = Roster.getInstanceFor(connection);
assertEquals("Size of roster", 1, roster.getEntries().size()); assertEquals("Size of roster", 1, roster.getEntries().size());
RosterEntry entry = roster.getEntry(vaglafItem.getUser()); RosterEntry entry = roster.getEntry(vaglafItem.getUser());
assertNotNull("Roster contains vaglaf entry", entry); assertNotNull("Roster contains vaglaf entry", entry);
assertEquals("vaglaf entry in roster equals the sent entry", vaglafItem, RosterEntry.toRosterItem(entry)); assertEquals("vaglaf entry in roster equals the sent entry", vaglafItem, RosterEntry.toRosterItem(entry));
RosterStore store = connection.getConfiguration().getRosterStore(); RosterStore store = roster.getRosterStore();
assertEquals("Size of store", 1, store.getEntries().size()); assertEquals("Size of store", 1, store.getEntries().size());
Item item = store.getEntry(vaglafItem.getUser()); Item item = store.getEntry(vaglafItem.getUser());
assertNotNull("Store contains vaglaf entry"); assertNotNull("Store contains vaglaf entry");
@ -173,7 +176,7 @@ public class RosterVersioningTest {
answerWithEmptyRosterResult(); answerWithEmptyRosterResult();
rosterListener.waitAndReset(); rosterListener.waitAndReset();
RosterStore store = connection.getConfiguration().getRosterStore(); RosterStore store = roster.getRosterStore();
// Simulate a roster push adding vaglaf // Simulate a roster push adding vaglaf
{ {

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smack.rosterstore; package org.jivesoftware.smack.roster.rosterstore;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
@ -25,10 +25,10 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.jivesoftware.smack.packet.RosterPacket; import org.jivesoftware.smack.roster.packet.RosterPacket;
import org.jivesoftware.smack.packet.RosterPacket.Item; import org.jivesoftware.smack.roster.packet.RosterPacket.Item;
import org.jivesoftware.smack.packet.RosterPacket.ItemStatus; import org.jivesoftware.smack.roster.packet.RosterPacket.ItemStatus;
import org.jivesoftware.smack.packet.RosterPacket.ItemType; import org.jivesoftware.smack.roster.packet.RosterPacket.ItemType;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;

View File

@ -23,7 +23,6 @@ import java.util.logging.Logger;
import org.jivesoftware.smack.ConnectionCreationListener; import org.jivesoftware.smack.ConnectionCreationListener;
import org.jivesoftware.smack.PacketListener; import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.RosterListener;
import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPConnectionRegistry; import org.jivesoftware.smack.XMPPConnectionRegistry;
@ -33,6 +32,8 @@ import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.provider.ProviderManager; import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smack.roster.RosterListener;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.jingleold.listeners.CreatedJingleSessionListener; import org.jivesoftware.smackx.jingleold.listeners.CreatedJingleSessionListener;
import org.jivesoftware.smackx.jingleold.listeners.JingleListener; import org.jivesoftware.smackx.jingleold.listeners.JingleListener;
@ -213,7 +214,7 @@ public class JingleManager implements JingleSessionListener {
this.connection = connection; this.connection = connection;
this.jingleMediaManagers = jingleMediaManagers; this.jingleMediaManagers = jingleMediaManagers;
connection.getRoster().addRosterListener(new RosterListener() { Roster.getInstanceFor(connection).addRosterListener(new RosterListener() {
public void entriesAdded(Collection<String> addresses) { public void entriesAdded(Collection<String> addresses) {
} }

View File

@ -25,15 +25,15 @@ import java.util.Set;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import org.jivesoftware.smack.PacketListener; import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterGroup;
import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.filter.PacketExtensionFilter; import org.jivesoftware.smack.filter.PacketExtensionFilter;
import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smack.roster.RosterEntry;
import org.jivesoftware.smack.roster.RosterGroup;
import org.jivesoftware.smackx.xroster.packet.RosterExchange; import org.jivesoftware.smackx.xroster.packet.RosterExchange;
/** /**

View File

@ -17,10 +17,10 @@
package org.jivesoftware.smackx.xroster.packet; package org.jivesoftware.smackx.xroster.packet;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterGroup;
import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smack.roster.RosterEntry;
import org.jivesoftware.smack.roster.RosterGroup;
import org.jivesoftware.smackx.xroster.RemoteRosterEntry; import org.jivesoftware.smackx.xroster.RemoteRosterEntry;
import org.jivesoftware.smackx.xroster.RosterExchangeManager; import org.jivesoftware.smackx.xroster.RosterExchangeManager;