1
0
Fork 0
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:
Matt Tucker 2006-10-07 23:16:20 +00:00 committed by matt
parent 48fac74878
commit 998172b111

View file

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