Index: roster-app/src/java/org/sakaiproject/tool/roster/FilteredParticipantListingBean.java =================================================================== --- roster-app/src/java/org/sakaiproject/tool/roster/FilteredParticipantListingBean.java (revision 329) +++ roster-app/src/java/org/sakaiproject/tool/roster/FilteredParticipantListingBean.java (working copy) @@ -23,6 +23,7 @@ import java.io.Serializable; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.SortedMap; @@ -124,8 +125,9 @@ return getSearchFilterString() != null && ! getSearchFilterString().equals(defaultSearchText) && ! searchMatches(getSearchFilterString(), participant.getUser()); } - protected SortedMap findRoleCounts(List participants) { + protected SortedMap findRoleCounts(Iterable participants) { SortedMap roleCountMap = new TreeMap(); + for(Iterator iter = participants.iterator(); iter.hasNext();) { Participant participant = iter.next(); String role = participant.getRoleTitle(); Index: roster-app/src/java/org/sakaiproject/tool/roster/RosterGroupMembership.java =================================================================== --- roster-app/src/java/org/sakaiproject/tool/roster/RosterGroupMembership.java (revision 329) +++ roster-app/src/java/org/sakaiproject/tool/roster/RosterGroupMembership.java (working copy) @@ -64,48 +64,61 @@ return filter.isGroupedBy(); } - public List getGroupedParticipants() { - Site site; + @SuppressWarnings("unchecked") + public Collection getGroupedParticipants() { + List groupedParticipants = null; + Site site = null; + try { site = filter.services.siteService.getSite(filter.getSiteReference().substring(6)); } catch (IdUnusedException e) { log.error("Unable to find site for: " + getSiteReference() + " " + e.getMessage(), e); return null; } - List groupedParticipants = new ArrayList(); - Collection groups = site.getGroups(); - for(Iterator groupIter = groups.iterator(); groupIter.hasNext();) - { - Group group = groupIter.next(); - List roster = filter.services.rosterManager.getRoster(group.getReference()); - groupedParticipants.add(new GroupedParticipants(group.getTitle(), roster, roster.size(), getRoleCountMessage(filter.findRoleCounts(roster)))); - } - - List fullRoster = filter.services.rosterManager.getRoster(); - List unassignedList = new ArrayList(); - // checking if there's any participants who are not in any groups - for(Iterator partIter = fullRoster.iterator(); partIter.hasNext();) - { - Participant participant = partIter.next(); - boolean userGrouped = filter.services.rosterManager.isParticipantGrouped(participant.getUser().getId()); - if (!userGrouped) - { - unassignedList.add(participant); - } - } - // if we have participants who are ungrouped, we add them here to a new one for rendering called "Unassigned" - if (!unassignedList.isEmpty()) - { - String unassigned = "Unassigned"; - groupedParticipants.add(new GroupedParticipants(unassigned, unassignedList, unassignedList.size(), getRoleCountMessage(filter.findRoleCounts(unassignedList)))); - } - - Collections.sort(groupedParticipants, sortByGroup()); + + if (site != null) { + groupedParticipants = new ArrayList(); + Collection groups = (Collection) site.getGroups(); + + //Use a HashSet because we'll have to use .removeAll() on it many times + //.remove() is roughly constant time for a HashSet. + Set unassignedParticipants = new HashSet( + filter.services.rosterManager.getRoster() + ); + + for(Iterator groupIter = groups.iterator(); groupIter.hasNext();) + { + Group group = groupIter.next(); + List roster = filter.services.rosterManager.getRoster(group.getReference()); + + //remove each grouped participant from the 'unassignedParticipants' set + unassignedParticipants.removeAll(roster); + + groupedParticipants.add(new GroupedParticipants(group.getTitle(), roster, roster.size(), getRoleCountMessage(filter.findRoleCounts(roster)))); + } + + // if we have participants who are ungrouped, we add them here to a new one for rendering called "Unassigned" + if (!unassignedParticipants.isEmpty()) + { + String unassigned = "Unassigned"; + groupedParticipants.add( + new GroupedParticipants( + unassigned, + unassignedParticipants, + unassignedParticipants.size(), + getRoleCountMessage(filter.findRoleCounts(unassignedParticipants)) + ) + ); + } + + Collections.sort(groupedParticipants, sortByGroup()); + } + return groupedParticipants; } public class GroupedParticipants { - List groupedParticipants = new ArrayList(); + Collection groupedParticipants = new ArrayList(); String groupTitle; int groupedParticipantCount; String roleCountMessage; @@ -122,10 +135,10 @@ public void setGroupTitle(String groupTitle) { this.groupTitle = groupTitle; } - public List getGroupedParticipants() { + public Collection getGroupedParticipants() { return groupedParticipants; } - public void setGroupedParticipants(List groupedParticipants) { + public void setGroupedParticipants(Collection groupedParticipants) { this.groupedParticipants = groupedParticipants; } public String getRoleCountMessage() { @@ -137,7 +150,7 @@ public GroupedParticipants() {} - public GroupedParticipants(String groupTitle, List groupedParticipants, int groupedParticipantCount, String roleCountMessage) { + public GroupedParticipants(String groupTitle, Collection groupedParticipants, int groupedParticipantCount, String roleCountMessage) { this.groupTitle = groupTitle; this.groupedParticipants = groupedParticipants; this.groupedParticipantCount = groupedParticipantCount; Index: roster-impl/src/java/org/sakaiproject/component/app/roster/ParticipantImpl.java =================================================================== --- roster-impl/src/java/org/sakaiproject/component/app/roster/ParticipantImpl.java (revision 329) +++ roster-impl/src/java/org/sakaiproject/component/app/roster/ParticipantImpl.java (working copy) @@ -130,4 +130,31 @@ } return groupsString; } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return user.hashCode(); + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + boolean rv = false; + Participant p = null; + + if (this == obj) { + rv = true; + } else if (user != null && obj != null && obj instanceof Participant) { + p = (Participant) obj; + + rv = user.equals(p.getUser()); + } + + return rv; + } }