mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-27 00:32:07 +01:00
Removed extra synchronization (SMACK-177).
git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@5645 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
parent
48fac74878
commit
998172b111
1 changed files with 42 additions and 73 deletions
|
@ -31,6 +31,7 @@ import org.jivesoftware.smack.util.StringUtils;
|
|||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* Represents a user's roster, which is the collection of users a person receives
|
||||
|
@ -99,10 +100,10 @@ public class Roster implements ConnectionListener {
|
|||
Roster(final XMPPConnection connection) {
|
||||
this.connection = connection;
|
||||
groups = new ConcurrentHashMap<String,RosterGroup>();
|
||||
unfiledEntries = new ArrayList<RosterEntry>();
|
||||
entries = new ArrayList<RosterEntry>();
|
||||
rosterListeners = new ArrayList<RosterListener>();
|
||||
presenceMap = new HashMap<String, Map<String, Presence>>();
|
||||
unfiledEntries = new CopyOnWriteArrayList<RosterEntry>();
|
||||
entries = new CopyOnWriteArrayList<RosterEntry>();
|
||||
rosterListeners = new CopyOnWriteArrayList<RosterListener>();
|
||||
presenceMap = new ConcurrentHashMap<String, Map<String, Presence>>();
|
||||
// Listen for any roster packets.
|
||||
PacketFilter rosterFilter = new PacketTypeFilter(RosterPacket.class);
|
||||
connection.addPacketListener(new RosterPacketListener(), rosterFilter);
|
||||
|
@ -160,12 +161,10 @@ public class Roster implements ConnectionListener {
|
|||
* @param rosterListener a roster listener.
|
||||
*/
|
||||
public void addRosterListener(RosterListener rosterListener) {
|
||||
synchronized (rosterListeners) {
|
||||
if (!rosterListeners.contains(rosterListener)) {
|
||||
rosterListeners.add(rosterListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a listener from this roster. The listener will be fired anytime one or more
|
||||
|
@ -174,10 +173,8 @@ public class Roster implements ConnectionListener {
|
|||
* @param rosterListener a roster listener.
|
||||
*/
|
||||
public void removeRosterListener(RosterListener rosterListener) {
|
||||
synchronized (rosterListeners) {
|
||||
rosterListeners.remove(rosterListener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new group.<p>
|
||||
|
@ -189,7 +186,6 @@ public class Roster implements ConnectionListener {
|
|||
* @return a new group.
|
||||
*/
|
||||
public RosterGroup createGroup(String name) {
|
||||
synchronized (groups) {
|
||||
if (groups.containsKey(name)) {
|
||||
throw new IllegalArgumentException("Group with name " + name + " alread exists.");
|
||||
}
|
||||
|
@ -197,7 +193,6 @@ public class Roster implements ConnectionListener {
|
|||
groups.put(name, group);
|
||||
return group;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new roster entry and presence subscription. The server will asynchronously
|
||||
|
@ -207,6 +202,7 @@ public class Roster implements ConnectionListener {
|
|||
* @param name the nickname of the user.
|
||||
* @param groups the list of group names the entry will belong to, or <tt>null</tt> if the
|
||||
* the roster entry won't belong to a group.
|
||||
* @throws XMPPException if an XMPP exception occurs.
|
||||
*/
|
||||
public void createEntry(String user, String name, String [] groups) throws XMPPException {
|
||||
// Create and send roster entry creation packet.
|
||||
|
@ -248,15 +244,14 @@ public class Roster implements ConnectionListener {
|
|||
* to send an updated subscription status.
|
||||
*
|
||||
* @param entry a roster entry.
|
||||
* @throws XMPPException if an XMPP error occurs.
|
||||
*/
|
||||
public void removeEntry(RosterEntry entry) throws XMPPException {
|
||||
// Only remove the entry if it's in the entry list.
|
||||
// The actual removal logic takes place in RosterPacketListenerprocess>>Packet(Packet)
|
||||
synchronized (entries) {
|
||||
if (!entries.contains(entry)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
RosterPacket packet = new RosterPacket();
|
||||
packet.setType(IQ.Type.SET);
|
||||
RosterPacket.Item item = RosterEntry.toRosterItem(entry);
|
||||
|
@ -302,9 +297,8 @@ public class Roster implements ConnectionListener {
|
|||
allEntries.addAll(rosterGroup.getEntries());
|
||||
}
|
||||
// Add the roster unfiled entries to the answer
|
||||
synchronized (unfiledEntries) {
|
||||
allEntries.addAll(unfiledEntries);
|
||||
}
|
||||
|
||||
return Collections.unmodifiableCollection(allEntries);
|
||||
}
|
||||
|
||||
|
@ -334,10 +328,8 @@ public class Roster implements ConnectionListener {
|
|||
* @return the number of unfiled entries in the roster.
|
||||
*/
|
||||
public int getUnfiledEntryCount() {
|
||||
synchronized (unfiledEntries) {
|
||||
return unfiledEntries.size();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable collection for the unfiled roster entries. An unfiled entry is
|
||||
|
@ -346,9 +338,7 @@ public class Roster implements ConnectionListener {
|
|||
* @return the unfiled roster entries.
|
||||
*/
|
||||
public Collection<RosterEntry> getUnfiledEntries() {
|
||||
synchronized (unfiledEntries) {
|
||||
return Collections.unmodifiableList(new ArrayList<RosterEntry>(unfiledEntries));
|
||||
}
|
||||
return Collections.unmodifiableList(unfiledEntries);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -364,13 +354,11 @@ public class Roster implements ConnectionListener {
|
|||
return null;
|
||||
}
|
||||
String userLowerCase = user.toLowerCase();
|
||||
synchronized (entries) {
|
||||
for (RosterEntry entry : entries) {
|
||||
if (entry.getUser().equals(userLowerCase)) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -539,13 +527,9 @@ public class Roster implements ConnectionListener {
|
|||
* @param deletedEntries the collection of address of the deleted contacts.
|
||||
*/
|
||||
private void fireRosterChangedEvent(Collection addedEntries, Collection updatedEntries,
|
||||
Collection deletedEntries) {
|
||||
RosterListener [] listeners;
|
||||
synchronized (rosterListeners) {
|
||||
listeners = new RosterListener[rosterListeners.size()];
|
||||
rosterListeners.toArray(listeners);
|
||||
}
|
||||
for (RosterListener listener : listeners) {
|
||||
Collection deletedEntries)
|
||||
{
|
||||
for (RosterListener listener : rosterListeners) {
|
||||
if (!addedEntries.isEmpty()) {
|
||||
listener.entriesAdded(addedEntries);
|
||||
}
|
||||
|
@ -560,14 +544,11 @@ public class Roster implements ConnectionListener {
|
|||
|
||||
/**
|
||||
* Fires roster presence changed event to roster listeners.
|
||||
*
|
||||
* @param user the user with a presence change.
|
||||
*/
|
||||
private void fireRosterPresenceEvent(String user) {
|
||||
RosterListener [] listeners;
|
||||
synchronized (rosterListeners) {
|
||||
listeners = new RosterListener[rosterListeners.size()];
|
||||
rosterListeners.toArray(listeners);
|
||||
}
|
||||
for (RosterListener listener : listeners) {
|
||||
for (RosterListener listener : rosterListeners) {
|
||||
listener.presenceChanged(user);
|
||||
}
|
||||
}
|
||||
|
@ -624,14 +605,12 @@ public class Roster implements ConnectionListener {
|
|||
userPresences.put(StringUtils.parseResource(from), presence);
|
||||
}
|
||||
// If the user is in the roster, fire an event.
|
||||
synchronized (entries) {
|
||||
for (RosterEntry entry : entries) {
|
||||
if (entry.getUser().equals(key)) {
|
||||
fireRosterPresenceEvent(from);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// If an "unavailable" packet, remove any entries in the presence map.
|
||||
else if (presence.getType() == Presence.Type.unavailable) {
|
||||
if (presenceMap.get(key) != null) {
|
||||
|
@ -644,14 +623,12 @@ public class Roster implements ConnectionListener {
|
|||
}
|
||||
}
|
||||
// If the user is in the roster, fire an event.
|
||||
synchronized (entries) {
|
||||
for (RosterEntry entry : entries) {
|
||||
if (entry.getUser().equals(key)) {
|
||||
fireRosterPresenceEvent(from);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (presence.getType() == Presence.Type.subscribe) {
|
||||
if (subscriptionMode == SubscriptionMode.accept_all) {
|
||||
// Accept all subscription requests.
|
||||
|
@ -705,11 +682,9 @@ public class Roster implements ConnectionListener {
|
|||
entries.remove(entry);
|
||||
}
|
||||
// Remove the entry from the unfiled entry list.
|
||||
synchronized (unfiledEntries) {
|
||||
if (unfiledEntries.contains(entry)) {
|
||||
unfiledEntries.remove(entry);
|
||||
}
|
||||
}
|
||||
// Removing the user from the roster, so remove any presence information
|
||||
// about them.
|
||||
String key = StringUtils.parseName(item.getUser()) + "@" +
|
||||
|
@ -736,19 +711,15 @@ public class Roster implements ConnectionListener {
|
|||
// If the roster entry belongs to any groups, remove it from the
|
||||
// list of unfiled entries.
|
||||
if (!item.getGroupNames().isEmpty()) {
|
||||
synchronized (unfiledEntries) {
|
||||
unfiledEntries.remove(entry);
|
||||
}
|
||||
}
|
||||
// Otherwise add it to the list of unfiled entries.
|
||||
else {
|
||||
synchronized (unfiledEntries) {
|
||||
if (!unfiledEntries.contains(entry)) {
|
||||
unfiledEntries.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find the list of groups that the user currently belongs to.
|
||||
List<String> currentGroupNames = new ArrayList<String>();
|
||||
|
@ -788,11 +759,9 @@ public class Roster implements ConnectionListener {
|
|||
RosterGroup group = getGroup(groupName);
|
||||
group.removeEntryLocal(entry);
|
||||
if (group.getEntryCount() == 0) {
|
||||
synchronized (groups) {
|
||||
groups.remove(groupName);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Remove all the groups with no entries. We have to do this because
|
||||
// RosterGroup.removeEntry removes the entry immediately (locally) and the
|
||||
// group could remain empty.
|
||||
|
|
Loading…
Reference in a new issue