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.
builtDate = (new java.text.SimpleDateFormat("yyyy-MM-dd")).format(new Date())
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()
androidJavadocOffline = getAndroidJavadocOffline()
}

View File

@ -39,7 +39,7 @@ XMPPConnection conn1 = …
// Create a new roster exchange manager on conn1
RosterExchangeManager rosterExchangeManager = new RosterExchangeManager(conn1);
// Send user1's roster to user2
rosterExchangeManager.send(conn1.getRoster(), user2);
rosterExchangeManager.send(Roster.getInstanceFor(conn1), user2);
```
Send a roster group
@ -67,7 +67,7 @@ XMPPConnection conn1 = …
// Create a new roster exchange manager on conn1
RosterExchangeManager rosterExchangeManager = new RosterExchangeManager(conn1);
// 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);
```
@ -96,7 +96,7 @@ XMPPConnection conn1 = …
// Create a new roster exchange manager on conn1
RosterExchangeManager rosterExchangeManager = new RosterExchangeManager(conn1);
// 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
@ -124,7 +124,7 @@ adds the received entries to his roster.
XMPPConnection conn1 = …
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
the entries received
@ -156,5 +156,5 @@ rosterExchangeManager2.addRosterListener(rosterExchangeListener);
// Create a RosterExchangeManager that will help user1 to send his roster
RosterExchangeManager rosterExchangeManager1 = new RosterExchangeManager(conn1);
// 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
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,
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
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
--------------
@ -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:
```
Roster roster = connection.getRoster();
Roster roster = Roster.getInstanceFor(connection);
Collection<RosterEntry> entries = roster.getEntries();
for (RosterEntry entry : entries) {
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.
```
Roster roster = con.getRoster();
Roster roster = Roster.getInstanceFor(con);
roster.addRosterListener(new RosterListener() {
// Ignored events public void entriesAdded(Collection<String> addresses) {}
public void entriesDeleted(Collection<String> addresses) {}

View File

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

View File

@ -34,7 +34,6 @@ import org.jivesoftware.smack.SmackException.ConnectionException;
import org.jivesoftware.smack.XMPPException.StreamErrorException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.ConnectionCreationListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Element;
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
* 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
* BOSH packet reader and {@link Roster} will not be removed; thus
* connection's state is kept.
* BOSH packet reader will not be removed; thus connection's state is kept.
*
*/
@Override

View File

@ -66,7 +66,6 @@ import org.jivesoftware.smack.packet.Mechanisms;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.RosterVer;
import org.jivesoftware.smack.packet.Session;
import org.jivesoftware.smack.packet.StartTls;
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.provider.PacketExtensionProvider;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.rosterstore.RosterStore;
import org.jivesoftware.smack.util.DNSUtil;
import org.jivesoftware.smack.util.PacketParserUtils;
import org.jivesoftware.smack.util.ParserUtils;
@ -264,8 +262,6 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
private final ExecutorService singleThreadedExecutorService = Executors.newSingleThreadExecutor(new SmackExecutorThreadFactory(
getConnectionCounter(), "Single Threaded Executor"));
private Roster roster;
/**
* The used host to establish the connection to
*/
@ -380,9 +376,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
* </p>
* <p>
* It is possible to log in without sending an initial available presence by using
* {@link ConnectionConfiguration.Builder#setSendPresence(boolean)}. If this connection is
* not interested in loading its roster upon login then use
* {@link ConnectionConfiguration.Builder#setRosterLoadedAtLogin(boolean)}.
* {@link ConnectionConfiguration.Builder#setSendPresence(boolean)}.
* 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
* {@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
// send the initial presence.
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));
}
}
@ -603,36 +592,6 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
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
* 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,
IOException, SmackException {
streamFeatures.clear();
@ -1318,16 +1267,6 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
case Session.ELEMENT:
streamFeature = PacketParserUtils.parseSessionFeature(parser);
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:
streamFeature = PacketParserUtils.parseCompressionFeature(parser);
break;

View File

@ -19,7 +19,6 @@ package org.jivesoftware.smack;
import org.jivesoftware.smack.packet.Session;
import org.jivesoftware.smack.proxy.ProxyInfo;
import org.jivesoftware.smack.rosterstore.RosterStore;
import javax.net.SocketFactory;
import javax.net.ssl.HostnameVerifier;
@ -66,8 +65,13 @@ public abstract class ConnectionConfiguration {
private final CharSequence username;
private final String password;
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 rosterLoadedAtLogin;
private final boolean legacySessionDisabled;
private final SecurityMode securityMode;
@ -83,11 +87,6 @@ public abstract class ConnectionConfiguration {
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)
protected final ProxyInfo proxy;
@ -127,9 +126,7 @@ public abstract class ConnectionConfiguration {
enabledSSLCiphers = builder.enabledSSLCiphers;
hostnameVerifier = builder.hostnameVerifier;
sendPresence = builder.sendPresence;
rosterLoadedAtLogin = builder.rosterLoadedAtLogin;
legacySessionDisabled = builder.legacySessionDisabled;
rosterStore = builder.rosterStore;
debuggerEnabled = builder.debuggerEnabled;
allowNullOrEmptyUsername = builder.allowEmptyOrNullUsername;
}
@ -234,17 +231,6 @@ public abstract class ConnectionConfiguration {
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
* 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;
}
/**
* Get the permanent roster store
*/
public RosterStore getRosterStore() {
return rosterStore;
}
/**
* An enumeration for TLS security modes that are available when making a connection
* to the XMPP server.
@ -394,9 +372,7 @@ public abstract class ConnectionConfiguration {
private String password;
private String resource = "Smack";
private boolean sendPresence = true;
private boolean rosterLoadedAtLogin = true;
private boolean legacySessionDisabled = false;
private RosterStore rosterStore;
private ProxyInfo proxy;
private CallbackHandler callbackHandler;
private boolean debuggerEnabled = SmackConfiguration.DEBUG;
@ -595,19 +571,6 @@ public abstract class ConnectionConfiguration {
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
* an available presence will be sent to the server indicating that this presence
@ -622,16 +585,6 @@ public abstract class ConnectionConfiguration {
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
* 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.initializer.SmackInitializer;
import org.jivesoftware.smack.packet.Bind;
import org.jivesoftware.smack.packet.RosterPacket;
import org.jivesoftware.smack.provider.BindIQProvider;
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.SCRAMSHA1Mechanism;
import org.jivesoftware.smack.util.FileUtils;
@ -140,7 +138,6 @@ public final class SmackInitialization {
SASLAuthentication.registerSASLMechanism(new SCRAMSHA1Mechanism());
SASLAuthentication.registerSASLMechanism(new SASLXOauth2Mechanism());
ProviderManager.addIQProvider(RosterPacket.ELEMENT, RosterPacket.NAMESPACE, RosterPacketProvider.INSTANCE);
ProviderManager.addIQProvider(Bind.ELEMENT, Bind.NAMESPACE, new BindIQProvider());
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.PacketExtension;
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
@ -167,20 +166,6 @@ public interface XMPPConnection {
*/
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
* the connection closes or fails.
@ -438,22 +423,6 @@ public interface XMPPConnection {
*/
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
* 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
* unsubscribe users from the roster.
*
* @see RosterPacket
* @author Matt Tucker
*/
public final class Presence extends Packet {

View File

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

View File

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

View File

@ -17,8 +17,8 @@
package org.jivesoftware.smackx.chatstates;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatMessageListener;
import org.jivesoftware.smack.chat.Chat;
import org.jivesoftware.smack.chat.ChatMessageListener;
/**
* 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.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.SmackException.NotConnectedException;
import org.jivesoftware.smack.XMPPConnection;
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.PacketExtensionFilter;
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.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.PacketCollector;
import org.jivesoftware.smack.PacketListener;
@ -42,6 +39,9 @@ import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
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.FromMatchesFilter;
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.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
/**
@ -147,7 +148,7 @@ public class DeliveryReceiptManager extends Manager {
case disabled:
return;
case ifIsSubscribed:
if (!connection.getRoster().isSubscribedToMyPresence(from)) {
if (!Roster.getInstanceFor(connection).isSubscribedToMyPresence(from)) {
return;
}
break;

View File

@ -18,9 +18,9 @@
package org.jivesoftware.smackx.xdata.provider;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.packet.RosterPacket;
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.packet.DataForm;
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.
*/
package org.jivesoftware.smack;
package org.jivesoftware.smack.chat;
import org.jivesoftware.smack.PacketCollector;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.util.StringUtils;

View File

@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.jivesoftware.smack;
package org.jivesoftware.smack.chat;
import java.util.Collections;
import java.util.Map;
@ -25,6 +25,11 @@ import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
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.filter.AndFilter;
import org.jivesoftware.smack.filter.FlexiblePacketTypeFilter;

View File

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

View File

@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.jivesoftware.smack;
package org.jivesoftware.smack.chat;
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.
*/
package org.jivesoftware.smack;
package org.jivesoftware.smack.roster;
import java.util.ArrayList;
import java.util.Arrays;
@ -27,14 +27,23 @@ import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;
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.NotConnectedException;
import org.jivesoftware.smack.SmackException.NotLoggedInException;
import org.jivesoftware.smack.XMPPConnectionRegistry;
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.filter.PacketFilter;
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.Packet;
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.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;
/**
@ -63,22 +72,55 @@ import org.jxmpp.util.XmppStringUtils;
* </ul>
*
* @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());
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 boolean rosterLoadedAtLoginDefault = true;
/**
* The default subscription processing mode to use when a Roster is created. By default
* all subscription requests are automatically accepted.
*/
private static SubscriptionMode defaultSubscriptionMode = SubscriptionMode.accept_all;
private final XMPPConnection connection;
private final RosterStore rosterStore;
private RosterStore rosterStore;
private final Map<String, RosterGroup> groups = new ConcurrentHashMap<String, RosterGroup>();
private final Map<String,RosterEntry> entries = new ConcurrentHashMap<String,RosterEntry>();
private final List<RosterEntry> unfiledEntries = new CopyOnWriteArrayList<RosterEntry>();
@ -91,6 +133,11 @@ public class Roster {
private final PresencePacketListener presencePacketListener = new PresencePacketListener();
/**
*
*/
private boolean rosterLoadedAtLogin = rosterLoadedAtLoginDefault;
private SubscriptionMode subscriptionMode = getDefaultSubscriptionMode();
/**
@ -122,9 +169,8 @@ public class Roster {
*
* @param connection an XMPP connection.
*/
Roster(final XMPPConnection connection) {
this.connection = connection;
rosterStore = connection.getRosterStore();
private Roster(final XMPPConnection connection) {
super(connection);
// Note that we use sync packet listeners because RosterListeners should be invoked in the same order as the
// roster stanzas arrive.
@ -143,7 +189,7 @@ public class Roster {
// again if it's an anonymous connection.
if (connection.isAnonymous())
return;
if (!connection.isRosterLoadedAtLogin())
if (!isRosterLoadedAtLogin())
return;
// We are done here if the connection was resumed
if (resumed) {
@ -214,6 +260,7 @@ public class Roster {
* @throws NotConnectedException
*/
public void reload() throws NotLoggedInException, NotConnectedException{
final XMPPConnection connection = connection();
if (!connection.isAuthenticated()) {
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() {
final XMPPConnection connection = connection();
while (!loaded) {
long waitTime = connection.getPacketReplyTimeout();
long start = System.currentTimeMillis();
@ -301,6 +366,7 @@ public class Roster {
* @throws IllegalStateException if logged in anonymously
*/
public RosterGroup createGroup(String name) {
final XMPPConnection connection = connection();
if (connection.isAnonymous()) {
throw new IllegalStateException("Anonymous users can't have a roster.");
}
@ -327,6 +393,7 @@ public class Roster {
* @throws NotConnectedException
*/
public void createEntry(String user, String name, String[] groups) throws NotLoggedInException, NoResponseException, XMPPErrorException, NotConnectedException {
final XMPPConnection connection = connection();
if (!connection.isAuthenticated()) {
throw new NotLoggedInException();
}
@ -368,6 +435,7 @@ public class Roster {
* @throws IllegalStateException if connection is not logged in or logged in anonymously
*/
public void removeEntry(RosterEntry entry) throws NotLoggedInException, NoResponseException, XMPPErrorException, NotConnectedException {
final XMPPConnection connection = connection();
if (!connection.isAuthenticated()) {
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.
* The roster can contain any valid address format such us "domain/resource",
@ -921,7 +1016,7 @@ public class Roster {
}
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 {
final XMPPConnection connection = connection();
Presence presence = (Presence) packet;
String from = presence.getFrom();
String key = getMapKey(from);
@ -1078,6 +1174,7 @@ public class Roster {
@Override
public void processPacket(Packet packet) {
final XMPPConnection connection = connection();
LOGGER.fine("RosterResultListener received stanza");
Collection<String> addedEntries = new ArrayList<String>();
Collection<String> updatedEntries = new ArrayList<String>();
@ -1153,6 +1250,7 @@ public class Roster {
@Override
public IQ handleIQRequest(IQ iqRequest) {
final XMPPConnection connection = connection();
RosterPacket rosterPacket = (RosterPacket) iqRequest;
// Roster push (RFC 6121, 2.1.6)

View File

@ -15,16 +15,17 @@
* limitations under the License.
*/
package org.jivesoftware.smack;
package org.jivesoftware.smack.roster;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.SmackException.NotConnectedException;
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.
*/
package org.jivesoftware.smack;
package org.jivesoftware.smack.roster;
import java.util.ArrayList;
import java.util.LinkedHashSet;
@ -23,11 +23,13 @@ import java.util.List;
import java.util.Locale;
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.NotConnectedException;
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.RosterPacket;
import org.jivesoftware.smack.roster.packet.RosterPacket;
import org.jxmpp.util.XmppStringUtils;
/**

View File

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

View File

@ -15,8 +15,10 @@
* 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 java.util.ArrayList;

View File

@ -14,8 +14,9 @@
* See the License for the specific language governing permissions and
* 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;
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");
* 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
* limitations under the License.
*/
package org.jivesoftware.smack.provider;
package org.jivesoftware.smack.roster.provider;
import java.io.IOException;
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.XmlPullParserException;
@ -27,9 +28,6 @@ public class RosterPacketProvider extends IQProvider<RosterPacket> {
public static final RosterPacketProvider INSTANCE = new RosterPacketProvider();
private RosterPacketProvider() {
}
@Override
public RosterPacket parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException,
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
* limitations under the License.
*/
package org.jivesoftware.smack.rosterstore;
package org.jivesoftware.smack.roster.rosterstore;
import java.io.File;
import java.io.FileFilter;
@ -26,8 +26,8 @@ import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jivesoftware.smack.packet.RosterPacket;
import org.jivesoftware.smack.packet.RosterPacket.Item;
import org.jivesoftware.smack.roster.packet.RosterPacket;
import org.jivesoftware.smack.roster.packet.RosterPacket.Item;
import org.jivesoftware.smack.util.FileUtils;
import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jivesoftware.smack.util.stringencoder.Base32;

View File

@ -14,11 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smack.rosterstore;
package org.jivesoftware.smack.roster.rosterstore;
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
@ -29,13 +29,13 @@ public interface RosterStore {
/**
* 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();
/**
* This method returns the roster item in this store for the given JID.
* @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);
/**

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
* limitations under the License.
*/
package org.jivesoftware.smack;
package org.jivesoftware.smack.chat;
import static org.junit.Assert.assertFalse;
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.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.Type;
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
* 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.assertNotNull;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.DummyConnection;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPException;
import org.junit.Before;
@ -32,16 +32,16 @@ import org.junit.Test;
*/
public class RosterOfflineTest {
XMPPTCPConnection connection;
DummyConnection connection;
Roster roster;
@Before
public void setup() throws XMPPException, SmackException {
this.connection = new XMPPTCPConnection("user", "pass", "example.org");
this.connection = new DummyConnection();
assertFalse(connection.isConnected());
roster = connection.getRoster();
roster = Roster.getInstanceFor(connection);
assertNotNull(roster);
}

View File

@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.jivesoftware.smack;
package org.jivesoftware.smack.roster;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@ -30,15 +30,20 @@ import java.util.Collections;
import java.util.List;
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.IQ;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.RosterPacket;
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.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.WaitForPacketListener;
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>
* @author Guenther Niess
*/
public class RosterTest {
public class RosterTest extends InitSmackIm {
private DummyConnection connection;
private Roster roster;
@ -62,14 +67,11 @@ public class RosterTest {
@Before
public void setUp() throws Exception {
// Uncomment this to enable debug output
//SmackConfiguration.DEBUG = true;
connection = new DummyConnection();
connection.connect();
connection.login();
rosterListener = new TestRosterListener();
roster = connection.getRoster();
roster = Roster.getInstanceFor(connection);
roster.addRosterListener(rosterListener);
connection.setPacketReplyTimeout(1000 * 60 * 5);
}
@ -77,8 +79,8 @@ public class RosterTest {
@After
public void tearDown() throws Exception {
if (connection != null) {
if (rosterListener != null && connection.getRoster() != null) {
connection.getRoster().removeRosterListener(rosterListener);
if (rosterListener != null) {
roster.removeRosterListener(rosterListener);
rosterListener = null;
}
connection.disconnect();
@ -381,7 +383,7 @@ public class RosterTest {
assertEquals(requestId, errorIQ.getPacketID());
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
* limitations under the License.
*/
package org.jivesoftware.smack;
package org.jivesoftware.smack.roster;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@ -26,16 +26,19 @@ import java.io.IOException;
import java.util.Collection;
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.RosterTest.TestRosterListener;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.IQ.Type;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.RosterPacket;
import org.jivesoftware.smack.packet.RosterPacket.Item;
import org.jivesoftware.smack.packet.RosterPacket.ItemType;
import org.jivesoftware.smack.rosterstore.DirectoryRosterStore;
import org.jivesoftware.smack.rosterstore.RosterStore;
import org.jivesoftware.smack.roster.RosterTest.TestRosterListener;
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.roster.rosterstore.DirectoryRosterStore;
import org.jivesoftware.smack.roster.rosterstore.RosterStore;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@ -66,12 +69,12 @@ public class RosterVersioningTest {
populateStore(store);
Builder<?, ?> builder = DummyConnection.getDummyConfigurationBuilder();
builder.setRosterStore(store);
connection = new DummyConnection(builder.build());
connection.connect();
connection.login();
rosterListener = new TestRosterListener();
roster = connection.getRoster();
roster = Roster.getInstanceFor(connection);
roster.setRosterStore(store);
roster.addRosterListener(rosterListener);
roster.reload();
}
@ -152,13 +155,13 @@ public class RosterVersioningTest {
assertTrue("Expected to get a RosterPacket ", false);
}
Roster roster = connection.getRoster();
Roster roster = Roster.getInstanceFor(connection);
assertEquals("Size of roster", 1, roster.getEntries().size());
RosterEntry entry = roster.getEntry(vaglafItem.getUser());
assertNotNull("Roster contains vaglaf entry", 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());
Item item = store.getEntry(vaglafItem.getUser());
assertNotNull("Store contains vaglaf entry");
@ -173,7 +176,7 @@ public class RosterVersioningTest {
answerWithEmptyRosterResult();
rosterListener.waitAndReset();
RosterStore store = connection.getConfiguration().getRosterStore();
RosterStore store = roster.getRosterStore();
// Simulate a roster push adding vaglaf
{

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* 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.assertNotNull;
@ -25,10 +25,10 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.jivesoftware.smack.packet.RosterPacket;
import org.jivesoftware.smack.packet.RosterPacket.Item;
import org.jivesoftware.smack.packet.RosterPacket.ItemStatus;
import org.jivesoftware.smack.packet.RosterPacket.ItemType;
import org.jivesoftware.smack.roster.packet.RosterPacket;
import org.jivesoftware.smack.roster.packet.RosterPacket.Item;
import org.jivesoftware.smack.roster.packet.RosterPacket.ItemStatus;
import org.jivesoftware.smack.roster.packet.RosterPacket.ItemType;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;

View File

@ -23,7 +23,6 @@ import java.util.logging.Logger;
import org.jivesoftware.smack.ConnectionCreationListener;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.RosterListener;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection;
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.Presence;
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.jingleold.listeners.CreatedJingleSessionListener;
import org.jivesoftware.smackx.jingleold.listeners.JingleListener;
@ -213,7 +214,7 @@ public class JingleManager implements JingleSessionListener {
this.connection = connection;
this.jingleMediaManagers = jingleMediaManagers;
connection.getRoster().addRosterListener(new RosterListener() {
Roster.getInstanceFor(connection).addRosterListener(new RosterListener() {
public void entriesAdded(Collection<String> addresses) {
}

View File

@ -25,15 +25,15 @@ import java.util.Set;
import java.util.WeakHashMap;
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.XMPPConnection;
import org.jivesoftware.smack.filter.PacketExtensionFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.Message;
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;
/**

View File

@ -17,10 +17,10 @@
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.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.RosterExchangeManager;