1
0
Fork 0
mirror of https://codeberg.org/Mercury-IM/Smack synced 2025-12-08 06:01:07 +01:00

Use Jid (and subclasses) from jxmpp-jid

Fixes SMACK-634
This commit is contained in:
Florian Schmaus 2015-02-14 17:15:02 +01:00
parent 0ee2d9ed1e
commit 5bb4727c57
180 changed files with 1510 additions and 1032 deletions

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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.

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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.

View file

@ -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);
}

View file

@ -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);
}