Commit e1287128 authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gaston

Group is using MemberCollection again as a wrapper for group users.


git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@783 b35dd754-fafc-0310-a699-88a17e54d16e
parent 4a4279b5
...@@ -19,7 +19,6 @@ import org.jivesoftware.messenger.XMPPServer; ...@@ -19,7 +19,6 @@ import org.jivesoftware.messenger.XMPPServer;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
...@@ -48,8 +47,8 @@ public class Group implements Cacheable { ...@@ -48,8 +47,8 @@ public class Group implements Cacheable {
private String name; private String name;
private String description; private String description;
private Map<String, String> properties; private Map<String, String> properties;
private Collection<String> members = new CopyOnWriteArrayList<String>(); private Collection<String> members;
private Collection<String> administrators = new CopyOnWriteArrayList<String>(); private Collection<String> administrators;
/** /**
* Constructs a new group. * Constructs a new group.
...@@ -67,8 +66,8 @@ public class Group implements Cacheable { ...@@ -67,8 +66,8 @@ public class Group implements Cacheable {
this.groupManager = GroupManager.getInstance(); this.groupManager = GroupManager.getInstance();
this.name = name; this.name = name;
this.description = description; this.description = description;
this.members.addAll(members); this.members = members;
this.administrators.addAll(administrators); this.administrators = administrators;
} }
/** /**
...@@ -144,35 +143,23 @@ public class Group implements Cacheable { ...@@ -144,35 +143,23 @@ public class Group implements Cacheable {
} }
/** /**
* Returns a Collection of the group administrators. Use <code>getUsers()</code> to get the * Returns a Collection of the group administrators.
* complete list of group users.
* *
* @return a Collection of the group administrators. * @return a Collection of the group administrators.
*/ */
public Collection<String> getAdmins() { public Collection<String> getAdmins() {
return Collections.unmodifiableCollection(administrators); // Return a wrapper that will intercept add and remove commands.
return new MemberCollection(administrators, true);
} }
/** /**
* Returns a Collection of the group members. Use <code>getUsers()</code> to get the complete * Returns a Collection of the group members.
* list of group users.
* *
* @return a Collection of the group members. * @return a Collection of the group members.
*/ */
public Collection<String> getMembers() { public Collection<String> getMembers() {
return Collections.unmodifiableCollection(members); // Return a wrapper that will intercept add and remove commands.
} return new MemberCollection(members, false);
/**
* Returns a Collection with all the group users. The collection will include group members
* as well as group administrators.
*
* @return a Collection with all the group users.
*/
public Collection<String> getUsers() {
Collection<String> answer = new ArrayList<String>(members);
answer.addAll(administrators);
return Collections.unmodifiableCollection(answer);
} }
/** /**
...@@ -185,110 +172,84 @@ public class Group implements Cacheable { ...@@ -185,110 +172,84 @@ public class Group implements Cacheable {
return members.contains(username) || administrators.contains(username); return members.contains(username) || administrators.contains(username);
} }
/** public int getCachedSize() {
* Returns true if the provided username belongs to a member of the group. // Approximate the size of the object in bytes by calculating the size
* // of each field.
* @param username the username to check. int size = 0;
* @return true if the provided username belongs to a member of the group. size += CacheSizes.sizeOfObject(); // overhead of object
*/ size += CacheSizes.sizeOfString(name);
public boolean isMember(String username) { size += CacheSizes.sizeOfString(description);
return members.contains(username); return size;
} }
/** /**
* Returns true if the provided username belongs to an administrator of the group. * Collection implementation that notifies the GroupProvider of any
* * changes to the collection.
* @param username the username to check.
* @return true if the provided username belongs to an administrator of the group.
*/ */
public boolean isAdmin(String username) { private class MemberCollection extends AbstractCollection {
return administrators.contains(username);
private Collection<String> users;
private boolean adminCollection;
public MemberCollection(Collection<String> users, boolean adminCollection) {
this.users = users;
this.adminCollection = adminCollection;
} }
/** public Iterator iterator() {
* Adds a new user as a member of the group. The roster of all group users that are currently return new Iterator() {
* logged into the server will be updated.
* Iterator iter = users.iterator();
* @param user the user to add as a member of the goup. Object current = null;
*/
public void addMember(String user) { public boolean hasNext() {
if (members.contains(user)) { return iter.hasNext();
return;
} }
members.add(user);
userAdded(user, false); public Object next() {
current = iter.next();
return current;
} }
/** public void remove() {
* Removes a member from the group. The roster of all group users that are currently if (current == null) {
* logged into the server will be updated. throw new IllegalStateException();
*
* @param user the user to remove as a member of the group.
*/
public void removeMember(String user) {
if (members.remove(user)) {
userRemoved(user);
} }
iter.remove();
String user = (String) current;
// Remove the group user from the backend store
provider.deleteMember(name, user);
// Update the group users' roster
XMPPServer.getInstance().getRosterManager().groupUserDeleted(Group.this, user);
} }
};
/**
* Adds a new user as an administrator of the group. The roster of all group users that are
* currently logged into the server will be updated.
*
* @param user the user to add as an administrator of the goup.
*/
public void addAdmin(String user) {
if (administrators.contains(user)) {
return;
} }
administrators.add(user);
userAdded(user, true); public int size() {
return users.size();
} }
/** public boolean add(Object member) {
* Removes an administrator from the group. The roster of all group users that are currently String user = (String) member;
* logged into the server will be updated. if (adminCollection) {
* if (members.contains(user)) {
* @param user the user to remove as an administrator of the group. throw new IllegalArgumentException("The user is already a member of the group");
*/
public void removeAdmin(String user) {
if (administrators.remove(user)) {
userRemoved(user);
} }
} }
else {
/** if (administrators.contains(user)) {
* Update backend store and update group users' roster. throw new IllegalArgumentException("The user is already an admin of the group");
*
* @param user the user that was added to the group.
*/
private void userAdded(String user, boolean administrator) {
// Add the new group user to the backend store
provider.addMember(name, user, administrator);
// Update the group users' roster
XMPPServer.getInstance().getRosterManager().groupUserAdded(this, user);
} }
}
/** if (users.add(user)) {
* Update backend store and update group users' roster. // Add the group user to the backend store
* provider.addMember(name, user, adminCollection);
* @param user the user that was removed from the group.
*/
private void userRemoved(String user) {
// Remove the group user from the backend store
provider.deleteMember(name, user);
// Update the group users' roster // Update the group users' roster
XMPPServer.getInstance().getRosterManager().groupUserDeleted(this, user); XMPPServer.getInstance().getRosterManager().groupUserAdded(Group.this, user);
return true;
}
return false;
} }
public int getCachedSize() {
// Approximate the size of the object in bytes by calculating the size
// of each field.
int size = 0;
size += CacheSizes.sizeOfObject(); // overhead of object
size += CacheSizes.sizeOfString(name);
size += CacheSizes.sizeOfString(description);
return size;
} }
/** /**
......
...@@ -134,11 +134,11 @@ public class GroupManager { ...@@ -134,11 +134,11 @@ public class GroupManager {
*/ */
public void deleteUser(User user) { public void deleteUser(User user) {
for (Group group : getGroups(user)) { for (Group group : getGroups(user)) {
if (group.isAdmin(user.getUsername())) { if (group.getAdmins().contains(user.getUsername())) {
group.removeAdmin(user.getUsername()); group.getAdmins().remove(user.getUsername());
} }
else { else {
group.removeMember(user.getUsername()); group.getMembers().remove(user.getUsername());
} }
} }
} }
......
...@@ -401,8 +401,11 @@ public class Roster implements Cacheable { ...@@ -401,8 +401,11 @@ public class Roster implements Cacheable {
// will have one entry in the map associated with all the groups // will have one entry in the map associated with all the groups
Map<JID,List<String>> sharedGroupUsers = new HashMap<JID,List<String>>(); Map<JID,List<String>> sharedGroupUsers = new HashMap<JID,List<String>>();
for (Group group : sharedGroups) { for (Group group : sharedGroups) {
// Get all the group users
Collection<String> users = new ArrayList<String>(group.getMembers());
users.addAll(group.getAdmins());
// Add the users of the group to the general list of users to process // Add the users of the group to the general list of users to process
for (String groupUser : group.getUsers()) { for (String groupUser : users) {
// Add the user to the answer if the user doesn't belong to the personal roster // Add the user to the answer if the user doesn't belong to the personal roster
// (since we have already added the user to the answer) // (since we have already added the user to the answer)
JID jid = new JID(groupUser, XMPPServer.getInstance().getServerInfo().getName(), JID jid = new JID(groupUser, XMPPServer.getInstance().getServerInfo().getName(),
......
...@@ -20,6 +20,8 @@ import org.jivesoftware.messenger.SharedGroupException; ...@@ -20,6 +20,8 @@ import org.jivesoftware.messenger.SharedGroupException;
import org.jivesoftware.messenger.group.Group; import org.jivesoftware.messenger.group.Group;
import java.util.Iterator; import java.util.Iterator;
import java.util.Collection;
import java.util.ArrayList;
/** /**
* A simple service that allows components to retrieve a roster based solely on the ID * A simple service that allows components to retrieve a roster based solely on the ID
...@@ -125,8 +127,11 @@ public class RosterManager extends BasicModule { ...@@ -125,8 +127,11 @@ public class RosterManager extends BasicModule {
* @param group the group that has been deleted. * @param group the group that has been deleted.
*/ */
public void groupDeleted(Group group) { public void groupDeleted(Group group) {
// Get all the group users
Collection<String> users = new ArrayList<String>(group.getMembers());
users.addAll(group.getAdmins());
// Iterate on all the group users and update their rosters // Iterate on all the group users and update their rosters
for (String deletedUser : group.getUsers()) { for (String deletedUser : users) {
groupUserDeleted(group, deletedUser); groupUserDeleted(group, deletedUser);
} }
} }
...@@ -138,8 +143,11 @@ public class RosterManager extends BasicModule { ...@@ -138,8 +143,11 @@ public class RosterManager extends BasicModule {
* @param addedUser the username of the user that has been added to the group. * @param addedUser the username of the user that has been added to the group.
*/ */
public void groupUserAdded(Group group, String addedUser) { public void groupUserAdded(Group group, String addedUser) {
// Get all the group users
Collection<String> users = new ArrayList<String>(group.getMembers());
users.addAll(group.getAdmins());
// Iterate on all the group users and update their rosters // Iterate on all the group users and update their rosters
for (String userToUpdate : group.getUsers()) { for (String userToUpdate : users) {
if (!addedUser.equals(userToUpdate)) { if (!addedUser.equals(userToUpdate)) {
// Get the roster to update // Get the roster to update
Roster roster = (Roster)CacheManager.getCache("username2roster").get(userToUpdate); Roster roster = (Roster)CacheManager.getCache("username2roster").get(userToUpdate);
...@@ -158,8 +166,11 @@ public class RosterManager extends BasicModule { ...@@ -158,8 +166,11 @@ public class RosterManager extends BasicModule {
* @param deletedUser the username of the user that has been deleted from the group. * @param deletedUser the username of the user that has been deleted from the group.
*/ */
public void groupUserDeleted(Group group, String deletedUser) { public void groupUserDeleted(Group group, String deletedUser) {
// Get all the group users
Collection<String> users = new ArrayList<String>(group.getMembers());
users.addAll(group.getAdmins());
// Iterate on all the group users and update their rosters // Iterate on all the group users and update their rosters
for (String userToUpdate : group.getUsers()) { for (String userToUpdate : users) {
if (!deletedUser.equals(userToUpdate)) { if (!deletedUser.equals(userToUpdate)) {
// Get the roster to update // Get the roster to update
Roster roster = (Roster)CacheManager.getCache("username2roster").get(userToUpdate); Roster roster = (Roster)CacheManager.getCache("username2roster").get(userToUpdate);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment