package org.sakaiproject.site.tool.helper.managegroup.impl;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.authz.api.AuthzGroupService;
import org.sakaiproject.authz.api.Member;
import org.sakaiproject.authz.api.Role;
import org.sakaiproject.component.api.ServerConfigurationService;
import org.sakaiproject.event.cover.EventTrackingService;
import org.sakaiproject.exception.IdUnusedException;
import org.sakaiproject.exception.PermissionException;
import org.sakaiproject.site.api.Group;
import org.sakaiproject.site.api.Site;
import org.sakaiproject.site.api.SiteService;
import org.sakaiproject.site.util.Participant;
import org.sakaiproject.site.util.SiteConstants;
import org.sakaiproject.site.util.SiteParticipantHelper;
import org.sakaiproject.tool.api.SessionManager;
import org.sakaiproject.tool.api.Tool;
import org.sakaiproject.tool.api.ToolManager;
import org.sakaiproject.tool.api.ToolSession;
import uk.org.ponder.messageutil.TargettedMessage;
import uk.org.ponder.messageutil.TargettedMessageList;
/**
*
* @author
*
*/
public class SiteManageGroupHandler {
/** Our log (commons). */
private static Log M_log = LogFactory.getLog(SiteManageGroupHandler.class);
private Collection<Member> groupMembers;
private GroupComparator groupComparator = new GroupComparator();
public Site site = null;
public SiteService siteService = null;
public AuthzGroupService authzGroupService = null;
public ToolManager toolManager = null;
public SessionManager sessionManager = null;
public ServerConfigurationService serverConfigurationService;
private List<Group> groups = null;
private Set unhideables = null;
public String memberList = "";
public boolean update = false;
public boolean done = false;
public String[] selectedGroupMembers = new String[]{};
public String[] selectedSiteMembers = new String[]{};
private String NULL_STRING = "";
private final String TOOL_CFG_FUNCTIONS = "functions.require";
private final String TOOL_CFG_MULTI = "allowMultiple";
private final String SITE_UPD = "site.upd";
private final String HELPER_ID = "sakai.tool.helper.id";
private final String UNHIDEABLES_CFG = "poh.unhideables";
private final String GROUP_ADD = "group.add";
private final String GROUP_DELETE = "group.delete";
private final String GROUP_RENAME = "group.rename";
private final String GROUP_SHOW = "group.show";
private final String GROUP_HIDE = "group.hide";
private final String SITE_REORDER = "group.reorder";
private final String SITE_RESET = "group.reset";
// Tool session attribute name used to schedule a whole page refresh.
public static final String ATTR_TOP_REFRESH = "sakai.vppa.top.refresh";
public TargettedMessageList messages;
public void setMessages(TargettedMessageList messages) {
this.messages = messages;
}
/**
* reset the message list
*/
private void resetTargettedMessageList()
{
this.messages = new TargettedMessageList();
}
// the group title
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
// group title
private String title;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
// group description
private String description;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
// for those to be deleted groups
public String[] deleteGroupIds;
/**
* reset the variables
*/
public void resetParams()
{
id = "";
title = "";
description ="";
deleteGroupIds=new String[]{};
selectedGroupMembers = new String[]{};
selectedSiteMembers = new String[]{};
}
/**
* Gets the groups for the current site
* @return Map of groups (id, group)
*/
public List<Group> getGroups() {
if (site == null) {
init();
}
if (update) {
groups = new Vector<Group>();
if (site != null)
{
// only show groups created by WSetup tool itself
Collection allGroups = (Collection) site.getGroups();
for (Iterator gIterator = allGroups.iterator(); gIterator.hasNext();) {
Group gNext = (Group) gIterator.next();
String gProp = gNext.getProperties().getProperty(gNext.GROUP_PROP_WSETUP_CREATED);
if (gProp != null && gProp.equals(Boolean.TRUE.toString())) {
groups.add(gNext);
}
}
}
}
Collections.sort( groups, groupComparator );
return groups;
}
/**
* Initialization method, just gets the current site in preperation for other calls
*
*/
public void init() {
if (site == null) {
String siteId = null;
try {
siteId = sessionManager.getCurrentToolSession()
.getAttribute(HELPER_ID + ".siteId").toString();
}
catch (java.lang.NullPointerException npe) {
// Site ID wasn't set in the helper call!!
}
if (siteId == null) {
siteId = toolManager.getCurrentPlacement().getContext();
}
try {
site = siteService.getSite(siteId);
update = siteService.allowUpdateSite(site.getId()) || siteService.allowUpdateGroupMembership(site.getId());
} catch (IdUnusedException e) {
// The siteId we were given was bogus
e.printStackTrace();
}
}
title = "";
String conf = serverConfigurationService.getString(UNHIDEABLES_CFG);
if (conf != null) {
unhideables = new HashSet();
String[] toolIds = conf.split(",");
for (int i = 0; i < toolIds.length; i++) {
unhideables.add(toolIds[i].trim());
}
}
if (groupMembers == null)
{
groupMembers = new Vector<Member>();
}
}
/**
* Wrapper around siteService to save a site
* @param site
* @throws IdUnusedException
* @throws PermissionException
*/
public void saveSite(Site site) throws IdUnusedException, PermissionException {
siteService.save(site);
}
public List<Participant> getSiteParticipant(Group group)
{
List<Participant> rv = new Vector<Participant>();
if (site != null)
{
String siteId = site.getId();
String realmId = siteService.siteReference(siteId);
List<String> providerCourseList = SiteParticipantHelper.getProviderCourseList(siteId);
Collection<Participant> rvCopy = SiteParticipantHelper.prepareParticipants(siteId, providerCourseList);
// check with group attendents
if (group != null)
{
// need to remove those inside group already
for(Participant p:rvCopy)
{
if (p.getUniqname() != null && group.getMember(p.getUniqname()) == null)
{
rv.add(p);
}
}
}
else
{
// if the group is null, add all site members
rv.addAll(rvCopy);
}
}
return rv;
}
public Collection<Member> getGroupParticipant()
{
return groupMembers;
}
/**
* Allows the Cancel button to return control to the tool calling this helper
*
*/
public String processCancel() {
// reset the warning messages
resetTargettedMessageList();
ToolSession session = sessionManager.getCurrentToolSession();
session.setAttribute(ATTR_TOP_REFRESH, Boolean.TRUE);
return "done";
}
/**
* Cancel out of the current action and go back to main view
*
*/
public String processBack() {
// reset the warning messages
resetTargettedMessageList();
return "cancel";
}
public String reset() {
try {
siteService.save(site);
EventTrackingService.post(
EventTrackingService.newEvent(SITE_RESET, "/site/" + site.getId(), false));
}
catch (IdUnusedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (PermissionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "";
}
/**
* Adds a new group to the current site
* @param toolId
* @param title
* @return the newly added Group
*/
public String processAddGroup () {
// reset the warning messages
resetTargettedMessageList();
Group group = null;
id = StringUtils.trimToNull(id);
title = StringUtils.trimToNull(title);
if (title == null)
{
//we need something in the title field SAK-21517
messages.addMessage(new TargettedMessage("editgroup.titlemissing",new Object[]{}, TargettedMessage.SEVERITY_ERROR));
return null;
}
else if (title != null && title.length() > SiteConstants.SITE_GROUP_TITLE_LIMIT)
{
messages.addMessage(new TargettedMessage("site_group_title_length_limit",new Object[] { String.valueOf(SiteConstants.SITE_GROUP_TITLE_LIMIT) }, TargettedMessage.SEVERITY_ERROR));
return null;
}
else if (id == null)
{
Collection siteGroups = site.getGroups();
if (siteGroups != null && siteGroups.size() > 0)
{
// when adding a group, check whether the group title has
// been used already
boolean titleExist = false;
for (Iterator iGroups = siteGroups.iterator(); !titleExist
&& iGroups.hasNext();) {
Group iGroup = (Group) iGroups.next();
if (title.equals(iGroup.getTitle())) {
// found same title
titleExist = true;
}
}
if (titleExist) {
messages.addMessage(new TargettedMessage("group.title.same",new Object[] {}, TargettedMessage.SEVERITY_ERROR));
return null;
}
}
}
if (id != null)
{
// editing existing group
group = site.getGroup(id);
}
else
{
// adding a new group
group= site.addGroup();
group.getProperties().addProperty(group.GROUP_PROP_WSETUP_CREATED, Boolean.TRUE.toString());
}
if (group != null)
{
group.setTitle(title);
group.setDescription(description);
boolean found = false;
// remove those no longer included in the group
Set members = group.getMembers();
String[] membersSelected = memberList.split("##");
for (Iterator iMembers = members.iterator(); iMembers
.hasNext();) {
found = false;
String mId = ((Member) iMembers.next()).getUserId();
for (int i = 0; !found && i < membersSelected.length; i++)
{
if (mId.equals(membersSelected[i])) {
found = true;
}
}
if (!found) {
group.removeMember(mId);
}
}
// add those seleted members
for (int i = 0; i < membersSelected.length; i++) {
String memberId = membersSelected[i];
memberId = StringUtils.trimToNull(memberId);
if (memberId != null && group.getUserRole(memberId) == null) {
Role r = site.getUserRole(memberId);
Member m = site.getMember(memberId);
Role memberRole = m != null ? m.getRole() : null;
// for every member added through the "Manage
// Groups" interface, he should be defined as
// non-provided
// get role first from site definition.
// However, if the user is inactive, getUserRole would return null; then use member role instead
group.addMember(memberId, r != null ? r.getId()
: memberRole != null? memberRole.getId() : "", m != null ? m.isActive() : true,
false);
}
}
// save the changes
try
{
siteService.save(site);
// reset the form params
resetParams();
}
catch (IdUnusedException e) {
M_log.warn(this + ".processAddGroup: cannot find site " + site.getId(), e);
return null;
}
catch (PermissionException e) {
M_log.warn(this + ".processAddGroup: cannot find site " + site.getId(), e);
return null;
}
}
return "success";
}
public String processConfirmGroupDelete()
{
// reset the warning messages
resetTargettedMessageList();
if (deleteGroupIds == null || deleteGroupIds.length == 0)
{
// no group chosen to be deleted
M_log.debug(this + ".processConfirmGroupDelete: no group chosen to be deleted.");
messages.addMessage(new TargettedMessage("delete_group_nogroup","no group chosen"));
return null;
}
else
{
List<Group> groups = new Vector<Group>();
for (int i = 0; i < deleteGroupIds.length; i++) {
String groupId = deleteGroupIds[i];
//
Group g = site.getGroup(groupId);
groups.add(g);
}
return "confirm";
}
}
public String processDeleteGroups()
{
// reset the warning messages
resetTargettedMessageList();
if (site != null)
{
for (int i = 0; i < deleteGroupIds.length; i++) {
String groupId = deleteGroupIds[i];
Group g = site.getGroup(groupId);
if (g != null) {
site.removeGroup(g);
}
}
try {
siteService.save(site);
} catch (IdUnusedException e) {
messages.addMessage(new TargettedMessage("editgroup.site.notfound.alert","cannot find site"));
M_log.warn(this + ".processDeleteGroups: Problem of saving site after group removal: site id =" + site.getId(), e);
} catch (PermissionException e) {
messages.addMessage(new TargettedMessage("editgroup.site.permission.alert","not allowed to find site"));
M_log.warn(this + ".processDeleteGroups: Permission problem of saving site after group removal: site id=" + site.getId(), e);
}
}
return "success";
}
public String processCancelDelete()
{
// reset the warning messages
resetTargettedMessageList();
return "cancel";
}
/**
* Removes a group from the site
*
* @param groupId
* @return title of page removed
* @throws IdUnusedException
* @throws PermissionException
*/
public String removeGroup(String groupId)
throws IdUnusedException, PermissionException {
Group group = site.getGroup(groupId);
site.removeGroup(group);
saveSite(site);
EventTrackingService.post(
EventTrackingService.newEvent(GROUP_DELETE, "/site/" + site.getId() +
"/group/" + group.getId(), false));
return group.getTitle();
}
public String[] getDeleteGroupIds() {
return deleteGroupIds;
}
public List<Group> getSelectedGroups()
{
List<Group> rv = new Vector<Group>();
if (deleteGroupIds != null && deleteGroupIds.length > 0 && site != null)
{
for (int i = 0; i<deleteGroupIds.length; i++)
{
String groupId = deleteGroupIds[i];
Group g = site.getGroup(groupId);
rv.add(g);
}
}
return rv;
}
public void setDeleteGroupIds(String[] deleteGroupIds) {
this.deleteGroupIds = deleteGroupIds;
}
/**
* Gets the current tool
* @return Tool
*/
public Tool getCurrentTool() {
return toolManager.getCurrentTool();
}
/**
** Comparator for sorting Group objects
**/
private class GroupComparator implements Comparator {
public int compare(Object o1, Object o2) {
return ((Group)o1).getTitle().compareToIgnoreCase( ((Group)o2).getTitle() );
}
}
}