mirror of
https://github.com/vanitasvitae/Smack.git
synced 2025-09-09 09:09:38 +02:00
Use Jid (and subclasses) from jxmpp-jid
Fixes SMACK-634
This commit is contained in:
parent
0ee2d9ed1e
commit
5bb4727c57
180 changed files with 1510 additions and 1032 deletions
|
@ -21,6 +21,7 @@ import org.jivesoftware.smack.PacketCollector;
|
|||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jxmpp.jid.JidWithLocalpart;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.Collections;
|
||||
|
@ -40,7 +41,7 @@ public class Chat {
|
|||
|
||||
private ChatManager chatManager;
|
||||
private String threadID;
|
||||
private String participant;
|
||||
private JidWithLocalpart participant;
|
||||
private final Set<ChatMessageListener> listeners = new CopyOnWriteArraySet<ChatMessageListener>();
|
||||
|
||||
/**
|
||||
|
@ -50,7 +51,7 @@ public class Chat {
|
|||
* @param participant the user to chat with.
|
||||
* @param threadID the thread ID to use.
|
||||
*/
|
||||
Chat(ChatManager chatManager, String participant, String threadID) {
|
||||
Chat(ChatManager chatManager, JidWithLocalpart participant, String threadID) {
|
||||
if (StringUtils.isEmpty(threadID)) {
|
||||
throw new IllegalArgumentException("Thread ID must not be null");
|
||||
}
|
||||
|
@ -75,7 +76,7 @@ public class Chat {
|
|||
*
|
||||
* @return the name of the user the chat is occuring with.
|
||||
*/
|
||||
public String getParticipant() {
|
||||
public JidWithLocalpart getParticipant() {
|
||||
return participant;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.UUID;
|
|||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.Manager;
|
||||
import org.jivesoftware.smack.MessageListener;
|
||||
|
@ -41,7 +42,9 @@ import org.jivesoftware.smack.filter.ThreadFilter;
|
|||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Message.Type;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jxmpp.util.XmppStringUtils;
|
||||
import org.jxmpp.jid.BareJid;
|
||||
import org.jxmpp.jid.Jid;
|
||||
import org.jxmpp.jid.JidWithLocalpart;
|
||||
|
||||
/**
|
||||
* The chat manager keeps track of references to all current chats. It will not hold any references
|
||||
|
@ -51,6 +54,9 @@ import org.jxmpp.util.XmppStringUtils;
|
|||
* @author Alexander Wenckus
|
||||
*/
|
||||
public class ChatManager extends Manager{
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(ChatManager.class.getName());
|
||||
|
||||
private static final Map<XMPPConnection, ChatManager> INSTANCES = new WeakHashMap<XMPPConnection, ChatManager>();
|
||||
|
||||
/**
|
||||
|
@ -124,12 +130,12 @@ public class ChatManager extends Manager{
|
|||
/**
|
||||
* Maps jids to chats
|
||||
*/
|
||||
private Map<String, Chat> jidChats = new ConcurrentHashMap<>();
|
||||
private Map<Jid, Chat> jidChats = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Maps base jids to chats
|
||||
*/
|
||||
private Map<String, Chat> baseJidChats = new ConcurrentHashMap<>();
|
||||
private Map<BareJid, Chat> baseJidChats = new ConcurrentHashMap<>();
|
||||
|
||||
private Set<ChatManagerListener> chatManagerListeners
|
||||
= new CopyOnWriteArraySet<ChatManagerListener>();
|
||||
|
@ -209,7 +215,7 @@ public class ChatManager extends Manager{
|
|||
* @param userJID the user this chat is with.
|
||||
* @return the created chat.
|
||||
*/
|
||||
public Chat createChat(String userJID) {
|
||||
public Chat createChat(JidWithLocalpart userJID) {
|
||||
return createChat(userJID, null);
|
||||
}
|
||||
|
||||
|
@ -220,7 +226,7 @@ public class ChatManager extends Manager{
|
|||
* @param listener the optional listener which will listen for new messages from this chat.
|
||||
* @return the created chat.
|
||||
*/
|
||||
public Chat createChat(String userJID, ChatMessageListener listener) {
|
||||
public Chat createChat(JidWithLocalpart userJID, ChatMessageListener listener) {
|
||||
return createChat(userJID, null, listener);
|
||||
}
|
||||
|
||||
|
@ -232,7 +238,7 @@ public class ChatManager extends Manager{
|
|||
* @param listener the optional listener to add to the chat
|
||||
* @return the created chat.
|
||||
*/
|
||||
public Chat createChat(String userJID, String thread, ChatMessageListener listener) {
|
||||
public Chat createChat(JidWithLocalpart userJID, String thread, ChatMessageListener listener) {
|
||||
if (thread == null) {
|
||||
thread = nextID();
|
||||
}
|
||||
|
@ -245,11 +251,11 @@ public class ChatManager extends Manager{
|
|||
return chat;
|
||||
}
|
||||
|
||||
private Chat createChat(String userJID, String threadID, boolean createdLocally) {
|
||||
private Chat createChat(JidWithLocalpart userJID, String threadID, boolean createdLocally) {
|
||||
Chat chat = new Chat(this, userJID, threadID);
|
||||
threadChats.put(threadID, chat);
|
||||
jidChats.put(userJID, chat);
|
||||
baseJidChats.put(XmppStringUtils.parseBareJid(userJID), chat);
|
||||
baseJidChats.put(userJID.asBareJid(), chat);
|
||||
|
||||
for(ChatManagerListener listener : chatManagerListeners) {
|
||||
listener.chatCreated(chat, createdLocally);
|
||||
|
@ -260,9 +266,9 @@ public class ChatManager extends Manager{
|
|||
|
||||
void closeChat(Chat chat) {
|
||||
threadChats.remove(chat.getThreadID());
|
||||
String userJID = chat.getParticipant();
|
||||
JidWithLocalpart userJID = chat.getParticipant();
|
||||
jidChats.remove(userJID);
|
||||
baseJidChats.remove(XmppStringUtils.parseBareJid(userJID));
|
||||
baseJidChats.remove(userJID.withoutResource());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -273,10 +279,16 @@ public class ChatManager extends Manager{
|
|||
* @return a Chat or null if none can be created
|
||||
*/
|
||||
private Chat createChat(Message message) {
|
||||
String userJID = message.getFrom();
|
||||
Jid from = message.getFrom();
|
||||
// According to RFC6120 8.1.2.1 4. messages without a 'from' attribute are valid, but they
|
||||
// are of no use in this case for ChatManager
|
||||
if (from == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
JidWithLocalpart userJID = from.asJidWithLocalpartIfPossible();
|
||||
if (userJID == null) {
|
||||
LOGGER.warning("Message from JID without localpart: '" +message.toXML() + "'");
|
||||
return null;
|
||||
}
|
||||
String threadID = message.getThread();
|
||||
|
@ -296,7 +308,7 @@ public class ChatManager extends Manager{
|
|||
* @param userJID jid in the from field of message.
|
||||
* @return Matching chat, or null if no match found.
|
||||
*/
|
||||
private Chat getUserChat(String userJID) {
|
||||
private Chat getUserChat(Jid userJID) {
|
||||
if (matchMode == MatchMode.NONE) {
|
||||
return null;
|
||||
}
|
||||
|
@ -308,7 +320,7 @@ public class ChatManager extends Manager{
|
|||
Chat match = jidChats.get(userJID);
|
||||
|
||||
if (match == null && (matchMode == MatchMode.BARE_JID)) {
|
||||
match = baseJidChats.get(XmppStringUtils.parseBareJid(userJID));
|
||||
match = baseJidChats.get(userJID.asBareJidIfPossible());
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.util.Collections;
|
|||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
@ -60,7 +59,11 @@ import org.jivesoftware.smack.roster.packet.RosterVer;
|
|||
import org.jivesoftware.smack.roster.packet.RosterPacket.Item;
|
||||
import org.jivesoftware.smack.roster.rosterstore.RosterStore;
|
||||
import org.jivesoftware.smack.util.Objects;
|
||||
import org.jxmpp.util.XmppStringUtils;
|
||||
import org.jxmpp.jid.BareJid;
|
||||
import org.jxmpp.jid.Jid;
|
||||
import org.jxmpp.jid.JidWithResource;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.jxmpp.jid.parts.Resourcepart;
|
||||
|
||||
/**
|
||||
* Represents a user's roster, which is the collection of users a person receives
|
||||
|
@ -96,7 +99,7 @@ public class Roster extends Manager {
|
|||
* <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[])},
|
||||
* like {@link Roster#createEntry(Jid, String, String[])},
|
||||
* {@link Roster#removeEntry(RosterEntry)} , etc. except adding or removing
|
||||
* {@link RosterListener}s will throw an IllegalStateException.
|
||||
*
|
||||
|
@ -128,11 +131,16 @@ public class Roster extends Manager {
|
|||
/**
|
||||
* Concurrent hash map from JID to its roster entry.
|
||||
*/
|
||||
private final Map<String,RosterEntry> entries = new ConcurrentHashMap<String,RosterEntry>();
|
||||
private final Map<Jid, RosterEntry> entries = new ConcurrentHashMap<>();
|
||||
|
||||
private final Set<RosterEntry> unfiledEntries = new CopyOnWriteArraySet<>();
|
||||
private final Set<RosterListener> rosterListeners = new LinkedHashSet<>();
|
||||
private final Map<String, Map<String, Presence>> presenceMap = new ConcurrentHashMap<String, Map<String, Presence>>();
|
||||
|
||||
/**
|
||||
* A map of JIDs to another Map of Resourceparts to Presences. The 'inner' map may contain
|
||||
* {@link Resourcepart#EMPTY} if there are no other Presences available.
|
||||
*/
|
||||
private final Map<Jid, Map<Resourcepart, Presence>> presenceMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Mutually exclude roster listener invocation and changing the {@link entries} map. Also used
|
||||
|
@ -421,7 +429,7 @@ public class Roster extends Manager {
|
|||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void createEntry(String user, String name, String[] groups) throws NotLoggedInException, NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
public void createEntry(Jid user, String name, String[] groups) throws NotLoggedInException, NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
final XMPPConnection connection = connection();
|
||||
if (!connection.isAuthenticated()) {
|
||||
throw new NotLoggedInException();
|
||||
|
@ -568,11 +576,11 @@ public class Roster extends Manager {
|
|||
* in any valid format (e.g. "domain/resource", "user@domain" or "user@domain/resource").
|
||||
* @return the roster entry or <tt>null</tt> if it does not exist.
|
||||
*/
|
||||
public RosterEntry getEntry(String user) {
|
||||
public RosterEntry getEntry(Jid user) {
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
String key = getMapKey(user);
|
||||
Jid key = getMapKey(user);
|
||||
return entries.get(key);
|
||||
}
|
||||
|
||||
|
@ -584,7 +592,7 @@ public class Roster extends Manager {
|
|||
* "user@domain" or "user@domain/resource").
|
||||
* @return true if the XMPP address is an entry in the roster.
|
||||
*/
|
||||
public boolean contains(String user) {
|
||||
public boolean contains(Jid user) {
|
||||
return getEntry(user) != null;
|
||||
}
|
||||
|
||||
|
@ -645,9 +653,9 @@ public class Roster extends Manager {
|
|||
* @return the user's current presence, or unavailable presence if the user is offline
|
||||
* or if no presence information is available..
|
||||
*/
|
||||
public Presence getPresence(String user) {
|
||||
String key = getMapKey(XmppStringUtils.parseBareJid(user));
|
||||
Map<String, Presence> userPresences = presenceMap.get(key);
|
||||
public Presence getPresence(Jid user) {
|
||||
Jid key = getMapKey(user);
|
||||
Map<Resourcepart, Presence> userPresences = presenceMap.get(key);
|
||||
if (userPresences == null) {
|
||||
Presence presence = new Presence(Presence.Type.unavailable);
|
||||
presence.setFrom(user);
|
||||
|
@ -660,7 +668,7 @@ public class Roster extends Manager {
|
|||
// This is used in case no available presence is found
|
||||
Presence unavailable = null;
|
||||
|
||||
for (String resource : userPresences.keySet()) {
|
||||
for (Resourcepart resource : userPresences.keySet()) {
|
||||
Presence p = userPresences.get(resource);
|
||||
if (!p.isAvailable()) {
|
||||
unavailable = p;
|
||||
|
@ -712,10 +720,10 @@ public class Roster extends Manager {
|
|||
* @return the user's current presence, or unavailable presence if the user is offline
|
||||
* or if no presence information is available.
|
||||
*/
|
||||
public Presence getPresenceResource(String userWithResource) {
|
||||
String key = getMapKey(userWithResource);
|
||||
String resource = XmppStringUtils.parseResource(userWithResource);
|
||||
Map<String, Presence> userPresences = presenceMap.get(key);
|
||||
public Presence getPresenceResource(JidWithResource userWithResource) {
|
||||
Jid key = getMapKey(userWithResource);
|
||||
Resourcepart resource = userWithResource.getResourcepart();
|
||||
Map<Resourcepart, Presence> userPresences = presenceMap.get(key);
|
||||
if (userPresences == null) {
|
||||
Presence presence = new Presence(Presence.Type.unavailable);
|
||||
presence.setFrom(userWithResource);
|
||||
|
@ -742,8 +750,8 @@ public class Roster extends Manager {
|
|||
* @return a List of Presence objects for all the user's current presences, or an unavailable presence if no
|
||||
* presence information is available.
|
||||
*/
|
||||
public List<Presence> getAllPresences(String bareJid) {
|
||||
Map<String, Presence> userPresences = presenceMap.get(getMapKey(bareJid));
|
||||
public List<Presence> getAllPresences(Jid bareJid) {
|
||||
Map<Resourcepart, Presence> userPresences = presenceMap.get(getMapKey(bareJid));
|
||||
List<Presence> res;
|
||||
if (userPresences == null) {
|
||||
// Create an unavailable presence if none was found
|
||||
|
@ -763,7 +771,7 @@ public class Roster extends Manager {
|
|||
* @param bareJid the bare JID from which the presences should be retrieved.
|
||||
* @return available presences for the bare JID.
|
||||
*/
|
||||
public List<Presence> getAvailablePresences(String bareJid) {
|
||||
public List<Presence> getAvailablePresences(Jid bareJid) {
|
||||
List<Presence> allPresences = getAllPresences(bareJid);
|
||||
List<Presence> res = new ArrayList<>(allPresences.size());
|
||||
for (Presence presence : allPresences) {
|
||||
|
@ -785,10 +793,10 @@ public class Roster extends Manager {
|
|||
* or an unavailable presence if the user is offline or if no presence information
|
||||
* is available.
|
||||
*/
|
||||
public List<Presence> getPresences(String user) {
|
||||
public List<Presence> getPresences(Jid user) {
|
||||
List<Presence> res;
|
||||
String key = getMapKey(user);
|
||||
Map<String, Presence> userPresences = presenceMap.get(key);
|
||||
Jid key = getMapKey(user);
|
||||
Map<Resourcepart, Presence> userPresences = presenceMap.get(key);
|
||||
if (userPresences == null) {
|
||||
Presence presence = new Presence(Presence.Type.unavailable);
|
||||
presence.setFrom(user);
|
||||
|
@ -835,7 +843,7 @@ public class Roster extends Manager {
|
|||
* @return true if the given JID is allowed to see the users presence.
|
||||
* @since 4.1
|
||||
*/
|
||||
public boolean isSubscribedToMyPresence(String jid) {
|
||||
public boolean isSubscribedToMyPresence(Jid jid) {
|
||||
if (connection().getServiceName().equals(jid)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -892,15 +900,19 @@ public class Roster extends Manager {
|
|||
* jdoe@example.com/Work.
|
||||
* @return the key to use in the presenceMap and entries Map for the fully qualified XMPP ID.
|
||||
*/
|
||||
private String getMapKey(String user) {
|
||||
private Jid getMapKey(Jid user) {
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
if (entries.containsKey(user)) {
|
||||
return user;
|
||||
}
|
||||
String key = XmppStringUtils.parseBareJid(user);
|
||||
return key.toLowerCase(Locale.US);
|
||||
BareJid bareJid = user.asBareJidIfPossible();
|
||||
if (bareJid != null) {
|
||||
return bareJid;
|
||||
}
|
||||
// jid validate, log this case?
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -911,12 +923,17 @@ public class Roster extends Manager {
|
|||
*/
|
||||
private void setOfflinePresencesAndResetLoaded() {
|
||||
Presence packetUnavailable;
|
||||
outerloop: for (String user : presenceMap.keySet()) {
|
||||
Map<String, Presence> resources = presenceMap.get(user);
|
||||
outerloop: for (Jid user : presenceMap.keySet()) {
|
||||
Map<Resourcepart, Presence> resources = presenceMap.get(user);
|
||||
if (resources != null) {
|
||||
for (String resource : resources.keySet()) {
|
||||
for (Resourcepart resource : resources.keySet()) {
|
||||
packetUnavailable = new Presence(Presence.Type.unavailable);
|
||||
packetUnavailable.setFrom(user + "/" + resource);
|
||||
BareJid bareUserJid = user.asBareJidIfPossible();
|
||||
if (bareUserJid == null) {
|
||||
LOGGER.warning("Can not transform user JID to bare JID: '" + user + "'");
|
||||
continue;
|
||||
}
|
||||
packetUnavailable.setFrom(JidCreate.fullFrom(bareUserJid, resource));
|
||||
try {
|
||||
presencePacketListener.processPacket(packetUnavailable);
|
||||
}
|
||||
|
@ -943,8 +960,8 @@ public class Roster extends Manager {
|
|||
* @param updatedEntries the collection of address of the updated contacts.
|
||||
* @param deletedEntries the collection of address of the deleted contacts.
|
||||
*/
|
||||
private void fireRosterChangedEvent(final Collection<String> addedEntries, final Collection<String> updatedEntries,
|
||||
final Collection<String> deletedEntries) {
|
||||
private void fireRosterChangedEvent(final Collection<Jid> addedEntries, final Collection<Jid> updatedEntries,
|
||||
final Collection<Jid> deletedEntries) {
|
||||
synchronized (rosterListenersAndEntriesLock) {
|
||||
for (RosterListener listener : rosterListeners) {
|
||||
if (!addedEntries.isEmpty()) {
|
||||
|
@ -973,8 +990,8 @@ public class Roster extends Manager {
|
|||
}
|
||||
}
|
||||
|
||||
private void addUpdateEntry(Collection<String> addedEntries, Collection<String> updatedEntries,
|
||||
Collection<String> unchangedEntries, RosterPacket.Item item, RosterEntry entry) {
|
||||
private void addUpdateEntry(Collection<Jid> addedEntries, Collection<Jid> updatedEntries,
|
||||
Collection<Jid> unchangedEntries, RosterPacket.Item item, RosterEntry entry) {
|
||||
RosterEntry oldEntry;
|
||||
synchronized (rosterListenersAndEntriesLock) {
|
||||
oldEntry = entries.put(item.getUser(), entry);
|
||||
|
@ -1032,11 +1049,11 @@ public class Roster extends Manager {
|
|||
}
|
||||
}
|
||||
|
||||
private void deleteEntry(Collection<String> deletedEntries, RosterEntry entry) {
|
||||
String user = entry.getUser();
|
||||
private void deleteEntry(Collection<Jid> deletedEntries, RosterEntry entry) {
|
||||
Jid user = entry.getUser();
|
||||
entries.remove(user);
|
||||
unfiledEntries.remove(entry);
|
||||
presenceMap.remove(XmppStringUtils.parseBareJid(user));
|
||||
presenceMap.remove(user);
|
||||
deletedEntries.add(user);
|
||||
|
||||
for (Entry<String,RosterGroup> e: groups.entrySet()) {
|
||||
|
@ -1131,8 +1148,8 @@ public class Roster extends Manager {
|
|||
* @param key the presence map key
|
||||
* @return the user presences
|
||||
*/
|
||||
private Map<String, Presence> getUserPresences(String key) {
|
||||
Map<String, Presence> userPresences = presenceMap.get(key);
|
||||
private Map<Resourcepart, Presence> getUserPresences(Jid key) {
|
||||
Map<Resourcepart, Presence> userPresences = presenceMap.get(key);
|
||||
if (userPresences == null) {
|
||||
userPresences = new ConcurrentHashMap<>();
|
||||
presenceMap.put(key, userPresences);
|
||||
|
@ -1144,9 +1161,13 @@ public class Roster extends Manager {
|
|||
public void processPacket(Stanza packet) throws NotConnectedException, InterruptedException {
|
||||
final XMPPConnection connection = connection();
|
||||
Presence presence = (Presence) packet;
|
||||
String from = presence.getFrom();
|
||||
String key = getMapKey(from);
|
||||
Map<String, Presence> userPresences;
|
||||
Jid from = presence.getFrom();
|
||||
Resourcepart fromResource = from.getResourceOrNull();
|
||||
if (fromResource == null) {
|
||||
fromResource = Resourcepart.EMPTY;
|
||||
}
|
||||
Jid key = getMapKey(from);
|
||||
Map<Resourcepart, Presence> userPresences;
|
||||
Presence response = null;
|
||||
|
||||
// If an "available" presence, add it to the presence map. Each presence
|
||||
|
@ -1158,9 +1179,9 @@ public class Roster extends Manager {
|
|||
userPresences = getUserPresences(key);
|
||||
// See if an offline presence was being stored in the map. If so, remove
|
||||
// it since we now have an online presence.
|
||||
userPresences.remove("");
|
||||
userPresences.remove(Resourcepart.EMPTY);
|
||||
// Add the new presence, using the resources as a key.
|
||||
userPresences.put(XmppStringUtils.parseResource(from), presence);
|
||||
userPresences.put(fromResource, presence);
|
||||
// If the user is in the roster, fire an event.
|
||||
if (entries.containsKey(key)) {
|
||||
fireRosterPresenceEvent(presence);
|
||||
|
@ -1170,17 +1191,17 @@ public class Roster extends Manager {
|
|||
case unavailable:
|
||||
// If no resource, this is likely an offline presence as part of
|
||||
// a roster presence flood. In that case, we store it.
|
||||
if ("".equals(XmppStringUtils.parseResource(from))) {
|
||||
if (from.hasNoResource()) {
|
||||
// Get the user presence map
|
||||
userPresences = getUserPresences(key);
|
||||
userPresences.put("", presence);
|
||||
userPresences.put(Resourcepart.EMPTY, presence);
|
||||
}
|
||||
// Otherwise, this is a normal offline presence.
|
||||
else if (presenceMap.get(key) != null) {
|
||||
userPresences = presenceMap.get(key);
|
||||
// Store the offline presence, as it may include extra information
|
||||
// such as the user being on vacation.
|
||||
userPresences.put(XmppStringUtils.parseResource(from), presence);
|
||||
userPresences.put(fromResource, presence);
|
||||
}
|
||||
// If the user is in the roster, fire an event.
|
||||
if (entries.containsKey(key)) {
|
||||
|
@ -1221,7 +1242,7 @@ public class Roster extends Manager {
|
|||
// Error presence packets from a bare JID mean we invalidate all existing
|
||||
// presence info for the user.
|
||||
case error:
|
||||
if (!"".equals(XmppStringUtils.parseResource(from))) {
|
||||
if (!from.isBareJid()) {
|
||||
break;
|
||||
}
|
||||
userPresences = getUserPresences(key);
|
||||
|
@ -1229,7 +1250,7 @@ public class Roster extends Manager {
|
|||
userPresences.clear();
|
||||
|
||||
// Set the new presence using the empty resource as a key.
|
||||
userPresences.put("", presence);
|
||||
userPresences.put(Resourcepart.EMPTY, presence);
|
||||
// If the user is in the roster, fire an event.
|
||||
if (entries.containsKey(key)) {
|
||||
fireRosterPresenceEvent(presence);
|
||||
|
@ -1250,10 +1271,10 @@ public class Roster extends Manager {
|
|||
public void processPacket(Stanza packet) {
|
||||
final XMPPConnection connection = connection();
|
||||
LOGGER.fine("RosterResultListener received stanza");
|
||||
Collection<String> addedEntries = new ArrayList<String>();
|
||||
Collection<String> updatedEntries = new ArrayList<String>();
|
||||
Collection<String> deletedEntries = new ArrayList<String>();
|
||||
Collection<String> unchangedEntries = new ArrayList<String>();
|
||||
Collection<Jid> addedEntries = new ArrayList<>();
|
||||
Collection<Jid> updatedEntries = new ArrayList<>();
|
||||
Collection<Jid> deletedEntries = new ArrayList<>();
|
||||
Collection<Jid> unchangedEntries = new ArrayList<>();
|
||||
|
||||
if (packet instanceof RosterPacket) {
|
||||
// Non-empty roster result. This stanza contains all the roster elements.
|
||||
|
@ -1274,14 +1295,14 @@ public class Roster extends Manager {
|
|||
}
|
||||
|
||||
// Delete all entries which where not added or updated
|
||||
Set<String> toDelete = new HashSet<String>();
|
||||
Set<Jid> toDelete = new HashSet<>();
|
||||
for (RosterEntry entry : entries.values()) {
|
||||
toDelete.add(entry.getUser());
|
||||
}
|
||||
toDelete.removeAll(addedEntries);
|
||||
toDelete.removeAll(updatedEntries);
|
||||
toDelete.removeAll(unchangedEntries);
|
||||
for (String user : toDelete) {
|
||||
for (Jid user : toDelete) {
|
||||
deleteEntry(deletedEntries, entries.get(user));
|
||||
}
|
||||
|
||||
|
@ -1329,8 +1350,8 @@ public class Roster extends Manager {
|
|||
|
||||
// Roster push (RFC 6121, 2.1.6)
|
||||
// A roster push with a non-empty from not matching our address MUST be ignored
|
||||
String jid = XmppStringUtils.parseBareJid(connection.getUser());
|
||||
String from = rosterPacket.getFrom();
|
||||
BareJid jid = connection.getUser().asBareJid();
|
||||
Jid from = rosterPacket.getFrom();
|
||||
if (from != null && !from.equals(jid)) {
|
||||
LOGGER.warning("Ignoring roster push with a non matching 'from' ourJid='" + jid + "' from='" + from
|
||||
+ "'");
|
||||
|
@ -1344,10 +1365,10 @@ public class Roster extends Manager {
|
|||
return IQ.createErrorResponse(iqRequest, new XMPPError(Condition.bad_request));
|
||||
}
|
||||
|
||||
Collection<String> addedEntries = new ArrayList<String>();
|
||||
Collection<String> updatedEntries = new ArrayList<String>();
|
||||
Collection<String> deletedEntries = new ArrayList<String>();
|
||||
Collection<String> unchangedEntries = new ArrayList<String>();
|
||||
Collection<Jid> addedEntries = new ArrayList<>();
|
||||
Collection<Jid> updatedEntries = new ArrayList<>();
|
||||
Collection<Jid> deletedEntries = new ArrayList<>();
|
||||
Collection<Jid> unchangedEntries = new ArrayList<>();
|
||||
|
||||
// We assured above that the size of items is exaclty 1, therefore we are able to
|
||||
// safely retrieve this single item here.
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.jivesoftware.smack.SmackException.NotConnectedException;
|
|||
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.roster.packet.RosterPacket;
|
||||
import org.jxmpp.jid.Jid;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -41,7 +42,7 @@ public class RosterEntry {
|
|||
/**
|
||||
* The JID of the entity/user.
|
||||
*/
|
||||
private final String user;
|
||||
private final Jid user;
|
||||
|
||||
private String name;
|
||||
private RosterPacket.ItemType type;
|
||||
|
@ -58,7 +59,7 @@ public class RosterEntry {
|
|||
* @param status the subscription status (related to subscriptions pending to be approbed).
|
||||
* @param connection a connection to the XMPP server.
|
||||
*/
|
||||
RosterEntry(String user, String name, RosterPacket.ItemType type,
|
||||
RosterEntry(Jid user, String name, RosterPacket.ItemType type,
|
||||
RosterPacket.ItemStatus status, Roster roster, XMPPConnection connection) {
|
||||
this.user = user;
|
||||
this.name = name;
|
||||
|
@ -73,7 +74,7 @@ public class RosterEntry {
|
|||
*
|
||||
* @return the user associated with this entry.
|
||||
*/
|
||||
public String getUser() {
|
||||
public Jid getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package org.jivesoftware.smack.roster;
|
||||
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jxmpp.jid.Jid;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
|
@ -35,21 +36,21 @@ public interface RosterListener {
|
|||
*
|
||||
* @param addresses the XMPP addresses of the contacts that have been added to the roster.
|
||||
*/
|
||||
public void entriesAdded(Collection<String> addresses);
|
||||
public void entriesAdded(Collection<Jid> addresses);
|
||||
|
||||
/**
|
||||
* Called when a roster entries are updated.
|
||||
*
|
||||
* @param addresses the XMPP addresses of the contacts whose entries have been updated.
|
||||
*/
|
||||
public void entriesUpdated(Collection<String> addresses);
|
||||
public void entriesUpdated(Collection<Jid> addresses);
|
||||
|
||||
/**
|
||||
* Called when a roster entries are removed.
|
||||
*
|
||||
* @param addresses the XMPP addresses of the contacts that have been removed from the roster.
|
||||
*/
|
||||
public void entriesDeleted(Collection<String> addresses);
|
||||
public void entriesDeleted(Collection<Jid> addresses);
|
||||
|
||||
/**
|
||||
* Called when the presence of a roster entry is changed. Care should be taken
|
||||
|
@ -74,7 +75,7 @@ public interface RosterListener {
|
|||
* presence packets will not cause this method to be called.
|
||||
*
|
||||
* @param presence the presence that changed.
|
||||
* @see Roster#getPresence(String)
|
||||
* @see Roster#getPresence(Jid)
|
||||
*/
|
||||
public void presenceChanged(Presence presence);
|
||||
}
|
||||
|
|
|
@ -20,11 +20,11 @@ package org.jivesoftware.smack.roster.packet;
|
|||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||
import org.jxmpp.jid.Jid;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
|
@ -107,7 +107,7 @@ public class RosterPacket extends IQ {
|
|||
|
||||
public static final String GROUP = "group";
|
||||
|
||||
private String user;
|
||||
private final Jid user;
|
||||
private String name;
|
||||
private ItemType itemType;
|
||||
private ItemStatus itemStatus;
|
||||
|
@ -119,8 +119,8 @@ public class RosterPacket extends IQ {
|
|||
* @param user the user.
|
||||
* @param name the user's name.
|
||||
*/
|
||||
public Item(String user, String name) {
|
||||
this.user = user.toLowerCase(Locale.US);
|
||||
public Item(Jid user, String name) {
|
||||
this.user = user;
|
||||
this.name = name;
|
||||
itemType = null;
|
||||
itemStatus = null;
|
||||
|
@ -132,7 +132,7 @@ public class RosterPacket extends IQ {
|
|||
*
|
||||
* @return the user.
|
||||
*/
|
||||
public String getUser() {
|
||||
public Jid getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ import java.io.IOException;
|
|||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.provider.IQProvider;
|
||||
import org.jivesoftware.smack.roster.packet.RosterPacket;
|
||||
import org.jxmpp.jid.Jid;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
|
@ -44,8 +46,9 @@ public class RosterPacketProvider extends IQProvider<RosterPacket> {
|
|||
String startTag = parser.getName();
|
||||
switch (startTag) {
|
||||
case "item":
|
||||
String jid = parser.getAttributeValue("", "jid");
|
||||
String jidString = parser.getAttributeValue("", "jid");
|
||||
String name = parser.getAttributeValue("", "name");
|
||||
Jid jid = JidCreate.from(jidString);
|
||||
// Create packet.
|
||||
item = new RosterPacket.Item(jid, name);
|
||||
// Set status.
|
||||
|
|
|
@ -31,6 +31,8 @@ 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;
|
||||
import org.jxmpp.jid.Jid;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.xmlpull.v1.XmlPullParserFactory;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
@ -131,7 +133,7 @@ public class DirectoryRosterStore implements RosterStore {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Item getEntry(String bareJid) {
|
||||
public Item getEntry(Jid bareJid) {
|
||||
return readEntry(getBareJidFile(bareJid));
|
||||
}
|
||||
|
||||
|
@ -158,7 +160,7 @@ public class DirectoryRosterStore implements RosterStore {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean removeEntry(String bareJid, String version) {
|
||||
public boolean removeEntry(Jid bareJid, String version) {
|
||||
return getBareJidFile(bareJid).delete() && setRosterVersion(version);
|
||||
}
|
||||
|
||||
|
@ -182,7 +184,7 @@ public class DirectoryRosterStore implements RosterStore {
|
|||
}
|
||||
|
||||
String parserName;
|
||||
String user = null;
|
||||
Jid user = null;
|
||||
String name = null;
|
||||
String type = null;
|
||||
String status = null;
|
||||
|
@ -199,11 +201,12 @@ public class DirectoryRosterStore implements RosterStore {
|
|||
parserName = parser.getName();
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parserName.equals("item")) {
|
||||
user = name = type = status = null;
|
||||
user = null;
|
||||
name = type = status = null;
|
||||
}
|
||||
else if (parserName.equals("user")) {
|
||||
parser.next();
|
||||
user = parser.getText();
|
||||
user = JidCreate.from(parser.getText());
|
||||
}
|
||||
else if (parserName.equals("name")) {
|
||||
parser.next();
|
||||
|
@ -297,8 +300,8 @@ public class DirectoryRosterStore implements RosterStore {
|
|||
}
|
||||
|
||||
|
||||
private File getBareJidFile(String bareJid) {
|
||||
String encodedJid = Base32.encode(bareJid);
|
||||
private File getBareJidFile(Jid bareJid) {
|
||||
String encodedJid = Base32.encode(bareJid.toString());
|
||||
return new File(fileDir, ENTRY_PREFIX + encodedJid);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.jivesoftware.smack.roster.rosterstore;
|
|||
import java.util.Collection;
|
||||
|
||||
import org.jivesoftware.smack.roster.packet.RosterPacket;
|
||||
import org.jxmpp.jid.Jid;
|
||||
|
||||
/**
|
||||
* This is an interface for persistent roster store needed to implement
|
||||
|
@ -37,7 +38,7 @@ public interface RosterStore {
|
|||
* @param bareJid The bare JID of the RosterEntry
|
||||
* @return The {@link org.jivesoftware.smack.roster.RosterEntry} which belongs to that user
|
||||
*/
|
||||
public RosterPacket.Item getEntry(String bareJid);
|
||||
public RosterPacket.Item getEntry(Jid bareJid);
|
||||
/**
|
||||
* This method returns the version number as specified by the "ver" attribute
|
||||
* of the local store. For a fresh store, this MUST be the empty string.
|
||||
|
@ -64,6 +65,6 @@ public interface RosterStore {
|
|||
* @param version the new roster version
|
||||
* @return True if successful
|
||||
*/
|
||||
public boolean removeEntry(String bareJid, String version);
|
||||
public boolean removeEntry(Jid bareJid, String version);
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ import org.jivesoftware.smack.test.util.WaitForPacketListener;
|
|||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.jxmpp.jid.Jid;
|
||||
import org.jxmpp.jid.JidTestUtil;
|
||||
|
||||
public class ChatConnectionTest {
|
||||
|
||||
|
@ -219,7 +221,7 @@ public class ChatConnectionTest {
|
|||
*/
|
||||
@Test
|
||||
public void chatFoundWhenNoThreadFullJid() {
|
||||
Chat outgoing = cm.createChat("you@testserver", null);
|
||||
Chat outgoing = cm.createChat(JidTestUtil.DUMMY_AT_EXAMPLE_ORG, null);
|
||||
|
||||
Stanza incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat);
|
||||
|
@ -235,7 +237,7 @@ public class ChatConnectionTest {
|
|||
*/
|
||||
@Test
|
||||
public void chatFoundWhenNoThreadBaseJid() {
|
||||
Chat outgoing = cm.createChat("you@testserver", null);
|
||||
Chat outgoing = cm.createChat(JidTestUtil.DUMMY_AT_EXAMPLE_ORG, null);
|
||||
|
||||
Stanza incomingChat = createChatPacket(null, false);
|
||||
processServerMessage(incomingChat);
|
||||
|
@ -251,7 +253,7 @@ public class ChatConnectionTest {
|
|||
*/
|
||||
@Test
|
||||
public void chatFoundWithSameThreadFullJid() {
|
||||
Chat outgoing = cm.createChat("you@testserver", null);
|
||||
Chat outgoing = cm.createChat(JidTestUtil.DUMMY_AT_EXAMPLE_ORG, null);
|
||||
|
||||
Stanza incomingChat = createChatPacket(outgoing.getThreadID(), true);
|
||||
processServerMessage(incomingChat);
|
||||
|
@ -267,7 +269,7 @@ public class ChatConnectionTest {
|
|||
*/
|
||||
@Test
|
||||
public void chatFoundWithSameThreadBaseJid() {
|
||||
Chat outgoing = cm.createChat("you@testserver", null);
|
||||
Chat outgoing = cm.createChat(JidTestUtil.DUMMY_AT_EXAMPLE_ORG, null);
|
||||
|
||||
Stanza incomingChat = createChatPacket(outgoing.getThreadID(), false);
|
||||
processServerMessage(incomingChat);
|
||||
|
@ -283,7 +285,7 @@ public class ChatConnectionTest {
|
|||
*/
|
||||
@Test
|
||||
public void chatNotFoundWithDiffThreadBaseJid() {
|
||||
Chat outgoing = cm.createChat("you@testserver", null);
|
||||
Chat outgoing = cm.createChat(JidTestUtil.DUMMY_AT_EXAMPLE_ORG, null);
|
||||
|
||||
Stanza incomingChat = createChatPacket(outgoing.getThreadID() + "ff", false);
|
||||
processServerMessage(incomingChat);
|
||||
|
@ -299,7 +301,7 @@ public class ChatConnectionTest {
|
|||
*/
|
||||
@Test
|
||||
public void chatNotFoundWithDiffThreadFullJid() {
|
||||
Chat outgoing = cm.createChat("you@testserver", null);
|
||||
Chat outgoing = cm.createChat(JidTestUtil.DUMMY_AT_EXAMPLE_ORG, null);
|
||||
|
||||
Stanza incomingChat = createChatPacket(outgoing.getThreadID() + "ff", true);
|
||||
processServerMessage(incomingChat);
|
||||
|
@ -321,9 +323,15 @@ public class ChatConnectionTest {
|
|||
}
|
||||
|
||||
private Message createChatPacket(final String threadId, final boolean isFullJid) {
|
||||
Message chatMsg = new Message("me@testserver", Message.Type.chat);
|
||||
Message chatMsg = new Message(JidTestUtil.BARE_JID_1, Message.Type.chat);
|
||||
chatMsg.setBody("the body message - " + System.currentTimeMillis());
|
||||
chatMsg.setFrom("you@testserver" + (isFullJid ? "/resource" : ""));
|
||||
Jid jid;
|
||||
if (isFullJid) {
|
||||
jid = JidTestUtil.DUMMY_AT_EXAMPLE_ORG_SLASH_DUMMYRESOURCE;
|
||||
} else {
|
||||
jid = JidTestUtil.DUMMY_AT_EXAMPLE_ORG;
|
||||
}
|
||||
chatMsg.setFrom(jid);
|
||||
chatMsg.setThread(threadId);
|
||||
return chatMsg;
|
||||
}
|
||||
|
|
|
@ -45,11 +45,6 @@ public class RosterOfflineTest {
|
|||
assertNotNull(roster);
|
||||
}
|
||||
|
||||
@Test(expected = SmackException.class)
|
||||
public void shouldThrowExceptionOnCreateEntry() throws Exception {
|
||||
roster.createEntry("test", "test", null);
|
||||
}
|
||||
|
||||
@Test(expected = SmackException.class)
|
||||
public void shouldThrowExceptionOnReload() throws Exception {
|
||||
roster.reload();
|
||||
|
|
|
@ -50,6 +50,9 @@ import org.jivesoftware.smack.util.PacketParserUtils;
|
|||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.jxmpp.jid.Jid;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.jxmpp.stringprep.XmppStringprepException;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
|
@ -104,18 +107,18 @@ public class RosterTest extends InitSmackIm {
|
|||
|
||||
// Verify roster
|
||||
assertTrue("Roster can't be loaded!", roster.waitUntilLoaded());
|
||||
verifyRomeosEntry(roster.getEntry("romeo@example.net"));
|
||||
verifyMercutiosEntry(roster.getEntry("mercutio@example.com"));
|
||||
verifyBenvoliosEntry(roster.getEntry("benvolio@example.net"));
|
||||
verifyRomeosEntry(roster.getEntry(JidCreate.from("romeo@example.net")));
|
||||
verifyMercutiosEntry(roster.getEntry(JidCreate.from("mercutio@example.com")));
|
||||
verifyBenvoliosEntry(roster.getEntry(JidCreate.from("benvolio@example.net")));
|
||||
assertSame("Wrong number of roster entries.", 3, roster.getEntries().size());
|
||||
|
||||
// Verify roster listener
|
||||
assertTrue("The roster listener wasn't invoked for Romeo.",
|
||||
rosterListener.getAddedAddresses().contains("romeo@example.net"));
|
||||
rosterListener.addedAddressesContains("romeo@example.net"));
|
||||
assertTrue("The roster listener wasn't invoked for Mercutio.",
|
||||
rosterListener.getAddedAddresses().contains("mercutio@example.com"));
|
||||
rosterListener.addedAddressesContains("mercutio@example.com"));
|
||||
assertTrue("The roster listener wasn't invoked for Benvolio.",
|
||||
rosterListener.getAddedAddresses().contains("benvolio@example.net"));
|
||||
rosterListener.addedAddressesContains("benvolio@example.net"));
|
||||
assertSame("RosterListeners implies that a item was deleted!",
|
||||
0,
|
||||
rosterListener.getDeletedAddresses().size());
|
||||
|
@ -132,7 +135,7 @@ public class RosterTest extends InitSmackIm {
|
|||
@Test
|
||||
public void testAddRosterItem() throws Throwable {
|
||||
// Constants for the new contact
|
||||
final String contactJID = "nurse@example.com";
|
||||
final Jid contactJID = JidCreate.from("nurse@example.com");
|
||||
final String contactName = "Nurse";
|
||||
final String[] contactGroup = {"Servants"};
|
||||
|
||||
|
@ -189,9 +192,9 @@ public class RosterTest extends InitSmackIm {
|
|||
addedEntry.getGroups().iterator().next().getName());
|
||||
|
||||
// Verify the unchanged roster items
|
||||
verifyRomeosEntry(roster.getEntry("romeo@example.net"));
|
||||
verifyMercutiosEntry(roster.getEntry("mercutio@example.com"));
|
||||
verifyBenvoliosEntry(roster.getEntry("benvolio@example.net"));
|
||||
verifyRomeosEntry(roster.getEntry(JidCreate.from("romeo@example.net")));
|
||||
verifyMercutiosEntry(roster.getEntry(JidCreate.from("mercutio@example.com")));
|
||||
verifyBenvoliosEntry(roster.getEntry(JidCreate.from("benvolio@example.net")));
|
||||
assertSame("Wrong number of roster entries.", 4, roster.getEntries().size());
|
||||
}
|
||||
|
||||
|
@ -203,7 +206,7 @@ public class RosterTest extends InitSmackIm {
|
|||
@Test
|
||||
public void testUpdateRosterItem() throws Throwable {
|
||||
// Constants for the updated contact
|
||||
final String contactJID = "romeo@example.net";
|
||||
final Jid contactJID = JidCreate.from("romeo@example.net");
|
||||
final String contactName = "Romeo";
|
||||
final String[] contactGroups = {"Friends", "Lovers"};
|
||||
|
||||
|
@ -263,8 +266,8 @@ public class RosterTest extends InitSmackIm {
|
|||
addedEntry.getGroups().size());
|
||||
|
||||
// Verify the unchanged roster items
|
||||
verifyMercutiosEntry(roster.getEntry("mercutio@example.com"));
|
||||
verifyBenvoliosEntry(roster.getEntry("benvolio@example.net"));
|
||||
verifyMercutiosEntry(roster.getEntry(JidCreate.from("mercutio@example.com")));
|
||||
verifyBenvoliosEntry(roster.getEntry(JidCreate.from("benvolio@example.net")));
|
||||
assertSame("Wrong number of roster entries (" + roster.getEntries() + ").",
|
||||
3,
|
||||
roster.getEntries().size());
|
||||
|
@ -278,7 +281,7 @@ public class RosterTest extends InitSmackIm {
|
|||
@Test
|
||||
public void testDeleteRosterItem() throws Throwable {
|
||||
// The contact which should be deleted
|
||||
final String contactJID = "romeo@example.net";
|
||||
final Jid contactJID = JidCreate.from("romeo@example.net");
|
||||
|
||||
// Setup
|
||||
assertNotNull("Can't get the roster from the provided connection!", roster);
|
||||
|
@ -310,8 +313,8 @@ public class RosterTest extends InitSmackIm {
|
|||
assertNull("The contact wasn't deleted from the roster!", deletedEntry);
|
||||
assertTrue("The roster listener wasn't invoked for the deleted contact!",
|
||||
rosterListener.getDeletedAddresses().contains(contactJID));
|
||||
verifyMercutiosEntry(roster.getEntry("mercutio@example.com"));
|
||||
verifyBenvoliosEntry(roster.getEntry("benvolio@example.net"));
|
||||
verifyMercutiosEntry(roster.getEntry(JidCreate.from("mercutio@example.com")));
|
||||
verifyBenvoliosEntry(roster.getEntry(JidCreate.from("benvolio@example.net")));
|
||||
assertSame("Wrong number of roster entries (" + roster.getEntries() + ").",
|
||||
2,
|
||||
roster.getEntries().size());
|
||||
|
@ -324,7 +327,7 @@ public class RosterTest extends InitSmackIm {
|
|||
*/
|
||||
@Test
|
||||
public void testSimpleRosterPush() throws Throwable {
|
||||
final String contactJID = "nurse@example.com";
|
||||
final Jid contactJID = JidCreate.from("nurse@example.com");
|
||||
assertNotNull("Can't get the roster from the provided connection!", roster);
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("<iq id=\"rostertest1\" type=\"set\" ")
|
||||
|
@ -355,24 +358,26 @@ public class RosterTest extends InitSmackIm {
|
|||
addedEntry.getGroups().size());
|
||||
|
||||
// Verify the unchanged roster items
|
||||
verifyRomeosEntry(roster.getEntry("romeo@example.net"));
|
||||
verifyMercutiosEntry(roster.getEntry("mercutio@example.com"));
|
||||
verifyBenvoliosEntry(roster.getEntry("benvolio@example.net"));
|
||||
verifyRomeosEntry(roster.getEntry(JidCreate.from("romeo@example.net")));
|
||||
verifyMercutiosEntry(roster.getEntry(JidCreate.from("mercutio@example.com")));
|
||||
verifyBenvoliosEntry(roster.getEntry(JidCreate.from("benvolio@example.net")));
|
||||
assertSame("Wrong number of roster entries.", 4, roster.getEntries().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that roster pushes with invalid from are ignored.
|
||||
* @throws XmppStringprepException
|
||||
*
|
||||
* @see <a href="http://xmpp.org/rfcs/rfc6121.html#roster-syntax-actions-push">RFC 6121, Section 2.1.6</a>
|
||||
*/
|
||||
@Test
|
||||
public void testIgnoreInvalidFrom() {
|
||||
public void testIgnoreInvalidFrom() throws XmppStringprepException {
|
||||
final Jid spammerJid = JidCreate.from("spam@example.com");
|
||||
RosterPacket packet = new RosterPacket();
|
||||
packet.setType(Type.set);
|
||||
packet.setTo(connection.getUser());
|
||||
packet.setFrom("mallory@example.com");
|
||||
packet.addRosterItem(new Item("spam@example.com", "Cool products!"));
|
||||
packet.setFrom(JidCreate.from("mallory@example.com"));
|
||||
packet.addRosterItem(new Item(spammerJid, "Cool products!"));
|
||||
|
||||
final String requestId = packet.getStanzaId();
|
||||
// Simulate receiving the roster push
|
||||
|
@ -383,7 +388,7 @@ public class RosterTest extends InitSmackIm {
|
|||
assertEquals(requestId, errorIQ.getStanzaId());
|
||||
assertEquals(Condition.service_unavailable, errorIQ.getError().getCondition());
|
||||
|
||||
assertNull("Contact was added to roster", Roster.getInstanceFor(connection).getEntry("spam@example.com"));
|
||||
assertNull("Contact was added to roster", Roster.getInstanceFor(connection).getEntry(spammerJid));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -395,7 +400,7 @@ public class RosterTest extends InitSmackIm {
|
|||
@Test(timeout=5000)
|
||||
public void testAddEmptyGroupEntry() throws Throwable {
|
||||
// Constants for the new contact
|
||||
final String contactJID = "nurse@example.com";
|
||||
final Jid contactJID = JidCreate.from("nurse@example.com");
|
||||
final String contactName = "Nurse";
|
||||
final String[] contactGroup = {""};
|
||||
|
||||
|
@ -447,9 +452,9 @@ public class RosterTest extends InitSmackIm {
|
|||
addedEntry.getGroups().size());
|
||||
|
||||
// Verify the unchanged roster items
|
||||
verifyRomeosEntry(roster.getEntry("romeo@example.net"));
|
||||
verifyMercutiosEntry(roster.getEntry("mercutio@example.com"));
|
||||
verifyBenvoliosEntry(roster.getEntry("benvolio@example.net"));
|
||||
verifyRomeosEntry(roster.getEntry(JidCreate.from("romeo@example.net")));
|
||||
verifyMercutiosEntry(roster.getEntry(JidCreate.from("mercutio@example.com")));
|
||||
verifyBenvoliosEntry(roster.getEntry(JidCreate.from("benvolio@example.net")));
|
||||
assertSame("Wrong number of roster entries.", 4, roster.getEntries().size());
|
||||
}
|
||||
|
||||
|
@ -461,7 +466,7 @@ public class RosterTest extends InitSmackIm {
|
|||
*/
|
||||
@Test
|
||||
public void testEmptyGroupRosterPush() throws Throwable {
|
||||
final String contactJID = "nurse@example.com";
|
||||
final Jid contactJID = JidCreate.from("nurse@example.com");
|
||||
assertNotNull("Can't get the roster from the provided connection!", roster);
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("<iq id=\"rostertest2\" type=\"set\" ")
|
||||
|
@ -494,9 +499,9 @@ public class RosterTest extends InitSmackIm {
|
|||
addedEntry.getGroups().size());
|
||||
|
||||
// Verify the unchanged roster items
|
||||
verifyRomeosEntry(roster.getEntry("romeo@example.net"));
|
||||
verifyMercutiosEntry(roster.getEntry("mercutio@example.com"));
|
||||
verifyBenvoliosEntry(roster.getEntry("benvolio@example.net"));
|
||||
verifyRomeosEntry(roster.getEntry(JidCreate.from("romeo@example.net")));
|
||||
verifyMercutiosEntry(roster.getEntry(JidCreate.from("mercutio@example.com")));
|
||||
verifyBenvoliosEntry(roster.getEntry(JidCreate.from("benvolio@example.net")));
|
||||
assertSame("Wrong number of roster entries.", 4, roster.getEntries().size());
|
||||
}
|
||||
|
||||
|
@ -533,8 +538,9 @@ public class RosterTest extends InitSmackIm {
|
|||
* @param connection the dummy connection of which the provided roster belongs to.
|
||||
* @param roster the roster (or buddy list) which should be initialized.
|
||||
* @throws SmackException
|
||||
* @throws XmppStringprepException
|
||||
*/
|
||||
private void initRoster() throws InterruptedException, XMPPException, SmackException {
|
||||
private void initRoster() throws InterruptedException, XMPPException, SmackException, XmppStringprepException {
|
||||
roster.reload();
|
||||
while (true) {
|
||||
final Stanza sentPacket = connection.getSentPacket();
|
||||
|
@ -552,18 +558,18 @@ public class RosterTest extends InitSmackIm {
|
|||
rosterResult.setStanzaId(rosterRequest.getStanzaId());
|
||||
|
||||
// prepare romeo's roster entry
|
||||
final Item romeo = new Item("romeo@example.net", "Romeo");
|
||||
final Item romeo = new Item(JidCreate.from("romeo@example.net"), "Romeo");
|
||||
romeo.addGroupName("Friends");
|
||||
romeo.setItemType(ItemType.both);
|
||||
rosterResult.addRosterItem(romeo);
|
||||
|
||||
// prepare mercutio's roster entry
|
||||
final Item mercutio = new Item("mercutio@example.com", "Mercutio");
|
||||
final Item mercutio = new Item(JidCreate.from("mercutio@example.com"), "Mercutio");
|
||||
mercutio.setItemType(ItemType.from);
|
||||
rosterResult.addRosterItem(mercutio);
|
||||
|
||||
// prepare benvolio's roster entry
|
||||
final Item benvolio = new Item("benvolio@example.net", "Benvolio");
|
||||
final Item benvolio = new Item(JidCreate.from("benvolio@example.net"), "Benvolio");
|
||||
benvolio.setItemType(ItemType.both);
|
||||
rosterResult.addRosterItem(benvolio);
|
||||
|
||||
|
@ -704,34 +710,34 @@ public class RosterTest extends InitSmackIm {
|
|||
* This class can be used to check if the RosterListener was invoked.
|
||||
*/
|
||||
public static class TestRosterListener extends WaitForPacketListener implements RosterListener {
|
||||
private final List<String> addressesAdded = new CopyOnWriteArrayList<>();
|
||||
private final List<String> addressesDeleted = new CopyOnWriteArrayList<>();
|
||||
private final List<String> addressesUpdated = new CopyOnWriteArrayList<>();
|
||||
private final List<Jid> addressesAdded = new CopyOnWriteArrayList<>();
|
||||
private final List<Jid> addressesDeleted = new CopyOnWriteArrayList<>();
|
||||
private final List<Jid> addressesUpdated = new CopyOnWriteArrayList<>();
|
||||
|
||||
public synchronized void entriesAdded(Collection<String> addresses) {
|
||||
public synchronized void entriesAdded(Collection<Jid> addresses) {
|
||||
addressesAdded.addAll(addresses);
|
||||
if (SmackConfiguration.DEBUG) {
|
||||
for (String address : addresses) {
|
||||
for (Jid address : addresses) {
|
||||
System.out.println("Roster entry for " + address + " added.");
|
||||
}
|
||||
}
|
||||
reportInvoked();
|
||||
}
|
||||
|
||||
public synchronized void entriesDeleted(Collection<String> addresses) {
|
||||
public synchronized void entriesDeleted(Collection<Jid> addresses) {
|
||||
addressesDeleted.addAll(addresses);
|
||||
if (SmackConfiguration.DEBUG) {
|
||||
for (String address : addresses) {
|
||||
for (Jid address : addresses) {
|
||||
System.out.println("Roster entry for " + address + " deleted.");
|
||||
}
|
||||
}
|
||||
reportInvoked();
|
||||
}
|
||||
|
||||
public synchronized void entriesUpdated(Collection<String> addresses) {
|
||||
public synchronized void entriesUpdated(Collection<Jid> addresses) {
|
||||
addressesUpdated.addAll(addresses);
|
||||
if (SmackConfiguration.DEBUG) {
|
||||
for (String address : addresses) {
|
||||
for (Jid address : addresses) {
|
||||
System.out.println("Roster entry for " + address + " updated.");
|
||||
}
|
||||
}
|
||||
|
@ -750,7 +756,7 @@ public class RosterTest extends InitSmackIm {
|
|||
*
|
||||
* @return the collection of addresses which were added.
|
||||
*/
|
||||
public Collection<String> getAddedAddresses() {
|
||||
public Collection<Jid> getAddedAddresses() {
|
||||
return Collections.unmodifiableCollection(addressesAdded);
|
||||
}
|
||||
|
||||
|
@ -759,7 +765,7 @@ public class RosterTest extends InitSmackIm {
|
|||
*
|
||||
* @return the collection of addresses which were deleted.
|
||||
*/
|
||||
public Collection<String> getDeletedAddresses() {
|
||||
public Collection<Jid> getDeletedAddresses() {
|
||||
return Collections.unmodifiableCollection(addressesDeleted);
|
||||
}
|
||||
|
||||
|
@ -768,10 +774,43 @@ public class RosterTest extends InitSmackIm {
|
|||
*
|
||||
* @return the collection of addresses which were updated.
|
||||
*/
|
||||
public Collection<String> getUpdatedAddresses() {
|
||||
public Collection<Jid> getUpdatedAddresses() {
|
||||
return Collections.unmodifiableCollection(addressesUpdated);
|
||||
}
|
||||
|
||||
public boolean addedAddressesContains(String jidString) {
|
||||
Jid jid;
|
||||
try {
|
||||
jid = JidCreate.from(jidString);
|
||||
}
|
||||
catch (XmppStringprepException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
return addressesAdded.contains(jid);
|
||||
}
|
||||
|
||||
public boolean deletedAddressesContains(String jidString) {
|
||||
Jid jid;
|
||||
try {
|
||||
jid = JidCreate.from(jidString);
|
||||
}
|
||||
catch (XmppStringprepException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
return addressesDeleted.contains(jid);
|
||||
}
|
||||
|
||||
public boolean updatedAddressesContains(String jidString) {
|
||||
Jid jid;
|
||||
try {
|
||||
jid = JidCreate.from(jidString);
|
||||
}
|
||||
catch (XmppStringprepException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
return addressesUpdated.contains(jid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the lists of added, deleted or updated items.
|
||||
*/
|
||||
|
|
|
@ -44,6 +44,8 @@ import org.junit.Before;
|
|||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.jxmpp.stringprep.XmppStringprepException;
|
||||
|
||||
/**
|
||||
* Tests that verify the correct behavior of the {@link Roster} implementation
|
||||
|
@ -130,9 +132,10 @@ public class RosterVersioningTest {
|
|||
* Tests that a non-empty roster result empties the store.
|
||||
* @throws SmackException
|
||||
* @throws XMPPException
|
||||
* @throws XmppStringprepException
|
||||
*/
|
||||
@Test(timeout = 5000)
|
||||
public void testOtherVersionStored() throws InterruptedException, XMPPException, SmackException {
|
||||
public void testOtherVersionStored() throws InterruptedException, XMPPException, SmackException, XmppStringprepException {
|
||||
Item vaglafItem = vaglafItem();
|
||||
|
||||
// We expect that the roster request is the only packet sent. This is not part of the specification,
|
||||
|
@ -181,7 +184,7 @@ public class RosterVersioningTest {
|
|||
// Simulate a roster push adding vaglaf
|
||||
{
|
||||
RosterPacket rosterPush = new RosterPacket();
|
||||
rosterPush.setTo("rostertest@example.com/home");
|
||||
rosterPush.setTo(JidCreate.from("rostertest@example.com/home"));
|
||||
rosterPush.setType(Type.set);
|
||||
rosterPush.setVersion("v97");
|
||||
|
||||
|
@ -193,7 +196,7 @@ public class RosterVersioningTest {
|
|||
|
||||
assertEquals("Expect store version after push", "v97", store.getRosterVersion());
|
||||
|
||||
Item storedItem = store.getEntry("vaglaf@example.com");
|
||||
Item storedItem = store.getEntry(JidCreate.from("vaglaf@example.com"));
|
||||
assertNotNull("Expect vaglaf to be added", storedItem);
|
||||
assertEquals("Expect vaglaf to be equal to pushed item", pushedItem, storedItem);
|
||||
|
||||
|
@ -207,24 +210,24 @@ public class RosterVersioningTest {
|
|||
// Simulate a roster push removing vaglaf
|
||||
{
|
||||
RosterPacket rosterPush = new RosterPacket();
|
||||
rosterPush.setTo("rostertest@example.com/home");
|
||||
rosterPush.setTo(JidCreate.from("rostertest@example.com/home"));
|
||||
rosterPush.setType(Type.set);
|
||||
rosterPush.setVersion("v98");
|
||||
|
||||
Item item = new Item("vaglaf@example.com", "vaglaf the only");
|
||||
Item item = new Item(JidCreate.from("vaglaf@example.com"), "vaglaf the only");
|
||||
item.setItemType(ItemType.remove);
|
||||
rosterPush.addRosterItem(item);
|
||||
rosterListener.reset();
|
||||
connection.processPacket(rosterPush);
|
||||
rosterListener.waitAndReset();
|
||||
|
||||
assertNull("Store doses not contain vaglaf", store.getEntry("vaglaf@example.com"));
|
||||
assertNull("Store doses not contain vaglaf", store.getEntry(JidCreate.from("vaglaf@example.com")));
|
||||
assertEquals("Expect store version after push", "v98", store.getRosterVersion());
|
||||
}
|
||||
}
|
||||
|
||||
private Item vaglafItem() {
|
||||
Item item = new Item("vaglaf@example.com", "vaglaf the only");
|
||||
private Item vaglafItem() throws XmppStringprepException {
|
||||
Item item = new Item(JidCreate.from("vaglaf@example.com"), "vaglaf the only");
|
||||
item.setItemType(ItemType.both);
|
||||
item.addGroupName("all");
|
||||
item.addGroupName("friends");
|
||||
|
@ -233,14 +236,14 @@ public class RosterVersioningTest {
|
|||
}
|
||||
|
||||
private void populateStore(RosterStore store) throws IOException {
|
||||
store.addEntry(new RosterPacket.Item("geoff@example.com", "geoff hurley"), "");
|
||||
store.addEntry(new RosterPacket.Item(JidCreate.from("geoff@example.com"), "geoff hurley"), "");
|
||||
|
||||
RosterPacket.Item item = new RosterPacket.Item("joe@example.com", "joe stevens");
|
||||
RosterPacket.Item item = new RosterPacket.Item(JidCreate.from("joe@example.com"), "joe stevens");
|
||||
item.addGroupName("friends");
|
||||
item.addGroupName("partners");
|
||||
store.addEntry(item, "");
|
||||
|
||||
item = new RosterPacket.Item("higgins@example.com", "higgins mcmann");
|
||||
item = new RosterPacket.Item(JidCreate.from("higgins@example.com"), "higgins mcmann");
|
||||
item.addGroupName("all");
|
||||
item.addGroupName("friends");
|
||||
store.addEntry(item, "v96");
|
||||
|
|
|
@ -34,6 +34,9 @@ import org.junit.Before;
|
|||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.jxmpp.jid.Jid;
|
||||
import org.jxmpp.jid.JidTestUtil;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
|
||||
/**
|
||||
* Tests the implementation of {@link DirectoryRosterStore}.
|
||||
|
@ -86,7 +89,7 @@ public class DirectoryRosterStoreTest {
|
|||
|
||||
assertEquals("Initial roster version", "", store.getRosterVersion());
|
||||
|
||||
String userName = "user@example.com";
|
||||
Jid userName = JidTestUtil.DUMMY_AT_EXAMPLE_ORG;
|
||||
|
||||
final RosterPacket.Item item1 = new Item(userName, null);
|
||||
final String version1 = "1";
|
||||
|
@ -130,13 +133,13 @@ public class DirectoryRosterStoreTest {
|
|||
List<Item> entries = store.getEntries();
|
||||
assertEquals("Number of entries", 1, entries.size());
|
||||
|
||||
final RosterPacket.Item item3 = new Item("foobar@example.com", "Foo Bar");
|
||||
final RosterPacket.Item item3 = new Item(JidTestUtil.BARE_JID_1, "Foo Bar");
|
||||
item3.addGroupName("The Foo Fighters");
|
||||
item3.addGroupName("Bar Friends");
|
||||
item3.setItemStatus(ItemStatus.unsubscribe);
|
||||
item3.setItemType(ItemType.both);
|
||||
|
||||
final RosterPacket.Item item4 = new Item("baz@example.com", "Baba Baz");
|
||||
final RosterPacket.Item item4 = new Item(JidTestUtil.BARE_JID_2, "Baba Baz");
|
||||
item4.addGroupName("The Foo Fighters");
|
||||
item4.addGroupName("Bar Friends");
|
||||
item4.setItemStatus(ItemStatus.subscribe);
|
||||
|
@ -149,7 +152,7 @@ public class DirectoryRosterStoreTest {
|
|||
String version3 = "3";
|
||||
store.resetEntries(items34, version3);
|
||||
|
||||
storedItem = store.getEntry("foobar@example.com");
|
||||
storedItem = store.getEntry(JidTestUtil.BARE_JID_1);
|
||||
assertNotNull("Added entry not found", storedItem);
|
||||
assertEquals("User of added entry",
|
||||
item3.getUser(), storedItem.getUser());
|
||||
|
@ -162,7 +165,7 @@ public class DirectoryRosterStoreTest {
|
|||
item3.getItemStatus(), storedItem.getItemStatus());
|
||||
|
||||
|
||||
storedItem = store.getEntry("baz@example.com");
|
||||
storedItem = store.getEntry(JidTestUtil.BARE_JID_2);
|
||||
assertNotNull("Added entry not found", storedItem);
|
||||
assertEquals("User of added entry",
|
||||
item4.getUser(), storedItem.getUser());
|
||||
|
@ -178,7 +181,7 @@ public class DirectoryRosterStoreTest {
|
|||
assertEquals("Number of entries", 2, entries.size());
|
||||
|
||||
String version4 = "4";
|
||||
store.removeEntry("baz@example.com", version4);
|
||||
store.removeEntry(JidTestUtil.BARE_JID_2, version4);
|
||||
assertEquals("Removing entry sets version correctly",
|
||||
version4, store.getRosterVersion());
|
||||
assertNull("Removed entry is gone", store.getEntry(userName));
|
||||
|
@ -195,7 +198,7 @@ public class DirectoryRosterStoreTest {
|
|||
File storeDir = tmpFolder.newFolder();
|
||||
DirectoryRosterStore store = DirectoryRosterStore.init(storeDir);
|
||||
|
||||
String user = "../_#;\"'\\&@example.com";
|
||||
Jid user = JidCreate.from(".._#;'&@example.com");
|
||||
String name = "\n../_#\0\t;\"'&@\\";
|
||||
String group1 = "\t;\"'&@\\\n../_#\0";
|
||||
String group2 = "#\0\t;\"'&@\\\n../_";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue