/**********************************************************************************
* $URL: https://source.sakaiproject.org/svn/msgcntr/trunk/messageforums-component-impl/src/java/org/sakaiproject/component/app/messageforums/MembershipManagerImpl.java $
* $Id: MembershipManagerImpl.java 9227 2006-05-15 15:02:42Z cwen@iupui.edu $
***********************************************************************************
*
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008 The Sakai Foundation
*
* Licensed under the Educational Community License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.opensource.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**********************************************************************************/
package org.sakaiproject.component.app.messageforums;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.api.app.messageforums.MembershipManager;
import org.sakaiproject.api.app.messageforums.ui.PrivateMessageManager;
import org.sakaiproject.api.privacy.PrivacyManager;
import org.sakaiproject.authz.api.AuthzGroup;
import org.sakaiproject.authz.api.AuthzGroupService;
import org.sakaiproject.authz.api.GroupNotDefinedException;
import org.sakaiproject.authz.api.Member;
import org.sakaiproject.authz.api.Role;
import org.sakaiproject.authz.api.SecurityService;
import org.sakaiproject.component.cover.ServerConfigurationService;
import org.sakaiproject.exception.IdUnusedException;
import org.sakaiproject.site.api.Group;
import org.sakaiproject.site.api.Site;
import org.sakaiproject.site.api.SiteService;
import org.sakaiproject.tool.api.ToolManager;
import org.sakaiproject.user.api.User;
import org.sakaiproject.user.api.UserDirectoryService;
import org.sakaiproject.user.api.UserNotDefinedException;
import org.sakaiproject.util.ResourceLoader;
public class MembershipManagerImpl implements MembershipManager{
private static final Log LOG = LogFactory.getLog(MembershipManagerImpl.class);
private SiteService siteService;
private UserDirectoryService userDirectoryService;
private AuthzGroupService authzGroupService;
private ToolManager toolManager;
private SecurityService securityService;
private PrivacyManager privacyManager;
private PrivateMessageManager prtMsgManager;
private static final String MESSAGECENTER_BUNDLE = "org.sakaiproject.api.app.messagecenter.bundle.Messages";
private ResourceLoader rl = new ResourceLoader(MESSAGECENTER_BUNDLE);
public void init() {
LOG.info("init()");
;
}
/**
*
* @param privacyManager
*/
public void setPrivacyManager(PrivacyManager privacyManager)
{
this.privacyManager = privacyManager;
}
/**
* sets users' privacy status so can be filtered out
*
* @param allCourseUsers - used to get user ids so can call PrivacyManager
* @param courseUserMap - map of all course users
*
* @return Map of all course users with privacy status set
*/
private Map setPrivacyStatus(List allCourseUsers, Map courseUserMap) {
List userIds = new ArrayList();
Map results = new HashMap();
Collection userCollection = courseUserMap.values();
for (Iterator usersIter = allCourseUsers.iterator(); usersIter.hasNext();) {
MembershipItem memberItem = (MembershipItem) usersIter.next();
if (memberItem.getUser() != null) {
userIds.add(memberItem.getUser().getId());
}
}
// set privacy status
Set memberSet = null;
memberSet = privacyManager.findViewable(
("/site/" + toolManager.getCurrentPlacement().getContext()), new HashSet(userIds));
/** look through the members again to pick out Member objects corresponding
to only those who are visible (as well as current user) */
for (Iterator userIterator = userCollection.iterator(); userIterator.hasNext();) {
MembershipItem memberItem = (MembershipItem) userIterator.next();
if (memberItem.getUser() != null) {
memberItem.setViewable(memberSet.contains(memberItem.getUser().getId()));
}
else {
// want groups to be displayed
memberItem.setViewable(true);
}
results.put(memberItem.getId(), memberItem);
}
return results;
}
/**
* @see org.sakaiproject.api.app.messageforums.MembershipManager#getFilteredCourseMembers(boolean)
*/
public Map getFilteredCourseMembers(boolean filterFerpa, List<String> hiddenGroups){
List allCourseUsers = getAllCourseUsers();
Set membershipRoleSet = new HashSet();
if(getPrtMsgManager().isAllowToFieldRoles()){
/** generate set of roles which has members */
for (Iterator i = allCourseUsers.iterator(); i.hasNext();){
MembershipItem item = (MembershipItem) i.next();
if (item.getRole() != null){
membershipRoleSet.add(item.getRole());
}
}
}
/** filter member map */
Map memberMap = getAllCourseMembers(filterFerpa, true, true, hiddenGroups);
// if (filterFerpa) {
// memberMap = setPrivacyStatus(allCourseUsers, memberMap);
// }
Set<String> viewableUsersForTA = new HashSet<String>();
if (prtMsgManager.isSectionTA()) {
viewableUsersForTA = getFellowSectionMembers();
}
for (Iterator i = memberMap.entrySet().iterator(); i.hasNext();){
Map.Entry entry = (Map.Entry) i.next();
MembershipItem item = (MembershipItem) entry.getValue();
if (MembershipItem.TYPE_ROLE.equals(item.getType())){
/** if no member belongs to role, filter role */
if (!membershipRoleSet.contains(item.getRole())){
i.remove();
}
}
else if (MembershipItem.TYPE_GROUP.equals(item.getType())){
/** if no member belongs to group, filter group */
if (item.getGroup().getMembers().size() == 0){
i.remove();
}
}
else{
if (!item.isViewable() && !prtMsgManager.isInstructor()) {
if (prtMsgManager.isSectionTA() && viewableUsersForTA.contains(item.getUser().getId())) {
// if this user is a member of this TA's section, they
// are viewable
} else {
i.remove();
}
}
}
}
return memberMap;
}
/**
*
* @return a non-null set of userIds for all of the members in the current user's section(s). Useful for determining students
* who are viewable to a user in a TA role
*/
private Set<String> getFellowSectionMembers() {
Set<String> fellowMembers = new HashSet<String>();
try {
Collection<Group> groups = siteService.getSite(toolManager.getCurrentPlacement().getContext()).getGroupsWithMember(userDirectoryService.getCurrentUser().getId());
if (groups != null) {
for (Group group : groups) {
Set<Member> groupMembers = group.getMembers();
if (groupMembers != null) {
for (Member groupMember : groupMembers) {
fellowMembers.add(groupMember.getUserId());
}
}
}
}
} catch (IdUnusedException e) {
LOG.warn("Unable to retrieve site to determine current user's fellow section members.");
}
return fellowMembers;
}
/**
* @see org.sakaiproject.api.app.messageforums.MembershipManager#getAllCourseMembers(boolean, boolean, boolean)
*/
public Map getAllCourseMembers(boolean filterFerpa, boolean includeRoles, boolean includeAllParticipantsMember, List<String> hiddenGroups)
{
Map returnMap = new HashMap();
String realmId = getContextSiteId();
Site currentSite = null;
if(getPrtMsgManager().isAllowToFieldAllParticipants()){
/** add all participants */
if (includeAllParticipantsMember){
MembershipItem memberAll = MembershipItem.getInstance();
memberAll.setType(MembershipItem.TYPE_ALL_PARTICIPANTS);
//memberAll.setName(MembershipItem.ALL_PARTICIPANTS_DESC);
memberAll.setName(rl.getString("all_participants_desc"));
returnMap.put(memberAll.getId(), memberAll);
}
}
AuthzGroup realm = null;
try{
realm = authzGroupService.getAuthzGroup(realmId);
currentSite = siteService.getSite(toolManager.getCurrentPlacement().getContext());
if (currentSite == null) // SAK-12988
throw new RuntimeException("Could not obtain Site object!");
}
catch (IdUnusedException e){
//FIXME Is this expected behavior? If so it should be documented - LDS
LOG.debug(e.getMessage(), e);
return returnMap;
} catch (GroupNotDefinedException e) {
//FIXME Is this expected behavior? If so it should be documented - LDS
LOG.error(e.getMessage(), e);
}
if(getPrtMsgManager().isAllowToFieldGroups()){
boolean viewHiddenGroups = getPrtMsgManager().isAllowToViewHiddenGroups();
/** handle groups */
if (currentSite == null)
throw new IllegalStateException("Site currentSite == null!");
Collection groups = currentSite.getGroups();
for (Iterator groupIterator = groups.iterator(); groupIterator.hasNext();){
Group currentGroup = (Group) groupIterator.next();
//only show groups the user has access to
if(viewHiddenGroups || !containsId(currentGroup.getTitle(), hiddenGroups)){
MembershipItem member = MembershipItem.getInstance();
member.setType(MembershipItem.TYPE_GROUP);
//member.setName(currentGroup.getTitle() + " Group");
member.setName(rl.getFormattedMessage("participants_group_desc",new Object[]{currentGroup.getTitle()}));
member.setGroup(currentGroup);
returnMap.put(member.getId(), member);
}
}
}
if(getPrtMsgManager().isAllowToFieldRoles()){
/** handle roles */
if (includeRoles && realm != null){
Set roles = realm.getRoles();
for (Iterator roleIterator = roles.iterator(); roleIterator.hasNext();){
Role role = (Role) roleIterator.next();
MembershipItem member = MembershipItem.getInstance();
member.setType(MembershipItem.TYPE_ROLE);
String roleId = role.getId();
if (roleId != null && roleId.length() > 0){
roleId = roleId.substring(0,1).toUpperCase() + roleId.substring(1);
}
// member.setName(roleId + " Role");
member.setName(rl.getFormattedMessage("participants_role_desc",new Object[]{roleId}));
member.setRole(role);
returnMap.put(member.getId(), member);
}
}
}
/** handle users */
if (realm == null)
throw new IllegalStateException("AuthzGroup realm == null!");
Set users = realm.getMembers();
if (users == null)
throw new RuntimeException("Could not obtain members from realm!");
/** create our HashSet of user ids */
for (Iterator userIterator = users.iterator(); userIterator.hasNext();){
Member member = (Member) userIterator.next();
String userId = member.getUserId();
Role userRole = member.getRole();
User user = null;
try{
if(realm.getMember(userId) != null && realm.getMember(userId).isActive())
{
user = userDirectoryService.getUser(userId);
}
} catch (UserNotDefinedException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
LOG.warn(" User " + userId + " not defined");
}
if(user != null)
{
MembershipItem memberItem = MembershipItem.getInstance();
memberItem.setType(MembershipItem.TYPE_USER);
if (ServerConfigurationService.getBoolean("msg.displayEid", true)) {
memberItem.setName(user.getSortName() + " (" + user.getDisplayId() + ")");
}
else {
memberItem.setName(user.getSortName());
}
memberItem.setUser(user);
memberItem.setRole(userRole);
// Don't want admin as part of the list
if(!"admin".equals(userId))
{
returnMap.put(memberItem.getId(), memberItem);
}
}
}
// set FERPA status for all items in map - allCourseUsers
// needed by PrivacyManager to determine status
return setPrivacyStatus(getAllCourseUsers(), returnMap);
}
private boolean containsId(String searchId, List<String> ids){
if(ids != null && searchId != null){
for (String id : ids) {
if(id.equals(searchId))
return true;
}
}
return false;
}
/**
* @see org.sakaiproject.api.app.messageforums.MembershipManager#getAllCourseUsers()
*/
public List getAllCourseUsers()
{
Map userMap = new HashMap();
String realmId = getContextSiteId();
AuthzGroup realm = null;
try{
realm = authzGroupService.getAuthzGroup(realmId);
} catch (GroupNotDefinedException e) {
//FIXME Is this expected behavior? If so it should be documented - LDS
LOG.error(e.getMessage(), e);
}
/** handle users */
if (realm == null)
throw new IllegalStateException("AuthzGroup realm == null!");
Set users = realm.getMembers();
List userIds = getRealmIdList(users);
List<User> userList = userDirectoryService.getUsers(userIds);
Map<String, User> userMMap = getuserMap(userList);
if (users == null)
throw new RuntimeException("Could not obtain members from realm!");
for (Iterator userIterator = users.iterator(); userIterator.hasNext();){
Member member = (Member) userIterator.next();
String userId = member.getUserId();
Role userRole = member.getRole();
User user = null;
if(realm.getMember(userId) != null && realm.getMember(userId).isActive())
{
if (userMMap.containsKey(member.getUserId())) {
user = getUserFromList(member.getUserId(), userList);
}
}
if (user == null){
//user does not exits
continue;
}
if(user != null)
{
MembershipItem memberItem = MembershipItem.getInstance();
memberItem.setType(MembershipItem.TYPE_USER);
memberItem.setName(user.getSortName());
memberItem.setUser(user);
memberItem.setRole(userRole);
if(!"admin".equals(userId))
{
userMap.put(memberItem.getId(), memberItem);
}
}
}
return convertMemberMapToList(userMap);
}
/**
* @see org.sakaiproject.api.app.messageforums.MembershipManager#convertMemberMapToList(java.util.Map)
*/
public List convertMemberMapToList(Map memberMap){
MembershipItem[] membershipArray = new MembershipItem[memberMap.size()];
membershipArray = (MembershipItem[]) memberMap.values().toArray(membershipArray);
Arrays.sort(membershipArray);
return Arrays.asList(membershipArray);
}
private User getUserFromList(String userId, List<User> userList) {
User u = null;
for (int i = 0; i < userList.size(); i++) {
User tu = (User) userList.get(i);
if (userId.equals(tu.getId()))
return tu;
}
return u;
}
private List<String> getRealmIdList(Set realmUsers) {
List ret = new ArrayList();
Iterator it = realmUsers.iterator();
while (it.hasNext()) {
Member mem = (Member)it.next();
ret.add(mem.getUserId());
}
return ret;
}
private Map<String, User> getuserMap(List userList) {
Map<String, User> ret = new HashMap<String, User>();
for (int i = 0; i < userList.size(); i++) {
User tu = (User) userList.get(i);
ret.put(tu.getId(), tu);
}
return ret;
}
/**
* get site reference
* @return siteId
*/
public String getContextSiteId()
{
return ("/site/" + toolManager.getCurrentPlacement().getContext());
}
/** setters */
public void setSiteService(SiteService siteService)
{
this.siteService = siteService;
}
public void setUserDirectoryService(UserDirectoryService userDirectoryService)
{
this.userDirectoryService = userDirectoryService;
}
public void setAuthzGroupService(AuthzGroupService authzGroupService)
{
this.authzGroupService = authzGroupService;
}
public void setToolManager(ToolManager toolManager)
{
this.toolManager = toolManager;
}
public void setSecurityService(SecurityService securityService)
{
this.securityService = securityService;
}
public PrivateMessageManager getPrtMsgManager() {
return prtMsgManager;
}
public void setPrtMsgManager(PrivateMessageManager prtMsgManager) {
this.prtMsgManager = prtMsgManager;
}
}