/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* 12.10.2011 by frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.modules.vitero.ui;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import org.olat.basesecurity.GroupRoles;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.table.ColumnDescriptor;
import org.olat.core.gui.components.table.CustomRenderColumnDescriptor;
import org.olat.core.gui.components.table.TableController;
import org.olat.core.gui.components.table.TableDataModel;
import org.olat.core.gui.components.table.TableEvent;
import org.olat.core.gui.components.table.TableGuiConfiguration;
import org.olat.core.gui.components.table.TableMultiSelectEvent;
import org.olat.core.gui.components.velocity.VelocityContainer;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.controller.BasicController;
import org.olat.core.gui.translator.Translator;
import org.olat.core.id.Identity;
import org.olat.core.id.OLATResourceable;
import org.olat.core.id.UserConstants;
import org.olat.course.CourseFactory;
import org.olat.course.ICourse;
import org.olat.course.groupsandrights.CourseGroupManager;
import org.olat.group.BusinessGroup;
import org.olat.group.BusinessGroupService;
import org.olat.modules.vitero.manager.ViteroManager;
import org.olat.modules.vitero.manager.VmsNotAvailableException;
import org.olat.modules.vitero.model.GroupRole;
import org.olat.modules.vitero.model.ViteroBooking;
import org.olat.modules.vitero.model.ViteroGroupRoles;
import org.olat.modules.vitero.model.ViteroStatus;
import org.olat.repository.RepositoryEntry;
import org.olat.repository.RepositoryManager;
import org.olat.repository.RepositoryService;
import org.olat.user.UserManager;
import org.olat.user.propertyhandlers.UserPropertyHandler;
import org.springframework.beans.factory.annotation.Autowired;
/**
*
* Description:<br>
*
* <P>
* Initial Date: 7 oct. 2011 <br>
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class ViteroUserToGroupController extends BasicController {
private final ViteroBooking booking;
private final BusinessGroup group;
private final OLATResourceable ores;
private final TableController tableCtr;
private final VelocityContainer mainVC;
@Autowired
private ViteroManager viteroManager;
@Autowired
private RepositoryManager repositoryManager;
@Autowired
private RepositoryService repositoryService;
@Autowired
private BusinessGroupService businessGroupService;
private CourseGroupManager courseGroupManager;
public ViteroUserToGroupController(UserRequest ureq, WindowControl wControl, BusinessGroup group, OLATResourceable ores, ViteroBooking booking, boolean readOnly) {
super(ureq, wControl);
this.ores = ores;
this.group = group;
this.booking = booking;
mainVC = createVelocityContainer("user_admin");
TableGuiConfiguration tableConfig = new TableGuiConfiguration();
tableConfig.setTableEmptyMessage(translate("vc.table.empty"));
Translator trans = UserManager.getInstance().getPropertyHandlerTranslator(getTranslator());
tableCtr = new TableController(tableConfig, ureq, getWindowControl(), trans, true);
listenTo(tableCtr);
tableCtr.addColumnDescriptor(getColumnDescriptor(Col.firstName.ordinal(), UserConstants.FIRSTNAME, getLocale()));
tableCtr.addColumnDescriptor(getColumnDescriptor(Col.lastName.ordinal(), UserConstants.LASTNAME, getLocale()));
tableCtr.addColumnDescriptor(getColumnDescriptor(Col.email.ordinal(), UserConstants.EMAIL, getLocale()));
tableCtr.addColumnDescriptor(new CustomRenderColumnDescriptor("user.role", Col.role.ordinal(),null, getLocale(),
ColumnDescriptor.ALIGNMENT_LEFT, new RoleCellRenderer(getTranslator())){
@Override
public int compareTo(int rowa, int rowb) {
Object a = table.getTableDataModel().getValueAt(rowa,dataColumn);
Object b = table.getTableDataModel().getValueAt(rowb,dataColumn);
String r1 = null;
if(a instanceof GroupRole) {
r1 = ((GroupRole)a).name();
} else if(a instanceof String) {
r1 = ("owner".equals(a) || "coach".equals(a)) ? GroupRole.teamleader.name() : (String)a;
}
String r2 = null;
if(b instanceof GroupRole) {
r2 = ((GroupRole)b).name();
} else if(b instanceof String) {
r2 = ("owner".equals(b) || "coach".equals(b)) ? GroupRole.teamleader.name() : (String)b;
}
return super.compareString(r1, r2);
}
});
if(!readOnly) {
tableCtr.addColumnDescriptor(new SignColumnDescriptor("signin", Col.sign.ordinal(), getLocale(), getTranslator()));
tableCtr.addMultiSelectAction("signin", "signin");
tableCtr.addMultiSelectAction("signout", "signout");
}
tableCtr.addMultiSelectAction("reload", "reload");
tableCtr.setMultiSelect(true);
loadModel();
mainVC.put("userTable", tableCtr.getInitialComponent());
putInitialPanel(mainVC);
}
private ColumnDescriptor getColumnDescriptor(int pos, String attrName, Locale locale) {
List<UserPropertyHandler> userPropertyHandlers = UserManager.getInstance().getAllUserPropertyHandlers();
for(UserPropertyHandler handler:userPropertyHandlers) {
if(handler.getName().equals(attrName)) {
return handler.getColumnDescriptor(pos, null, locale);
}
}
return null;
}
@Override
protected void doDispose() {
//
}
@Override
protected void event(UserRequest ureq, Component source, Event event) {
//
}
@Override
protected void event(UserRequest ureq, Controller source, Event event) {
if(source == tableCtr) {
if(event instanceof TableEvent) {
TableEvent e = (TableEvent)event;
int row = e.getRowId();
Identity identity = (Identity)tableCtr.getTableDataModel().getObject(row);
if("signin".equals(e.getActionId())) {
signIn(Collections.singletonList(identity));
} else if("signout".equals(e.getActionId())) {
signOut(Collections.singletonList(identity));
}
} else if(event instanceof TableMultiSelectEvent) {
TableMultiSelectEvent e = (TableMultiSelectEvent)event;
List<Identity> identities = new ArrayList<Identity>();
for (int i = e.getSelection().nextSetBit(0); i >= 0; i = e.getSelection().nextSetBit(i + 1)) {
Identity identity = (Identity)tableCtr.getTableDataModel().getObject(i);
identities.add(identity);
}
if("signin".equals(e.getAction())) {
signIn(identities);
} else if("signout".equals(e.getAction())) {
signOut(identities);
} else if("reload".equals(e.getAction())) {
loadModel();
}
}
}
super.event(ureq, source, event);
}
private void signIn(List<Identity> identities) {
try {
ResourceMembers members = ((UserToGroupDataModel)tableCtr.getTableDataModel()).getMembers();
for(Identity identity:identities) {
boolean upgrade = members.getCoaches().contains(identity) || members.getOwners().contains(identity);
GroupRole role = upgrade ? GroupRole.teamleader : null;
ViteroStatus status = viteroManager.addToRoom(booking, identity, role);
if(status.isOk()) {
showInfo("signin.ok");
} else {
showInfo("signin.nok");
break;
}
}
loadModel();
} catch (VmsNotAvailableException e) {
showError(VmsNotAvailableException.I18N_KEY);
}
}
private void signOut(List<Identity> identities) {
try {
for(Identity identity:identities) {
ViteroStatus status = viteroManager.removeFromRoom(booking, identity);
if(status.isOk()) {
showInfo("signout.ok");
} else {
showInfo("signout.nok");
break;
}
}
loadModel();
} catch (VmsNotAvailableException e) {
showError(VmsNotAvailableException.I18N_KEY);
}
}
private void loadModel() {
try {
ViteroGroupRoles groupRoles = viteroManager.getGroupRoles(booking.getGroupId());
ResourceMembers members = getIdentitiesInResource(groupRoles);
tableCtr.setTableDataModel(new UserToGroupDataModel(members, groupRoles));
int numOfFreePlaces = booking.getRoomSize() - groupRoles.size();
mainVC.contextPut("freePlaces", new String[]{Integer.toString(numOfFreePlaces)});
} catch (VmsNotAvailableException e) {
showError(VmsNotAvailableException.I18N_KEY);
}
}
private ResourceMembers getIdentitiesInResource(ViteroGroupRoles groupRoles) {
Set<Identity> owners = new HashSet<Identity>();
Set<Identity> coaches = new HashSet<Identity>();
Set<Identity> participants = new HashSet<Identity>();
Set<Identity> selfParticipants = new HashSet<Identity>();
if(group != null) {
owners.addAll(businessGroupService.getMembers(group, GroupRoles.coach.name()));
participants.addAll(businessGroupService.getMembers(group, GroupRoles.participant.name()));
} else {
RepositoryEntry repoEntry = repositoryManager.lookupRepositoryEntry(ores, false);
if ("CourseModule".equals(ores.getResourceableTypeName())) {
if(courseGroupManager == null) {
ICourse course = CourseFactory.loadCourse(repoEntry);
courseGroupManager = course.getCourseEnvironment().getCourseGroupManager();
}
coaches.addAll(courseGroupManager.getCoachesFromAreas());
coaches.addAll(courseGroupManager.getCoachesFromBusinessGroups());
participants.addAll(courseGroupManager.getParticipantsFromAreas());
participants.addAll(courseGroupManager.getParticipantsFromBusinessGroups());
}
List<Identity> repoOwners = repositoryService.getMembers(repoEntry, GroupRoles.owner.name());
owners.addAll(repoOwners);
List<Identity> repoParticipants = repositoryService.getMembers(repoEntry, GroupRoles.participant.name());
participants.addAll(repoParticipants);
List<Identity> repoTutors = repositoryService.getMembers(repoEntry, GroupRoles.coach.name());
coaches.addAll(repoTutors);
}
//add all self signed participants
if(booking.isAutoSignIn()) {
List<String> emailsOfParticipants = new ArrayList<>(groupRoles.getEmailsOfParticipants());
//remove owners, coaches and already participating users
for(Identity owner:owners) {
emailsOfParticipants.remove(owner.getUser().getProperty(UserConstants.EMAIL, null));
}
for(Identity coach:coaches) {
emailsOfParticipants.remove(coach.getUser().getProperty(UserConstants.EMAIL, null));
}
for(Identity participant:participants) {
emailsOfParticipants.remove(participant.getUser().getProperty(UserConstants.EMAIL, null));
}
if(!emailsOfParticipants.isEmpty()) {
List<Identity> selfSignedParticipants = UserManager.getInstance().findIdentitiesByEmail(emailsOfParticipants);
selfParticipants.addAll(selfSignedParticipants);
}
}
return new ResourceMembers(owners, coaches, participants, selfParticipants);
}
public class ResourceMembers {
private final List<Identity> owners = new ArrayList<Identity>();
private final List<Identity> coaches = new ArrayList<Identity>();
private final List<Identity> participants = new ArrayList<Identity>();
private final List<Identity> selfParticipants = new ArrayList<Identity>();
public ResourceMembers() {
//
}
public ResourceMembers(Collection<Identity> owners, Collection<Identity> coaches, Collection<Identity> participants,
Collection<Identity> selfParticipants) {
this.owners.addAll(owners);
this.coaches.addAll(coaches);
this.participants.addAll(participants);
this.selfParticipants.addAll(selfParticipants);
//remove duplicates
this.coaches.removeAll(owners);
this.participants.removeAll(owners);
this.participants.removeAll(coaches);
this.selfParticipants.removeAll(owners);
this.selfParticipants.removeAll(coaches);
this.selfParticipants.removeAll(participants);
}
public List<Identity> getOwners() {
return owners;
}
public List<Identity> getCoaches() {
return coaches;
}
public List<Identity> getParticipants() {
return participants;
}
public List<Identity> getSelfParticipants() {
return selfParticipants;
}
}
public class UserToGroupDataModel implements TableDataModel<Identity> {
private ResourceMembers members;
private List<Identity> identities;
private final ViteroGroupRoles groupRoles;
public UserToGroupDataModel(ResourceMembers members, ViteroGroupRoles groupRoles) {
this.members = members;
this.groupRoles = groupRoles;
identities = new ArrayList<Identity>();
identities.addAll(members.getOwners());
identities.addAll(members.getCoaches());
identities.addAll(members.getParticipants());
identities.addAll(members.getSelfParticipants());
}
public ResourceMembers getMembers() {
return members;
}
@Override
public int getColumnCount() {
return 5;
}
@Override
public int getRowCount() {
return identities == null ? 0 : identities.size();
}
@Override
public Object getValueAt(int row, int col) {
Identity identity = getObject(row);
switch(Col.values()[col]) {
case firstName: return identity.getUser().getProperty(UserConstants.FIRSTNAME, null);
case lastName: return identity.getUser().getProperty(UserConstants.LASTNAME, null);
case email: return identity.getUser().getProperty(UserConstants.EMAIL, null);
case role: {
String email = identity.getUser().getProperty(UserConstants.EMAIL, null);
GroupRole role = groupRoles.getEmailsToRole().get(email);
if(role != null) {
return role;
}
if(members == null) return null;
if(members.owners.contains(identity)) {
return "owner";
}
if(members.coaches.contains(identity)) {
return "coach";
}
return null;
}
case sign: {
String email = identity.getUser().getProperty(UserConstants.EMAIL, null);
if(groupRoles.getEmailsOfParticipants().contains(email)) {
return Sign.signout;
}
return Sign.signin;
}
}
return null;
}
@Override
public Identity getObject(int row) {
return identities.get(row);
}
@Override
public void setObjects(List<Identity> objects) {
this.identities = objects;
}
@Override
public Object createCopyWithEmptyList() {
return new UserToGroupDataModel(new ResourceMembers(), groupRoles);
}
}
public enum Col {
firstName,
lastName,
email,
role,
sign,
}
}